dfx 0.51.0 → 0.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cache/driver.d.ts +17 -16
- package/Cache/driver.d.ts.map +1 -1
- package/Cache/driver.js +10 -2
- package/Cache/driver.js.map +1 -1
- package/Cache/memory.d.ts +3 -3
- package/Cache/memory.d.ts.map +1 -1
- package/Cache/memory.js +55 -45
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.d.ts +7 -6
- package/Cache/memoryTTL.d.ts.map +1 -1
- package/Cache/memoryTTL.js +126 -118
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.d.ts +53 -47
- package/Cache/prelude.d.ts.map +1 -1
- package/Cache/prelude.js +125 -96
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts +33 -32
- package/Cache.d.ts.map +1 -1
- package/Cache.js +137 -65
- package/Cache.js.map +1 -1
- package/DiscordConfig.d.ts +26 -20
- package/DiscordConfig.d.ts.map +1 -1
- package/DiscordConfig.js +43 -25
- package/DiscordConfig.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +17 -14
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +49 -30
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Shard/heartbeats.d.ts +7 -3
- package/DiscordGateway/Shard/heartbeats.d.ts.map +1 -1
- package/DiscordGateway/Shard/heartbeats.js +28 -18
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/identify.d.ts +10 -8
- package/DiscordGateway/Shard/identify.d.ts.map +1 -1
- package/DiscordGateway/Shard/identify.js +41 -24
- package/DiscordGateway/Shard/identify.js.map +1 -1
- package/DiscordGateway/Shard/invalidSession.d.ts +6 -3
- package/DiscordGateway/Shard/invalidSession.d.ts.map +1 -1
- package/DiscordGateway/Shard/invalidSession.js +14 -5
- package/DiscordGateway/Shard/invalidSession.js.map +1 -1
- package/DiscordGateway/Shard/sendEvents.d.ts +1 -1
- package/DiscordGateway/Shard/sendEvents.d.ts.map +1 -1
- package/DiscordGateway/Shard/sendEvents.js +30 -18
- package/DiscordGateway/Shard/sendEvents.js.map +1 -1
- package/DiscordGateway/Shard/utils.d.ts +7 -3
- package/DiscordGateway/Shard/utils.d.ts.map +1 -1
- package/DiscordGateway/Shard/utils.js +19 -9
- package/DiscordGateway/Shard/utils.js.map +1 -1
- package/DiscordGateway/Shard.d.ts +15 -10
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +109 -87
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +9 -6
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +30 -18
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts +17 -11
- package/DiscordGateway/Sharder.d.ts.map +1 -1
- package/DiscordGateway/Sharder.js +82 -52
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts +13 -10
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +100 -74
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts +19 -13
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js +45 -32
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/types.d.ts +5 -5
- package/DiscordREST/types.d.ts.map +1 -1
- package/DiscordREST/types.js +5 -1
- package/DiscordREST/types.js.map +1 -1
- package/DiscordREST/utils.d.ts +3 -2
- package/DiscordREST/utils.d.ts.map +1 -1
- package/DiscordREST/utils.js +27 -17
- package/DiscordREST/utils.js.map +1 -1
- package/DiscordREST.d.ts +11 -8
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +141 -127
- package/DiscordREST.js.map +1 -1
- package/Helpers/flags.js +31 -19
- package/Helpers/flags.js.map +1 -1
- package/Helpers/intents.d.ts.map +1 -1
- package/Helpers/intents.js +22 -10
- package/Helpers/intents.js.map +1 -1
- package/Helpers/interactions.d.ts +22 -21
- package/Helpers/interactions.d.ts.map +1 -1
- package/Helpers/interactions.js +75 -39
- package/Helpers/interactions.js.map +1 -1
- package/Helpers/members.d.ts +3 -3
- package/Helpers/members.d.ts.map +1 -1
- package/Helpers/members.js +10 -3
- package/Helpers/members.js.map +1 -1
- package/Helpers/permissions.d.ts +5 -4
- package/Helpers/permissions.d.ts.map +1 -1
- package/Helpers/permissions.js +69 -52
- package/Helpers/permissions.js.map +1 -1
- package/Helpers/ui.d.ts +1 -1
- package/Helpers/ui.d.ts.map +1 -1
- package/Helpers/ui.js +44 -29
- package/Helpers/ui.js.map +1 -1
- package/Interactions/builder.d.ts +20 -19
- package/Interactions/builder.d.ts.map +1 -1
- package/Interactions/builder.js +66 -63
- package/Interactions/builder.js.map +1 -1
- package/Interactions/context.d.ts +26 -23
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +86 -57
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +33 -30
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/definitions.js +61 -47
- package/Interactions/definitions.js.map +1 -1
- package/Interactions/gateway.d.ts +15 -10
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js +55 -42
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts +6 -4
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/handlers.js +68 -57
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/index.d.ts +11 -10
- package/Interactions/index.d.ts.map +1 -1
- package/Interactions/index.js +95 -10
- package/Interactions/index.js.map +1 -1
- package/Interactions/utils.d.ts +42 -40
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js +40 -32
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts +20 -16
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js +73 -41
- package/Interactions/webhook.js.map +1 -1
- package/Log.d.ts +8 -5
- package/Log.d.ts.map +1 -1
- package/Log.js +23 -14
- package/Log.js.map +1 -1
- package/RateLimit/memory.d.ts +1 -1
- package/RateLimit/memory.d.ts.map +1 -1
- package/RateLimit/memory.js +46 -33
- package/RateLimit/memory.js.map +1 -1
- package/RateLimit/utils.d.ts +1 -1
- package/RateLimit/utils.d.ts.map +1 -1
- package/RateLimit/utils.js +23 -16
- package/RateLimit/utils.js.map +1 -1
- package/RateLimit.d.ts +18 -14
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js +40 -26
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +20 -13
- package/gateway.d.ts.map +1 -1
- package/gateway.js +72 -25
- package/gateway.js.map +1 -1
- package/index.d.ts +14 -13
- package/index.d.ts.map +1 -1
- package/index.js +71 -13
- package/index.js.map +1 -1
- package/mjs/Cache/driver.mjs +3 -0
- package/mjs/Cache/driver.mjs.map +1 -0
- package/mjs/Cache/memory.mjs +48 -0
- package/mjs/Cache/memory.mjs.map +1 -0
- package/mjs/Cache/memoryTTL.mjs +119 -0
- package/mjs/Cache/memoryTTL.mjs.map +1 -0
- package/mjs/Cache/prelude.mjs +125 -0
- package/mjs/Cache/prelude.mjs.map +1 -0
- package/mjs/Cache.mjs +87 -0
- package/mjs/Cache.mjs.map +1 -0
- package/mjs/DiscordConfig.mjs +34 -0
- package/mjs/DiscordConfig.mjs.map +1 -0
- package/mjs/DiscordGateway/DiscordWS.mjs +39 -0
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard/heartbeats.mjs +21 -0
- package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard/identify.mjs +37 -0
- package/mjs/DiscordGateway/Shard/identify.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard/invalidSession.mjs +6 -0
- package/mjs/DiscordGateway/Shard/invalidSession.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard/sendEvents.mjs +25 -0
- package/mjs/DiscordGateway/Shard/sendEvents.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard/utils.mjs +11 -0
- package/mjs/DiscordGateway/Shard/utils.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard.mjs +99 -0
- package/mjs/DiscordGateway/Shard.mjs.map +1 -0
- package/mjs/DiscordGateway/ShardStore.mjs +24 -0
- package/mjs/DiscordGateway/ShardStore.mjs.map +1 -0
- package/mjs/DiscordGateway/Sharder.mjs +73 -0
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -0
- package/mjs/DiscordGateway/WS.mjs +94 -0
- package/mjs/DiscordGateway/WS.mjs.map +1 -0
- package/mjs/DiscordGateway.mjs +36 -0
- package/mjs/DiscordGateway.mjs.map +1 -0
- package/mjs/DiscordREST/types.mjs +2 -0
- package/mjs/DiscordREST/types.mjs.map +1 -0
- package/mjs/DiscordREST/utils.mjs +19 -0
- package/mjs/DiscordREST/utils.mjs.map +1 -0
- package/mjs/DiscordREST.mjs +129 -0
- package/mjs/DiscordREST.mjs.map +1 -0
- package/mjs/Helpers/flags.mjs +36 -0
- package/mjs/Helpers/flags.mjs.map +1 -0
- package/mjs/Helpers/intents.mjs +27 -0
- package/mjs/Helpers/intents.mjs.map +1 -0
- package/mjs/Helpers/interactions.mjs +104 -0
- package/mjs/Helpers/interactions.mjs.map +1 -0
- package/mjs/Helpers/members.mjs +9 -0
- package/mjs/Helpers/members.mjs.map +1 -0
- package/mjs/Helpers/permissions.mjs +82 -0
- package/mjs/Helpers/permissions.mjs.map +1 -0
- package/mjs/Helpers/ui.mjs +66 -0
- package/mjs/Helpers/ui.mjs.map +1 -0
- package/mjs/Interactions/builder.mjs +62 -0
- package/mjs/Interactions/builder.mjs.map +1 -0
- package/mjs/Interactions/context.mjs +63 -0
- package/mjs/Interactions/context.mjs.map +1 -0
- package/mjs/Interactions/definitions.mjs +51 -0
- package/mjs/Interactions/definitions.mjs.map +1 -0
- package/mjs/Interactions/gateway.mjs +48 -0
- package/mjs/Interactions/gateway.mjs.map +1 -0
- package/mjs/Interactions/handlers.mjs +61 -0
- package/mjs/Interactions/handlers.mjs.map +1 -0
- package/mjs/Interactions/index.mjs +12 -0
- package/mjs/Interactions/index.mjs.map +1 -0
- package/mjs/Interactions/utils.mjs +35 -0
- package/mjs/Interactions/utils.mjs.map +1 -0
- package/mjs/Interactions/webhook.mjs +73 -0
- package/mjs/Interactions/webhook.mjs.map +1 -0
- package/mjs/Log.mjs +15 -0
- package/mjs/Log.mjs.map +1 -0
- package/mjs/RateLimit/memory.mjs +39 -0
- package/mjs/RateLimit/memory.mjs.map +1 -0
- package/mjs/RateLimit/utils.mjs +18 -0
- package/mjs/RateLimit/utils.mjs.map +1 -0
- package/mjs/RateLimit.mjs +29 -0
- package/mjs/RateLimit.mjs.map +1 -0
- package/mjs/gateway.mjs +27 -0
- package/mjs/gateway.mjs.map +1 -0
- package/mjs/index.mjs +15 -0
- package/mjs/index.mjs.map +1 -0
- package/mjs/types.mjs +1211 -0
- package/mjs/types.mjs.map +1 -0
- package/mjs/utils/Effect.mjs +28 -0
- package/mjs/utils/Effect.mjs.map +1 -0
- package/mjs/utils/tsplus.mjs +2 -0
- package/mjs/utils/tsplus.mjs.map +1 -0
- package/mjs/version.mjs +2 -0
- package/mjs/version.mjs.map +1 -0
- package/mjs/webhooks.mjs +30 -0
- package/mjs/webhooks.mjs.map +1 -0
- package/package.json +46 -50
- package/src/Cache/driver.ts +27 -15
- package/src/Cache/memory.ts +9 -5
- package/src/Cache/memoryTTL.ts +69 -53
- package/src/Cache/prelude.ts +113 -91
- package/src/Cache.ts +73 -58
- package/src/DiscordConfig.ts +33 -19
- package/src/DiscordGateway/DiscordWS.ts +28 -25
- package/src/DiscordGateway/Shard/heartbeats.ts +47 -27
- package/src/DiscordGateway/Shard/identify.ts +29 -25
- package/src/DiscordGateway/Shard/invalidSession.ts +9 -7
- package/src/DiscordGateway/Shard/sendEvents.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +33 -9
- package/src/DiscordGateway/Shard.ts +119 -99
- package/src/DiscordGateway/ShardStore.ts +12 -5
- package/src/DiscordGateway/Sharder.ts +95 -74
- package/src/DiscordGateway/WS.ts +85 -60
- package/src/DiscordGateway.ts +58 -18
- package/src/DiscordREST/types.ts +5 -5
- package/src/DiscordREST/utils.ts +10 -7
- package/src/DiscordREST.ts +152 -132
- package/src/Helpers/intents.ts +1 -0
- package/src/Helpers/interactions.ts +51 -38
- package/src/Helpers/members.ts +2 -0
- package/src/Helpers/permissions.ts +6 -5
- package/src/Helpers/ui.ts +1 -1
- package/src/Interactions/builder.ts +56 -43
- package/src/Interactions/context.ts +68 -38
- package/src/Interactions/definitions.ts +32 -24
- package/src/Interactions/gateway.ts +72 -47
- package/src/Interactions/handlers.ts +56 -39
- package/src/Interactions/index.ts +6 -5
- package/src/Interactions/utils.ts +32 -21
- package/src/Interactions/webhook.ts +78 -42
- package/src/Log.ts +4 -0
- package/src/RateLimit/memory.ts +10 -4
- package/src/RateLimit/utils.ts +1 -1
- package/src/RateLimit.ts +38 -25
- package/src/gateway.ts +62 -25
- package/src/index.ts +29 -15
- package/src/utils/Effect.ts +69 -0
- package/src/version.ts +1 -0
- package/src/webhooks.ts +47 -20
- package/tsconfig.base.json +48 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.examples.json +11 -0
- package/tsconfig.json +12 -8
- package/tsconfig.madge.json +12 -0
- package/tsconfig.test.json +10 -0
- package/types.d.ts.map +1 -1
- package/types.js +1216 -1200
- package/types.js.map +1 -1
- package/utils/Effect.d.ts +8 -0
- package/utils/Effect.d.ts.map +1 -0
- package/utils/Effect.js +38 -0
- package/utils/Effect.js.map +1 -0
- package/utils/tsplus.js +5 -1
- package/utils/tsplus.js.map +1 -1
- package/version.d.ts +2 -0
- package/version.d.ts.map +1 -0
- package/version.js +9 -0
- package/version.js.map +1 -0
- package/webhooks.d.ts +14 -9
- package/webhooks.d.ts.map +1 -1
- package/webhooks.js +76 -27
- package/webhooks.js.map +1 -1
- package/_common.d.ts +0 -37
- package/_common.d.ts.map +0 -1
- package/_common.js +0 -8
- package/_common.js.map +0 -1
- package/global.d.ts +0 -18
- package/global.d.ts.map +0 -1
- package/global.js +0 -2
- package/global.js.map +0 -1
- package/src/_common.ts +0 -43
- package/src/global.ts +0 -45
- package/src/package.json +0 -52
- package/src/utils/effect.ts +0 -0
- package/src/utils/hub.ts +0 -47
- package/tsplus.config.json +0 -8
- package/utils/effect.d.ts +0 -2
- package/utils/effect.d.ts.map +0 -1
- package/utils/effect.js +0 -2
- package/utils/effect.js.map +0 -1
- package/utils/hub.d.ts +0 -12
- package/utils/hub.d.ts.map +0 -1
- package/utils/hub.js +0 -26
- 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 =
|
|
33
|
-
const ws =
|
|
34
|
-
const encoding =
|
|
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
|
-
|
|
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
|
-
|
|
48
|
-
const takeOutbound =
|
|
49
|
-
|
|
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 =
|
|
52
|
-
const take = socket.take
|
|
50
|
+
const socket = yield* _(ws.connect(urlRef, takeOutbound, onConnecting))
|
|
51
|
+
const take = Effect.map(socket.take, encoding.decode)
|
|
53
52
|
|
|
54
|
-
const run =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
(
|
|
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 =
|
|
72
|
+
export const LiveDiscordWS = Layer.provide(
|
|
73
|
+
LiveWS,
|
|
74
|
+
Layer.effect(DiscordWS, make),
|
|
75
|
+
)
|
|
@@ -1,44 +1,64 @@
|
|
|
1
1
|
import { millis } from "@effect/data/Duration"
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
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 = (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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 = (
|
|
12
|
-
ref.
|
|
13
|
-
|
|
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<
|
|
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
|
-
|
|
24
|
-
const ackedRef =
|
|
38
|
+
Effect.gen(function* (_) {
|
|
39
|
+
const ackedRef = yield* _(Ref.make(true))
|
|
25
40
|
|
|
26
|
-
const heartbeats =
|
|
27
|
-
.take()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.
|
|
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
|
-
).
|
|
49
|
+
).pipe(
|
|
50
|
+
Schedule.andThen(Schedule.fixed(millis(p.d!.heartbeat_interval))),
|
|
51
|
+
),
|
|
36
52
|
),
|
|
37
|
-
|
|
53
|
+
),
|
|
54
|
+
)
|
|
38
55
|
|
|
39
|
-
const run =
|
|
56
|
+
const run = Queue.take(acks).pipe(
|
|
57
|
+
Effect.tap(() => Ref.set(ackedRef, true)),
|
|
58
|
+
Effect.forever,
|
|
59
|
+
)
|
|
40
60
|
|
|
41
|
-
return
|
|
61
|
+
return yield* _(
|
|
42
62
|
Effect.all(run, heartbeats, {
|
|
43
63
|
concurrency: "unbounded",
|
|
44
64
|
discard: true,
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import * as SendEvents from "./sendEvents.js"
|
|
2
|
-
import * as OS from "os"
|
|
3
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"
|
|
6
|
+
import * as OS from "os"
|
|
4
7
|
|
|
5
8
|
export interface Options {
|
|
6
|
-
token: string
|
|
7
|
-
intents: number
|
|
8
|
-
shard: [number, number]
|
|
9
|
-
presence?: Discord.UpdatePresence
|
|
9
|
+
readonly token: string
|
|
10
|
+
readonly intents: number
|
|
11
|
+
readonly shard: [number, number]
|
|
12
|
+
readonly presence?: Discord.UpdatePresence
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export interface Requirements {
|
|
13
|
-
latestReady: Ref<
|
|
14
|
-
latestSequence: Ref<
|
|
16
|
+
readonly latestReady: Ref.Ref<Option.Option<Discord.ReadyEvent>>
|
|
17
|
+
readonly latestSequence: Ref.Ref<Option.Option<number>>
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
const identify = ({
|
|
20
|
+
const identify = ({ intents, presence, shard, token }: Options) =>
|
|
18
21
|
SendEvents.identify({
|
|
19
22
|
token,
|
|
20
23
|
intents,
|
|
@@ -36,19 +39,20 @@ const resume = (token: string, ready: Discord.ReadyEvent, seq: number) =>
|
|
|
36
39
|
|
|
37
40
|
export const identifyOrResume = (
|
|
38
41
|
opts: Options,
|
|
39
|
-
ready: Ref<
|
|
40
|
-
seq: Ref<
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
2
|
-
import
|
|
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<
|
|
7
|
-
) =>
|
|
8
|
-
(p.d ? Effect.unit :
|
|
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,17 +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>(
|
|
4
|
-
|
|
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
|
+
)
|
|
5
15
|
|
|
6
16
|
const maybeUpdateRef =
|
|
7
|
-
<T>(
|
|
8
|
-
|
|
9
|
-
|
|
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(_), {
|
|
10
23
|
onNone: () => Effect.unit,
|
|
11
|
-
onSome: a =>
|
|
24
|
+
onSome: a => Ref.set(ref, Option.some(a)),
|
|
12
25
|
})
|
|
13
26
|
|
|
14
|
-
export const latest = <T>(
|
|
15
|
-
|
|
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()),
|
|
39
|
+
|
|
16
40
|
ref => [ref, maybeUpdateRef(f, ref)] as const,
|
|
17
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 "
|
|
4
|
-
import * as Heartbeats from "
|
|
5
|
-
import * as Identify from "
|
|
6
|
-
import * as InvalidSession from "
|
|
7
|
-
import * as Utils from "
|
|
8
|
-
import { Reconnect } from "
|
|
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 =
|
|
18
|
-
const { token, gateway } =
|
|
19
|
-
const limiter =
|
|
20
|
-
const dws =
|
|
21
|
-
const 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
|
-
|
|
29
|
-
const outboundQueue =
|
|
30
|
-
const pendingQueue =
|
|
31
|
-
const phase =
|
|
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
|
-
|
|
34
|
-
const outbound =
|
|
35
|
-
.take()
|
|
36
|
-
.
|
|
37
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
?
|
|
44
|
-
:
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
?
|
|
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) =>
|
|
64
|
+
const prioritySend = (p: Message) => Queue.offer(outboundQueue, p)
|
|
55
65
|
|
|
56
|
-
const resume = setPhase(Phase.Connected)
|
|
57
|
-
.zipRight(
|
|
58
|
-
.tap(_ =>
|
|
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
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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,39 +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 =
|
|
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
|
-
|
|
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 =>
|
|
102
|
+
const [latestSequence, updateLatestSequence] = yield* _(
|
|
103
|
+
Utils.latest(p => Option.fromNullable(p.s)),
|
|
89
104
|
)
|
|
90
105
|
const maybeUpdateUrl = (p: Discord.GatewayPayload) =>
|
|
91
|
-
|
|
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({
|
|
110
|
+
),
|
|
111
|
+
Option.map(p => p.d!),
|
|
112
|
+
Option.match({
|
|
98
113
|
onNone: () => Effect.unit,
|
|
99
114
|
onSome: ({ resume_gateway_url }) =>
|
|
100
115
|
socket.setUrl(resume_gateway_url),
|
|
101
|
-
})
|
|
116
|
+
}),
|
|
117
|
+
)
|
|
102
118
|
|
|
103
|
-
const hellos =
|
|
104
|
-
const acks =
|
|
119
|
+
const hellos = yield* _(Queue.unbounded<Discord.GatewayPayload>())
|
|
120
|
+
const acks = yield* _(Queue.unbounded<Discord.GatewayPayload>())
|
|
105
121
|
|
|
106
122
|
// heartbeats
|
|
107
123
|
const heartbeats = Heartbeats.send(
|
|
@@ -114,7 +130,7 @@ export const make = Do($ => {
|
|
|
114
130
|
// identify
|
|
115
131
|
const identify = Identify.identifyOrResume(
|
|
116
132
|
{
|
|
117
|
-
token:
|
|
133
|
+
token: ConfigSecret.value(token),
|
|
118
134
|
shard,
|
|
119
135
|
intents: gateway.intents,
|
|
120
136
|
presence: gateway.presence,
|
|
@@ -124,45 +140,47 @@ export const make = Do($ => {
|
|
|
124
140
|
)
|
|
125
141
|
|
|
126
142
|
const onPayload = (p: Discord.GatewayPayload) =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
updateLatestReady(p)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
+
)
|
|
163
181
|
|
|
164
182
|
const run = Effect.all(
|
|
165
|
-
socket.take.flatMap(onPayload).forever,
|
|
183
|
+
socket.take.pipe(Effect.flatMap(onPayload), Effect.forever),
|
|
166
184
|
heartbeats,
|
|
167
185
|
drainSendQueue,
|
|
168
186
|
socket.run,
|
|
@@ -175,10 +193,12 @@ export const make = Do($ => {
|
|
|
175
193
|
return { connect } as const
|
|
176
194
|
})
|
|
177
195
|
|
|
178
|
-
export interface Shard extends Effect.Success<typeof make> {}
|
|
196
|
+
export interface Shard extends Effect.Effect.Success<typeof make> {}
|
|
179
197
|
export const Shard = Tag<Shard>()
|
|
180
|
-
export const LiveShard =
|
|
181
|
-
(LiveDiscordWS
|
|
198
|
+
export const LiveShard = Layer.provide(
|
|
199
|
+
Layer.merge(LiveDiscordWS, LiveRateLimiter),
|
|
200
|
+
Layer.effect(Shard, make),
|
|
201
|
+
)
|
|
182
202
|
|
|
183
203
|
export interface RunningShard
|
|
184
|
-
extends Effect.Success<ReturnType<Shard["connect"]>> {}
|
|
204
|
+
extends Effect.Effect.Success<ReturnType<Shard["connect"]>> {}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
import * as Effect from "@effect/io/Effect"
|
|
2
|
+
import * as Layer from "@effect/io/Layer"
|
|
3
|
+
import { Tag } from "@effect/data/Context"
|
|
4
|
+
import * as Option from "@effect/data/Option"
|
|
5
|
+
|
|
1
6
|
export interface ClaimIdContext {
|
|
2
7
|
sharderCount: number
|
|
3
8
|
totalCount: number
|
|
4
9
|
}
|
|
5
10
|
|
|
6
11
|
export interface ShardStore {
|
|
7
|
-
claimId: (
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
claimId: (
|
|
13
|
+
ctx: ClaimIdContext,
|
|
14
|
+
) => Effect.Effect<never, never, Option.Option<number>>
|
|
15
|
+
allClaimed: (totalCount: number) => Effect.Effect<never, never, boolean>
|
|
16
|
+
heartbeat?: (shardId: number) => Effect.Effect<never, never, void>
|
|
10
17
|
}
|
|
11
18
|
export const ShardStore = Tag<ShardStore>()
|
|
12
19
|
|
|
@@ -18,12 +25,12 @@ const memoryStore = (): ShardStore => {
|
|
|
18
25
|
claimId: ({ totalCount }) =>
|
|
19
26
|
Effect.sync(() => {
|
|
20
27
|
if (currentId >= totalCount) {
|
|
21
|
-
return
|
|
28
|
+
return Option.none()
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
const id = currentId
|
|
25
32
|
currentId++
|
|
26
|
-
return
|
|
33
|
+
return Option.some(id)
|
|
27
34
|
}),
|
|
28
35
|
|
|
29
36
|
allClaimed: totalCount => Effect.sync(() => currentId >= totalCount),
|