dfx 0.86.0 → 0.88.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 +15 -15
- package/Cache/driver.d.ts.map +1 -1
- package/Cache/driver.js.map +1 -1
- package/Cache/memory.d.ts +2 -2
- package/Cache/memory.d.ts.map +1 -1
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.d.ts +2 -2
- package/Cache/memoryTTL.d.ts.map +1 -1
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.d.ts +13 -16
- package/Cache/prelude.d.ts.map +1 -1
- package/Cache/prelude.js +4 -4
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts +25 -25
- package/Cache.d.ts.map +1 -1
- package/Cache.js.map +1 -1
- package/DiscordConfig.d.ts +3 -4
- package/DiscordConfig.d.ts.map +1 -1
- package/DiscordConfig.js +1 -1
- package/DiscordConfig.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +10 -11
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +2 -2
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Messaging.d.ts +12 -13
- package/DiscordGateway/Messaging.d.ts.map +1 -1
- package/DiscordGateway/Messaging.js +1 -1
- package/DiscordGateway/Messaging.js.map +1 -1
- package/DiscordGateway/Shard/heartbeats.d.ts +1 -1
- package/DiscordGateway/Shard/heartbeats.d.ts.map +1 -1
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/identify.d.ts +1 -1
- package/DiscordGateway/Shard/identify.d.ts.map +1 -1
- package/DiscordGateway/Shard/identify.js.map +1 -1
- package/DiscordGateway/Shard/invalidSession.d.ts +1 -1
- package/DiscordGateway/Shard/invalidSession.d.ts.map +1 -1
- package/DiscordGateway/Shard/utils.d.ts +2 -2
- package/DiscordGateway/Shard/utils.d.ts.map +1 -1
- package/DiscordGateway/Shard/utils.js.map +1 -1
- package/DiscordGateway/Shard.d.ts +10 -11
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +1 -1
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +5 -6
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +1 -1
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts +3 -4
- package/DiscordGateway/Sharder.d.ts.map +1 -1
- package/DiscordGateway/Sharder.js +1 -1
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts +7 -8
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +1 -1
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts +8 -9
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js +1 -1
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/types.d.ts +6 -2
- package/DiscordREST/types.d.ts.map +1 -1
- package/DiscordREST.d.ts +4 -4
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +19 -2
- package/DiscordREST.js.map +1 -1
- package/Helpers/permissions.d.ts +3 -3
- package/Helpers/permissions.d.ts.map +1 -1
- package/Interactions/builder.d.ts +12 -12
- package/Interactions/builder.d.ts.map +1 -1
- package/Interactions/context.d.ts +22 -23
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +6 -6
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +23 -23
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/gateway.d.ts +5 -6
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js +5 -5
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts +2 -2
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/index.d.ts +5 -5
- package/Interactions/utils.d.ts +26 -26
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts +7 -8
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js +1 -1
- package/Interactions/webhook.js.map +1 -1
- package/RateLimit.d.ts +11 -12
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js +2 -2
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +2 -2
- package/mjs/Cache/driver.mjs.map +1 -1
- package/mjs/Cache/memory.mjs.map +1 -1
- package/mjs/Cache/memoryTTL.mjs.map +1 -1
- package/mjs/Cache/prelude.mjs +4 -4
- package/mjs/Cache/prelude.mjs.map +1 -1
- package/mjs/Cache.mjs.map +1 -1
- package/mjs/DiscordConfig.mjs +2 -2
- package/mjs/DiscordConfig.mjs.map +1 -1
- package/mjs/DiscordGateway/DiscordWS.mjs +3 -3
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -1
- package/mjs/DiscordGateway/Messaging.mjs +2 -2
- package/mjs/DiscordGateway/Messaging.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/identify.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/utils.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard.mjs +2 -2
- 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 +2 -2
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -1
- package/mjs/DiscordGateway/WS.mjs +2 -2
- package/mjs/DiscordGateway/WS.mjs.map +1 -1
- package/mjs/DiscordGateway.mjs +2 -2
- package/mjs/DiscordGateway.mjs.map +1 -1
- package/mjs/DiscordREST.mjs +20 -3
- package/mjs/DiscordREST.mjs.map +1 -1
- package/mjs/Interactions/context.mjs +7 -7
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/gateway.mjs +6 -6
- package/mjs/Interactions/gateway.mjs.map +1 -1
- package/mjs/Interactions/utils.mjs.map +1 -1
- package/mjs/Interactions/webhook.mjs +2 -2
- package/mjs/Interactions/webhook.mjs.map +1 -1
- package/mjs/RateLimit.mjs +3 -3
- package/mjs/RateLimit.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/package.json +4 -4
- package/src/Cache/driver.ts +15 -21
- package/src/Cache/memory.ts +1 -7
- package/src/Cache/memoryTTL.ts +3 -4
- package/src/Cache/prelude.ts +33 -34
- package/src/Cache.ts +31 -31
- package/src/DiscordConfig.ts +4 -4
- package/src/DiscordGateway/DiscordWS.ts +8 -7
- package/src/DiscordGateway/Messaging.ts +9 -8
- package/src/DiscordGateway/Shard/heartbeats.ts +2 -2
- package/src/DiscordGateway/Shard/identify.ts +0 -2
- package/src/DiscordGateway/Shard/invalidSession.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +4 -6
- package/src/DiscordGateway/Shard.ts +2 -2
- package/src/DiscordGateway/ShardStore.ts +5 -7
- package/src/DiscordGateway/Sharder.ts +10 -4
- package/src/DiscordGateway/WS.ts +7 -10
- package/src/DiscordGateway.ts +8 -12
- package/src/DiscordREST/types.ts +7 -6
- package/src/DiscordREST.ts +36 -7
- package/src/Helpers/permissions.ts +1 -1
- package/src/Interactions/builder.ts +11 -11
- package/src/Interactions/context.ts +25 -24
- package/src/Interactions/definitions.ts +35 -34
- package/src/Interactions/gateway.ts +19 -18
- package/src/Interactions/handlers.ts +4 -4
- package/src/Interactions/utils.ts +10 -12
- package/src/Interactions/webhook.ts +17 -16
- package/src/RateLimit.ts +9 -9
- package/src/utils/Effect.ts +9 -9
- package/src/version.ts +1 -1
- package/utils/Effect.d.ts +2 -2
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/webhooks.d.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
3
|
import * as Layer from "effect/Layer"
|
|
4
4
|
import * as Ref from "effect/Ref"
|
|
@@ -12,8 +12,8 @@ export interface OpenOpts {
|
|
|
12
12
|
url?: string
|
|
13
13
|
version?: number
|
|
14
14
|
encoding?: DiscordWSCodec
|
|
15
|
-
outbound: Effect.Effect<
|
|
16
|
-
onConnecting?: Effect.Effect<
|
|
15
|
+
outbound: Effect.Effect<Message>
|
|
16
|
+
onConnecting?: Effect.Effect<void>
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface DiscordWSCodecService {
|
|
@@ -24,7 +24,7 @@ export interface DiscordWSCodecService {
|
|
|
24
24
|
export interface DiscordWSCodec {
|
|
25
25
|
readonly _: unique symbol
|
|
26
26
|
}
|
|
27
|
-
export const DiscordWSCodec =
|
|
27
|
+
export const DiscordWSCodec = GenericTag<DiscordWSCodec, DiscordWSCodecService>(
|
|
28
28
|
"dfx/DiscordGateway/DiscordWS/Codec",
|
|
29
29
|
)
|
|
30
30
|
export const JsonDiscordWSCodecLive = Layer.succeed(DiscordWSCodec, {
|
|
@@ -76,9 +76,10 @@ const make = Effect.gen(function* (_) {
|
|
|
76
76
|
export interface DiscordWS {
|
|
77
77
|
readonly _: unique symbol
|
|
78
78
|
}
|
|
79
|
-
export const DiscordWS =
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
export const DiscordWS = GenericTag<
|
|
80
|
+
DiscordWS,
|
|
81
|
+
Effect.Effect.Success<typeof make>
|
|
82
|
+
>("dfx/DiscordGateway/DiscordWS")
|
|
82
83
|
export const DiscordWSLive = Layer.provide(
|
|
83
84
|
Layer.effect(DiscordWS, make),
|
|
84
85
|
WSLive,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
3
|
import * as PubSub from "effect/PubSub"
|
|
4
4
|
import * as Layer from "effect/Layer"
|
|
@@ -9,11 +9,11 @@ import * as EffectUtils from "dfx/utils/Effect"
|
|
|
9
9
|
|
|
10
10
|
const fromDispatchFactory =
|
|
11
11
|
<R, E>(
|
|
12
|
-
source: Stream.Stream<
|
|
12
|
+
source: Stream.Stream<Discord.GatewayPayload<Discord.ReceiveEvent>, E, R>,
|
|
13
13
|
) =>
|
|
14
14
|
<K extends keyof Discord.ReceiveEvents>(
|
|
15
15
|
event: K,
|
|
16
|
-
): Stream.Stream<
|
|
16
|
+
): Stream.Stream<Discord.ReceiveEvents[K], E, R> =>
|
|
17
17
|
Stream.map(
|
|
18
18
|
Stream.filter(source, p => p.t === event),
|
|
19
19
|
p => p.d! as any,
|
|
@@ -23,8 +23,8 @@ const handleDispatchFactory =
|
|
|
23
23
|
(hub: PubSub.PubSub<Discord.GatewayPayload<Discord.ReceiveEvent>>) =>
|
|
24
24
|
<K extends keyof Discord.ReceiveEvents, R, E, A>(
|
|
25
25
|
event: K,
|
|
26
|
-
handle: (event: Discord.ReceiveEvents[K]) => Effect.Effect<
|
|
27
|
-
): Effect.Effect<
|
|
26
|
+
handle: (event: Discord.ReceiveEvents[K]) => Effect.Effect<A, E, R>,
|
|
27
|
+
): Effect.Effect<never, E, R> =>
|
|
28
28
|
EffectUtils.subscribeForEachPar(hub, _ => {
|
|
29
29
|
if (_.t === event) {
|
|
30
30
|
return handle(_.d as any)
|
|
@@ -66,7 +66,8 @@ export const make = Effect.gen(function* (_) {
|
|
|
66
66
|
export interface Messsaging {
|
|
67
67
|
readonly _: unique symbol
|
|
68
68
|
}
|
|
69
|
-
export const Messaging =
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
export const Messaging = GenericTag<
|
|
70
|
+
Messsaging,
|
|
71
|
+
Effect.Effect.Success<typeof make>
|
|
72
|
+
>("dfx/DiscordGateway/Messaging")
|
|
72
73
|
export const MesssagingLive = Layer.scoped(Messaging, make)
|
|
@@ -21,7 +21,7 @@ const payloadOrReconnect = (
|
|
|
21
21
|
) =>
|
|
22
22
|
Effect.flatMap(
|
|
23
23
|
Ref.get(ref),
|
|
24
|
-
(acked): Effect.Effect<
|
|
24
|
+
(acked): Effect.Effect<DiscordWS.Message> =>
|
|
25
25
|
acked ? payload(seqRef) : Effect.succeed(Reconnect),
|
|
26
26
|
)
|
|
27
27
|
|
|
@@ -29,7 +29,7 @@ export const send = (
|
|
|
29
29
|
hellos: Queue.Dequeue<Discord.GatewayPayload>,
|
|
30
30
|
acks: Queue.Dequeue<Discord.GatewayPayload>,
|
|
31
31
|
seqRef: Ref.Ref<Option.Option<number>>,
|
|
32
|
-
send: (p: DiscordWS.Message) => Effect.Effect<
|
|
32
|
+
send: (p: DiscordWS.Message) => Effect.Effect<boolean>,
|
|
33
33
|
) =>
|
|
34
34
|
Effect.flatMap(Ref.make(true), ackedRef => {
|
|
35
35
|
const heartbeats = EffectU.foreverSwitch(
|
|
@@ -42,8 +42,6 @@ export const identifyOrResume = (
|
|
|
42
42
|
ready: Ref.Ref<Option.Option<Discord.ReadyEvent>>,
|
|
43
43
|
seq: Ref.Ref<Option.Option<number>>,
|
|
44
44
|
): Effect.Effect<
|
|
45
|
-
never,
|
|
46
|
-
never,
|
|
47
45
|
| Discord.GatewayPayload<Discord.Identify>
|
|
48
46
|
| Discord.GatewayPayload<Discord.Resume>
|
|
49
47
|
> =>
|
|
@@ -8,5 +8,5 @@ import type * as Discord from "dfx/types"
|
|
|
8
8
|
export const fromPayload = (
|
|
9
9
|
p: Discord.GatewayPayload,
|
|
10
10
|
latestReady: Ref.Ref<Option.Option<Discord.ReadyEvent>>,
|
|
11
|
-
): Effect.Effect<
|
|
11
|
+
): Effect.Effect<Message> =>
|
|
12
12
|
Effect.as(p.d ? Effect.unit : Ref.set(latestReady, Option.none()), Reconnect)
|
|
@@ -5,10 +5,10 @@ import * as Stream from "effect/Stream"
|
|
|
5
5
|
import type * as Discord from "dfx/types"
|
|
6
6
|
|
|
7
7
|
export const opCode =
|
|
8
|
-
<R, E>(source: Stream.Stream<
|
|
8
|
+
<R, E>(source: Stream.Stream<Discord.GatewayPayload, E, R>) =>
|
|
9
9
|
<T = any>(
|
|
10
10
|
code: Discord.GatewayOpcode,
|
|
11
|
-
): Stream.Stream<
|
|
11
|
+
): Stream.Stream<Discord.GatewayPayload<T>, E, R> =>
|
|
12
12
|
source.pipe(
|
|
13
13
|
Stream.filter((p): p is Discord.GatewayPayload<T> => p.op === code),
|
|
14
14
|
)
|
|
@@ -18,7 +18,7 @@ const maybeUpdateRef =
|
|
|
18
18
|
f: (p: Discord.GatewayPayload) => Option.Option<T>,
|
|
19
19
|
ref: Ref.Ref<Option.Option<T>>,
|
|
20
20
|
) =>
|
|
21
|
-
(_: Discord.GatewayPayload): Effect.Effect<
|
|
21
|
+
(_: Discord.GatewayPayload): Effect.Effect<void> =>
|
|
22
22
|
Option.match(f(_), {
|
|
23
23
|
onNone: () => Effect.unit,
|
|
24
24
|
onSome: a => Ref.set(ref, Option.some(a)),
|
|
@@ -27,11 +27,9 @@ const maybeUpdateRef =
|
|
|
27
27
|
export const latest = <T>(
|
|
28
28
|
f: (p: Discord.GatewayPayload) => Option.Option<T>,
|
|
29
29
|
): Effect.Effect<
|
|
30
|
-
never,
|
|
31
|
-
never,
|
|
32
30
|
readonly [
|
|
33
31
|
Ref.Ref<Option.Option<T>>,
|
|
34
|
-
(_: Discord.GatewayPayload<any>) => Effect.Effect<
|
|
32
|
+
(_: Discord.GatewayPayload<any>) => Effect.Effect<void>,
|
|
35
33
|
]
|
|
36
34
|
> =>
|
|
37
35
|
Effect.map(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Chunk from "effect/Chunk"
|
|
2
|
-
import {
|
|
2
|
+
import { GenericTag } from "effect/Context"
|
|
3
3
|
import * as Duration from "effect/Duration"
|
|
4
4
|
import { pipe } from "effect/Function"
|
|
5
5
|
import * as Option from "effect/Option"
|
|
@@ -207,7 +207,7 @@ type ShardService = Effect.Effect.Success<typeof make>
|
|
|
207
207
|
export interface Shard {
|
|
208
208
|
readonly _: unique symbol
|
|
209
209
|
}
|
|
210
|
-
export const Shard =
|
|
210
|
+
export const Shard = GenericTag<Shard, ShardService>("dfx/DiscordGateway/Shard")
|
|
211
211
|
export const ShardLive = Layer.effect(Shard, make).pipe(
|
|
212
212
|
Layer.provide(DiscordWSLive),
|
|
213
213
|
Layer.provide(MesssagingLive),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import * as Option from "effect/Option"
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
4
|
import * as Layer from "effect/Layer"
|
|
@@ -9,16 +9,14 @@ export interface ClaimIdContext {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export interface ShardStoreService {
|
|
12
|
-
claimId: (
|
|
13
|
-
|
|
14
|
-
) => Effect.Effect<
|
|
15
|
-
allClaimed: (totalCount: number) => Effect.Effect<never, never, boolean>
|
|
16
|
-
heartbeat?: (shardId: number) => Effect.Effect<never, never, void>
|
|
12
|
+
claimId: (ctx: ClaimIdContext) => Effect.Effect<Option.Option<number>>
|
|
13
|
+
allClaimed: (totalCount: number) => Effect.Effect<boolean>
|
|
14
|
+
heartbeat?: (shardId: number) => Effect.Effect<void>
|
|
17
15
|
}
|
|
18
16
|
export interface ShardStore {
|
|
19
17
|
readonly _: unique symbol
|
|
20
18
|
}
|
|
21
|
-
export const ShardStore =
|
|
19
|
+
export const ShardStore = GenericTag<ShardStore, ShardStoreService>(
|
|
22
20
|
"dfx/DiscordGateway/ShardStore",
|
|
23
21
|
)
|
|
24
22
|
|
|
@@ -5,7 +5,7 @@ import { ShardStore } from "dfx/DiscordGateway/ShardStore"
|
|
|
5
5
|
import { DiscordREST, DiscordRESTLive } from "dfx/DiscordREST"
|
|
6
6
|
import { RateLimiter, RateLimiterLive } from "dfx/RateLimit"
|
|
7
7
|
import type * as Discord from "dfx/types"
|
|
8
|
-
import {
|
|
8
|
+
import { GenericTag } from "effect/Context"
|
|
9
9
|
import * as Duration from "effect/Duration"
|
|
10
10
|
import * as Effect from "effect/Effect"
|
|
11
11
|
import { pipe } from "effect/Function"
|
|
@@ -47,7 +47,7 @@ const make = Effect.gen(function* (_) {
|
|
|
47
47
|
|
|
48
48
|
const totalCount = config.shardCount ?? gateway.shards
|
|
49
49
|
const currentCount = yield* _(Ref.make(0))
|
|
50
|
-
const claimId = (sharderCount: number): Effect.Effect<
|
|
50
|
+
const claimId = (sharderCount: number): Effect.Effect<number> =>
|
|
51
51
|
pipe(
|
|
52
52
|
store.claimId({
|
|
53
53
|
totalCount,
|
|
@@ -59,7 +59,13 @@ const make = Effect.gen(function* (_) {
|
|
|
59
59
|
const takeConfig = pipe(
|
|
60
60
|
Ref.getAndUpdate(currentCount, _ => _ + 1),
|
|
61
61
|
Effect.flatMap(claimId),
|
|
62
|
-
Effect.map(
|
|
62
|
+
Effect.map(
|
|
63
|
+
id =>
|
|
64
|
+
({
|
|
65
|
+
id,
|
|
66
|
+
totalCount,
|
|
67
|
+
}) as const,
|
|
68
|
+
),
|
|
63
69
|
)
|
|
64
70
|
|
|
65
71
|
const spawner = pipe(
|
|
@@ -105,7 +111,7 @@ const make = Effect.gen(function* (_) {
|
|
|
105
111
|
export interface Sharder {
|
|
106
112
|
readonly _: unique symbol
|
|
107
113
|
}
|
|
108
|
-
export const Sharder =
|
|
114
|
+
export const Sharder = GenericTag<Sharder, Effect.Effect.Success<typeof make>>(
|
|
109
115
|
"dfx/DiscordGateway/Sharder",
|
|
110
116
|
)
|
|
111
117
|
export const SharderLive = Layer.scoped(Sharder, make).pipe(
|
package/src/DiscordGateway/WS.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import type * as Duration from "effect/Duration"
|
|
3
3
|
import { identity, pipe } from "effect/Function"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
@@ -51,7 +51,7 @@ const offer = (
|
|
|
51
51
|
ws: globalThis.WebSocket,
|
|
52
52
|
queue: Queue.Enqueue<WebSocket.Data>,
|
|
53
53
|
) =>
|
|
54
|
-
Effect.async<never, WebSocketError | WebSocketCloseError
|
|
54
|
+
Effect.async<never, WebSocketError | WebSocketCloseError>(resume => {
|
|
55
55
|
ws.addEventListener("message", message => {
|
|
56
56
|
Queue.unsafeOffer(queue, message.data)
|
|
57
57
|
})
|
|
@@ -75,7 +75,7 @@ const waitForOpen = (
|
|
|
75
75
|
return Effect.unit
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
return Effect.async<
|
|
78
|
+
return Effect.async<void>(resume => {
|
|
79
79
|
ws.addEventListener("open", () => resume(Effect.unit), {
|
|
80
80
|
once: true,
|
|
81
81
|
})
|
|
@@ -87,10 +87,7 @@ const waitForOpen = (
|
|
|
87
87
|
},
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
const send = (
|
|
91
|
-
ws: globalThis.WebSocket,
|
|
92
|
-
take: Effect.Effect<never, never, Message>,
|
|
93
|
-
) =>
|
|
90
|
+
const send = (ws: globalThis.WebSocket, take: Effect.Effect<Message>) =>
|
|
94
91
|
pipe(
|
|
95
92
|
take,
|
|
96
93
|
Effect.tap(data => Effect.logTrace(data)),
|
|
@@ -119,8 +116,8 @@ const wsImpl = {
|
|
|
119
116
|
urlRef,
|
|
120
117
|
}: {
|
|
121
118
|
readonly urlRef: Ref.Ref<string>
|
|
122
|
-
readonly takeOutbound: Effect.Effect<
|
|
123
|
-
readonly onConnecting?: Effect.Effect<
|
|
119
|
+
readonly takeOutbound: Effect.Effect<Message>
|
|
120
|
+
readonly onConnecting?: Effect.Effect<void>
|
|
124
121
|
readonly openTimeout?: Duration.DurationInput
|
|
125
122
|
readonly reconnectWhen?: Predicate<WebSocketError | WebSocketCloseError>
|
|
126
123
|
}) =>
|
|
@@ -182,5 +179,5 @@ const wsImpl = {
|
|
|
182
179
|
export interface WS {
|
|
183
180
|
readonly _: unique symbol
|
|
184
181
|
}
|
|
185
|
-
export const WS =
|
|
182
|
+
export const WS = GenericTag<WS, typeof wsImpl>("dfx/DiscordGateway/WS")
|
|
186
183
|
export const WSLive = Layer.succeed(WS, wsImpl)
|
package/src/DiscordGateway.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Messaging, MesssagingLive } from "dfx/DiscordGateway/Messaging"
|
|
|
2
2
|
import type { RunningShard } from "dfx/DiscordGateway/Shard"
|
|
3
3
|
import { Sharder, SharderLive } from "dfx/DiscordGateway/Sharder"
|
|
4
4
|
import type * as Discord from "dfx/types"
|
|
5
|
-
import {
|
|
5
|
+
import { GenericTag } from "effect/Context"
|
|
6
6
|
import * as Effect from "effect/Effect"
|
|
7
7
|
import type * as HashSet from "effect/HashSet"
|
|
8
8
|
import * as Layer from "effect/Layer"
|
|
@@ -14,25 +14,21 @@ export type TypeId = typeof TypeId
|
|
|
14
14
|
export interface DiscordGateway {
|
|
15
15
|
readonly [TypeId]: TypeId
|
|
16
16
|
|
|
17
|
-
readonly dispatch: Stream.Stream<
|
|
18
|
-
never,
|
|
19
|
-
never,
|
|
20
|
-
Discord.GatewayPayload<Discord.ReceiveEvent>
|
|
21
|
-
>
|
|
17
|
+
readonly dispatch: Stream.Stream<Discord.GatewayPayload<Discord.ReceiveEvent>>
|
|
22
18
|
readonly fromDispatch: <K extends keyof Discord.ReceiveEvents>(
|
|
23
19
|
event: K,
|
|
24
|
-
) => Stream.Stream<
|
|
20
|
+
) => Stream.Stream<Discord.ReceiveEvents[K]>
|
|
25
21
|
readonly handleDispatch: <K extends keyof Discord.ReceiveEvents, R, E, A>(
|
|
26
22
|
event: K,
|
|
27
|
-
handle: (event: Discord.ReceiveEvents[K]) => Effect.Effect<
|
|
28
|
-
) => Effect.Effect<
|
|
23
|
+
handle: (event: Discord.ReceiveEvents[K]) => Effect.Effect<A, E, R>,
|
|
24
|
+
) => Effect.Effect<never, E, R>
|
|
29
25
|
readonly send: (
|
|
30
26
|
payload: Discord.GatewayPayload<Discord.SendEvent>,
|
|
31
|
-
) => Effect.Effect<
|
|
32
|
-
readonly shards: Effect.Effect<
|
|
27
|
+
) => Effect.Effect<boolean>
|
|
28
|
+
readonly shards: Effect.Effect<HashSet.HashSet<RunningShard>>
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
export const DiscordGateway =
|
|
31
|
+
export const DiscordGateway = GenericTag<DiscordGateway>("dfx/DiscordGateway")
|
|
36
32
|
|
|
37
33
|
export const make = Effect.gen(function* (_) {
|
|
38
34
|
const sharder = yield* _(Sharder)
|
package/src/DiscordREST/types.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type * as Effect from "effect/Effect"
|
|
2
2
|
import type * as Http from "@effect/platform/HttpClient"
|
|
3
3
|
import type { DiscordRESTError } from "dfx/DiscordREST"
|
|
4
|
+
import type { Scope } from "effect/Scope"
|
|
4
5
|
|
|
5
6
|
export interface ResponseWithData<A> extends Http.response.ClientResponse {
|
|
6
|
-
readonly json: Effect.Effect<
|
|
7
|
+
readonly json: Effect.Effect<A, Http.error.ResponseError>
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
DiscordRESTError
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
export interface RestResponse<T>
|
|
11
|
+
extends Effect.Effect<ResponseWithData<T>, DiscordRESTError, Scope> {
|
|
12
|
+
readonly json: Effect.Effect<T, DiscordRESTError | Http.error.ResponseError>
|
|
13
|
+
readonly asUnit: Effect.Effect<void, DiscordRESTError>
|
|
14
|
+
}
|
package/src/DiscordREST.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import * as Duration from "effect/Duration"
|
|
3
3
|
import { millis } from "effect/Duration"
|
|
4
4
|
import { pipe } from "effect/Function"
|
|
@@ -19,6 +19,8 @@ import {
|
|
|
19
19
|
import { RateLimiterLive, RateLimiter, RateLimitStore } from "dfx/RateLimit"
|
|
20
20
|
import * as Discord from "dfx/types"
|
|
21
21
|
import { LIB_VERSION } from "dfx/version"
|
|
22
|
+
import type { Scope } from "effect/Scope"
|
|
23
|
+
import * as Effectable from "effect/Effectable"
|
|
22
24
|
|
|
23
25
|
export class DiscordRESTError {
|
|
24
26
|
readonly _tag = "DiscordRESTError"
|
|
@@ -155,14 +157,14 @@ const make = Effect.gen(function* (_) {
|
|
|
155
157
|
|
|
156
158
|
const executor = <A = unknown>(
|
|
157
159
|
request: Http.request.ClientRequest,
|
|
158
|
-
): Effect.Effect<
|
|
160
|
+
): Effect.Effect<ResponseWithData<A>, DiscordRESTError, Scope> =>
|
|
159
161
|
requestRateLimit(request.url, request).pipe(
|
|
160
162
|
Effect.zipLeft(globalRateLimit),
|
|
161
163
|
Effect.zipRight(
|
|
162
164
|
httpExecutor(request) as Effect.Effect<
|
|
163
|
-
|
|
165
|
+
ResponseWithData<A>,
|
|
164
166
|
DiscordRESTError,
|
|
165
|
-
|
|
167
|
+
Scope
|
|
166
168
|
>,
|
|
167
169
|
),
|
|
168
170
|
Effect.tap(response => updateBuckets(request, response)),
|
|
@@ -243,7 +245,7 @@ const make = Effect.gen(function* (_) {
|
|
|
243
245
|
request = Http.request.unsafeJsonBody(request, params)
|
|
244
246
|
}
|
|
245
247
|
|
|
246
|
-
return executor(request)
|
|
248
|
+
return new RestResponseImpl(executor(request))
|
|
247
249
|
},
|
|
248
250
|
)
|
|
249
251
|
|
|
@@ -253,6 +255,33 @@ const make = Effect.gen(function* (_) {
|
|
|
253
255
|
}
|
|
254
256
|
})
|
|
255
257
|
|
|
258
|
+
class RestResponseImpl<T>
|
|
259
|
+
extends Effectable.Class<ResponseWithData<T>, DiscordRESTError, Scope>
|
|
260
|
+
implements RestResponse<T>
|
|
261
|
+
{
|
|
262
|
+
constructor(
|
|
263
|
+
readonly response: Effect.Effect<
|
|
264
|
+
ResponseWithData<T>,
|
|
265
|
+
DiscordRESTError,
|
|
266
|
+
Scope
|
|
267
|
+
>,
|
|
268
|
+
) {
|
|
269
|
+
super()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
commit(): Effect.Effect<ResponseWithData<T>, DiscordRESTError, Scope> {
|
|
273
|
+
return this.response
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get json() {
|
|
277
|
+
return Effect.scoped(Effect.flatMap(this.response, _ => _.json))
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
get asUnit() {
|
|
281
|
+
return Effect.scoped(this.response)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
256
285
|
export interface DiscordREST {
|
|
257
286
|
readonly _: unique symbol
|
|
258
287
|
}
|
|
@@ -261,10 +290,10 @@ export interface DiscordRESTService
|
|
|
261
290
|
extends Discord.Endpoints<Partial<Http.request.Options.NoUrl>> {
|
|
262
291
|
readonly executor: <A = unknown>(
|
|
263
292
|
request: Http.request.ClientRequest,
|
|
264
|
-
) => Effect.Effect<
|
|
293
|
+
) => Effect.Effect<ResponseWithData<A>, DiscordRESTError, Scope>
|
|
265
294
|
}
|
|
266
295
|
|
|
267
|
-
export const DiscordREST =
|
|
296
|
+
export const DiscordREST = GenericTag<DiscordREST, DiscordRESTService>(
|
|
268
297
|
"dfx/DiscordREST",
|
|
269
298
|
)
|
|
270
299
|
export const DiscordRESTLive = Layer.effect(DiscordREST, make).pipe(
|
|
@@ -112,7 +112,7 @@ export const applyOverwrites =
|
|
|
112
112
|
interface RolesCache<E> {
|
|
113
113
|
getForParent: (
|
|
114
114
|
parentId: string,
|
|
115
|
-
) => Effect.Effect<
|
|
115
|
+
) => Effect.Effect<ReadonlyMap<string, Discord.Role>, E>
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
export const hasInChannel =
|
|
@@ -24,12 +24,12 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
24
24
|
handler: D.InteractionDefinition<R, E>,
|
|
25
25
|
transform: (
|
|
26
26
|
self: Effect.Effect<any, any, any>,
|
|
27
|
-
) => Effect.Effect<
|
|
27
|
+
) => Effect.Effect<void, TE, R>,
|
|
28
28
|
]
|
|
29
29
|
>,
|
|
30
30
|
readonly transform: (
|
|
31
31
|
self: Effect.Effect<any, any, any>,
|
|
32
|
-
) => Effect.Effect<
|
|
32
|
+
) => Effect.Effect<void, TE, R>,
|
|
33
33
|
) {}
|
|
34
34
|
|
|
35
35
|
add<R1, E1>(definition: D.InteractionDefinition<R1, E1>) {
|
|
@@ -47,7 +47,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
private transformTransform<R1, E1>(
|
|
50
|
-
f: (selr: Effect.Effect<
|
|
50
|
+
f: (selr: Effect.Effect<void, TE, R>) => Effect.Effect<void, E1, R1>,
|
|
51
51
|
) {
|
|
52
52
|
return new InteractionBuilder<R1, E, E1>(
|
|
53
53
|
Chunk.map(this.definitions, ([d, t]) => [d as any, _ => f(t(_)) as any]),
|
|
@@ -57,8 +57,8 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
57
57
|
|
|
58
58
|
private transformHandlers<R1, E1>(
|
|
59
59
|
f: (
|
|
60
|
-
selr: Effect.Effect<
|
|
61
|
-
) => Effect.Effect<
|
|
60
|
+
selr: Effect.Effect<Discord.InteractionResponse, E, R>,
|
|
61
|
+
) => Effect.Effect<Discord.InteractionResponse, E1, R1>,
|
|
62
62
|
) {
|
|
63
63
|
return new InteractionBuilder<
|
|
64
64
|
R1,
|
|
@@ -79,7 +79,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
catchAllCause<R1, E1>(
|
|
82
|
-
f: (cause: Cause.Cause<TE>) => Effect.Effect<
|
|
82
|
+
f: (cause: Cause.Cause<TE>) => Effect.Effect<void, E1, R1>,
|
|
83
83
|
) {
|
|
84
84
|
return this.transformTransform<R | R1, E1>(Effect.catchAllCause(f))
|
|
85
85
|
}
|
|
@@ -87,24 +87,24 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
87
87
|
catchAllCauseRespond<R1, E1>(
|
|
88
88
|
f: (
|
|
89
89
|
cause: Cause.Cause<E>,
|
|
90
|
-
) => Effect.Effect<
|
|
90
|
+
) => Effect.Effect<Discord.InteractionResponse, E1, R1>,
|
|
91
91
|
) {
|
|
92
92
|
return this.transformHandlers<R | R1, E1>(Effect.catchAllCause(f))
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
catchAll<R1, E1>(f: (error: TE) => Effect.Effect<
|
|
95
|
+
catchAll<R1, E1>(f: (error: TE) => Effect.Effect<void, E1, R1>) {
|
|
96
96
|
return this.transformTransform<R | R1, E1>(Effect.catchAll(f))
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
catchAllRespond<R1, E1>(
|
|
100
|
-
f: (error: E) => Effect.Effect<
|
|
100
|
+
f: (error: E) => Effect.Effect<Discord.InteractionResponse, E1, R1>,
|
|
101
101
|
) {
|
|
102
102
|
return this.transformHandlers<R | R1, E1>(Effect.catchAll(f))
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
catchTag<T extends ExtractTag<E>, R1, E1>(
|
|
106
106
|
tag: T,
|
|
107
|
-
f: (error: Extract<TE, { _tag: T }>) => Effect.Effect<
|
|
107
|
+
f: (error: Extract<TE, { _tag: T }>) => Effect.Effect<void, E1, R1>,
|
|
108
108
|
) {
|
|
109
109
|
return this.transformTransform<R | R1, Exclude<TE, { _tag: T }> | E1>(
|
|
110
110
|
_ => catchTag(_ as any, tag, f as any) as any,
|
|
@@ -115,7 +115,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
115
115
|
tag: T,
|
|
116
116
|
f: (
|
|
117
117
|
error: Extract<E, { _tag: T }>,
|
|
118
|
-
) => Effect.Effect<
|
|
118
|
+
) => Effect.Effect<Discord.InteractionResponse, E1, R1>,
|
|
119
119
|
) {
|
|
120
120
|
return this.transformHandlers<R | R1, Exclude<E, { _tag: T }> | E1>(
|
|
121
121
|
_ => catchTag(_ as any, tag, f as any) as any,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericTag } from "effect/Context"
|
|
2
2
|
import type * as HashMap from "effect/HashMap"
|
|
3
3
|
import * as Option from "effect/Option"
|
|
4
4
|
import * as Arr from "effect/ReadonlyArray"
|
|
@@ -9,14 +9,14 @@ import type * as Discord from "dfx/types"
|
|
|
9
9
|
export interface DiscordInteraction {
|
|
10
10
|
readonly _: unique symbol
|
|
11
11
|
}
|
|
12
|
-
export const Interaction =
|
|
12
|
+
export const Interaction = GenericTag<DiscordInteraction, Discord.Interaction>(
|
|
13
13
|
"dfx/Interactions/Interaction",
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
export interface DiscordApplicationCommand {
|
|
17
17
|
readonly _: unique symbol
|
|
18
18
|
}
|
|
19
|
-
export const ApplicationCommand =
|
|
19
|
+
export const ApplicationCommand = GenericTag<
|
|
20
20
|
DiscordApplicationCommand,
|
|
21
21
|
Discord.ApplicationCommandDatum
|
|
22
22
|
>("dfx/Interactions/ApplicationCommand")
|
|
@@ -24,7 +24,7 @@ export const ApplicationCommand = Tag<
|
|
|
24
24
|
export interface DiscordMessageComponent {
|
|
25
25
|
readonly _: unique symbol
|
|
26
26
|
}
|
|
27
|
-
export const MessageComponentData =
|
|
27
|
+
export const MessageComponentData = GenericTag<
|
|
28
28
|
DiscordMessageComponent,
|
|
29
29
|
Discord.MessageComponentDatum
|
|
30
30
|
>("dfx/Interactions/MessageComponentData")
|
|
@@ -32,7 +32,7 @@ export const MessageComponentData = Tag<
|
|
|
32
32
|
export interface DiscordModalSubmit {
|
|
33
33
|
readonly _: unique symbol
|
|
34
34
|
}
|
|
35
|
-
export const ModalSubmitData =
|
|
35
|
+
export const ModalSubmitData = GenericTag<
|
|
36
36
|
DiscordModalSubmit,
|
|
37
37
|
Discord.ModalSubmitDatum
|
|
38
38
|
>("dfx/Interactions/ModalSubmitData")
|
|
@@ -43,7 +43,7 @@ export interface DiscordFocusedOption {
|
|
|
43
43
|
export interface FocusedOptionContext {
|
|
44
44
|
readonly focusedOption: Discord.ApplicationCommandInteractionDataOption
|
|
45
45
|
}
|
|
46
|
-
export const FocusedOptionContext =
|
|
46
|
+
export const FocusedOptionContext = GenericTag<
|
|
47
47
|
DiscordFocusedOption,
|
|
48
48
|
FocusedOptionContext
|
|
49
49
|
>("dfx/Interactions/FocusedOptionContext")
|
|
@@ -54,9 +54,10 @@ export interface DiscordSubCommand {
|
|
|
54
54
|
export interface SubCommandContext {
|
|
55
55
|
readonly command: Discord.ApplicationCommandInteractionDataOption
|
|
56
56
|
}
|
|
57
|
-
export const SubCommandContext =
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
export const SubCommandContext = GenericTag<
|
|
58
|
+
DiscordSubCommand,
|
|
59
|
+
SubCommandContext
|
|
60
|
+
>("dfx/Interactions/SubCommandContext")
|
|
60
61
|
|
|
61
62
|
export class ResolvedDataNotFound {
|
|
62
63
|
readonly _tag = "ResolvedDataNotFound"
|
|
@@ -68,7 +69,7 @@ export class ResolvedDataNotFound {
|
|
|
68
69
|
|
|
69
70
|
export const resolvedValues = <A>(
|
|
70
71
|
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => A | undefined,
|
|
71
|
-
): Effect.Effect<
|
|
72
|
+
): Effect.Effect<ReadonlyArray<A>, ResolvedDataNotFound, DiscordInteraction> =>
|
|
72
73
|
Effect.flatMap(Interaction, ix =>
|
|
73
74
|
Effect.mapError(
|
|
74
75
|
IxHelpers.resolveValues(f)(ix),
|
|
@@ -79,7 +80,7 @@ export const resolvedValues = <A>(
|
|
|
79
80
|
export const resolved = <A>(
|
|
80
81
|
name: string,
|
|
81
82
|
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => A | undefined,
|
|
82
|
-
): Effect.Effect<
|
|
83
|
+
): Effect.Effect<A, ResolvedDataNotFound, DiscordInteraction> =>
|
|
83
84
|
Effect.flatMap(Interaction, ix =>
|
|
84
85
|
Effect.mapError(
|
|
85
86
|
IxHelpers.resolveOptionValue(name, f)(ix),
|
|
@@ -100,11 +101,18 @@ export class SubCommandNotFound {
|
|
|
100
101
|
export const handleSubCommands = <
|
|
101
102
|
NER extends Record<
|
|
102
103
|
string,
|
|
103
|
-
Effect.Effect<
|
|
104
|
+
Effect.Effect<Discord.InteractionResponse, any, any>
|
|
104
105
|
>,
|
|
105
106
|
>(
|
|
106
107
|
commands: NER,
|
|
107
108
|
): Effect.Effect<
|
|
109
|
+
Discord.InteractionResponse,
|
|
110
|
+
| ([NER[keyof NER]] extends [
|
|
111
|
+
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
112
|
+
]
|
|
113
|
+
? E
|
|
114
|
+
: never)
|
|
115
|
+
| SubCommandNotFound,
|
|
108
116
|
| Exclude<
|
|
109
117
|
[NER[keyof NER]] extends [
|
|
110
118
|
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
@@ -114,14 +122,7 @@ export const handleSubCommands = <
|
|
|
114
122
|
SubCommandContext
|
|
115
123
|
>
|
|
116
124
|
| Discord.Interaction
|
|
117
|
-
| Discord.ApplicationCommandDatum
|
|
118
|
-
| ([NER[keyof NER]] extends [
|
|
119
|
-
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
120
|
-
]
|
|
121
|
-
? E
|
|
122
|
-
: never)
|
|
123
|
-
| SubCommandNotFound,
|
|
124
|
-
Discord.InteractionResponse
|
|
125
|
+
| Discord.ApplicationCommandDatum
|
|
125
126
|
> =>
|
|
126
127
|
ApplicationCommand.pipe(
|
|
127
128
|
Effect.flatMap(data =>
|
|
@@ -138,15 +139,15 @@ export const handleSubCommands = <
|
|
|
138
139
|
)
|
|
139
140
|
|
|
140
141
|
export const currentSubCommand: Effect.Effect<
|
|
141
|
-
|
|
142
|
+
Discord.ApplicationCommandInteractionDataOption,
|
|
142
143
|
never,
|
|
143
|
-
|
|
144
|
+
DiscordSubCommand
|
|
144
145
|
> = Effect.map(SubCommandContext, _ => _.command)
|
|
145
146
|
|
|
146
147
|
export const optionsMap: Effect.Effect<
|
|
147
|
-
|
|
148
|
+
HashMap.HashMap<string, string | undefined>,
|
|
148
149
|
never,
|
|
149
|
-
|
|
150
|
+
DiscordApplicationCommand
|
|
150
151
|
> = Effect.map(ApplicationCommand, IxHelpers.optionsMap)
|
|
151
152
|
|
|
152
153
|
export class RequiredOptionNotFound {
|