dfx 0.50.1 → 0.51.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 (335) hide show
  1. package/Cache/driver.d.ts +17 -16
  2. package/Cache/driver.d.ts.map +1 -1
  3. package/Cache/driver.js +10 -2
  4. package/Cache/driver.js.map +1 -1
  5. package/Cache/memory.d.ts +3 -3
  6. package/Cache/memory.d.ts.map +1 -1
  7. package/Cache/memory.js +55 -45
  8. package/Cache/memory.js.map +1 -1
  9. package/Cache/memoryTTL.d.ts +7 -6
  10. package/Cache/memoryTTL.d.ts.map +1 -1
  11. package/Cache/memoryTTL.js +126 -118
  12. package/Cache/memoryTTL.js.map +1 -1
  13. package/Cache/prelude.d.ts +53 -47
  14. package/Cache/prelude.d.ts.map +1 -1
  15. package/Cache/prelude.js +125 -95
  16. package/Cache/prelude.js.map +1 -1
  17. package/Cache.d.ts +33 -32
  18. package/Cache.d.ts.map +1 -1
  19. package/Cache.js +137 -57
  20. package/Cache.js.map +1 -1
  21. package/DiscordConfig.d.ts +26 -20
  22. package/DiscordConfig.d.ts.map +1 -1
  23. package/DiscordConfig.js +43 -26
  24. package/DiscordConfig.js.map +1 -1
  25. package/DiscordGateway/DiscordWS.d.ts +17 -14
  26. package/DiscordGateway/DiscordWS.d.ts.map +1 -1
  27. package/DiscordGateway/DiscordWS.js +49 -29
  28. package/DiscordGateway/DiscordWS.js.map +1 -1
  29. package/DiscordGateway/Shard/heartbeats.d.ts +7 -3
  30. package/DiscordGateway/Shard/heartbeats.d.ts.map +1 -1
  31. package/DiscordGateway/Shard/heartbeats.js +28 -15
  32. package/DiscordGateway/Shard/heartbeats.js.map +1 -1
  33. package/DiscordGateway/Shard/identify.d.ts +11 -8
  34. package/DiscordGateway/Shard/identify.d.ts.map +1 -1
  35. package/DiscordGateway/Shard/identify.js +41 -21
  36. package/DiscordGateway/Shard/identify.js.map +1 -1
  37. package/DiscordGateway/Shard/invalidSession.d.ts +6 -3
  38. package/DiscordGateway/Shard/invalidSession.d.ts.map +1 -1
  39. package/DiscordGateway/Shard/invalidSession.js +14 -5
  40. package/DiscordGateway/Shard/invalidSession.js.map +1 -1
  41. package/DiscordGateway/Shard/sendEvents.d.ts +1 -1
  42. package/DiscordGateway/Shard/sendEvents.d.ts.map +1 -1
  43. package/DiscordGateway/Shard/sendEvents.js +30 -18
  44. package/DiscordGateway/Shard/sendEvents.js.map +1 -1
  45. package/DiscordGateway/Shard/utils.d.ts +7 -3
  46. package/DiscordGateway/Shard/utils.d.ts.map +1 -1
  47. package/DiscordGateway/Shard/utils.js +20 -8
  48. package/DiscordGateway/Shard/utils.js.map +1 -1
  49. package/DiscordGateway/Shard.d.ts +15 -10
  50. package/DiscordGateway/Shard.d.ts.map +1 -1
  51. package/DiscordGateway/Shard.js +109 -81
  52. package/DiscordGateway/Shard.js.map +1 -1
  53. package/DiscordGateway/ShardStore.d.ts +9 -6
  54. package/DiscordGateway/ShardStore.d.ts.map +1 -1
  55. package/DiscordGateway/ShardStore.js +30 -18
  56. package/DiscordGateway/ShardStore.js.map +1 -1
  57. package/DiscordGateway/Sharder.d.ts +17 -11
  58. package/DiscordGateway/Sharder.d.ts.map +1 -1
  59. package/DiscordGateway/Sharder.js +82 -51
  60. package/DiscordGateway/Sharder.js.map +1 -1
  61. package/DiscordGateway/WS.d.ts +13 -10
  62. package/DiscordGateway/WS.d.ts.map +1 -1
  63. package/DiscordGateway/WS.js +102 -71
  64. package/DiscordGateway/WS.js.map +1 -1
  65. package/DiscordGateway.d.ts +19 -13
  66. package/DiscordGateway.d.ts.map +1 -1
  67. package/DiscordGateway.js +45 -31
  68. package/DiscordGateway.js.map +1 -1
  69. package/DiscordREST/types.d.ts +5 -5
  70. package/DiscordREST/types.d.ts.map +1 -1
  71. package/DiscordREST/types.js +5 -1
  72. package/DiscordREST/types.js.map +1 -1
  73. package/DiscordREST/utils.d.ts +6 -4
  74. package/DiscordREST/utils.d.ts.map +1 -1
  75. package/DiscordREST/utils.js +27 -17
  76. package/DiscordREST/utils.js.map +1 -1
  77. package/DiscordREST.d.ts +11 -8
  78. package/DiscordREST.d.ts.map +1 -1
  79. package/DiscordREST.js +141 -123
  80. package/DiscordREST.js.map +1 -1
  81. package/Helpers/flags.js +31 -19
  82. package/Helpers/flags.js.map +1 -1
  83. package/Helpers/intents.d.ts.map +1 -1
  84. package/Helpers/intents.js +22 -10
  85. package/Helpers/intents.js.map +1 -1
  86. package/Helpers/interactions.d.ts +23 -22
  87. package/Helpers/interactions.d.ts.map +1 -1
  88. package/Helpers/interactions.js +75 -40
  89. package/Helpers/interactions.js.map +1 -1
  90. package/Helpers/members.d.ts +3 -3
  91. package/Helpers/members.d.ts.map +1 -1
  92. package/Helpers/members.js +10 -3
  93. package/Helpers/members.js.map +1 -1
  94. package/Helpers/permissions.d.ts +5 -4
  95. package/Helpers/permissions.d.ts.map +1 -1
  96. package/Helpers/permissions.js +69 -52
  97. package/Helpers/permissions.js.map +1 -1
  98. package/Helpers/ui.d.ts +1 -1
  99. package/Helpers/ui.d.ts.map +1 -1
  100. package/Helpers/ui.js +44 -29
  101. package/Helpers/ui.js.map +1 -1
  102. package/Interactions/builder.d.ts +20 -19
  103. package/Interactions/builder.d.ts.map +1 -1
  104. package/Interactions/builder.js +66 -63
  105. package/Interactions/builder.js.map +1 -1
  106. package/Interactions/context.d.ts +26 -23
  107. package/Interactions/context.d.ts.map +1 -1
  108. package/Interactions/context.js +87 -55
  109. package/Interactions/context.js.map +1 -1
  110. package/Interactions/definitions.d.ts +33 -30
  111. package/Interactions/definitions.d.ts.map +1 -1
  112. package/Interactions/definitions.js +61 -47
  113. package/Interactions/definitions.js.map +1 -1
  114. package/Interactions/gateway.d.ts +15 -10
  115. package/Interactions/gateway.d.ts.map +1 -1
  116. package/Interactions/gateway.js +55 -36
  117. package/Interactions/gateway.js.map +1 -1
  118. package/Interactions/handlers.d.ts +6 -4
  119. package/Interactions/handlers.d.ts.map +1 -1
  120. package/Interactions/handlers.js +68 -42
  121. package/Interactions/handlers.js.map +1 -1
  122. package/Interactions/index.d.ts +11 -10
  123. package/Interactions/index.d.ts.map +1 -1
  124. package/Interactions/index.js +95 -10
  125. package/Interactions/index.js.map +1 -1
  126. package/Interactions/utils.d.ts +42 -40
  127. package/Interactions/utils.d.ts.map +1 -1
  128. package/Interactions/utils.js +40 -32
  129. package/Interactions/utils.js.map +1 -1
  130. package/Interactions/webhook.d.ts +22 -17
  131. package/Interactions/webhook.d.ts.map +1 -1
  132. package/Interactions/webhook.js +74 -39
  133. package/Interactions/webhook.js.map +1 -1
  134. package/Log.d.ts +8 -5
  135. package/Log.d.ts.map +1 -1
  136. package/Log.js +23 -14
  137. package/Log.js.map +1 -1
  138. package/RateLimit/memory.d.ts +1 -1
  139. package/RateLimit/memory.d.ts.map +1 -1
  140. package/RateLimit/memory.js +46 -33
  141. package/RateLimit/memory.js.map +1 -1
  142. package/RateLimit/utils.d.ts +1 -1
  143. package/RateLimit/utils.d.ts.map +1 -1
  144. package/RateLimit/utils.js +23 -16
  145. package/RateLimit/utils.js.map +1 -1
  146. package/RateLimit.d.ts +18 -14
  147. package/RateLimit.d.ts.map +1 -1
  148. package/RateLimit.js +40 -24
  149. package/RateLimit.js.map +1 -1
  150. package/gateway.d.ts +20 -13
  151. package/gateway.d.ts.map +1 -1
  152. package/gateway.js +72 -25
  153. package/gateway.js.map +1 -1
  154. package/index.d.ts +14 -13
  155. package/index.d.ts.map +1 -1
  156. package/index.js +71 -13
  157. package/index.js.map +1 -1
  158. package/mjs/Cache/driver.mjs +3 -0
  159. package/mjs/Cache/driver.mjs.map +1 -0
  160. package/mjs/Cache/memory.mjs +48 -0
  161. package/mjs/Cache/memory.mjs.map +1 -0
  162. package/mjs/Cache/memoryTTL.mjs +119 -0
  163. package/mjs/Cache/memoryTTL.mjs.map +1 -0
  164. package/mjs/Cache/prelude.mjs +125 -0
  165. package/mjs/Cache/prelude.mjs.map +1 -0
  166. package/mjs/Cache.mjs +87 -0
  167. package/mjs/Cache.mjs.map +1 -0
  168. package/mjs/DiscordConfig.mjs +34 -0
  169. package/mjs/DiscordConfig.mjs.map +1 -0
  170. package/mjs/DiscordGateway/DiscordWS.mjs +39 -0
  171. package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -0
  172. package/mjs/DiscordGateway/Shard/heartbeats.mjs +21 -0
  173. package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -0
  174. package/mjs/DiscordGateway/Shard/identify.mjs +37 -0
  175. package/mjs/DiscordGateway/Shard/identify.mjs.map +1 -0
  176. package/mjs/DiscordGateway/Shard/invalidSession.mjs +6 -0
  177. package/mjs/DiscordGateway/Shard/invalidSession.mjs.map +1 -0
  178. package/mjs/DiscordGateway/Shard/sendEvents.mjs +25 -0
  179. package/mjs/DiscordGateway/Shard/sendEvents.mjs.map +1 -0
  180. package/mjs/DiscordGateway/Shard/utils.mjs +11 -0
  181. package/mjs/DiscordGateway/Shard/utils.mjs.map +1 -0
  182. package/mjs/DiscordGateway/Shard.mjs +99 -0
  183. package/mjs/DiscordGateway/Shard.mjs.map +1 -0
  184. package/mjs/DiscordGateway/ShardStore.mjs +24 -0
  185. package/mjs/DiscordGateway/ShardStore.mjs.map +1 -0
  186. package/mjs/DiscordGateway/Sharder.mjs +73 -0
  187. package/mjs/DiscordGateway/Sharder.mjs.map +1 -0
  188. package/mjs/DiscordGateway/WS.mjs +94 -0
  189. package/mjs/DiscordGateway/WS.mjs.map +1 -0
  190. package/mjs/DiscordGateway.mjs +36 -0
  191. package/mjs/DiscordGateway.mjs.map +1 -0
  192. package/mjs/DiscordREST/types.mjs +2 -0
  193. package/mjs/DiscordREST/types.mjs.map +1 -0
  194. package/mjs/DiscordREST/utils.mjs +19 -0
  195. package/mjs/DiscordREST/utils.mjs.map +1 -0
  196. package/mjs/DiscordREST.mjs +129 -0
  197. package/mjs/DiscordREST.mjs.map +1 -0
  198. package/mjs/Helpers/flags.mjs +36 -0
  199. package/mjs/Helpers/flags.mjs.map +1 -0
  200. package/mjs/Helpers/intents.mjs +27 -0
  201. package/mjs/Helpers/intents.mjs.map +1 -0
  202. package/mjs/Helpers/interactions.mjs +104 -0
  203. package/mjs/Helpers/interactions.mjs.map +1 -0
  204. package/mjs/Helpers/members.mjs +9 -0
  205. package/mjs/Helpers/members.mjs.map +1 -0
  206. package/mjs/Helpers/permissions.mjs +82 -0
  207. package/mjs/Helpers/permissions.mjs.map +1 -0
  208. package/mjs/Helpers/ui.mjs +66 -0
  209. package/mjs/Helpers/ui.mjs.map +1 -0
  210. package/mjs/Interactions/builder.mjs +62 -0
  211. package/mjs/Interactions/builder.mjs.map +1 -0
  212. package/mjs/Interactions/context.mjs +63 -0
  213. package/mjs/Interactions/context.mjs.map +1 -0
  214. package/mjs/Interactions/definitions.mjs +51 -0
  215. package/mjs/Interactions/definitions.mjs.map +1 -0
  216. package/mjs/Interactions/gateway.mjs +48 -0
  217. package/mjs/Interactions/gateway.mjs.map +1 -0
  218. package/mjs/Interactions/handlers.mjs +61 -0
  219. package/mjs/Interactions/handlers.mjs.map +1 -0
  220. package/mjs/Interactions/index.mjs +12 -0
  221. package/mjs/Interactions/index.mjs.map +1 -0
  222. package/mjs/Interactions/utils.mjs +35 -0
  223. package/mjs/Interactions/utils.mjs.map +1 -0
  224. package/mjs/Interactions/webhook.mjs +73 -0
  225. package/mjs/Interactions/webhook.mjs.map +1 -0
  226. package/mjs/Log.mjs +15 -0
  227. package/mjs/Log.mjs.map +1 -0
  228. package/mjs/RateLimit/memory.mjs +39 -0
  229. package/mjs/RateLimit/memory.mjs.map +1 -0
  230. package/mjs/RateLimit/utils.mjs +18 -0
  231. package/mjs/RateLimit/utils.mjs.map +1 -0
  232. package/mjs/RateLimit.mjs +29 -0
  233. package/mjs/RateLimit.mjs.map +1 -0
  234. package/mjs/gateway.mjs +27 -0
  235. package/mjs/gateway.mjs.map +1 -0
  236. package/mjs/index.mjs +15 -0
  237. package/mjs/index.mjs.map +1 -0
  238. package/mjs/types.mjs +1211 -0
  239. package/mjs/types.mjs.map +1 -0
  240. package/mjs/utils/Effect.mjs +28 -0
  241. package/mjs/utils/Effect.mjs.map +1 -0
  242. package/mjs/utils/tsplus.mjs +2 -0
  243. package/mjs/utils/tsplus.mjs.map +1 -0
  244. package/mjs/version.mjs +2 -0
  245. package/mjs/version.mjs.map +1 -0
  246. package/mjs/webhooks.mjs +30 -0
  247. package/mjs/webhooks.mjs.map +1 -0
  248. package/package.json +42 -50
  249. package/src/Cache/driver.ts +27 -15
  250. package/src/Cache/memory.ts +13 -9
  251. package/src/Cache/memoryTTL.ts +69 -53
  252. package/src/Cache/prelude.ts +113 -91
  253. package/src/Cache.ts +86 -61
  254. package/src/DiscordConfig.ts +34 -19
  255. package/src/DiscordGateway/DiscordWS.ts +28 -25
  256. package/src/DiscordGateway/Shard/heartbeats.ts +52 -27
  257. package/src/DiscordGateway/Shard/identify.ts +29 -23
  258. package/src/DiscordGateway/Shard/invalidSession.ts +9 -7
  259. package/src/DiscordGateway/Shard/sendEvents.ts +1 -1
  260. package/src/DiscordGateway/Shard/utils.ts +36 -9
  261. package/src/DiscordGateway/Shard.ts +129 -104
  262. package/src/DiscordGateway/ShardStore.ts +12 -5
  263. package/src/DiscordGateway/Sharder.ts +98 -77
  264. package/src/DiscordGateway/WS.ts +87 -58
  265. package/src/DiscordGateway.ts +59 -18
  266. package/src/DiscordREST/types.ts +5 -5
  267. package/src/DiscordREST/utils.ts +13 -8
  268. package/src/DiscordREST.ts +160 -131
  269. package/src/Helpers/intents.ts +1 -0
  270. package/src/Helpers/interactions.ts +76 -65
  271. package/src/Helpers/members.ts +2 -0
  272. package/src/Helpers/permissions.ts +6 -5
  273. package/src/Helpers/ui.ts +1 -1
  274. package/src/Interactions/builder.ts +56 -43
  275. package/src/Interactions/context.ts +67 -37
  276. package/src/Interactions/definitions.ts +32 -24
  277. package/src/Interactions/gateway.ts +80 -46
  278. package/src/Interactions/handlers.ts +68 -48
  279. package/src/Interactions/index.ts +6 -5
  280. package/src/Interactions/utils.ts +32 -21
  281. package/src/Interactions/webhook.ts +90 -51
  282. package/src/Log.ts +5 -1
  283. package/src/RateLimit/memory.ts +10 -4
  284. package/src/RateLimit/utils.ts +1 -1
  285. package/src/RateLimit.ts +38 -25
  286. package/src/gateway.ts +62 -25
  287. package/src/index.ts +29 -15
  288. package/src/utils/Effect.ts +69 -0
  289. package/src/version.ts +1 -0
  290. package/src/webhooks.ts +47 -20
  291. package/tsconfig.base.json +48 -0
  292. package/tsconfig.build.json +10 -0
  293. package/tsconfig.examples.json +11 -0
  294. package/tsconfig.json +12 -8
  295. package/tsconfig.madge.json +12 -0
  296. package/tsconfig.test.json +10 -0
  297. package/types.d.ts.map +1 -1
  298. package/types.js +1216 -1200
  299. package/types.js.map +1 -1
  300. package/utils/Effect.d.ts +8 -0
  301. package/utils/Effect.d.ts.map +1 -0
  302. package/utils/Effect.js +38 -0
  303. package/utils/Effect.js.map +1 -0
  304. package/utils/tsplus.js +5 -1
  305. package/utils/tsplus.js.map +1 -1
  306. package/version.d.ts +2 -0
  307. package/version.d.ts.map +1 -0
  308. package/version.js +9 -0
  309. package/version.js.map +1 -0
  310. package/webhooks.d.ts +14 -9
  311. package/webhooks.d.ts.map +1 -1
  312. package/webhooks.js +76 -27
  313. package/webhooks.js.map +1 -1
  314. package/_common.d.ts +0 -37
  315. package/_common.d.ts.map +0 -1
  316. package/_common.js +0 -8
  317. package/_common.js.map +0 -1
  318. package/global.d.ts +0 -18
  319. package/global.d.ts.map +0 -1
  320. package/global.js +0 -2
  321. package/global.js.map +0 -1
  322. package/src/_common.ts +0 -43
  323. package/src/global.ts +0 -45
  324. package/src/package.json +0 -52
  325. package/src/utils/effect.ts +0 -0
  326. package/src/utils/hub.ts +0 -47
  327. package/tsplus.config.json +0 -8
  328. package/utils/effect.d.ts +0 -2
  329. package/utils/effect.d.ts.map +0 -1
  330. package/utils/effect.js +0 -2
  331. package/utils/effect.js.map +0 -1
  332. package/utils/hub.d.ts +0 -12
  333. package/utils/hub.d.ts.map +0 -1
  334. package/utils/hub.js +0 -23
  335. package/utils/hub.js.map +0 -1
