dfx 0.59.0 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cache/driver.d.ts +1 -1
- package/Cache/driver.d.ts.map +1 -1
- package/Cache/memory.js +2 -2
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.d.ts.map +1 -1
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.d.ts.map +1 -1
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts +1 -1
- package/Cache.d.ts.map +1 -1
- package/Cache.js +1 -1
- package/Cache.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +5 -5
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +2 -2
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/utils.d.ts +1 -1
- package/DiscordGateway/Shard/utils.d.ts.map +1 -1
- package/DiscordGateway/Shard/utils.js.map +1 -1
- package/DiscordGateway/Shard.d.ts +8 -8
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +11 -11
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +2 -2
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +2 -2
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts +4 -4
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +6 -6
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/types.d.ts +1 -1
- package/DiscordREST/types.d.ts.map +1 -1
- package/DiscordREST/utils.d.ts +1 -1
- package/DiscordREST/utils.d.ts.map +1 -1
- package/DiscordREST/utils.js +1 -1
- package/DiscordREST/utils.js.map +1 -1
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js.map +1 -1
- package/Helpers/flags.d.ts.map +1 -1
- package/Helpers/flags.js.map +1 -1
- package/Helpers/intents.d.ts.map +1 -1
- package/Helpers/intents.js.map +1 -1
- package/Helpers/interactions.d.ts +1 -1
- package/Helpers/interactions.d.ts.map +1 -1
- package/Helpers/interactions.js +2 -2
- package/Helpers/interactions.js.map +1 -1
- package/Helpers/members.d.ts.map +1 -1
- package/Helpers/members.js.map +1 -1
- package/Helpers/permissions.js.map +1 -1
- package/Interactions/builder.d.ts +1 -1
- package/Interactions/builder.d.ts.map +1 -1
- package/Interactions/builder.js.map +1 -1
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/definitions.js.map +1 -1
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/index.d.ts +1 -1
- package/Interactions/index.d.ts.map +1 -1
- package/Interactions/index.js.map +1 -1
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js.map +1 -1
- package/LICENSE +21 -0
- package/Log.d.ts +1 -1
- package/Log.d.ts.map +1 -1
- package/Log.js +1 -1
- package/Log.js.map +1 -1
- package/RateLimit.d.ts +2 -2
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +1 -1
- package/gateway.d.ts.map +1 -1
- package/gateway.js +1 -1
- package/gateway.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/mjs/Cache/memory.mjs +2 -2
- package/mjs/Cache/memory.mjs.map +1 -1
- package/mjs/Cache/memoryTTL.mjs.map +1 -1
- package/mjs/Cache/prelude.mjs.map +1 -1
- package/mjs/Cache.mjs +1 -1
- package/mjs/Cache.mjs.map +1 -1
- package/mjs/DiscordGateway/DiscordWS.mjs +2 -2
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/utils.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard.mjs +11 -11
- package/mjs/DiscordGateway/Shard.mjs.map +1 -1
- package/mjs/DiscordGateway/ShardStore.mjs +2 -2
- package/mjs/DiscordGateway/ShardStore.mjs.map +1 -1
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -1
- package/mjs/DiscordGateway/WS.mjs +5 -5
- package/mjs/DiscordGateway/WS.mjs.map +1 -1
- package/mjs/DiscordGateway.mjs.map +1 -1
- package/mjs/DiscordREST/utils.mjs +1 -1
- package/mjs/DiscordREST/utils.mjs.map +1 -1
- package/mjs/DiscordREST.mjs +1 -1
- package/mjs/DiscordREST.mjs.map +1 -1
- package/mjs/Helpers/flags.mjs.map +1 -1
- package/mjs/Helpers/intents.mjs.map +1 -1
- package/mjs/Helpers/interactions.mjs +2 -2
- package/mjs/Helpers/interactions.mjs.map +1 -1
- package/mjs/Helpers/members.mjs.map +1 -1
- package/mjs/Helpers/permissions.mjs.map +1 -1
- package/mjs/Interactions/builder.mjs.map +1 -1
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/definitions.mjs.map +1 -1
- package/mjs/Interactions/gateway.mjs +1 -1
- package/mjs/Interactions/gateway.mjs.map +1 -1
- package/mjs/Interactions/handlers.mjs.map +1 -1
- package/mjs/Interactions/index.mjs.map +1 -1
- package/mjs/Interactions/utils.mjs.map +1 -1
- package/mjs/Interactions/webhook.mjs.map +1 -1
- package/mjs/Log.mjs +1 -1
- package/mjs/Log.mjs.map +1 -1
- package/mjs/RateLimit.mjs.map +1 -1
- package/mjs/gateway.mjs +1 -1
- package/mjs/gateway.mjs.map +1 -1
- package/mjs/index.mjs +1 -1
- package/mjs/index.mjs.map +1 -1
- package/mjs/types.mjs.map +1 -1
- package/mjs/utils/Effect.mjs +4 -4
- package/mjs/utils/Effect.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/mjs/webhooks.mjs +1 -1
- package/mjs/webhooks.mjs.map +1 -1
- package/package.json +32 -26
- package/src/Cache/driver.ts +1 -1
- package/src/Cache/memory.ts +2 -2
- package/src/Cache/memoryTTL.ts +6 -4
- package/src/Cache/prelude.ts +15 -13
- package/src/Cache.ts +3 -3
- package/src/DiscordGateway/DiscordWS.ts +9 -10
- package/src/DiscordGateway/Shard/heartbeats.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +10 -12
- package/src/DiscordGateway/Shard.ts +23 -24
- package/src/DiscordGateway/ShardStore.ts +2 -2
- package/src/DiscordGateway/Sharder.ts +7 -7
- package/src/DiscordGateway/WS.ts +10 -10
- package/src/DiscordGateway.ts +8 -9
- package/src/DiscordREST/types.ts +1 -1
- package/src/DiscordREST/utils.ts +5 -3
- package/src/DiscordREST.ts +27 -24
- package/src/Helpers/flags.ts +2 -4
- package/src/Helpers/intents.ts +3 -4
- package/src/Helpers/interactions.ts +53 -56
- package/src/Helpers/members.ts +2 -2
- package/src/Helpers/permissions.ts +2 -2
- package/src/Interactions/builder.ts +21 -19
- package/src/Interactions/context.ts +16 -23
- package/src/Interactions/definitions.ts +27 -34
- package/src/Interactions/gateway.ts +80 -83
- package/src/Interactions/handlers.ts +34 -35
- package/src/Interactions/index.ts +17 -21
- package/src/Interactions/utils.ts +13 -17
- package/src/Interactions/webhook.ts +19 -15
- package/src/Log.ts +3 -3
- package/src/RateLimit.ts +5 -4
- package/src/gateway.ts +2 -2
- package/src/index.ts +1 -1
- package/src/types.ts +50 -26
- package/src/utils/Effect.ts +16 -17
- package/src/version.ts +1 -1
- package/src/webhooks.ts +2 -2
- package/types.d.ts.map +1 -1
- package/types.js.map +1 -1
- package/utils/Effect.d.ts.map +1 -1
- package/utils/Effect.js +4 -4
- package/utils/Effect.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/webhooks.d.ts +1 -1
- package/webhooks.d.ts.map +1 -1
package/src/Cache/memoryTTL.ts
CHANGED
|
@@ -160,16 +160,18 @@ export const createWithParent = <T>(opts: MemoryTTLOpts) =>
|
|
|
160
160
|
if (item._tag === "None") {
|
|
161
161
|
ids.delete(id)
|
|
162
162
|
}
|
|
163
|
-
})
|
|
163
|
+
})
|
|
164
164
|
),
|
|
165
165
|
Effect.map(item => [id, item] as const),
|
|
166
166
|
),
|
|
167
167
|
{ concurrency: "unbounded" },
|
|
168
|
-
)
|
|
168
|
+
)
|
|
169
169
|
),
|
|
170
170
|
Effect.map(
|
|
171
|
-
ReadonlyArray.reduce(
|
|
172
|
-
|
|
171
|
+
ReadonlyArray.reduce(
|
|
172
|
+
new Map<string, T>(),
|
|
173
|
+
(acc, [id, item]) =>
|
|
174
|
+
item._tag === "Some" ? acc.set(id, item.value) : acc,
|
|
173
175
|
),
|
|
174
176
|
),
|
|
175
177
|
Effect.option,
|
package/src/Cache/prelude.ts
CHANGED
|
@@ -32,17 +32,19 @@ export const opsWithParent = <E, T>({
|
|
|
32
32
|
remove,
|
|
33
33
|
update,
|
|
34
34
|
}: OptsWithParentOptions<E, T>) => {
|
|
35
|
-
const fromParentOps = Stream.flatMap(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
const fromParentOps = Stream.flatMap(
|
|
36
|
+
fromParent,
|
|
37
|
+
([parentId, a]) =>
|
|
38
|
+
Stream.fromIterable(
|
|
39
|
+
a.map(
|
|
40
|
+
(resource): ParentCacheOp<T> => ({
|
|
41
|
+
op: "create",
|
|
42
|
+
parentId,
|
|
43
|
+
resourceId: id(resource),
|
|
44
|
+
resource,
|
|
45
|
+
}),
|
|
46
|
+
),
|
|
44
47
|
),
|
|
45
|
-
),
|
|
46
48
|
)
|
|
47
49
|
|
|
48
50
|
const createOps = Stream.map(
|
|
@@ -129,7 +131,7 @@ export const ops = <E, T>({ create, id, remove, update }: OpsOptions<E, T>) => {
|
|
|
129
131
|
export const guilds = <RM, EM, E>(
|
|
130
132
|
makeDriver: Effect.Effect<RM, EM, CacheDriver<E, Discord.Guild>>,
|
|
131
133
|
) =>
|
|
132
|
-
Effect.gen(function*
|
|
134
|
+
Effect.gen(function*(_) {
|
|
133
135
|
const driver = yield* _(makeDriver)
|
|
134
136
|
const gateway = yield* _(DiscordGateway)
|
|
135
137
|
const rest = yield* _(DiscordREST)
|
|
@@ -156,7 +158,7 @@ export const guilds = <RM, EM, E>(
|
|
|
156
158
|
export const channels = <RM, EM, E>(
|
|
157
159
|
makeDriver: Effect.Effect<RM, EM, ParentCacheDriver<E, Discord.Channel>>,
|
|
158
160
|
) =>
|
|
159
|
-
Effect.gen(function*
|
|
161
|
+
Effect.gen(function*(_) {
|
|
160
162
|
const driver = yield* _(makeDriver)
|
|
161
163
|
const gateway = yield* _(DiscordGateway)
|
|
162
164
|
const rest = yield* _(DiscordREST)
|
|
@@ -199,7 +201,7 @@ export const channels = <RM, EM, E>(
|
|
|
199
201
|
export const roles = <RM, EM, E>(
|
|
200
202
|
makeDriver: Effect.Effect<RM, EM, ParentCacheDriver<E, Discord.Role>>,
|
|
201
203
|
) =>
|
|
202
|
-
Effect.gen(function*
|
|
204
|
+
Effect.gen(function*(_) {
|
|
203
205
|
const driver = yield* _(makeDriver)
|
|
204
206
|
const gateway = yield* _(DiscordGateway)
|
|
205
207
|
const rest = yield* _(DiscordREST)
|
package/src/Cache.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { CacheDriver, ParentCacheDriver } from "dfx/Cache/driver"
|
|
2
|
-
import * as Effect from "@effect/io/Effect"
|
|
3
1
|
import * as Option from "@effect/data/Option"
|
|
2
|
+
import * as Effect from "@effect/io/Effect"
|
|
4
3
|
import * as Stream from "@effect/stream/Stream"
|
|
4
|
+
import type { CacheDriver, ParentCacheDriver } from "dfx/Cache/driver"
|
|
5
5
|
|
|
6
6
|
export * from "dfx/Cache/driver"
|
|
7
7
|
export {
|
|
@@ -97,7 +97,7 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
|
|
|
97
97
|
Effect.all(
|
|
98
98
|
entries.map(([id, a]) => driver.set(parentId, id, a)),
|
|
99
99
|
{ concurrency: "unbounded" },
|
|
100
|
-
)
|
|
100
|
+
)
|
|
101
101
|
),
|
|
102
102
|
Effect.map(entries => new Map(entries) as ReadonlyMap<string, A>),
|
|
103
103
|
),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type WebSocket from "isomorphic-ws"
|
|
3
|
-
import type * as Discord from "dfx/types"
|
|
1
|
+
import { Tag } from "@effect/data/Context"
|
|
4
2
|
import * as Effect from "@effect/io/Effect"
|
|
5
3
|
import * as Layer from "@effect/io/Layer"
|
|
6
|
-
import { Tag } from "@effect/data/Context"
|
|
7
4
|
import * as Ref from "@effect/io/Ref"
|
|
5
|
+
import { LiveWS, Reconnect, WS } from "dfx/DiscordGateway/WS"
|
|
6
|
+
import type * as Discord from "dfx/types"
|
|
7
|
+
import type WebSocket from "isomorphic-ws"
|
|
8
8
|
|
|
9
9
|
export type Message = Discord.GatewayPayload | Reconnect
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ export const LiveJsonDiscordWSCodec = Layer.succeed(DiscordWSCodec, {
|
|
|
28
28
|
decode: p => JSON.parse(p.toString("utf8")),
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
-
const make = Effect.gen(function*
|
|
31
|
+
const make = Effect.gen(function*(_) {
|
|
32
32
|
const ws = yield* _(WS)
|
|
33
33
|
const encoding = yield* _(DiscordWSCodec)
|
|
34
34
|
|
|
@@ -38,23 +38,22 @@ const make = Effect.gen(function* (_) {
|
|
|
38
38
|
url = "wss://gateway.discord.gg/",
|
|
39
39
|
version = 10,
|
|
40
40
|
}: OpenOpts) =>
|
|
41
|
-
Effect.gen(function*
|
|
41
|
+
Effect.gen(function*(_) {
|
|
42
42
|
const urlRef = yield* _(
|
|
43
43
|
Ref.make(`${url}?v=${version}&encoding=${encoding.type}`),
|
|
44
44
|
)
|
|
45
45
|
const setUrl = (url: string) =>
|
|
46
46
|
Ref.set(urlRef, `${url}?v=${version}&encoding=${encoding.type}`)
|
|
47
47
|
const takeOutbound = Effect.map(outbound, msg =>
|
|
48
|
-
msg === Reconnect ? msg : encoding.encode(msg)
|
|
49
|
-
)
|
|
48
|
+
msg === Reconnect ? msg : encoding.encode(msg))
|
|
50
49
|
const socket = yield* _(ws.connect(urlRef, takeOutbound, onConnecting))
|
|
51
50
|
const take = Effect.map(socket.take, encoding.decode)
|
|
52
51
|
|
|
53
52
|
const run = Effect.retryWhile(
|
|
54
53
|
socket.run,
|
|
55
54
|
e =>
|
|
56
|
-
(e._tag === "WebSocketCloseError" && e.code < 2000)
|
|
57
|
-
(e._tag === "WebSocketError" && e.reason === "open-timeout"),
|
|
55
|
+
(e._tag === "WebSocketCloseError" && e.code < 2000)
|
|
56
|
+
|| (e._tag === "WebSocketError" && e.reason === "open-timeout"),
|
|
58
57
|
)
|
|
59
58
|
|
|
60
59
|
return {
|
|
@@ -35,7 +35,7 @@ export const send = (
|
|
|
35
35
|
seqRef: Ref.Ref<Option.Option<number>>,
|
|
36
36
|
send: (p: DiscordWS.Message) => Effect.Effect<never, never, boolean>,
|
|
37
37
|
) =>
|
|
38
|
-
Effect.gen(function*
|
|
38
|
+
Effect.gen(function*(_) {
|
|
39
39
|
const ackedRef = yield* _(Ref.make(true))
|
|
40
40
|
|
|
41
41
|
const heartbeats = EffectU.foreverSwitch(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as Option from "@effect/data/Option"
|
|
2
2
|
import * as Effect from "@effect/io/Effect"
|
|
3
3
|
import * as Ref from "@effect/io/Ref"
|
|
4
|
-
import type * as Discord from "dfx/types"
|
|
5
4
|
import * as Stream from "@effect/stream/Stream"
|
|
5
|
+
import type * as Discord from "dfx/types"
|
|
6
6
|
|
|
7
7
|
export const opCode =
|
|
8
8
|
<R, E>(source: Stream.Stream<R, E, Discord.GatewayPayload>) =>
|
|
@@ -13,16 +13,15 @@ export const opCode =
|
|
|
13
13
|
Stream.filter((p): p is Discord.GatewayPayload<T> => p.op === code),
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
const maybeUpdateRef =
|
|
17
|
-
<T
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
(_
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
16
|
+
const maybeUpdateRef = <T>(
|
|
17
|
+
f: (p: Discord.GatewayPayload) => Option.Option<T>,
|
|
18
|
+
ref: Ref.Ref<Option.Option<T>>,
|
|
19
|
+
) =>
|
|
20
|
+
(_: Discord.GatewayPayload): Effect.Effect<never, never, void> =>
|
|
21
|
+
Option.match(f(_), {
|
|
22
|
+
onNone: () => Effect.unit,
|
|
23
|
+
onSome: a => Ref.set(ref, Option.some(a)),
|
|
24
|
+
})
|
|
26
25
|
|
|
27
26
|
export const latest = <T>(
|
|
28
27
|
f: (p: Discord.GatewayPayload) => Option.Option<T>,
|
|
@@ -36,6 +35,5 @@ export const latest = <T>(
|
|
|
36
35
|
> =>
|
|
37
36
|
Effect.map(
|
|
38
37
|
Ref.make<Option.Option<T>>(Option.none()),
|
|
39
|
-
|
|
40
38
|
ref => [ref, maybeUpdateRef(f, ref)] as const,
|
|
41
39
|
)
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import * as Chunk from "@effect/data/Chunk"
|
|
2
|
+
import { Tag } from "@effect/data/Context"
|
|
3
|
+
import * as Duration from "@effect/data/Duration"
|
|
4
|
+
import * as Option from "@effect/data/Option"
|
|
5
|
+
import * as ConfigSecret from "@effect/io/Config/Secret"
|
|
6
|
+
import * as Effect from "@effect/io/Effect"
|
|
7
|
+
import * as Hub from "@effect/io/Hub"
|
|
8
|
+
import * as Layer from "@effect/io/Layer"
|
|
9
|
+
import * as Queue from "@effect/io/Queue"
|
|
10
|
+
import * as Ref from "@effect/io/Ref"
|
|
1
11
|
import { DiscordConfig } from "dfx/DiscordConfig"
|
|
2
|
-
import { LiveRateLimiter, RateLimiter } from "dfx/RateLimit"
|
|
3
12
|
import type { Message } from "dfx/DiscordGateway/DiscordWS"
|
|
4
13
|
import { DiscordWS, LiveDiscordWS } from "dfx/DiscordGateway/DiscordWS"
|
|
5
14
|
import * as Heartbeats from "dfx/DiscordGateway/Shard/heartbeats"
|
|
@@ -8,17 +17,8 @@ import * as InvalidSession from "dfx/DiscordGateway/Shard/invalidSession"
|
|
|
8
17
|
import * as Utils from "dfx/DiscordGateway/Shard/utils"
|
|
9
18
|
import { Reconnect } from "dfx/DiscordGateway/WS"
|
|
10
19
|
import { Log } from "dfx/Log"
|
|
20
|
+
import { LiveRateLimiter, RateLimiter } from "dfx/RateLimit"
|
|
11
21
|
import * as Discord from "dfx/types"
|
|
12
|
-
import * as Effect from "@effect/io/Effect"
|
|
13
|
-
import * as Layer from "@effect/io/Layer"
|
|
14
|
-
import { Tag } from "@effect/data/Context"
|
|
15
|
-
import * as Option from "@effect/data/Option"
|
|
16
|
-
import * as Hub from "@effect/io/Hub"
|
|
17
|
-
import * as Queue from "@effect/io/Queue"
|
|
18
|
-
import * as Ref from "@effect/io/Ref"
|
|
19
|
-
import * as Duration from "@effect/data/Duration"
|
|
20
|
-
import * as Chunk from "@effect/data/Chunk"
|
|
21
|
-
import * as ConfigSecret from "@effect/io/Config/Secret"
|
|
22
22
|
|
|
23
23
|
const enum Phase {
|
|
24
24
|
Connecting,
|
|
@@ -26,7 +26,7 @@ const enum Phase {
|
|
|
26
26
|
Connected,
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export const make = Effect.gen(function*
|
|
29
|
+
export const make = Effect.gen(function*(_) {
|
|
30
30
|
const { gateway, token } = yield* _(DiscordConfig)
|
|
31
31
|
const limiter = yield* _(RateLimiter)
|
|
32
32
|
const dws = yield* _(DiscordWS)
|
|
@@ -37,7 +37,7 @@ export const make = Effect.gen(function* (_) {
|
|
|
37
37
|
hub: Hub.Hub<Discord.GatewayPayload<Discord.ReceiveEvent>>,
|
|
38
38
|
sendQueue: Queue.Dequeue<Discord.GatewayPayload<Discord.SendEvent>>,
|
|
39
39
|
) =>
|
|
40
|
-
Effect.gen(function*
|
|
40
|
+
Effect.gen(function*(_) {
|
|
41
41
|
const outboundQueue = yield* _(Queue.unbounded<Message>())
|
|
42
42
|
const pendingQueue = yield* _(Queue.unbounded<Message>())
|
|
43
43
|
const phase = yield* _(Ref.make(Phase.Connecting))
|
|
@@ -52,15 +52,13 @@ export const make = Effect.gen(function* (_) {
|
|
|
52
52
|
Effect.flatMap(Ref.get(phase), phase =>
|
|
53
53
|
phase === Phase.Connected
|
|
54
54
|
? Queue.offer(outboundQueue, p)
|
|
55
|
-
: Queue.offer(pendingQueue, p)
|
|
56
|
-
)
|
|
55
|
+
: Queue.offer(pendingQueue, p))
|
|
57
56
|
|
|
58
57
|
const heartbeatSend = (p: Message) =>
|
|
59
58
|
Effect.flatMap(Ref.get(phase), phase =>
|
|
60
59
|
phase !== Phase.Connecting
|
|
61
60
|
? Queue.offer(outboundQueue, p)
|
|
62
|
-
: Effect.succeed(false)
|
|
63
|
-
)
|
|
61
|
+
: Effect.succeed(false))
|
|
64
62
|
|
|
65
63
|
const prioritySend = (p: Message) => Queue.offer(outboundQueue, p)
|
|
66
64
|
|
|
@@ -77,12 +75,12 @@ export const make = Effect.gen(function* (_) {
|
|
|
77
75
|
Chunk.filter(
|
|
78
76
|
msgs,
|
|
79
77
|
msg =>
|
|
80
|
-
msg !== Reconnect
|
|
81
|
-
msg.op !== Discord.GatewayOpcode.IDENTIFY
|
|
82
|
-
msg.op !== Discord.GatewayOpcode.RESUME
|
|
83
|
-
msg.op !== Discord.GatewayOpcode.HEARTBEAT,
|
|
78
|
+
msg !== Reconnect
|
|
79
|
+
&& msg.op !== Discord.GatewayOpcode.IDENTIFY
|
|
80
|
+
&& msg.op !== Discord.GatewayOpcode.RESUME
|
|
81
|
+
&& msg.op !== Discord.GatewayOpcode.HEARTBEAT,
|
|
84
82
|
),
|
|
85
|
-
)
|
|
83
|
+
)
|
|
86
84
|
),
|
|
87
85
|
Effect.zipRight(setPhase(Phase.Connecting)),
|
|
88
86
|
)
|
|
@@ -97,7 +95,7 @@ export const make = Effect.gen(function* (_) {
|
|
|
97
95
|
p.op === Discord.GatewayOpcode.DISPATCH && p.t === "READY",
|
|
98
96
|
),
|
|
99
97
|
Option.map(p => p.d!),
|
|
100
|
-
)
|
|
98
|
+
)
|
|
101
99
|
),
|
|
102
100
|
)
|
|
103
101
|
const [latestSequence, updateLatestSequence] = yield* _(
|
|
@@ -198,4 +196,5 @@ export const LiveShard = Layer.provide(
|
|
|
198
196
|
)
|
|
199
197
|
|
|
200
198
|
export interface RunningShard
|
|
201
|
-
extends Effect.Effect.Success<ReturnType<Shard["connect"]>>
|
|
199
|
+
extends Effect.Effect.Success<ReturnType<Shard["connect"]>>
|
|
200
|
+
{}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as Effect from "@effect/io/Effect"
|
|
2
|
-
import * as Layer from "@effect/io/Layer"
|
|
3
1
|
import { Tag } from "@effect/data/Context"
|
|
4
2
|
import * as Option from "@effect/data/Option"
|
|
3
|
+
import * as Effect from "@effect/io/Effect"
|
|
4
|
+
import * as Layer from "@effect/io/Layer"
|
|
5
5
|
|
|
6
6
|
export interface ClaimIdContext {
|
|
7
7
|
sharderCount: number
|
|
@@ -24,7 +24,7 @@ const claimRepeatPolicy = Schedule.fixed("3 minutes").pipe(
|
|
|
24
24
|
Schedule.passthrough,
|
|
25
25
|
) as Schedule.Schedule<never, Option.Option<number>, Option.Some<number>>
|
|
26
26
|
|
|
27
|
-
const make = Effect.gen(function*
|
|
27
|
+
const make = Effect.gen(function*(_) {
|
|
28
28
|
const store = yield* _(ShardStore)
|
|
29
29
|
const rest = yield* _(DiscordREST)
|
|
30
30
|
const { gateway: config } = yield* _(DiscordConfig)
|
|
@@ -33,7 +33,7 @@ const make = Effect.gen(function* (_) {
|
|
|
33
33
|
const currentShards = yield* _(Ref.make(HashSet.empty<RunningShard>()))
|
|
34
34
|
|
|
35
35
|
const takeConfig = (totalCount: number) =>
|
|
36
|
-
Effect.gen(function*
|
|
36
|
+
Effect.gen(function*(_) {
|
|
37
37
|
const currentCount = yield* _(Ref.make(0))
|
|
38
38
|
|
|
39
39
|
const claimId = (
|
|
@@ -68,7 +68,7 @@ const make = Effect.gen(function* (_) {
|
|
|
68
68
|
reset_after: 0,
|
|
69
69
|
max_concurrency: 1,
|
|
70
70
|
},
|
|
71
|
-
})
|
|
71
|
+
})
|
|
72
72
|
),
|
|
73
73
|
)
|
|
74
74
|
|
|
@@ -76,7 +76,7 @@ const make = Effect.gen(function* (_) {
|
|
|
76
76
|
hub: Hub.Hub<Discord.GatewayPayload<Discord.ReceiveEvent>>,
|
|
77
77
|
sendQueue: Queue.Dequeue<Discord.GatewayPayload<Discord.SendEvent>>,
|
|
78
78
|
) =>
|
|
79
|
-
Effect.gen(function*
|
|
79
|
+
Effect.gen(function*(_) {
|
|
80
80
|
const deferred = yield* _(
|
|
81
81
|
Deferred.make<WebSocketError | WebSocketCloseError, never>(),
|
|
82
82
|
)
|
|
@@ -93,10 +93,10 @@ const make = Effect.gen(function* (_) {
|
|
|
93
93
|
`dfx.sharder.${id % concurrency}`,
|
|
94
94
|
Duration.millis(config.identifyRateLimit[0]),
|
|
95
95
|
config.identifyRateLimit[1],
|
|
96
|
-
)
|
|
96
|
+
)
|
|
97
97
|
),
|
|
98
98
|
Effect.flatMap(c =>
|
|
99
|
-
shard.connect([c.id, c.totalCount], hub, sendQueue)
|
|
99
|
+
shard.connect([c.id, c.totalCount], hub, sendQueue)
|
|
100
100
|
),
|
|
101
101
|
Effect.flatMap(shard =>
|
|
102
102
|
Effect.acquireUseRelease(
|
|
@@ -106,7 +106,7 @@ const make = Effect.gen(function* (_) {
|
|
|
106
106
|
).pipe(
|
|
107
107
|
Effect.catchAllCause(_ => Deferred.failCause(deferred, _)),
|
|
108
108
|
Effect.fork,
|
|
109
|
-
)
|
|
109
|
+
)
|
|
110
110
|
),
|
|
111
111
|
Effect.forever,
|
|
112
112
|
)
|
package/src/DiscordGateway/WS.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { Tag } from "@effect/data/Context"
|
|
2
|
+
import * as Duration from "@effect/data/Duration"
|
|
3
3
|
import * as Effect from "@effect/io/Effect"
|
|
4
4
|
import * as Layer from "@effect/io/Layer"
|
|
5
|
-
import { Tag } from "@effect/data/Context"
|
|
6
|
-
import * as Ref from "@effect/io/Ref"
|
|
7
5
|
import * as Queue from "@effect/io/Queue"
|
|
6
|
+
import * as Ref from "@effect/io/Ref"
|
|
8
7
|
import * as Runtime from "@effect/io/Runtime"
|
|
9
|
-
import
|
|
8
|
+
import { Log } from "dfx/Log"
|
|
9
|
+
import WebSocket from "isomorphic-ws"
|
|
10
10
|
|
|
11
11
|
export const Reconnect = Symbol()
|
|
12
12
|
export type Reconnect = typeof Reconnect
|
|
@@ -38,7 +38,7 @@ const socket = (urlRef: Ref.Ref<string>) =>
|
|
|
38
38
|
// eslint-disable-next-line no-extra-semi
|
|
39
39
|
;(ws as any).removeAllListeners?.()
|
|
40
40
|
ws.close()
|
|
41
|
-
})
|
|
41
|
+
})
|
|
42
42
|
),
|
|
43
43
|
)
|
|
44
44
|
|
|
@@ -72,7 +72,7 @@ const offer = (
|
|
|
72
72
|
resume(Effect.fail(new WebSocketCloseError(e.code, e.reason)))
|
|
73
73
|
})
|
|
74
74
|
},
|
|
75
|
-
)
|
|
75
|
+
)
|
|
76
76
|
),
|
|
77
77
|
)
|
|
78
78
|
|
|
@@ -117,7 +117,7 @@ const send = (
|
|
|
117
117
|
Effect.forever,
|
|
118
118
|
)
|
|
119
119
|
|
|
120
|
-
const make = Effect.gen(function*
|
|
120
|
+
const make = Effect.gen(function*(_) {
|
|
121
121
|
const log = yield* _(Log)
|
|
122
122
|
|
|
123
123
|
const connect = (
|
|
@@ -126,7 +126,7 @@ const make = Effect.gen(function* (_) {
|
|
|
126
126
|
onConnecting = Effect.unit,
|
|
127
127
|
openTimeout = Duration.seconds(3),
|
|
128
128
|
) =>
|
|
129
|
-
Effect.gen(function*
|
|
129
|
+
Effect.gen(function*(_) {
|
|
130
130
|
const queue = yield* _(Queue.unbounded<WebSocket.Data>())
|
|
131
131
|
|
|
132
132
|
const run = onConnecting.pipe(
|
|
@@ -140,7 +140,7 @@ const make = Effect.gen(function* (_) {
|
|
|
140
140
|
),
|
|
141
141
|
],
|
|
142
142
|
{ concurrency: "unbounded", discard: true },
|
|
143
|
-
)
|
|
143
|
+
)
|
|
144
144
|
),
|
|
145
145
|
Effect.scoped,
|
|
146
146
|
Effect.retryWhile(isReconnect),
|
package/src/DiscordGateway.ts
CHANGED
|
@@ -11,14 +11,13 @@ import type { WebSocketCloseError, WebSocketError } from "dfx/DiscordGateway/WS"
|
|
|
11
11
|
import type * as Discord from "dfx/types"
|
|
12
12
|
import * as EffectUtils from "dfx/utils/Effect"
|
|
13
13
|
|
|
14
|
-
const fromDispatchFactory =
|
|
15
|
-
<R, E
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Stream.filter(source, p => p.t === event).pipe(Stream.map(p => p.d! as any))
|
|
14
|
+
const fromDispatchFactory = <R, E>(
|
|
15
|
+
source: Stream.Stream<R, E, Discord.GatewayPayload<Discord.ReceiveEvent>>,
|
|
16
|
+
) =>
|
|
17
|
+
<K extends keyof Discord.ReceiveEvents>(
|
|
18
|
+
event: K,
|
|
19
|
+
): Stream.Stream<R, E, Discord.ReceiveEvents[K]> =>
|
|
20
|
+
Stream.filter(source, p => p.t === event).pipe(Stream.map(p => p.d! as any))
|
|
22
21
|
|
|
23
22
|
const handleDispatchFactory =
|
|
24
23
|
(hub: Hub.Hub<Discord.GatewayPayload<Discord.ReceiveEvent>>) =>
|
|
@@ -58,7 +57,7 @@ export interface DiscordGateway {
|
|
|
58
57
|
}
|
|
59
58
|
export const DiscordGateway = Tag<DiscordGateway>()
|
|
60
59
|
|
|
61
|
-
export const make = Effect.gen(function*
|
|
60
|
+
export const make = Effect.gen(function*(_) {
|
|
62
61
|
const sharder = yield* _(Sharder)
|
|
63
62
|
const hub = yield* _(
|
|
64
63
|
Hub.unbounded<Discord.GatewayPayload<Discord.ReceiveEvent>>(),
|
package/src/DiscordREST/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as Http from "@effect-http/client"
|
|
2
|
-
import type { DiscordRESTError } from "dfx/DiscordREST"
|
|
3
2
|
import type * as Effect from "@effect/io/Effect"
|
|
3
|
+
import type { DiscordRESTError } from "dfx/DiscordREST"
|
|
4
4
|
|
|
5
5
|
export interface ResponseWithData<A> extends Http.response.Response {
|
|
6
6
|
readonly json: Effect.Effect<never, Http.ResponseDecodeError, A>
|
package/src/DiscordREST/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as Option from "@effect/data/Option"
|
|
2
1
|
import * as Duration from "@effect/data/Duration"
|
|
2
|
+
import * as Option from "@effect/data/Option"
|
|
3
3
|
|
|
4
4
|
const majorResources = ["channels", "guilds", "webhooks"] as const
|
|
5
5
|
|
|
@@ -7,8 +7,10 @@ export const routeFromConfig = (path: string, method: string) => {
|
|
|
7
7
|
// Only keep major ID's
|
|
8
8
|
const routeURL = path
|
|
9
9
|
.split("?")[0]
|
|
10
|
-
.replace(
|
|
11
|
-
|
|
10
|
+
.replace(
|
|
11
|
+
/\/([A-Za-z]+)\/(\d{16,21}|@me)/g,
|
|
12
|
+
(match, resource) =>
|
|
13
|
+
majorResources.includes(resource) ? match : `/${resource}`,
|
|
12
14
|
)
|
|
13
15
|
// Strip reactions
|
|
14
16
|
.replace(/\/reactions\/(.*)/, "/reactions")
|
package/src/DiscordREST.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
routeFromConfig,
|
|
18
18
|
} from "dfx/DiscordREST/utils"
|
|
19
19
|
import { Log } from "dfx/Log"
|
|
20
|
-
import { LiveRateLimiter,
|
|
20
|
+
import { LiveRateLimiter, RateLimiter, RateLimitStore } from "dfx/RateLimit"
|
|
21
21
|
import * as Discord from "dfx/types"
|
|
22
22
|
import { LIB_VERSION } from "dfx/version"
|
|
23
23
|
|
|
@@ -28,7 +28,7 @@ export class DiscordRESTError {
|
|
|
28
28
|
|
|
29
29
|
export { ResponseDecodeError } from "@effect-http/client"
|
|
30
30
|
|
|
31
|
-
const make = Effect.gen(function*
|
|
31
|
+
const make = Effect.gen(function*(_) {
|
|
32
32
|
const { rest, token } = yield* _(DiscordConfig)
|
|
33
33
|
|
|
34
34
|
const http = yield* _(Http.HttpRequestExecutor)
|
|
@@ -64,7 +64,7 @@ const make = Effect.gen(function* (_) {
|
|
|
64
64
|
Effect.tap(invalid =>
|
|
65
65
|
invalid
|
|
66
66
|
? maybeWait("dfx.rest.invalid", Duration.minutes(10), 10000)
|
|
67
|
-
: Effect.unit
|
|
67
|
+
: Effect.unit
|
|
68
68
|
),
|
|
69
69
|
Effect.asUnit,
|
|
70
70
|
)
|
|
@@ -86,7 +86,7 @@ const make = Effect.gen(function* (_) {
|
|
|
86
86
|
bucket.limit,
|
|
87
87
|
),
|
|
88
88
|
),
|
|
89
|
-
})
|
|
89
|
+
})
|
|
90
90
|
),
|
|
91
91
|
)
|
|
92
92
|
|
|
@@ -95,8 +95,9 @@ const make = Effect.gen(function* (_) {
|
|
|
95
95
|
Effect.Do.pipe(
|
|
96
96
|
Effect.let("route", () => routeFromConfig(request.url, request.method)),
|
|
97
97
|
Effect.bind("rateLimit", () => rateLimitFromHeaders(response.headers)),
|
|
98
|
-
Effect.bind(
|
|
99
|
-
|
|
98
|
+
Effect.bind(
|
|
99
|
+
"hasBucket",
|
|
100
|
+
({ rateLimit }) => store.hasBucket(rateLimit.bucket),
|
|
100
101
|
),
|
|
101
102
|
Effect.flatMap(({ hasBucket, rateLimit, route }) => {
|
|
102
103
|
const effectsToRun = [
|
|
@@ -110,10 +111,9 @@ const make = Effect.gen(function* (_) {
|
|
|
110
111
|
store.putBucket({
|
|
111
112
|
key: rateLimit.bucket,
|
|
112
113
|
resetAfter: Duration.toMillis(rateLimit.retryAfter),
|
|
113
|
-
limit:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
: rateLimit.limit,
|
|
114
|
+
limit: !hasBucket && rateLimit.remaining > 0
|
|
115
|
+
? rateLimit.remaining
|
|
116
|
+
: rateLimit.limit,
|
|
117
117
|
}),
|
|
118
118
|
)
|
|
119
119
|
}
|
|
@@ -134,19 +134,20 @@ const make = Effect.gen(function* (_) {
|
|
|
134
134
|
Http.updateUrl(req, _ => `${rest.baseUrl}${_}`),
|
|
135
135
|
Http.setHeaders({
|
|
136
136
|
Authorization: `Bot ${ConfigSecret.value(token)}`,
|
|
137
|
-
"User-Agent":
|
|
137
|
+
"User-Agent":
|
|
138
|
+
`DiscordBot (https://github.com/tim-smart/dfx, ${LIB_VERSION})`,
|
|
138
139
|
}),
|
|
139
|
-
)
|
|
140
|
+
)
|
|
140
141
|
),
|
|
141
142
|
Http.executor.catchAll(error =>
|
|
142
143
|
error._tag === "StatusCodeError"
|
|
143
144
|
? error.response.json.pipe(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
: Effect.fail(new DiscordRESTError(error))
|
|
145
|
+
Effect.mapError(_ => new DiscordRESTError(_)),
|
|
146
|
+
Effect.flatMap(body =>
|
|
147
|
+
Effect.fail(new DiscordRESTError(error, body))
|
|
148
|
+
),
|
|
149
|
+
)
|
|
150
|
+
: Effect.fail(new DiscordRESTError(error))
|
|
150
151
|
),
|
|
151
152
|
)
|
|
152
153
|
|
|
@@ -194,8 +195,9 @@ const make = Effect.gen(function* (_) {
|
|
|
194
195
|
Effect.zipRight(updateBuckets(request, response)),
|
|
195
196
|
Effect.zipRight(
|
|
196
197
|
Effect.sleep(
|
|
197
|
-
Option.getOrElse(
|
|
198
|
-
|
|
198
|
+
Option.getOrElse(
|
|
199
|
+
retryAfter(response.headers),
|
|
200
|
+
() => Duration.seconds(5),
|
|
199
201
|
),
|
|
200
202
|
),
|
|
201
203
|
),
|
|
@@ -222,9 +224,9 @@ const make = Effect.gen(function* (_) {
|
|
|
222
224
|
request = Http.appendParams(request, params as any)
|
|
223
225
|
}
|
|
224
226
|
} else if (
|
|
225
|
-
params
|
|
226
|
-
request.body._tag === "Some"
|
|
227
|
-
request.body.value._tag === "FormDataBody"
|
|
227
|
+
params
|
|
228
|
+
&& request.body._tag === "Some"
|
|
229
|
+
&& request.body.value._tag === "FormDataBody"
|
|
228
230
|
) {
|
|
229
231
|
request.body.value.value.append("payload_json", JSON.stringify(params))
|
|
230
232
|
} else if (params) {
|
|
@@ -242,7 +244,8 @@ const make = Effect.gen(function* (_) {
|
|
|
242
244
|
})
|
|
243
245
|
|
|
244
246
|
export interface DiscordREST
|
|
245
|
-
extends Discord.Endpoints<Partial<Http.MakeOptions>>
|
|
247
|
+
extends Discord.Endpoints<Partial<Http.MakeOptions>>
|
|
248
|
+
{
|
|
246
249
|
readonly executor: <A = unknown>(
|
|
247
250
|
request: Http.Request,
|
|
248
251
|
) => Effect.Effect<never, DiscordRESTError, ResponseWithData<A>>
|
package/src/Helpers/flags.ts
CHANGED
|
@@ -33,16 +33,14 @@ export function toList<T extends Flags<any>>(
|
|
|
33
33
|
* Returns a function that converts a list of flags names to a bigint bitfield.
|
|
34
34
|
*/
|
|
35
35
|
export const fromListBigint =
|
|
36
|
-
<T extends Flags<bigint>>(flags: T) =>
|
|
37
|
-
(list: Array<keyof T>) =>
|
|
36
|
+
<T extends Flags<bigint>>(flags: T) => (list: Array<keyof T>) =>
|
|
38
37
|
list.reduce((acc, key) => acc | flags[key], BigInt(0))
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
40
|
* Returns a function that converts a list of flags names to a bitfield.
|
|
42
41
|
*/
|
|
43
42
|
export const fromList =
|
|
44
|
-
<T extends Flags<number>>(flags: T) =>
|
|
45
|
-
(list: Array<keyof T>) =>
|
|
43
|
+
<T extends Flags<number>>(flags: T) => (list: Array<keyof T>) =>
|
|
46
44
|
list.reduce((acc, key) => acc | flags[key], 0)
|
|
47
45
|
|
|
48
46
|
/**
|
package/src/Helpers/intents.ts
CHANGED
|
@@ -9,10 +9,9 @@ export const ALL = Flags.all(Discord.GatewayIntents)
|
|
|
9
9
|
/**
|
|
10
10
|
* Privileged intents
|
|
11
11
|
*/
|
|
12
|
-
export const PRIVILEGED =
|
|
13
|
-
Discord.GatewayIntents.
|
|
14
|
-
Discord.GatewayIntents.
|
|
15
|
-
Discord.GatewayIntents.MESSAGE_CONTENT
|
|
12
|
+
export const PRIVILEGED = Discord.GatewayIntents.GUILD_PRESENCES
|
|
13
|
+
| Discord.GatewayIntents.GUILD_MEMBERS
|
|
14
|
+
| Discord.GatewayIntents.MESSAGE_CONTENT
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* Un-privileged intents
|