@erinjs/core 1.0.0 → 1.2.4

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 (394) hide show
  1. package/{core/LICENSE → LICENSE} +203 -203
  2. package/README.md +46 -0
  3. package/dist/index.d.mts +2084 -0
  4. package/dist/index.d.ts +2084 -0
  5. package/dist/index.js +3867 -0
  6. package/dist/index.mjs +3809 -0
  7. package/package.json +50 -15
  8. package/core/.changeset/README.md +0 -8
  9. package/core/.changeset/community-bootstrap-release.md +0 -17
  10. package/core/.changeset/config.json +0 -11
  11. package/core/.changeset/no-changelog.js +0 -16
  12. package/core/.changeset/pre.json +0 -17
  13. package/core/.editorconfig +0 -13
  14. package/core/.gitattributes +0 -2
  15. package/core/.github/CODE_OF_CONDUCT.md +0 -23
  16. package/core/.github/FUNDING.yml +0 -7
  17. package/core/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  18. package/core/.github/ISSUE_TEMPLATE/feature_request.md +0 -23
  19. package/core/.github/PULL_REQUEST_TEMPLATE.md +0 -16
  20. package/core/.github/dependabot.yml +0 -16
  21. package/core/.github/workflows/autoapp.yml +0 -16
  22. package/core/.github/workflows/ci.yml +0 -187
  23. package/core/.github/workflows/codeql.yml +0 -30
  24. package/core/.github/workflows/deploy-docs.yml +0 -54
  25. package/core/.github/workflows/publish.yml +0 -43
  26. package/core/.lintstagedrc.json +0 -4
  27. package/core/.nvmrc +0 -1
  28. package/core/.prettierignore +0 -8
  29. package/core/.prettierrc +0 -11
  30. package/core/CONTRIBUTING.md +0 -70
  31. package/core/README.md +0 -61
  32. package/core/SECURITY.md +0 -21
  33. package/core/apps/docs/index.html +0 -28
  34. package/core/apps/docs/middleware.ts +0 -21
  35. package/core/apps/docs/package.json +0 -33
  36. package/core/apps/docs/public/@flux.png +0 -0
  37. package/core/apps/docs/public/docs/latest/guides.json +0 -1420
  38. package/core/apps/docs/public/docs/latest/main.json +0 -14981
  39. package/core/apps/docs/public/docs/latest/rag-index.json +0 -1
  40. package/core/apps/docs/public/docs/v1.0.5/guides.json +0 -226
  41. package/core/apps/docs/public/docs/v1.0.5/main.json +0 -7920
  42. package/core/apps/docs/public/docs/v1.0.6/guides.json +0 -226
  43. package/core/apps/docs/public/docs/v1.0.6/main.json +0 -7920
  44. package/core/apps/docs/public/docs/v1.0.7/guides.json +0 -259
  45. package/core/apps/docs/public/docs/v1.0.7/main.json +0 -8652
  46. package/core/apps/docs/public/docs/v1.0.8/guides.json +0 -313
  47. package/core/apps/docs/public/docs/v1.0.8/main.json +0 -9618
  48. package/core/apps/docs/public/docs/v1.0.9/guides.json +0 -319
  49. package/core/apps/docs/public/docs/v1.0.9/main.json +0 -10694
  50. package/core/apps/docs/public/docs/v1.1.0/guides.json +0 -589
  51. package/core/apps/docs/public/docs/v1.1.0/main.json +0 -12576
  52. package/core/apps/docs/public/docs/v1.1.2/guides.json +0 -650
  53. package/core/apps/docs/public/docs/v1.1.2/main.json +0 -13239
  54. package/core/apps/docs/public/docs/v1.1.3/guides.json +0 -650
  55. package/core/apps/docs/public/docs/v1.1.3/main.json +0 -13239
  56. package/core/apps/docs/public/docs/v1.1.4/guides.json +0 -708
  57. package/core/apps/docs/public/docs/v1.1.4/main.json +0 -13231
  58. package/core/apps/docs/public/docs/v1.1.5/guides.json +0 -1035
  59. package/core/apps/docs/public/docs/v1.1.5/main.json +0 -13838
  60. package/core/apps/docs/public/docs/v1.1.6/guides.json +0 -1041
  61. package/core/apps/docs/public/docs/v1.1.6/main.json +0 -14313
  62. package/core/apps/docs/public/docs/v1.1.8/guides.json +0 -1047
  63. package/core/apps/docs/public/docs/v1.1.8/main.json +0 -14421
  64. package/core/apps/docs/public/docs/v1.1.9/guides.json +0 -1047
  65. package/core/apps/docs/public/docs/v1.1.9/main.json +0 -14421
  66. package/core/apps/docs/public/docs/v1.2.0/guides.json +0 -1212
  67. package/core/apps/docs/public/docs/v1.2.0/main.json +0 -14663
  68. package/core/apps/docs/public/docs/v1.2.1/guides.json +0 -1293
  69. package/core/apps/docs/public/docs/v1.2.1/main.json +0 -14828
  70. package/core/apps/docs/public/docs/v1.2.2/guides.json +0 -1293
  71. package/core/apps/docs/public/docs/v1.2.2/main.json +0 -15025
  72. package/core/apps/docs/public/docs/v1.2.3/guides.json +0 -1420
  73. package/core/apps/docs/public/docs/v1.2.3/main.json +0 -14954
  74. package/core/apps/docs/public/docs/v1.2.4/guides.json +0 -1420
  75. package/core/apps/docs/public/docs/v1.2.4/main.json +0 -14981
  76. package/core/apps/docs/public/docs/versions.json +0 -24
  77. package/core/apps/docs/public/flux.png +0 -0
  78. package/core/apps/docs/public/locales/en.json +0 -50
  79. package/core/apps/docs/public/locales/guides-en.json +0 -512
  80. package/core/apps/docs/public/robots.txt +0 -4
  81. package/core/apps/docs/public/sitemap.xml +0 -33
  82. package/core/apps/docs/src/App.vue +0 -538
  83. package/core/apps/docs/src/components/ApiCategorySection.vue +0 -42
  84. package/core/apps/docs/src/components/ApiDiscordCompat.vue +0 -65
  85. package/core/apps/docs/src/components/ApiEndpointCard.vue +0 -313
  86. package/core/apps/docs/src/components/ApiSchemaBlock.vue +0 -131
  87. package/core/apps/docs/src/components/CodeBlock.vue +0 -177
  88. package/core/apps/docs/src/components/CommunityCallout.vue +0 -90
  89. package/core/apps/docs/src/components/ConstructorSection.vue +0 -82
  90. package/core/apps/docs/src/components/DocDescription.vue +0 -40
  91. package/core/apps/docs/src/components/FluxerLogo.vue +0 -3
  92. package/core/apps/docs/src/components/Footer.vue +0 -106
  93. package/core/apps/docs/src/components/GuideCodeBlock.vue +0 -102
  94. package/core/apps/docs/src/components/GuideDiscordCompat.vue +0 -77
  95. package/core/apps/docs/src/components/GuideDiscordCompatCallout.vue +0 -83
  96. package/core/apps/docs/src/components/GuideTable.vue +0 -77
  97. package/core/apps/docs/src/components/GuideTip.vue +0 -38
  98. package/core/apps/docs/src/components/MethodsSection.vue +0 -195
  99. package/core/apps/docs/src/components/ParamsTable.vue +0 -70
  100. package/core/apps/docs/src/components/PropertiesSection.vue +0 -143
  101. package/core/apps/docs/src/components/SearchBar.vue +0 -76
  102. package/core/apps/docs/src/components/SearchModal.vue +0 -361
  103. package/core/apps/docs/src/components/SidebarNav.vue +0 -225
  104. package/core/apps/docs/src/components/SponsorBanner.vue +0 -153
  105. package/core/apps/docs/src/components/TypeSignature.vue +0 -187
  106. package/core/apps/docs/src/components/VersionPicker.vue +0 -191
  107. package/core/apps/docs/src/composables/useSearchIndex.ts +0 -144
  108. package/core/apps/docs/src/composables/useVersionedPath.ts +0 -20
  109. package/core/apps/docs/src/data/apiEndpoints.ts +0 -1073
  110. package/core/apps/docs/src/data/changelog.ts +0 -717
  111. package/core/apps/docs/src/data/guides.ts +0 -2362
  112. package/core/apps/docs/src/env.d.ts +0 -7
  113. package/core/apps/docs/src/locales/guides-en.json +0 -512
  114. package/core/apps/docs/src/main.ts +0 -27
  115. package/core/apps/docs/src/pages/ApiReferenceLayout.vue +0 -175
  116. package/core/apps/docs/src/pages/ApiReferencePage.vue +0 -128
  117. package/core/apps/docs/src/pages/Changelog.vue +0 -288
  118. package/core/apps/docs/src/pages/ClassPage.vue +0 -319
  119. package/core/apps/docs/src/pages/ClassesList.vue +0 -100
  120. package/core/apps/docs/src/pages/DocsLayout.vue +0 -127
  121. package/core/apps/docs/src/pages/GuidePage.vue +0 -279
  122. package/core/apps/docs/src/pages/GuidesIndex.vue +0 -166
  123. package/core/apps/docs/src/pages/GuidesLayout.vue +0 -245
  124. package/core/apps/docs/src/pages/Home.vue +0 -125
  125. package/core/apps/docs/src/pages/NotFound.vue +0 -57
  126. package/core/apps/docs/src/pages/TypedefPage.vue +0 -230
  127. package/core/apps/docs/src/pages/TypedefsList.vue +0 -168
  128. package/core/apps/docs/src/pages/VersionLayout.vue +0 -15
  129. package/core/apps/docs/src/router.ts +0 -73
  130. package/core/apps/docs/src/stores/docs.ts +0 -54
  131. package/core/apps/docs/src/stores/guides.ts +0 -53
  132. package/core/apps/docs/src/stores/version.ts +0 -67
  133. package/core/apps/docs/src/styles/main.css +0 -278
  134. package/core/apps/docs/src/styles/prism.css +0 -95
  135. package/core/apps/docs/src/types/doc-schema.ts +0 -112
  136. package/core/apps/docs/tsconfig.json +0 -17
  137. package/core/apps/docs/tsconfig.node.json +0 -10
  138. package/core/apps/docs/vite.config.d.ts +0 -2
  139. package/core/apps/docs/vite.config.js +0 -26
  140. package/core/apps/docs/vite.config.ts +0 -28
  141. package/core/apps/docs-vitepress/.vitepress/config.ts +0 -141
  142. package/core/apps/docs-vitepress/api-data/latest/main.json +0 -15035
  143. package/core/apps/docs-vitepress/api-data/v1.2.4/main.json +0 -15035
  144. package/core/apps/docs-vitepress/api-data/versions.json +0 -6
  145. package/core/apps/docs-vitepress/index.md +0 -15
  146. package/core/apps/docs-vitepress/package-lock.json +0 -2924
  147. package/core/apps/docs-vitepress/package.json +0 -20
  148. package/core/apps/docs-vitepress/public/CNAME +0 -1
  149. package/core/apps/docs-vitepress/scripts/generate-api.ts +0 -243
  150. package/core/apps/docs-vitepress/scripts/migrate-guides.ts +0 -129
  151. package/core/apps/docs-vitepress/tsconfig.json +0 -11
  152. package/core/apps/docs-vitepress/v/latest/guides/attachments-by-url.md +0 -57
  153. package/core/apps/docs-vitepress/v/latest/guides/attachments.md +0 -62
  154. package/core/apps/docs-vitepress/v/latest/guides/basic-bot.md +0 -49
  155. package/core/apps/docs-vitepress/v/latest/guides/channels.md +0 -180
  156. package/core/apps/docs-vitepress/v/latest/guides/deprecated-apis.md +0 -58
  157. package/core/apps/docs-vitepress/v/latest/guides/discord-js-compatibility.md +0 -42
  158. package/core/apps/docs-vitepress/v/latest/guides/editing-embeds.md +0 -65
  159. package/core/apps/docs-vitepress/v/latest/guides/embed-media.md +0 -87
  160. package/core/apps/docs-vitepress/v/latest/guides/embeds.md +0 -166
  161. package/core/apps/docs-vitepress/v/latest/guides/emojis.md +0 -77
  162. package/core/apps/docs-vitepress/v/latest/guides/events.md +0 -202
  163. package/core/apps/docs-vitepress/v/latest/guides/gifs.md +0 -47
  164. package/core/apps/docs-vitepress/v/latest/guides/installation.md +0 -10
  165. package/core/apps/docs-vitepress/v/latest/guides/moderation.md +0 -89
  166. package/core/apps/docs-vitepress/v/latest/guides/permissions.md +0 -130
  167. package/core/apps/docs-vitepress/v/latest/guides/prefix-commands.md +0 -41
  168. package/core/apps/docs-vitepress/v/latest/guides/profile-urls.md +0 -58
  169. package/core/apps/docs-vitepress/v/latest/guides/reactions.md +0 -69
  170. package/core/apps/docs-vitepress/v/latest/guides/roles.md +0 -130
  171. package/core/apps/docs-vitepress/v/latest/guides/sending-without-reply.md +0 -172
  172. package/core/apps/docs-vitepress/v/latest/guides/voice.md +0 -109
  173. package/core/apps/docs-vitepress/v/latest/guides/wait-for-guilds.md +0 -37
  174. package/core/apps/docs-vitepress/v/latest/guides/webhook-attachments-embeds.md +0 -73
  175. package/core/apps/docs-vitepress/v/latest/guides/webhooks.md +0 -131
  176. package/core/eslint.config.js +0 -80
  177. package/core/examples/.env.example +0 -22
  178. package/core/examples/README.md +0 -68
  179. package/core/examples/first-steps-bot.js +0 -118
  180. package/core/examples/minimal-bot.js +0 -17
  181. package/core/examples/moderation-bot.js +0 -209
  182. package/core/examples/package.json +0 -14
  183. package/core/examples/ping-bot.js +0 -1146
  184. package/core/examples/reaction-bot.js +0 -70
  185. package/core/examples/reaction-roles-bot.js +0 -140
  186. package/core/examples/webhook-bot.js +0 -239
  187. package/core/flux.png +0 -0
  188. package/core/package.json +0 -78
  189. package/core/packages/builders/package.json +0 -51
  190. package/core/packages/builders/src/index.ts +0 -13
  191. package/core/packages/builders/src/messages/AttachmentBuilder.test.ts +0 -79
  192. package/core/packages/builders/src/messages/AttachmentBuilder.ts +0 -69
  193. package/core/packages/builders/src/messages/EmbedBuilder.test.ts +0 -266
  194. package/core/packages/builders/src/messages/EmbedBuilder.ts +0 -239
  195. package/core/packages/builders/src/messages/MessagePayload.test.ts +0 -118
  196. package/core/packages/builders/src/messages/MessagePayload.ts +0 -122
  197. package/core/packages/builders/tsconfig.json +0 -9
  198. package/core/packages/builders/tsup.config.ts +0 -9
  199. package/core/packages/builders/vitest.config.ts +0 -9
  200. package/core/packages/collection/package.json +0 -47
  201. package/core/packages/collection/src/Collection.test.ts +0 -232
  202. package/core/packages/collection/src/Collection.ts +0 -196
  203. package/core/packages/collection/src/index.ts +0 -1
  204. package/core/packages/collection/tsconfig.json +0 -9
  205. package/core/packages/collection/tsup.config.ts +0 -9
  206. package/core/packages/collection/vitest.config.ts +0 -9
  207. package/core/packages/docgen/package.json +0 -26
  208. package/core/packages/docgen/src/extract.ts +0 -262
  209. package/core/packages/docgen/src/formatType.ts +0 -24
  210. package/core/packages/docgen/src/index.ts +0 -103
  211. package/core/packages/docgen/src/schema.ts +0 -100
  212. package/core/packages/docgen/src/visitor.ts +0 -147
  213. package/core/packages/docgen/tsconfig.json +0 -9
  214. package/core/packages/docgen/tsup.config.ts +0 -9
  215. package/core/packages/fluxer-core/README.md +0 -26
  216. package/core/packages/fluxer-core/package.json +0 -60
  217. package/core/packages/fluxer-core/src/client/ChannelManager.ts +0 -143
  218. package/core/packages/fluxer-core/src/client/Client.gateway.test.ts +0 -84
  219. package/core/packages/fluxer-core/src/client/Client.resolveEmoji.test.ts +0 -45
  220. package/core/packages/fluxer-core/src/client/Client.ts +0 -558
  221. package/core/packages/fluxer-core/src/client/ClientUser.ts +0 -40
  222. package/core/packages/fluxer-core/src/client/EventHandlerRegistry.ts +0 -469
  223. package/core/packages/fluxer-core/src/client/GuildManager.ts +0 -79
  224. package/core/packages/fluxer-core/src/client/GuildMemberManager.ts +0 -91
  225. package/core/packages/fluxer-core/src/client/MessageManager.ts +0 -58
  226. package/core/packages/fluxer-core/src/client/UsersManager.ts +0 -122
  227. package/core/packages/fluxer-core/src/errors/ErrorCodes.test.ts +0 -19
  228. package/core/packages/fluxer-core/src/errors/ErrorCodes.ts +0 -12
  229. package/core/packages/fluxer-core/src/errors/FluxerError.test.ts +0 -32
  230. package/core/packages/fluxer-core/src/errors/FluxerError.ts +0 -15
  231. package/core/packages/fluxer-core/src/index.ts +0 -85
  232. package/core/packages/fluxer-core/src/structures/Base.ts +0 -7
  233. package/core/packages/fluxer-core/src/structures/Channel.ts +0 -508
  234. package/core/packages/fluxer-core/src/structures/Guild.test.ts +0 -189
  235. package/core/packages/fluxer-core/src/structures/Guild.ts +0 -734
  236. package/core/packages/fluxer-core/src/structures/GuildBan.ts +0 -35
  237. package/core/packages/fluxer-core/src/structures/GuildEmoji.ts +0 -57
  238. package/core/packages/fluxer-core/src/structures/GuildMember.test.ts +0 -203
  239. package/core/packages/fluxer-core/src/structures/GuildMember.ts +0 -213
  240. package/core/packages/fluxer-core/src/structures/GuildMemberRoleManager.ts +0 -121
  241. package/core/packages/fluxer-core/src/structures/GuildSticker.ts +0 -56
  242. package/core/packages/fluxer-core/src/structures/Invite.test.ts +0 -103
  243. package/core/packages/fluxer-core/src/structures/Invite.ts +0 -121
  244. package/core/packages/fluxer-core/src/structures/Message.test.ts +0 -109
  245. package/core/packages/fluxer-core/src/structures/Message.ts +0 -397
  246. package/core/packages/fluxer-core/src/structures/MessageReaction.ts +0 -72
  247. package/core/packages/fluxer-core/src/structures/PartialMessage.ts +0 -12
  248. package/core/packages/fluxer-core/src/structures/Role.test.ts +0 -77
  249. package/core/packages/fluxer-core/src/structures/Role.ts +0 -112
  250. package/core/packages/fluxer-core/src/structures/User.test.ts +0 -110
  251. package/core/packages/fluxer-core/src/structures/User.ts +0 -109
  252. package/core/packages/fluxer-core/src/structures/Webhook.test.ts +0 -109
  253. package/core/packages/fluxer-core/src/structures/Webhook.ts +0 -258
  254. package/core/packages/fluxer-core/src/util/Constants.test.ts +0 -16
  255. package/core/packages/fluxer-core/src/util/Constants.ts +0 -7
  256. package/core/packages/fluxer-core/src/util/Events.ts +0 -46
  257. package/core/packages/fluxer-core/src/util/MessageCollector.ts +0 -87
  258. package/core/packages/fluxer-core/src/util/Options.ts +0 -33
  259. package/core/packages/fluxer-core/src/util/ReactionCollector.ts +0 -116
  260. package/core/packages/fluxer-core/src/util/cdn.test.ts +0 -108
  261. package/core/packages/fluxer-core/src/util/cdn.ts +0 -130
  262. package/core/packages/fluxer-core/src/util/guildUtils.ts +0 -33
  263. package/core/packages/fluxer-core/src/util/messageUtils.test.ts +0 -74
  264. package/core/packages/fluxer-core/src/util/messageUtils.ts +0 -119
  265. package/core/packages/fluxer-core/src/util/permissions.test.ts +0 -95
  266. package/core/packages/fluxer-core/src/util/permissions.ts +0 -43
  267. package/core/packages/fluxer-core/tsconfig.json +0 -9
  268. package/core/packages/fluxer-core/tsup.config.ts +0 -9
  269. package/core/packages/fluxer-core/vitest.config.ts +0 -9
  270. package/core/packages/rest/package.json +0 -52
  271. package/core/packages/rest/src/REST.test.ts +0 -64
  272. package/core/packages/rest/src/REST.ts +0 -90
  273. package/core/packages/rest/src/RateLimitManager.test.ts +0 -71
  274. package/core/packages/rest/src/RateLimitManager.ts +0 -60
  275. package/core/packages/rest/src/RequestManager.test.ts +0 -87
  276. package/core/packages/rest/src/RequestManager.ts +0 -172
  277. package/core/packages/rest/src/errors/FluxerAPIError.test.ts +0 -57
  278. package/core/packages/rest/src/errors/FluxerAPIError.ts +0 -21
  279. package/core/packages/rest/src/errors/HTTPError.test.ts +0 -55
  280. package/core/packages/rest/src/errors/HTTPError.ts +0 -25
  281. package/core/packages/rest/src/errors/RateLimitError.test.ts +0 -41
  282. package/core/packages/rest/src/errors/RateLimitError.ts +0 -15
  283. package/core/packages/rest/src/errors/index.ts +0 -3
  284. package/core/packages/rest/src/index.ts +0 -6
  285. package/core/packages/rest/src/utils/constants.test.ts +0 -31
  286. package/core/packages/rest/src/utils/constants.ts +0 -5
  287. package/core/packages/rest/src/utils/files.test.ts +0 -37
  288. package/core/packages/rest/src/utils/files.ts +0 -75
  289. package/core/packages/rest/tsconfig.json +0 -9
  290. package/core/packages/rest/tsup.config.ts +0 -9
  291. package/core/packages/rest/vitest.config.ts +0 -9
  292. package/core/packages/types/package.json +0 -46
  293. package/core/packages/types/src/api/ban.ts +0 -8
  294. package/core/packages/types/src/api/channel.ts +0 -65
  295. package/core/packages/types/src/api/embed.ts +0 -82
  296. package/core/packages/types/src/api/emoji.ts +0 -12
  297. package/core/packages/types/src/api/errors.ts +0 -68
  298. package/core/packages/types/src/api/gateway.ts +0 -14
  299. package/core/packages/types/src/api/guild.ts +0 -123
  300. package/core/packages/types/src/api/index.ts +0 -15
  301. package/core/packages/types/src/api/instance.ts +0 -32
  302. package/core/packages/types/src/api/interaction.ts +0 -26
  303. package/core/packages/types/src/api/invite.ts +0 -28
  304. package/core/packages/types/src/api/message.ts +0 -140
  305. package/core/packages/types/src/api/role.ts +0 -41
  306. package/core/packages/types/src/api/sticker.ts +0 -14
  307. package/core/packages/types/src/api/user.ts +0 -79
  308. package/core/packages/types/src/api/webhook.ts +0 -41
  309. package/core/packages/types/src/common/index.ts +0 -1
  310. package/core/packages/types/src/common/snowflake.test.ts +0 -9
  311. package/core/packages/types/src/common/snowflake.ts +0 -8
  312. package/core/packages/types/src/gateway/events.ts +0 -189
  313. package/core/packages/types/src/gateway/index.ts +0 -3
  314. package/core/packages/types/src/gateway/opcodes.ts +0 -17
  315. package/core/packages/types/src/gateway/payloads.ts +0 -481
  316. package/core/packages/types/src/index.ts +0 -4
  317. package/core/packages/types/src/rest/index.ts +0 -1
  318. package/core/packages/types/src/rest/routes.test.ts +0 -169
  319. package/core/packages/types/src/rest/routes.ts +0 -109
  320. package/core/packages/types/tsconfig.json +0 -9
  321. package/core/packages/types/tsup.config.ts +0 -9
  322. package/core/packages/types/vitest.config.ts +0 -9
  323. package/core/packages/util/package.json +0 -51
  324. package/core/packages/util/src/BitField.test.ts +0 -96
  325. package/core/packages/util/src/BitField.ts +0 -105
  326. package/core/packages/util/src/MessageFlagsBitField.test.ts +0 -42
  327. package/core/packages/util/src/MessageFlagsBitField.ts +0 -20
  328. package/core/packages/util/src/PermissionsBitField.test.ts +0 -79
  329. package/core/packages/util/src/PermissionsBitField.ts +0 -97
  330. package/core/packages/util/src/SnowflakeUtil.test.ts +0 -69
  331. package/core/packages/util/src/SnowflakeUtil.ts +0 -65
  332. package/core/packages/util/src/UserFlagsBitField.test.ts +0 -39
  333. package/core/packages/util/src/UserFlagsBitField.ts +0 -48
  334. package/core/packages/util/src/deprecation.test.ts +0 -44
  335. package/core/packages/util/src/deprecation.ts +0 -28
  336. package/core/packages/util/src/emojiShortcodes.generated.ts +0 -5
  337. package/core/packages/util/src/emojiShortcodes.test.ts +0 -41
  338. package/core/packages/util/src/emojiShortcodes.ts +0 -22
  339. package/core/packages/util/src/formatters.test.ts +0 -65
  340. package/core/packages/util/src/formatters.ts +0 -35
  341. package/core/packages/util/src/index.ts +0 -34
  342. package/core/packages/util/src/resolvers.test.ts +0 -198
  343. package/core/packages/util/src/resolvers.ts +0 -127
  344. package/core/packages/util/src/tenorUtils.test.ts +0 -75
  345. package/core/packages/util/src/tenorUtils.ts +0 -86
  346. package/core/packages/util/tsconfig.json +0 -9
  347. package/core/packages/util/tsup.config.ts +0 -9
  348. package/core/packages/util/vitest.config.ts +0 -9
  349. package/core/packages/voice/README.md +0 -42
  350. package/core/packages/voice/package.json +0 -67
  351. package/core/packages/voice/src/LiveKitRtcConnection.receive.test.ts +0 -24
  352. package/core/packages/voice/src/LiveKitRtcConnection.ts +0 -1767
  353. package/core/packages/voice/src/VoiceConnection.ts +0 -413
  354. package/core/packages/voice/src/VoiceManager.receive.test.ts +0 -61
  355. package/core/packages/voice/src/VoiceManager.test.ts +0 -44
  356. package/core/packages/voice/src/VoiceManager.ts +0 -503
  357. package/core/packages/voice/src/exports.test.ts +0 -38
  358. package/core/packages/voice/src/index.ts +0 -51
  359. package/core/packages/voice/src/livekit.test.ts +0 -48
  360. package/core/packages/voice/src/livekit.ts +0 -33
  361. package/core/packages/voice/src/mp4box.d.ts +0 -32
  362. package/core/packages/voice/src/opusUtils.test.ts +0 -29
  363. package/core/packages/voice/src/opusUtils.ts +0 -86
  364. package/core/packages/voice/src/streamPreviewPlaceholder.test.ts +0 -16
  365. package/core/packages/voice/src/streamPreviewPlaceholder.ts +0 -8
  366. package/core/packages/voice/src/ws.d.ts +0 -1
  367. package/core/packages/voice/tsconfig.json +0 -5
  368. package/core/packages/voice/tsup.config.ts +0 -10
  369. package/core/packages/voice/vitest.config.ts +0 -9
  370. package/core/packages/ws/package.json +0 -52
  371. package/core/packages/ws/src/WebSocketManager.ts +0 -130
  372. package/core/packages/ws/src/WebSocketShard.ts +0 -296
  373. package/core/packages/ws/src/index.ts +0 -12
  374. package/core/packages/ws/src/utils/constants.test.ts +0 -46
  375. package/core/packages/ws/src/utils/constants.ts +0 -22
  376. package/core/packages/ws/src/utils/getWebSocket.ts +0 -55
  377. package/core/packages/ws/src/ws.d.ts +0 -10
  378. package/core/packages/ws/tsconfig.json +0 -9
  379. package/core/packages/ws/tsup.config.ts +0 -9
  380. package/core/pnpm-lock.yaml +0 -7033
  381. package/core/pnpm-workspace.yaml +0 -4
  382. package/core/scripts/generate-ai-rag.ts +0 -240
  383. package/core/scripts/generate-docs.ts +0 -143
  384. package/core/scripts/generate-emoji-shortcodes.ts +0 -58
  385. package/core/scripts/generate-types.ts +0 -6
  386. package/core/scripts/publish-ordered.js +0 -63
  387. package/core/scripts/test-cjs-require.mjs +0 -43
  388. package/core/scripts/test-esm-imports.mjs +0 -42
  389. package/core/scripts/test-package-exports.mjs +0 -98
  390. package/core/scripts/test-smoke.mjs +0 -103
  391. package/core/tsconfig.json +0 -18
  392. package/core/turbo.json +0 -30
  393. package/core/vitest.config.ts +0 -17
  394. package/core/wrangler.jsonc +0 -9