@@ -1,11 +1,10 @@
1
- import {
2
- LiveWS,
3
- Reconnect,
4
- WS,
5
- WebSocketCloseError,
6
- WebSocketError,
7
- } from "dfx/DiscordGateway/WS"
1
+ import { LiveWS, Reconnect, WS } from "dfx/DiscordGateway/WS"
8
2
  import WebSocket from "isomorphic-ws"
3
+ import * as Discord from "dfx/types"
4
+ import * as Effect from "@effect/io/Effect"
5
+ import * as Layer from "@effect/io/Layer"
6
+ import { Tag } from "@effect/data/Context"
7
+ import * as Ref from "@effect/io/Ref"
9
8
 
10
9
  export type Message = Discord.GatewayPayload | Reconnect
11
10
 
@@ -13,8 +12,8 @@ export interface OpenOpts {
13
12
  url?: string
14
13
  version?: number
15
14
  encoding?: DiscordWSCodec
16
- outbound: Effect<never, never, Message>
17
- onConnecting?: Effect<never, never, void>
15
+ outbound: Effect.Effect<never, never, Message>
16
+ onConnecting?: Effect.Effect<never, never, void>
18
17
  }
19
18
 
20
19
  export interface DiscordWSCodec {
@@ -29,9 +28,9 @@ export const LiveJsonDiscordWSCodec = Layer.succeed(DiscordWSCodec, {
29
28
  decode: p => JSON.parse(p.toString("utf8")),
30
29
  })
31
30
 
32
- const make = Do($ => {
33
- const ws = $(WS)
34
- const encoding = $(DiscordWSCodec)
31
+ const make = Effect.gen(function* (_) {
32
+ const ws = yield* _(WS)
33
+ const encoding = yield* _(DiscordWSCodec)
35
34
 
36
35
  const connect = ({
37
36
  url = "wss://gateway.discord.gg/",
@@ -39,22 +38,23 @@ const make = Do($ => {
39
38
  outbound,
40
39
  onConnecting,
41
40
  }: OpenOpts) =>
42
- Do($ => {
43
- const urlRef = $(
41
+ Effect.gen(function* (_) {
42
+ const urlRef = yield* _(
44
43
  Ref.make(`${url}?v=${version}&encoding=${encoding.type}`),
45
44
  )
46
45
  const setUrl = (url: string) =>
47
- urlRef.set(`${url}?v=${version}&encoding=${encoding.type}`)
48
- const takeOutbound = outbound.map(a =>
49
- a === Reconnect ? a : encoding.encode(a),
46
+ Ref.set(urlRef, `${url}?v=${version}&encoding=${encoding.type}`)
47
+ const takeOutbound = Effect.map(outbound, msg =>
48
+ msg === Reconnect ? msg : encoding.encode(msg),
50
49
  )
51
- const socket = $(ws.connect(urlRef, takeOutbound, onConnecting))
52
- const take = socket.take.map(encoding.decode)
50
+ const socket = yield* _(ws.connect(urlRef, takeOutbound, onConnecting))
51
+ const take = Effect.map(socket.take, encoding.decode)
53
52
 
54
- const run = socket.run.retryWhile(
55
- _ =>
56
- (_._tag === "WebSocketCloseError" && _.code < 2000) ||
57
- (_._tag === "WebSocketError" && _.reason === "open-timeout"),
53
+ const run = Effect.retryWhile(
54
+ socket.run,
55
+ e =>
56
+ (e._tag === "WebSocketCloseError" && e.code < 2000) ||
57
+ (e._tag === "WebSocketError" && e.reason === "open-timeout"),
58
58
  )
59
59
 
60
60
  return {
@@ -67,6 +67,9 @@ const make = Do($ => {
67
67
  return { connect } as const
68
68
  })
69
69
 
70
- export interface DiscordWS extends Effect.Success<typeof make> {}
70
+ export interface DiscordWS extends Effect.Effect.Success<typeof make> {}
71
71
  export const DiscordWS = Tag<DiscordWS>()
72
- export const LiveDiscordWS = LiveWS >> make.toLayer(DiscordWS)
72
+ export const LiveDiscordWS = Layer.provide(
73
+ LiveWS,
74
+ Layer.effect(DiscordWS, make),
75
+ )
@@ -1,42 +1,67 @@
1
1
  import { millis } from "@effect/data/Duration"
2
- import * as SendEvents from "./sendEvents.js"
3
- import * as DiscordWS from "dfx/DiscordGateway/DiscordWS"
4
- import { Reconnect } from "../WS.js"
2
+ import * as Option from "@effect/data/Option"
3
+ import * as Effect from "@effect/io/Effect"
4
+ import * as Queue from "@effect/io/Queue"
5
+ import * as Ref from "@effect/io/Ref"
6
+ import * as Schedule from "@effect/io/Schedule"
7
+ import type * as DiscordWS from "dfx/DiscordGateway/DiscordWS"
8
+ import * as SendEvents from "dfx/DiscordGateway/Shard/sendEvents"
9
+ import { Reconnect } from "dfx/DiscordGateway/WS"
10
+ import type * as Discord from "dfx/types"
11
+ import * as EffectU from "dfx/utils/Effect"
5
12
 
6
- const payload = (ref: Ref<boolean>, seqRef: Ref<Maybe<number>>) =>
7
- seqRef.get
8
- .map(a => SendEvents.heartbeat(a.getOrNull))
9
- .tap(() => ref.set(false))
13
+ const payload = (
14
+ ref: Ref.Ref<boolean>,
15
+ seqRef: Ref.Ref<Option.Option<number>>,
16
+ ) =>
17
+ Ref.get(seqRef).pipe(
18
+ Effect.map(o => SendEvents.heartbeat(Option.getOrNull(o))),
19
+ Effect.tap(() => Ref.set(ref, false)),
20
+ )
10
21
 
11
- const payloadOrReconnect = (ref: Ref<boolean>, seqRef: Ref<Maybe<number>>) =>
12
- ref.get.flatMap(
13
- (acked): Effect<never, never, DiscordWS.Message> =>
22
+ const payloadOrReconnect = (
23
+ ref: Ref.Ref<boolean>,
24
+ seqRef: Ref.Ref<Option.Option<number>>,
25
+ ) =>
26
+ Effect.flatMap(
27
+ Ref.get(ref),
28
+ (acked): Effect.Effect<never, never, DiscordWS.Message> =>
14
29
  acked ? payload(ref, seqRef) : Effect.succeed(Reconnect),
15
30
  )
16
31
 
17
32
  export const send = (
18
- hellos: Dequeue<Discord.GatewayPayload>,
19
- acks: Dequeue<Discord.GatewayPayload>,
20
- seqRef: Ref<Maybe<number>>,
21
- send: (p: DiscordWS.Message) => Effect<never, never, boolean>,
33
+ hellos: Queue.Dequeue<Discord.GatewayPayload>,
34
+ acks: Queue.Dequeue<Discord.GatewayPayload>,
35
+ seqRef: Ref.Ref<Option.Option<number>>,
36
+ send: (p: DiscordWS.Message) => Effect.Effect<never, never, boolean>,
22
37
  ) =>
23
- Do($ => {
24
- const ackedRef = $(Ref.make(true))
38
+ Effect.gen(function* (_) {
39
+ const ackedRef = yield* _(Ref.make(true))
25
40
 
26
- const heartbeats = hellos
27
- .take()
28
- .tap(() => ackedRef.set(true))
29
- .foreverSwitch(p =>
30
- payloadOrReconnect(ackedRef, seqRef)
31
- .tap(send)
32
- .schedule(
41
+ const heartbeats = EffectU.foreverSwitch(
42
+ Queue.take(hellos).pipe(Effect.tap(() => Ref.set(ackedRef, true))),
43
+ p =>
44
+ payloadOrReconnect(ackedRef, seqRef).pipe(
45
+ Effect.tap(send),
46
+ Effect.schedule(
33
47
  Schedule.duration(
34
48
  millis(p.d!.heartbeat_interval * Math.random()),
35
- ).andThen(Schedule.fixed(millis(p.d!.heartbeat_interval))),
49
+ ).pipe(
50
+ Schedule.andThen(Schedule.fixed(millis(p.d!.heartbeat_interval))),
51
+ ),
36
52
  ),
37
- )
53
+ ),
54
+ )
38
55
 
39
- const run = acks.take().tap(() => ackedRef.set(true)).forever
56
+ const run = Queue.take(acks).pipe(
57
+ Effect.tap(() => Ref.set(ackedRef, true)),
58
+ Effect.forever,
59
+ )
40
60
 
41
- return $(run.zipParLeft(heartbeats))
61
+ return yield* _(
62
+ Effect.all(run, heartbeats, {
63
+ concurrency: "unbounded",
64
+ discard: true,
65
+ }),
66
+ )
42
67
  })
@@ -1,19 +1,23 @@
1
- import * as SendEvents from "./sendEvents.js"
1
+ import * as Option from "@effect/data/Option"
2
+ import * as Effect from "@effect/io/Effect"
3
+ import * as Ref from "@effect/io/Ref"
4
+ import * as SendEvents from "dfx/DiscordGateway/Shard/sendEvents"
5
+ import type * as Discord from "dfx/types"
2
6
  import * as OS from "os"
3
7
 
4
8
  export interface Options {
5
- token: string
6
- intents: number
7
- shard: [number, number]
8
- presence?: Discord.UpdatePresence
9
+ readonly token: string
10
+ readonly intents: number
11
+ readonly shard: [number, number]
12
+ readonly presence?: Discord.UpdatePresence
9
13
  }
10
14
 
11
15
  export interface Requirements {
12
- latestReady: Ref<Maybe<Discord.ReadyEvent>>
13
- latestSequence: Ref<Maybe<number>>
16
+ readonly latestReady: Ref.Ref<Option.Option<Discord.ReadyEvent>>
17
+ readonly latestSequence: Ref.Ref<Option.Option<number>>
14
18
  }
15
19
 
16
- const identify = ({ token, intents, shard, presence }: Options) =>
20
+ const identify = ({ intents, presence, shard, token }: Options) =>
17
21
  SendEvents.identify({
18
22
  token,
19
23
  intents,
@@ -35,18 +39,20 @@ const resume = (token: string, ready: Discord.ReadyEvent, seq: number) =>
35
39
 
36
40
  export const identifyOrResume = (
37
41
  opts: Options,
38
- ready: Ref<Maybe<Discord.ReadyEvent>>,
39
- seq: Ref<Maybe<number>>,
40
- ) =>
41
- Do($ => {
42
- const readyEvent = $(ready.get)
43
- const seqNumber = $(seq.get)
44
-
45
- return Maybe.struct({
46
- readyEvent,
47
- seqNumber,
48
- }).match(
49
- () => identify(opts),
50
- ({ readyEvent, seqNumber }) => resume(opts.token, readyEvent, seqNumber),
51
- )
52
- })
42
+ ready: Ref.Ref<Option.Option<Discord.ReadyEvent>>,
43
+ seq: Ref.Ref<Option.Option<number>>,
44
+ ): Effect.Effect<
45
+ never,
46
+ never,
47
+ | Discord.GatewayPayload<Discord.Identify>
48
+ | Discord.GatewayPayload<Discord.Resume>
49
+ > =>
50
+ Effect.map(
51
+ Effect.all(Ref.get(ready), Ref.get(seq)),
52
+ ([readyEvent, seqNumber]) =>
53
+ Option.match(Option.all({ readyEvent, seqNumber }), {
54
+ onNone: () => identify(opts),
55
+ onSome: ({ readyEvent, seqNumber }) =>
56
+ resume(opts.token, readyEvent, seqNumber),
57
+ }),
58
+ )
@@ -1,10 +1,12 @@
1
- import { Message } from "../DiscordWS.js"
2
- import { Reconnect } from "../WS.js"
1
+ import * as Option from "@effect/data/Option"
2
+ import * as Effect from "@effect/io/Effect"
3
+ import * as Ref from "@effect/io/Ref"
4
+ import { Message } from "dfx/DiscordGateway/DiscordWS"
5
+ import { Reconnect } from "dfx/DiscordGateway/WS"
6
+ import * as Discord from "dfx/types"
3
7
 
4
8
  export const fromPayload = (
5
9
  p: Discord.GatewayPayload,
6
- latestReady: Ref<Maybe<Discord.ReadyEvent>>,
7
- ) =>
8
- (p.d ? Effect.unit() : latestReady.set(Maybe.none())).map(
9
- (): Message => Reconnect,
10
- )
10
+ latestReady: Ref.Ref<Option.Option<Discord.ReadyEvent>>,
11
+ ): Effect.Effect<never, never, Message> =>
12
+ Effect.as(p.d ? Effect.unit : Ref.set(latestReady, Option.none()), Reconnect)
@@ -1,4 +1,4 @@
1
- import { Discord } from "dfx/_common"
1
+ import * as Discord from "dfx/types"
2
2
 
3
3
  export const heartbeat = (
4
4
  d: Discord.Heartbeat,
@@ -1,14 +1,41 @@
1
+ import * as Option from "@effect/data/Option"
2
+ import * as Effect from "@effect/io/Effect"
3
+ import * as Ref from "@effect/io/Ref"
4
+ import * as Discord from "dfx/types"
5
+ import * as Stream from "@effect/stream/Stream"
6
+
1
7
  export const opCode =
2
- <R, E>(source: Stream<R, E, Discord.GatewayPayload>) =>
3
- <T = any>(code: Discord.GatewayOpcode) =>
4
- source.filter((p): p is Discord.GatewayPayload<T> => p.op === code)
8
+ <R, E>(source: Stream.Stream<R, E, Discord.GatewayPayload>) =>
9
+ <T = any>(
10
+ code: Discord.GatewayOpcode,
11
+ ): Stream.Stream<R, E, Discord.GatewayPayload<T>> =>
12
+ source.pipe(
13
+ Stream.filter((p): p is Discord.GatewayPayload<T> => p.op === code),
14
+ )
15
+
16
+ const maybeUpdateRef =
17
+ <T>(
18
+ f: (p: Discord.GatewayPayload) => Option.Option<T>,
19
+ ref: Ref.Ref<Option.Option<T>>,
20
+ ) =>
21
+ (_: Discord.GatewayPayload): Effect.Effect<never, never, void> =>
22
+ Option.match(f(_), {
23
+ onNone: () => Effect.unit,
24
+ onSome: a => Ref.set(ref, Option.some(a)),
25
+ })
5
26
 
6
- const maybeUpdateRef = <T>(
7
- f: (p: Discord.GatewayPayload) => Maybe<T>,
8
- ref: Ref<Maybe<T>>,
9
- ) => flow(f, o => o.match(Effect.unit, a => ref.set(Maybe.some(a))))
27
+ export const latest = <T>(
28
+ f: (p: Discord.GatewayPayload) => Option.Option<T>,
29
+ ): Effect.Effect<
30
+ never,
31
+ never,
32
+ readonly [
33
+ Ref.Ref<Option.Option<T>>,
34
+ (_: Discord.GatewayPayload<any>) => Effect.Effect<never, never, void>,
35
+ ]
36
+ > =>
37
+ Effect.map(
38
+ Ref.make<Option.Option<T>>(Option.none()),
10
39
 
11
- export const latest = <T>(f: (p: Discord.GatewayPayload) => Maybe<T>) =>
12
- Ref.make<Maybe<T>>(Maybe.none()).map(
13
40
  ref => [ref, maybeUpdateRef(f, ref)] as const,
14
41
  )
@@ -1,12 +1,23 @@
1
1
  import { DiscordConfig } from "dfx/DiscordConfig"
2
2
  import { LiveRateLimiter, RateLimiter } from "dfx/RateLimit"
3
- import { DiscordWS, LiveDiscordWS, Message } from "./DiscordWS.js"
4
- import * as Heartbeats from "./Shard/heartbeats.js"
5
- import * as Identify from "./Shard/identify.js"
6
- import * as InvalidSession from "./Shard/invalidSession.js"
7
- import * as Utils from "./Shard/utils.js"
8
- import { Reconnect } from "./WS.js"
3
+ import { DiscordWS, LiveDiscordWS, Message } from "dfx/DiscordGateway/DiscordWS"
4
+ import * as Heartbeats from "dfx/DiscordGateway/Shard/heartbeats"
5
+ import * as Identify from "dfx/DiscordGateway/Shard/identify"
6
+ import * as InvalidSession from "dfx/DiscordGateway/Shard/invalidSession"
7
+ import * as Utils from "dfx/DiscordGateway/Shard/utils"
8
+ import { Reconnect } from "dfx/DiscordGateway/WS"
9
9
  import { Log } from "dfx/Log"
10
+ import * as Discord from "dfx/types"
11
+ import * as Effect from "@effect/io/Effect"
12
+ import * as Layer from "@effect/io/Layer"
13
+ import { Tag } from "@effect/data/Context"
14
+ import * as Option from "@effect/data/Option"
15
+ import * as Hub from "@effect/io/Hub"
16
+ import * as Queue from "@effect/io/Queue"
17
+ import * as Ref from "@effect/io/Ref"
18
+ import * as Duration from "@effect/data/Duration"
19
+ import * as Chunk from "@effect/data/Chunk"
20
+ import * as ConfigSecret from "@effect/io/Config/Secret"
10
21
 
11
22
  const enum Phase {
12
23
  Connecting,
@@ -14,54 +25,56 @@ const enum Phase {
14
25
  Connected,
15
26
  }
16
27
 
17
- export const make = Do($ => {
18
- const { token, gateway } = $(DiscordConfig)
19
- const limiter = $(RateLimiter)
20
- const dws = $(DiscordWS)
21
- const log = $(Log)
28
+ export const make = Effect.gen(function* (_) {
29
+ const { token, gateway } = yield* _(DiscordConfig)
30
+ const limiter = yield* _(RateLimiter)
31
+ const dws = yield* _(DiscordWS)
32
+ const log = yield* _(Log)
22
33
 
23
34
  const connect = (
24
35
  shard: [id: number, count: number],
25
- hub: Hub<Discord.GatewayPayload<Discord.ReceiveEvent>>,
26
- sendQueue: Dequeue<Discord.GatewayPayload<Discord.SendEvent>>,
36
+ hub: Hub.Hub<Discord.GatewayPayload<Discord.ReceiveEvent>>,
37
+ sendQueue: Queue.Dequeue<Discord.GatewayPayload<Discord.SendEvent>>,
27
38
  ) =>
28
- Do($ => {
29
- const outboundQueue = $(Queue.unbounded<Message>())
30
- const pendingQueue = $(Queue.unbounded<Message>())
31
- const phase = $(Ref.make(Phase.Connecting))
39
+ Effect.gen(function* (_) {
40
+ const outboundQueue = yield* _(Queue.unbounded<Message>())
41
+ const pendingQueue = yield* _(Queue.unbounded<Message>())
42
+ const phase = yield* _(Ref.make(Phase.Connecting))
32
43
  const setPhase = (p: Phase) =>
33
- phase.set(p).zipLeft(log.debug("Shard", shard, "phase", p))
34
- const outbound = outboundQueue
35
- .take()
36
- .tap(() =>
37
- limiter.maybeWait("dfx.shard.send", Duration.minutes(1), 120),
38
- )
44
+ Effect.zipLeft(Ref.set(phase, p), log.debug("Shard", shard, "phase", p))
45
+ const outbound = Effect.zipLeft(
46
+ Queue.take(outboundQueue),
47
+ limiter.maybeWait("dfx.shard.send", Duration.minutes(1), 120),
48
+ )
39
49
 
40
50
  const send = (p: Message) =>
41
- phase.get.flatMap(_ =>
42
- _ === Phase.Connected
43
- ? outboundQueue.offer(p)
44
- : pendingQueue.offer(p),
51
+ Effect.flatMap(Ref.get(phase), phase =>
52
+ phase === Phase.Connected
53
+ ? Queue.offer(outboundQueue, p)
54
+ : Queue.offer(pendingQueue, p),
45
55
  )
46
56
 
47
57
  const heartbeatSend = (p: Message) =>
48
- phase.get.flatMap(_ =>
49
- _ !== Phase.Connecting
50
- ? outboundQueue.offer(p)
58
+ Effect.flatMap(Ref.get(phase), phase =>
59
+ phase !== Phase.Connecting
60
+ ? Queue.offer(outboundQueue, p)
51
61
  : Effect.succeed(false),
52
62
  )
53
63
 
54
- const prioritySend = (p: Message) => outboundQueue.offer(p)
64
+ const prioritySend = (p: Message) => Queue.offer(outboundQueue, p)
55
65
 
56
- const resume = setPhase(Phase.Connected)
57
- .zipRight(pendingQueue.takeAll())
58
- .tap(_ => outboundQueue.offerAll(_)).asUnit
66
+ const resume = setPhase(Phase.Connected).pipe(
67
+ Effect.zipRight(Queue.takeAll(pendingQueue)),
68
+ Effect.tap(_ => Queue.offerAll(outboundQueue, _)),
69
+ Effect.asUnit,
70
+ )
59
71
 
60
- const onConnecting = outboundQueue
61
- .takeAll()
62
- .tap(_ =>
63
- pendingQueue.offerAll(
64
- _.filter(
72
+ const onConnecting = Queue.takeAll(outboundQueue).pipe(
73
+ Effect.tap(msgs =>
74
+ Queue.offerAll(
75
+ pendingQueue,
76
+ Chunk.filter(
77
+ msgs,
65
78
  msg =>
66
79
  msg !== Reconnect &&
67
80
  msg.op !== Discord.GatewayOpcode.IDENTIFY &&
@@ -69,38 +82,42 @@ export const make = Do($ => {
69
82
  msg.op !== Discord.GatewayOpcode.HEARTBEAT,
70
83
  ),
71
84
  ),
72
- )
73
- .zipRight(setPhase(Phase.Connecting))
85
+ ),
86
+ Effect.zipRight(setPhase(Phase.Connecting)),
87
+ )
74
88
 
75
- const socket = $(dws.connect({ outbound, onConnecting }))
89
+ const socket = yield* _(dws.connect({ outbound, onConnecting }))
76
90
 
77
- const [latestReady, updateLatestReady] = $(
91
+ const [latestReady, updateLatestReady] = yield* _(
78
92
  Utils.latest(p =>
79
- Maybe.some(p)
80
- .filter(
93
+ Option.some(p).pipe(
94
+ Option.filter(
81
95
  (p): p is Discord.GatewayPayload<Discord.ReadyEvent> =>
82
96
  p.op === Discord.GatewayOpcode.DISPATCH && p.t === "READY",
83
- )
84
- .map(p => p.d!),
97
+ ),
98
+ Option.map(p => p.d!),
99
+ ),
85
100
  ),
86
101
  )
87
- const [latestSequence, updateLatestSequence] = $(
88
- Utils.latest(p => Maybe.fromNullable(p.s)),
102
+ const [latestSequence, updateLatestSequence] = yield* _(
103
+ Utils.latest(p => Option.fromNullable(p.s)),
89
104
  )
90
105
  const maybeUpdateUrl = (p: Discord.GatewayPayload) =>
91
- Maybe.some(p)
92
- .filter(
106
+ Option.some(p).pipe(
107
+ Option.filter(
93
108
  (p): p is Discord.GatewayPayload<Discord.ReadyEvent> =>
94
109
  p.op === Discord.GatewayOpcode.DISPATCH && p.t === "READY",
95
- )
96
- .map(p => p.d!)
97
- .match(
98
- () => Effect.unit(),
99
- a => socket.setUrl(a.resume_gateway_url),
100
- )
110
+ ),
111
+ Option.map(p => p.d!),
112
+ Option.match({
113
+ onNone: () => Effect.unit,
114
+ onSome: ({ resume_gateway_url }) =>
115
+ socket.setUrl(resume_gateway_url),
116
+ }),
117
+ )
101
118
 
102
- const hellos = $(Queue.unbounded<Discord.GatewayPayload>())
103
- const acks = $(Queue.unbounded<Discord.GatewayPayload>())
119
+ const hellos = yield* _(Queue.unbounded<Discord.GatewayPayload>())
120
+ const acks = yield* _(Queue.unbounded<Discord.GatewayPayload>())
104
121
 
105
122
  // heartbeats
106
123
  const heartbeats = Heartbeats.send(
@@ -113,7 +130,7 @@ export const make = Do($ => {
113
130
  // identify
114
131
  const identify = Identify.identifyOrResume(
115
132
  {
116
- token: token.value,
133
+ token: ConfigSecret.value(token),
117
134
  shard,
118
135
  intents: gateway.intents,
119
136
  presence: gateway.presence,
@@ -123,46 +140,52 @@ export const make = Do($ => {
123
140
  )
124
141
 
125
142
  const onPayload = (p: Discord.GatewayPayload) =>
126
- Do($ => {
127
- $(
128
- updateLatestReady(p)
129
- .zipPar(updateLatestSequence(p))
130
- .zipPar(maybeUpdateUrl(p)),
131
- )
132
-
133
- let effect = Effect.unit()
134
-
135
- switch (p.op) {
136
- case Discord.GatewayOpcode.HELLO:
137
- effect = identify
138
- .tap(prioritySend)
139
- .zipPar(setPhase(Phase.Handshake).zipRight(hellos.offer(p)))
140
- break
141
- case Discord.GatewayOpcode.HEARTBEAT_ACK:
142
- effect = acks.offer(p)
143
- break
144
- case Discord.GatewayOpcode.INVALID_SESSION:
145
- effect = InvalidSession.fromPayload(p, latestReady).tap(send)
146
- break
147
- case Discord.GatewayOpcode.DISPATCH:
148
- if (p.t === "READY" || p.t === "RESUMED") {
149
- effect = resume.zipRight(hub.publish(p))
150
- } else {
151
- effect = hub.publish(p)
152
- }
153
- break
154
- }
155
-
156
- $(effect)
157
- })
158
-
159
- const drainSendQueue = sendQueue.take().tap(send).forever
160
-
161
- const run = socket.take
162
- .flatMap(onPayload)
163
- .forever.zipParLeft(heartbeats)
164
- .zipParLeft(drainSendQueue)
165
- .zipParLeft(socket.run)
143
+ Effect.tap(
144
+ Effect.all(
145
+ updateLatestReady(p),
146
+ updateLatestSequence(p),
147
+ maybeUpdateUrl(p),
148
+ { discard: true },
149
+ ),
150
+ () => {
151
+ switch (p.op) {
152
+ case Discord.GatewayOpcode.HELLO:
153
+ return Effect.all(
154
+ Effect.tap(identify, prioritySend),
155
+ setPhase(Phase.Handshake),
156
+ Queue.offer(hellos, p),
157
+ { discard: true },
158
+ )
159
+ case Discord.GatewayOpcode.HEARTBEAT_ACK:
160
+ return Queue.offer(acks, p)
161
+ case Discord.GatewayOpcode.INVALID_SESSION:
162
+ return Effect.tap(
163
+ InvalidSession.fromPayload(p, latestReady),
164
+ send,
165
+ )
166
+ case Discord.GatewayOpcode.DISPATCH:
167
+ if (p.t === "READY" || p.t === "RESUMED") {
168
+ return Effect.zipRight(resume, Hub.publish(hub, p))
169
+ }
170
+ return Hub.publish(hub, p)
171
+ }
172
+
173
+ return Effect.unit
174
+ },
175
+ )
176
+
177
+ const drainSendQueue = Queue.take(sendQueue).pipe(
178
+ Effect.tap(send),
179
+ Effect.forever,
180
+ )
181
+
182
+ const run = Effect.all(
183
+ socket.take.pipe(Effect.flatMap(onPayload), Effect.forever),
184
+ heartbeats,
185
+ drainSendQueue,
186
+ socket.run,
187
+ { discard: true, concurrency: "unbounded" },
188
+ )
166
189
 
167
190
  return { id: shard, send, run } as const
168
191
  })
@@ -170,10 +193,12 @@ export const make = Do($ => {
170
193
  return { connect } as const
171
194
  })
172
195
 
173
- export interface Shard extends Effect.Success<typeof make> {}
196
+ export interface Shard extends Effect.Effect.Success<typeof make> {}
174
197
  export const Shard = Tag<Shard>()
175
- export const LiveShard =
176
- (LiveDiscordWS + LiveRateLimiter) >> make.toLayer(Shard)
198
+ export const LiveShard = Layer.provide(
199
+ Layer.merge(LiveDiscordWS, LiveRateLimiter),
200
+ Layer.effect(Shard, make),
201
+ )
177
202
 
178
203
  export interface RunningShard
179
- extends Effect.Success<ReturnType<Shard["connect"]>> {}
204
+ extends Effect.Effect.Success<ReturnType<Shard["connect"]>> {}