@@ -1,32 +0,0 @@
1
- declare module 'mp4box' {
2
- export interface MP4File {
3
- onReady?: (info: {
4
- tracks?: Array<{
5
- id: number;
6
- type: string;
7
- codec: string;
8
- video?: { width: number; height: number };
9
- timescale?: number;
10
- }>;
11
- }) => void;
12
- onError?: (e: Error) => void;
13
- onSamples?: (
14
- trackId: number,
15
- user: unknown,
16
- samples: Array<{
17
- data: ArrayBuffer;
18
- is_sync?: boolean;
19
- is_rap?: boolean;
20
- timescale: number;
21
- dts: number;
22
- duration: number;
23
- }>,
24
- ) => void;
25
- appendBuffer(data: ArrayBuffer): number;
26
- flush(): void;
27
- setExtractionOptions(trackId: number, user: unknown, options: { nbSamples?: number }): void;
28
- start(): void;
29
- }
30
-
31
- export function createFile(): MP4File;
32
- }
@@ -1,29 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { parseOpusPacketBoundaries } from './opusUtils.js';
3
-
4
- describe('parseOpusPacketBoundaries', () => {
5
- it('returns null for buffer shorter than 2 bytes', () => {
6
- expect(parseOpusPacketBoundaries(new Uint8Array([]))).toBeNull();
7
- expect(parseOpusPacketBoundaries(new Uint8Array([0]))).toBeNull();
8
- });
9
-
10
- it('returns single frame for c=0 (one frame)', () => {
11
- const buf = new Uint8Array([0x78, 0x01, 0x02, 0x03]); // c=0
12
- const result = parseOpusPacketBoundaries(buf);
13
- expect(result).not.toBeNull();
14
- expect(result!.frames).toHaveLength(1);
15
- expect(result!.consumed).toBe(4);
16
- });
17
-
18
- it('returns null for c=1 when not enough data', () => {
19
- const buf = new Uint8Array([0x79, 0x05]); // c=1, L1=5, need 2+5+1=8 min
20
- expect(parseOpusPacketBoundaries(buf)).toBeNull();
21
- });
22
-
23
- it('handles c=2 (two frames CBR)', () => {
24
- const buf = new Uint8Array([0x7a, 0x00, 0x01, 0x02, 0x03, 0x04]); // c=2, 4 bytes data -> 2 per frame
25
- const result = parseOpusPacketBoundaries(buf);
26
- expect(result).not.toBeNull();
27
- expect(result!.frames).toHaveLength(2);
28
- });
29
- });
@@ -1,86 +0,0 @@
1
- /**
2
- * Shared Opus parsing utilities for voice connections.
3
- */
4
-
5
- /**
6
- * Parse Opus packet (RFC 6716) and return single-frame packets for decodeFrame().
7
- * TOC byte: config (0-4), s (5), c (6-7). c=0: 1 frame; c=1: 2 frames + 1 length byte; c=2: 2 frames CBR + padding; c=3: N frames + (N-1) length bytes.
8
- * Returns { frames: Uint8Array[], consumed } or null if not enough data.
9
- */
10
- export function parseOpusPacketBoundaries(
11
- buffer: Uint8Array,
12
- ): { frames: Uint8Array[]; consumed: number } | null {
13
- if (buffer.length < 2) return null;
14
- const toc = buffer[0];
15
- const c = toc & 3; // frame count code
16
- const tocSingle = (toc & 0xfc) | 0; // same config/s, one frame
17
-
18
- if (c === 0) {
19
- return { frames: [buffer.slice()], consumed: buffer.length };
20
- }
21
-
22
- if (c === 1) {
23
- if (buffer.length < 2) return null;
24
- const L1 = buffer[1] + 1;
25
- if (buffer.length < 2 + L1) return null;
26
- const L2 = buffer.length - 2 - L1;
27
- const frame0 = new Uint8Array(1 + L1);
28
- frame0[0] = tocSingle;
29
- frame0.set(buffer.subarray(2, 2 + L1), 1);
30
- const frame1 = new Uint8Array(1 + L2);
31
- frame1[0] = tocSingle;
32
- frame1.set(buffer.subarray(2 + L1), 1);
33
- return { frames: [frame0, frame1], consumed: buffer.length };
34
- }
35
-
36
- if (c === 2) {
37
- if (buffer.length < 3) return null;
38
- const frameLen = Math.floor((buffer.length - 2) / 2);
39
- if (frameLen < 1) return null;
40
- const frame0 = new Uint8Array(1 + frameLen);
41
- frame0[0] = tocSingle;
42
- frame0.set(buffer.subarray(2, 2 + frameLen), 1);
43
- const frame1 = new Uint8Array(1 + frameLen);
44
- frame1[0] = tocSingle;
45
- frame1.set(buffer.subarray(2 + frameLen, 2 + 2 * frameLen), 1);
46
- return { frames: [frame0, frame1], consumed: 2 + 2 * frameLen };
47
- }
48
-
49
- if (c === 3) {
50
- if (buffer.length < 2) return null;
51
- const N = buffer[1];
52
- if (N < 1 || N > 255) return null;
53
- const numLengthBytes = N - 1;
54
- if (buffer.length < 2 + numLengthBytes) return null;
55
- const lengths: number[] = [];
56
- for (let i = 0; i < numLengthBytes; i++) {
57
- lengths.push(buffer[2 + i] + 1);
58
- }
59
- const headerLen = 2 + numLengthBytes;
60
- let offset = headerLen;
61
- const sumKnown = lengths.reduce((a, b) => a + b, 0);
62
- const lastLen = buffer.length - headerLen - sumKnown;
63
- if (lastLen < 0) return null;
64
- lengths.push(lastLen);
65
- const frames: Uint8Array[] = [];
66
- for (let i = 0; i < lengths.length; i++) {
67
- const L = lengths[i];
68
- if (offset + L > buffer.length) return null;
69
- const frame = new Uint8Array(1 + L);
70
- frame[0] = tocSingle;
71
- frame.set(buffer.subarray(offset, offset + L), 1);
72
- frames.push(frame);
73
- offset += L;
74
- }
75
- return { frames, consumed: offset };
76
- }
77
-
78
- return null;
79
- }
80
-
81
- export function concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array {
82
- const out = new Uint8Array(a.length + b.length);
83
- out.set(a);
84
- out.set(b, a.length);
85
- return out;
86
- }
@@ -1,16 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { thumbnail } from './streamPreviewPlaceholder.js';
3
-
4
- describe('streamPreviewPlaceholder', () => {
5
- it('exports valid base64 string', () => {
6
- expect(typeof thumbnail).toBe('string');
7
- expect(thumbnail.length).toBeGreaterThan(0);
8
- });
9
-
10
- it('decodes to valid PNG header', () => {
11
- const decoded = Buffer.from(thumbnail, 'base64');
12
- expect(decoded[0]).toBe(0x89);
13
- expect(decoded[1]).toBe(0x50);
14
- expect(decoded[2]).toBe(0x4e);
15
- });
16
- });
@@ -1,8 +0,0 @@
1
- /**
2
- * Minimal 1x1 grey PNG as base64 for stream preview placeholder.
3
- * Used when uploading preview before actual frames are available.
4
- */
5
- const MINIMAL_PNG_BASE64 =
6
- 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==';
7
-
8
- export const thumbnail = MINIMAL_PNG_BASE64;
@@ -1 +0,0 @@
1
- declare module 'ws';
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": { "outDir": "./dist", "rootDir": "./src", "noEmit": false },
4
- "include": ["src/**/*"]
5
- }
@@ -1,10 +0,0 @@
1
- import { defineConfig } from 'tsup';
2
-
3
- export default defineConfig({
4
- entry: ['src/index.ts'],
5
- format: ['cjs', 'esm'],
6
- dts: true,
7
- splitting: false,
8
- clean: true,
9
- external: ['node-webcodecs'],
10
- });
@@ -1,9 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- include: ['src/**/*.test.ts'],
8
- },
9
- });
@@ -1,52 +0,0 @@
1
- {
2
- "name": "@erinjs/ws",
3
- "publishConfig": {
4
- "access": "public"
5
- },
6
- "version": "1.2.4",
7
- "description": "WebSocket manager for the Fluxer Gateway",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/blstmo-abandoned-us-for-the-milk/core.git",
11
- "directory": "packages/ws"
12
- },
13
- "bugs": "https://github.com/blstmo-abandoned-us-for-the-milk/core/issues",
14
- "homepage": "https://github.com/blstmo-abandoned-us-for-the-milk/core#readme",
15
- "keywords": [
16
- "fluxer",
17
- "websocket",
18
- "gateway",
19
- "sdk"
20
- ],
21
- "license": "Apache-2.0",
22
- "main": "./dist/index.js",
23
- "module": "./dist/index.mjs",
24
- "types": "./dist/index.d.ts",
25
- "exports": {
26
- ".": {
27
- "types": "./dist/index.d.ts",
28
- "import": "./dist/index.mjs",
29
- "require": "./dist/index.js"
30
- }
31
- },
32
- "files": [
33
- "dist"
34
- ],
35
- "scripts": {
36
- "build": "tsup",
37
- "clean": "rm -rf dist",
38
- "lint": "eslint src --max-warnings 0 --config ../../eslint.config.js",
39
- "lint:fix": "eslint src --fix --config ../../eslint.config.js",
40
- "test": "vitest run --passWithNoTests",
41
- "test:coverage": "vitest run --coverage --passWithNoTests"
42
- },
43
- "dependencies": {
44
- "@erinjs/types": "workspace:*",
45
- "ws": "^8.18.0"
46
- },
47
- "devDependencies": {
48
- "@types/node": "^20.0.0",
49
- "tsup": "^8.3.0",
50
- "typescript": "^5.6.0"
51
- }
52
- }
@@ -1,130 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- import { APIGatewayBotResponse, GatewayPresenceUpdateData } from '@erinjs/types';
3
- import { WebSocketShard } from './WebSocketShard.js';
4
- import { getDefaultWebSocket } from './utils/getWebSocket.js';
5
-
6
- import { WebSocketConstructor as WSConstructor } from './WebSocketShard';
7
-
8
- export type WebSocketConstructor = WSConstructor;
9
-
10
- const RETRY_INITIAL_MS = 1000;
11
- const RETRY_MAX_MS = 45000;
12
-
13
- function sleep(ms: number): Promise<void> {
14
- return new Promise((resolve) => setTimeout(resolve, ms));
15
- }
16
-
17
- export interface WebSocketManagerOptions {
18
- token: string;
19
- intents: number;
20
- rest: { get: (route: string) => Promise<unknown> };
21
- version?: string;
22
- presence?: GatewayPresenceUpdateData;
23
- shardIds?: number[];
24
- shardCount?: number;
25
- WebSocket?: WebSocketConstructor;
26
- }
27
-
28
- export class WebSocketManager extends EventEmitter {
29
- private readonly options: WebSocketManagerOptions;
30
- private shards = new Map<number, WebSocketShard>();
31
- private gatewayUrl: string | null = null;
32
- private shardCount = 1;
33
- private _aborted = false;
34
-
35
- constructor(options: WebSocketManagerOptions) {
36
- super();
37
- this.options = options;
38
- }
39
-
40
- async connect(): Promise<void> {
41
- this._aborted = false;
42
-
43
- let WS = this.options.WebSocket;
44
- let delayMs = RETRY_INITIAL_MS;
45
-
46
- if (!WS) {
47
- while (!this._aborted) {
48
- try {
49
- WS = await getDefaultWebSocket();
50
- break;
51
- } catch (err) {
52
- const e = err instanceof Error ? err : new Error(String(err));
53
- this.emit('error', { shardId: -1, error: e });
54
- await sleep(delayMs);
55
- delayMs = Math.min(RETRY_MAX_MS, Math.floor(delayMs * 1.5));
56
- }
57
- }
58
- if (this._aborted) throw new Error('Connection aborted');
59
- if (!WS) throw new Error('Failed to load WebSocket');
60
- }
61
-
62
- let gateway: APIGatewayBotResponse | null = null;
63
- while (!this._aborted) {
64
- try {
65
- gateway = (await this.options.rest.get('/gateway/bot')) as APIGatewayBotResponse;
66
- break;
67
- } catch (err) {
68
- const e = err instanceof Error ? err : new Error(String(err));
69
- this.emit('error', { shardId: -1, error: e });
70
- await sleep(delayMs);
71
- delayMs = Math.min(RETRY_MAX_MS, Math.floor(delayMs * 1.5));
72
- }
73
- }
74
-
75
- if (this._aborted) throw new Error('Connection aborted');
76
- if (!gateway) throw new Error('Failed to fetch gateway');
77
-
78
- this.gatewayUrl = gateway.url;
79
- this.shardCount = this.options.shardCount ?? gateway.shards;
80
-
81
- const ids = this.options.shardIds ?? [...Array(this.shardCount).keys()];
82
-
83
- const version = this.options.version ?? '1';
84
-
85
- for (const id of ids) {
86
- const shard = new WebSocketShard({
87
- url: this.gatewayUrl ?? gateway.url,
88
- token: this.options.token,
89
- intents: this.options.intents,
90
- presence: this.options.presence,
91
- shardId: id,
92
- numShards: this.shardCount,
93
- version,
94
- WebSocket: WS,
95
- });
96
-
97
- shard.on('ready', (data) => this.emit('ready', { shardId: id, data }));
98
- shard.on('resumed', () => this.emit('resumed', id));
99
- shard.on('dispatch', (payload) => this.emit('dispatch', { shardId: id, payload }));
100
- shard.on('close', (code) => this.emit('close', { shardId: id, code }));
101
- shard.on('error', (err) => this.emit('error', { shardId: id, error: err }));
102
- shard.on('debug', (msg) => this.emit('debug', msg));
103
-
104
- this.shards.set(id, shard);
105
- try {
106
- shard.connect();
107
- } catch (err) {
108
- this.emit('error', {
109
- shardId: id,
110
- error: err instanceof Error ? err : new Error(String(err)),
111
- });
112
- }
113
- }
114
- }
115
-
116
- send(shardId: number, payload: Parameters<WebSocketShard['send']>[0]): void {
117
- this.shards.get(shardId)?.send(payload);
118
- }
119
-
120
- destroy(): void {
121
- this._aborted = true;
122
- for (const shard of this.shards.values()) shard.destroy();
123
- this.shards.clear();
124
- this.gatewayUrl = null;
125
- }
126
-
127
- getShardCount(): number {
128
- return this.shardCount;
129
- }
130
- }
@@ -1,296 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- import {
3
- GatewaySendPayload,
4
- GatewayHelloData,
5
- GatewayReceivePayload,
6
- GatewayIdentifyData,
7
- GatewayResumeData,
8
- GatewayPresenceUpdateData,
9
- } from '@erinjs/types';
10
- import { GatewayOpcodes } from '@erinjs/types';
11
- import { getDefaultWebSocketSync } from './utils/getWebSocket.js';
12
-
13
- export type WebSocketLike = {
14
- send(data: string | ArrayBufferLike): void;
15
- close(code?: number): void;
16
- readyState: number;
17
- addEventListener?(type: string, listener: (e: unknown) => void): void;
18
- on?(event: string, cb: (data?: unknown) => void): void;
19
- };
20
- export type WebSocketConstructor = new (url: string) => WebSocketLike;
21
-
22
- export interface WebSocketShardOptions {
23
- url: string;
24
- token: string;
25
- intents: number;
26
- presence?: GatewayPresenceUpdateData;
27
- shardId: number;
28
- numShards: number;
29
- /** Gateway API version (e.g. "1" for Fluxer). Defaults to "1" when not set. */
30
- version?: string;
31
- WebSocket?: WebSocketConstructor;
32
- }
33
-
34
- export interface WebSocketShardEvents {
35
- ready: [payload: unknown];
36
- resumed: [];
37
- dispatch: [payload: GatewayReceivePayload];
38
- close: [code: number];
39
- error: [error: Error];
40
- debug: [message: string];
41
- }
42
-
43
- const RECONNECT_INITIAL_MS = 1000;
44
- const RECONNECT_MAX_MS = 45000;
45
-
46
- export class WebSocketShard extends EventEmitter {
47
- private ws: WebSocketLike | null = null;
48
- private readonly options: WebSocketShardOptions;
49
- private heartbeatInterval: ReturnType<typeof setInterval> | null = null;
50
- private heartbeatAt = 0;
51
- /** True until we send a heartbeat; then false until we get HeartbeatAck. Avoids closing before first heartbeat. */
52
- private lastHeartbeatAck = true;
53
- private sessionId: string | null = null;
54
- private seq: number | null = null;
55
- private destroying = false;
56
- private readonly url: string;
57
- private readonly WS: WebSocketConstructor;
58
- /** Current reconnect delay in ms; resets on successful connect. */
59
- private reconnectDelayMs = RECONNECT_INITIAL_MS;
60
- private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;
61
-
62
- private scheduleReconnect(): void {
63
- if (this.destroying) return;
64
- if (this.reconnectTimeout !== null) return;
65
- const delay = Math.min(RECONNECT_MAX_MS, this.reconnectDelayMs * (0.75 + Math.random() * 0.5));
66
- this.reconnectDelayMs = Math.min(RECONNECT_MAX_MS, this.reconnectDelayMs * 1.5);
67
- this.debug(`Reconnecting in ${Math.round(delay)}ms…`);
68
- this.reconnectTimeout = setTimeout(() => {
69
- this.reconnectTimeout = null;
70
- this.connect();
71
- }, delay);
72
- }
73
-
74
- constructor(options: WebSocketShardOptions) {
75
- super();
76
- this.options = options;
77
- this.WS = options.WebSocket ?? (getDefaultWebSocketSync() as unknown as WebSocketConstructor);
78
- const version = options.version ?? '1';
79
- const params = new URLSearchParams({ v: version, encoding: 'json' });
80
- this.url = `${options.url}?${params}`;
81
- }
82
-
83
- get id(): number {
84
- return this.options.shardId;
85
- }
86
-
87
- get status(): number {
88
- if (!this.ws) return 0; // Idle
89
- switch (this.ws.readyState) {
90
- case 0:
91
- return 1; // Connecting
92
- case 1:
93
- return 2; // Ready
94
- case 2:
95
- return 3; // Closing
96
- case 3:
97
- return 0;
98
- default:
99
- return 0;
100
- }
101
- }
102
-
103
- connect(): void {
104
- if (this.ws?.readyState === 1) return;
105
- this.destroying = false;
106
- this.debug('Connecting');
107
- const ws = new this.WS(this.url);
108
- this.ws = ws;
109
-
110
- const handleMessage = (data: string | Buffer) => {
111
- try {
112
- const str = typeof data === 'string' ? data : (data as Buffer).toString();
113
- this.handlePayload(JSON.parse(str) as GatewayReceivePayload);
114
- } catch (err) {
115
- this.emit('error', err instanceof Error ? err : new Error(String(err)));
116
- }
117
- };
118
-
119
- const handleClose = (code: number) => {
120
- this.ws = null;
121
- this.stopHeartbeat();
122
- this.emit('close', code);
123
- this.debug(`Closed: ${code}`);
124
- if (!this.destroying && shouldReconnectOnClose(code)) {
125
- this.scheduleReconnect();
126
- }
127
- };
128
-
129
- const handleError = (err?: unknown) => {
130
- const error = err instanceof Error ? err : new Error('WebSocket error');
131
- this.emit('error', error);
132
- if (!this.destroying && this.ws) {
133
- this.ws = null;
134
- this.stopHeartbeat();
135
- this.debug('Connection error; will retry…');
136
- this.scheduleReconnect();
137
- }
138
- };
139
-
140
- const handleOpen = () => {
141
- this.debug('Socket open');
142
- this.reconnectDelayMs = RECONNECT_INITIAL_MS;
143
- };
144
-
145
- if (typeof ws.addEventListener === 'function') {
146
- ws.addEventListener('open', handleOpen);
147
- ws.addEventListener('message', (e: unknown) =>
148
- handleMessage((e as MessageEvent).data as string),
149
- );
150
- ws.addEventListener('close', (e: unknown) => handleClose((e as CloseEvent).code));
151
- ws.addEventListener('error', () => handleError(new Error('WebSocket error')));
152
- } else if (typeof ws.on === 'function') {
153
- ws.on('open', handleOpen);
154
- ws.on('message', (d: unknown) => handleMessage(d as Buffer | string));
155
- ws.on('close', (code?: unknown) => handleClose((code as number) ?? 1006));
156
- ws.on('error', (err?: unknown) => handleError(err));
157
- }
158
- }
159
-
160
- private debug(message: string): void {
161
- this.emit('debug', `[Shard ${this.id}] ${message}`);
162
- }
163
-
164
- private handlePayload(payload: GatewayReceivePayload): void {
165
- switch (payload.op) {
166
- case GatewayOpcodes.Hello:
167
- this.handleHello(payload.d as GatewayHelloData);
168
- break;
169
- case GatewayOpcodes.HeartbeatAck:
170
- this.lastHeartbeatAck = true;
171
- break;
172
- case GatewayOpcodes.Dispatch:
173
- if (payload.t === 'READY') {
174
- const d = payload.d as { session_id: string };
175
- this.sessionId = d.session_id;
176
- this.reconnectDelayMs = RECONNECT_INITIAL_MS;
177
- this.emit('ready', payload.d);
178
- } else if (payload.t === 'RESUMED') {
179
- this.reconnectDelayMs = RECONNECT_INITIAL_MS;
180
- this.emit('resumed');
181
- }
182
- if (payload.s !== undefined) this.seq = payload.s;
183
- this.emit('dispatch', payload);
184
- break;
185
- case GatewayOpcodes.InvalidSession:
186
- this.debug(`Invalid session (d=${payload.d}), reconnecting`);
187
- this.sessionId = null;
188
- this.seq = null;
189
- this.ws?.close(1000);
190
- // Let handleClose() own reconnect scheduling for this close.
191
- break;
192
- case GatewayOpcodes.Reconnect:
193
- this.debug('Reconnect requested');
194
- this.ws?.close(1000);
195
- setTimeout(() => this.connect(), 100);
196
- break;
197
- default:
198
- break;
199
- }
200
- }
201
-
202
- private handleHello(data: GatewayHelloData): void {
203
- const jitter = Math.random() * data.heartbeat_interval;
204
- this.heartbeatAt = Date.now() + jitter;
205
- this.startHeartbeat(data.heartbeat_interval);
206
-
207
- if (this.sessionId && this.seq !== null) {
208
- this.send({
209
- op: GatewayOpcodes.Resume,
210
- d: {
211
- token: this.options.token,
212
- session_id: this.sessionId,
213
- seq: this.seq,
214
- } as GatewayResumeData,
215
- });
216
- } else {
217
- const identify: GatewayIdentifyData = {
218
- token: this.options.token,
219
- intents: this.options.intents,
220
- properties: {
221
- os: process.platform ?? 'unknown',
222
- browser: 'erin.js',
223
- device: 'erin.js',
224
- },
225
- };
226
- if (this.options.presence) identify.presence = this.options.presence;
227
- this.send({ op: GatewayOpcodes.Identify, d: identify });
228
- }
229
- }
230
-
231
- private startHeartbeat(interval: number): void {
232
- this.stopHeartbeat();
233
- this.lastHeartbeatAck = true; // no heartbeat sent yet → don't treat as missed ack
234
- this.heartbeatInterval = setInterval(() => {
235
- if (!this.lastHeartbeatAck && this.seq !== null) {
236
- this.debug('Heartbeat ack missed; reconnecting');
237
- this.ws?.close(1000);
238
- if (!this.destroying) this.scheduleReconnect();
239
- return;
240
- }
241
- this.lastHeartbeatAck = false;
242
- this.send({ op: GatewayOpcodes.Heartbeat, d: this.seq ?? null });
243
- }, interval);
244
- }
245
-
246
- private stopHeartbeat(): void {
247
- if (this.heartbeatInterval) {
248
- clearInterval(this.heartbeatInterval);
249
- this.heartbeatInterval = null;
250
- }
251
- }
252
-
253
- send(payload: GatewaySendPayload): void {
254
- if (this.ws?.readyState !== 1) return;
255
- this.ws.send(JSON.stringify(payload));
256
- }
257
-
258
- destroy(): void {
259
- this.destroying = true;
260
- if (this.reconnectTimeout) {
261
- clearTimeout(this.reconnectTimeout);
262
- this.reconnectTimeout = null;
263
- }
264
- this.stopHeartbeat();
265
- this.ws?.close(1000);
266
- this.ws = null;
267
- this.sessionId = null;
268
- this.seq = null;
269
- }
270
- }
271
-
272
- /** Close codes after which we should reconnect (normal closure, server ask, or transient/network issues). */
273
- function shouldReconnectOnClose(code: number): boolean {
274
- switch (code) {
275
- case 1000: // Normal Closure (server may close with this to ask for reconnect)
276
- case 1001: // Going Away
277
- case 1011: // Internal Error (server hit unexpected condition; often transient)
278
- case 1005: // No Status Received
279
- case 1006: // Abnormal Closure (network drop, server crash)
280
- case 1012: // Service Restart
281
- case 1013: // Try Again Later
282
- case 1014: // Bad Gateway
283
- case 1015: // TLS Handshake Failed
284
- return true;
285
- case 4000: // Unknown error
286
- case 4007: // Invalid seq
287
- case 4009: // Session timeout
288
- case 4010: // Invalid shard
289
- case 4011: // Sharding required
290
- case 4012: // Invalid API version (after fix, reconnect is safe)
291
- case 4013: // Ack backpressure (server event buffer full; transient, safe to retry)
292
- return true;
293
- default:
294
- return false;
295
- }
296
- }