dfx 0.50.1 → 0.51.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/memory.js +4 -4
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.js +5 -5
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.js +4 -3
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts.map +1 -1
- package/Cache.js +15 -7
- package/Cache.js.map +1 -1
- package/DiscordConfig.d.ts +1 -1
- package/DiscordConfig.d.ts.map +1 -1
- package/DiscordConfig.js +4 -5
- package/DiscordConfig.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +3 -2
- package/DiscordGateway/DiscordWS.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 +4 -1
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/identify.d.ts +1 -0
- package/DiscordGateway/Shard/identify.d.ts.map +1 -1
- package/DiscordGateway/Shard/identify.js +8 -5
- package/DiscordGateway/Shard/identify.js.map +1 -1
- package/DiscordGateway/Shard/invalidSession.js +1 -1
- package/DiscordGateway/Shard/invalidSession.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 +4 -2
- package/DiscordGateway/Shard/utils.js.map +1 -1
- package/DiscordGateway/Shard.d.ts +1 -1
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +15 -9
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts.map +1 -1
- package/DiscordGateway/Sharder.js +16 -15
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +15 -10
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js +7 -6
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/utils.d.ts +4 -3
- package/DiscordREST/utils.d.ts.map +1 -1
- package/DiscordREST/utils.js +6 -6
- package/DiscordREST/utils.js.map +1 -1
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +21 -17
- package/DiscordREST.js.map +1 -1
- package/Helpers/interactions.d.ts +10 -10
- package/Helpers/interactions.d.ts.map +1 -1
- package/Helpers/interactions.js +12 -13
- package/Helpers/interactions.js.map +1 -1
- package/Interactions/builder.js +1 -1
- package/Interactions/builder.js.map +1 -1
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +4 -1
- package/Interactions/context.js.map +1 -1
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js +23 -17
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/handlers.js +25 -10
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/utils.js +1 -1
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts +7 -6
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js +23 -20
- package/Interactions/webhook.js.map +1 -1
- package/Log.js +1 -1
- package/Log.js.map +1 -1
- package/RateLimit/memory.js +1 -1
- package/RateLimit/memory.js.map +1 -1
- package/RateLimit.js +9 -7
- package/RateLimit.js.map +1 -1
- package/global.d.ts +1 -1
- package/global.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/Cache/memory.ts +4 -4
- package/src/Cache/memoryTTL.ts +5 -5
- package/src/Cache/prelude.ts +6 -6
- package/src/Cache.ts +28 -18
- package/src/DiscordConfig.ts +3 -2
- package/src/DiscordGateway/DiscordWS.ts +3 -3
- package/src/DiscordGateway/Shard/heartbeats.ts +6 -1
- package/src/DiscordGateway/Shard/identify.ts +7 -5
- package/src/DiscordGateway/Shard/invalidSession.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +7 -4
- package/src/DiscordGateway/Shard.ts +23 -18
- package/src/DiscordGateway/Sharder.ts +11 -11
- package/src/DiscordGateway/WS.ts +12 -8
- package/src/DiscordGateway.ts +4 -3
- package/src/DiscordREST/utils.ts +3 -1
- package/src/DiscordREST.ts +44 -35
- package/src/Helpers/interactions.ts +32 -34
- package/src/Interactions/builder.ts +3 -3
- package/src/Interactions/context.ts +15 -15
- package/src/Interactions/gateway.ts +15 -6
- package/src/Interactions/handlers.ts +43 -40
- package/src/Interactions/utils.ts +1 -1
- package/src/Interactions/webhook.ts +18 -15
- package/src/Log.ts +1 -1
- package/src/RateLimit.ts +6 -6
- package/src/global.ts +1 -1
- package/src/package.json +12 -12
- package/src/utils/hub.ts +6 -6
- package/utils/hub.js +6 -3
- package/utils/hub.js.map +1 -1
package/RateLimit.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import * as tsplus_module_1 from "dfx/_common";
|
|
2
2
|
import * as tsplus_module_2 from "@effect/io/Layer";
|
|
3
|
-
import * as tsplus_module_3 from "@effect/
|
|
3
|
+
import * as tsplus_module_3 from "@effect/data/Duration";
|
|
4
|
+
import * as tsplus_module_4 from "@effect/io/Effect";
|
|
5
|
+
import * as tsplus_module_5 from "@effect/data/Function";
|
|
4
6
|
import { delayFrom } from "./RateLimit/utils.js";
|
|
5
7
|
import * as Memory from "./RateLimit/memory.js";
|
|
6
8
|
import { Log } from "dfx/Log";
|
|
7
9
|
export const RateLimitStore = tsplus_module_1.Tag();
|
|
8
10
|
export const LiveMemoryRateLimitStore = tsplus_module_2.sync(RateLimitStore, Memory.make);
|
|
9
|
-
const makeLimiter =
|
|
11
|
+
const makeLimiter = tsplus_module_4.flatMap(tsplus_module_4.map(RateLimitStore, tsplus_module_5.identity), store => tsplus_module_4.map(tsplus_module_4.map(Log, tsplus_module_5.identity), log => {
|
|
10
12
|
const maybeWait = (key, window, limit, multiplier = 1.05) => {
|
|
11
|
-
const windowMs = window
|
|
12
|
-
return
|
|
13
|
+
const windowMs = tsplus_module_3.toMillis(window) * multiplier;
|
|
14
|
+
return tsplus_module_4.asUnit(tsplus_module_4.tap(tsplus_module_4.tap(tsplus_module_4.map(store
|
|
13
15
|
.incrementCounter(key, windowMs, limit), ([count, ttl]) => delayFrom(windowMs, limit, count, ttl)), d => log.debug("RateLimitStore maybeWait", {
|
|
14
16
|
key,
|
|
15
|
-
window: window
|
|
17
|
+
window: tsplus_module_3.toMillis(window),
|
|
16
18
|
windowMs,
|
|
17
19
|
limit,
|
|
18
|
-
delay: d
|
|
19
|
-
})), _ => (_
|
|
20
|
+
delay: tsplus_module_3.toMillis(d),
|
|
21
|
+
})), _ => (tsplus_module_3.toMillis(_) === 0 ? tsplus_module_4.unit : tsplus_module_4.sleep(_))));
|
|
20
22
|
};
|
|
21
23
|
return { maybeWait };
|
|
22
24
|
}));
|
package/RateLimit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimit.js","sourceRoot":"","sources":["src/RateLimit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RateLimit.js","sourceRoot":"","sources":["src/RateLimit.ts"],"names":[],"mappings":";;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AA+B7B,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAA,GAAG,EAAkB,CAAA;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAW,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;AAE/E,MAAM,WAAW,2BACC,oBAAA,cAAc,kBAAY,QAAQ,CAAC,EAA7C,KAAK,wBACG,oBAAA,GAAG,kBAAY,QAAQ,CAAC,EAAhC,GAAG;IAET,MAAM,SAAS,GAAG,CAChB,GAAW,EACX,MAAgB,EAChB,KAAa,EACb,UAAU,GAAG,IAAI,EACjB,EAAE;QACF,MAAM,QAAQ,GAAG,yBAAA,MAAM,IAAY,UAAU,CAAA;QAE7C,8BAAO,oBAAA,oBAAA,oBAAA,KAAK;aACT,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,EAClC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,EACzD,CAAC,CAAC,EAAE,CACP,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE;YACpC,GAAG;YACH,MAAM,2BAAE,MAAM,CAAS;YACvB,QAAQ;YACR,KAAK;YACL,KAAK,2BAAE,CAAC,CAAS;SAClB,CAAC,CACH,EACI,CAAC,CAAC,EAAE,CAAC,CAAC,yBAAA,CAAC,MAAc,CAAC,CAAC,CAAC,sBAAa,CAAC,CAAC,sBAAa,CAAC,CAAC,CAAC,CAAC,EAAO;IACxE,CAAC,CAAA;IAED,OAAO,EAAE,SAAS,EAAE,CAAA;GACpB,CAAA;AAGF,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAA,GAAG,EAAe,CAAA;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAa,WAAW,EAAE,WAAW,CAAC,CAAA"}
|
package/global.d.ts
CHANGED
package/global.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["src/global.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,GAAG,EACH,KAAK,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,GACR,MAAM,aAAa,CAAA;AAEpB;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["src/global.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,GAAG,EACH,KAAK,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,EACN,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,GACR,MAAM,aAAa,CAAA;AAEpB;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAEtD;;GAEG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dfx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -25,21 +25,21 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@tim-smart/discord-api-docs-parser": "^0.5.5",
|
|
28
|
-
"@tsplus-types/effect__data": "0.
|
|
29
|
-
"@tsplus-types/effect__io": "0.
|
|
30
|
-
"@tsplus-types/effect__stream": "0.
|
|
28
|
+
"@tsplus-types/effect__data": "0.13.5-11739c0",
|
|
29
|
+
"@tsplus-types/effect__io": "0.31.3-11739c0",
|
|
30
|
+
"@tsplus-types/effect__stream": "0.25.1-11739c0",
|
|
31
31
|
"@types/ws": "^8.5.5",
|
|
32
|
-
"dotenv": "^16.1
|
|
33
|
-
"lerna": "^7.
|
|
32
|
+
"dotenv": "^16.3.1",
|
|
33
|
+
"lerna": "^7.1.1",
|
|
34
34
|
"madge": "^6.1.0",
|
|
35
35
|
"typescript": "https://cdn.jsdelivr.net/npm/@tsplus/installer@0.0.177/compiler/typescript.tgz"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@effect-http/client": "^0.
|
|
39
|
-
"@effect/data": "^0.
|
|
40
|
-
"@effect/io": "~0.
|
|
41
|
-
"@effect/stream": "~0.
|
|
42
|
-
"discord-verify": "^1.
|
|
38
|
+
"@effect-http/client": "^0.29.0",
|
|
39
|
+
"@effect/data": "^0.13.5",
|
|
40
|
+
"@effect/io": "~0.31.3",
|
|
41
|
+
"@effect/stream": "~0.25.1",
|
|
42
|
+
"discord-verify": "^1.2.0"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
45
|
"bufferutil": "^4.0.7",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"ws": "^8.13.0"
|
|
49
49
|
},
|
|
50
50
|
"sideEffects": false,
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "7da97bf421f1b78e4d3ca866c3424f990db0e6e7"
|
|
52
52
|
}
|
package/src/Cache/memory.ts
CHANGED
|
@@ -43,9 +43,9 @@ export const createWithParent = <T>() =>
|
|
|
43
43
|
map.delete(parentId)
|
|
44
44
|
}),
|
|
45
45
|
|
|
46
|
-
refreshTTL: () => Effect.unit
|
|
46
|
+
refreshTTL: () => Effect.unit,
|
|
47
47
|
|
|
48
|
-
run: Effect.never
|
|
48
|
+
run: Effect.never,
|
|
49
49
|
})
|
|
50
50
|
})
|
|
51
51
|
|
|
@@ -69,8 +69,8 @@ export const create = <T>() =>
|
|
|
69
69
|
map.delete(resourceId)
|
|
70
70
|
}),
|
|
71
71
|
|
|
72
|
-
refreshTTL: () => Effect.unit
|
|
72
|
+
refreshTTL: () => Effect.unit,
|
|
73
73
|
|
|
74
|
-
run: Effect.never
|
|
74
|
+
run: Effect.never,
|
|
75
75
|
})
|
|
76
76
|
})
|
package/src/Cache/memoryTTL.ts
CHANGED
|
@@ -35,14 +35,14 @@ const make = <T>({
|
|
|
35
35
|
strategy = "usage",
|
|
36
36
|
}: MemoryTTLOpts) => {
|
|
37
37
|
const additionalMilliseconds =
|
|
38
|
-
(Math.floor(ttl.
|
|
38
|
+
(Math.floor(ttl.toMillis / resolution.toMillis) + 1) * resolution.toMillis
|
|
39
39
|
|
|
40
40
|
const items = new Map<string, WeakRef<CacheItem<T>>>()
|
|
41
41
|
const buckets: TTLBucket<T>[] = []
|
|
42
42
|
|
|
43
43
|
const refreshTTL = (item: CacheItem<T>) => {
|
|
44
44
|
const now = Date.now()
|
|
45
|
-
const remainder = now % resolution.
|
|
45
|
+
const remainder = now % resolution.toMillis
|
|
46
46
|
const expires = now - remainder + additionalMilliseconds
|
|
47
47
|
let currentBucket = buckets[buckets.length - 1]
|
|
48
48
|
|
|
@@ -59,7 +59,7 @@ const make = <T>({
|
|
|
59
59
|
|
|
60
60
|
const sweep = () => {
|
|
61
61
|
const now = Date.now()
|
|
62
|
-
const remainder = now % resolution.
|
|
62
|
+
const remainder = now % resolution.toMillis
|
|
63
63
|
const currentExpires = now - remainder
|
|
64
64
|
|
|
65
65
|
while (buckets.length && buckets[0].expires <= currentExpires) {
|
|
@@ -156,7 +156,7 @@ export const createWithParent = <T>(opts: MemoryTTLOpts) =>
|
|
|
156
156
|
)
|
|
157
157
|
})
|
|
158
158
|
|
|
159
|
-
const results = $(Effect.
|
|
159
|
+
const results = $(Effect.all(toGet, { concurrency: "unbounded" }))
|
|
160
160
|
const map = results.reduce(
|
|
161
161
|
(map, [id, a]) => (a._tag === "Some" ? map.set(id, a.value) : map),
|
|
162
162
|
new Map<string, T>(),
|
|
@@ -193,7 +193,7 @@ export const createWithParent = <T>(opts: MemoryTTLOpts) =>
|
|
|
193
193
|
})
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
$(Effect.
|
|
196
|
+
$(Effect.all(effects, { concurrency: "unbounded", discard: true }))
|
|
197
197
|
}),
|
|
198
198
|
|
|
199
199
|
run: store.run,
|
package/src/Cache/prelude.ts
CHANGED
|
@@ -120,8 +120,8 @@ export const guilds = <RM, EM, E>(
|
|
|
120
120
|
) =>
|
|
121
121
|
Do($ => {
|
|
122
122
|
const driver = $(makeDriver)
|
|
123
|
-
const gateway = $(DiscordGateway)
|
|
124
|
-
const rest = $(DiscordREST)
|
|
123
|
+
const gateway = $(DiscordGateway.accessWith(identity))
|
|
124
|
+
const rest = $(DiscordREST.accessWith(identity))
|
|
125
125
|
|
|
126
126
|
return make({
|
|
127
127
|
driver,
|
|
@@ -147,8 +147,8 @@ export const channels = <RM, EM, E>(
|
|
|
147
147
|
) =>
|
|
148
148
|
Do($ => {
|
|
149
149
|
const driver = $(makeDriver)
|
|
150
|
-
const gateway = $(DiscordGateway)
|
|
151
|
-
const rest = $(DiscordREST)
|
|
150
|
+
const gateway = $(DiscordGateway.accessWith(identity))
|
|
151
|
+
const rest = $(DiscordREST.accessWith(identity))
|
|
152
152
|
|
|
153
153
|
return makeWithParent({
|
|
154
154
|
driver,
|
|
@@ -186,8 +186,8 @@ export const roles = <RM, EM, E>(
|
|
|
186
186
|
) =>
|
|
187
187
|
Do($ => {
|
|
188
188
|
const driver = $(makeDriver)
|
|
189
|
-
const gateway = $(DiscordGateway)
|
|
190
|
-
const rest = $(DiscordREST)
|
|
189
|
+
const gateway = $(DiscordGateway.accessWith(identity))
|
|
190
|
+
const rest = $(DiscordREST.accessWith(identity))
|
|
191
191
|
|
|
192
192
|
return makeWithParent({
|
|
193
193
|
driver,
|
package/src/Cache.ts
CHANGED
|
@@ -51,11 +51,13 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
|
|
|
51
51
|
}).runDrain
|
|
52
52
|
|
|
53
53
|
const get = (parentId: string, id: string) =>
|
|
54
|
-
driver
|
|
55
|
-
.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
driver.get(parentId, id).flatMap(_ =>
|
|
55
|
+
_.match({
|
|
56
|
+
onNone: () =>
|
|
57
|
+
onMiss(parentId, id).tap(a => driver.set(parentId, id, a)),
|
|
58
|
+
onSome: Effect.succeed,
|
|
59
|
+
}),
|
|
60
|
+
)
|
|
59
61
|
|
|
60
62
|
const put = (_: A) =>
|
|
61
63
|
id(_).flatMap(([parentId, id]) => driver.set(parentId, id, _))
|
|
@@ -77,17 +79,22 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
|
|
|
77
79
|
update,
|
|
78
80
|
|
|
79
81
|
getForParent: (parentId: string) =>
|
|
80
|
-
driver.getForParent(parentId).
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
driver.getForParent(parentId).flatMap(_ =>
|
|
83
|
+
_.match({
|
|
84
|
+
onNone: () =>
|
|
85
|
+
onParentMiss(parentId)
|
|
86
|
+
.tap(entries =>
|
|
87
|
+
Effect.all(
|
|
88
|
+
entries.map(([id, a]) => driver.set(parentId, id, a)),
|
|
89
|
+
{ concurrency: "unbounded" },
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
.map(entries => new Map(entries) as ReadonlyMap<string, A>),
|
|
93
|
+
onSome: Effect.succeed,
|
|
94
|
+
}),
|
|
88
95
|
),
|
|
89
96
|
|
|
90
|
-
run: sync.
|
|
97
|
+
run: sync.zipRight(driver.run, { parallel: true }),
|
|
91
98
|
}
|
|
92
99
|
}
|
|
93
100
|
|
|
@@ -114,9 +121,12 @@ export const make = <EOps, EDriver, EMiss, A>({
|
|
|
114
121
|
}).runDrain
|
|
115
122
|
|
|
116
123
|
const get = (id: string) =>
|
|
117
|
-
driver
|
|
118
|
-
.
|
|
119
|
-
|
|
124
|
+
driver.get(id).flatMap(_ =>
|
|
125
|
+
_.match({
|
|
126
|
+
onNone: () => onMiss(id).tap(a => driver.set(id, a)),
|
|
127
|
+
onSome: Effect.succeed,
|
|
128
|
+
}),
|
|
129
|
+
)
|
|
120
130
|
|
|
121
131
|
const put = (_: A) => driver.set(id(_), _)
|
|
122
132
|
|
|
@@ -130,7 +140,7 @@ export const make = <EOps, EDriver, EMiss, A>({
|
|
|
130
140
|
get,
|
|
131
141
|
put,
|
|
132
142
|
update,
|
|
133
|
-
run: sync.
|
|
143
|
+
run: sync.zipRight(driver.run, { parallel: true }),
|
|
134
144
|
}
|
|
135
145
|
}
|
|
136
146
|
|
package/src/DiscordConfig.ts
CHANGED
|
@@ -51,6 +51,7 @@ export const make = ({
|
|
|
51
51
|
},
|
|
52
52
|
})
|
|
53
53
|
|
|
54
|
-
export const makeLayer =
|
|
54
|
+
export const makeLayer = (opts: MakeOpts) =>
|
|
55
|
+
Layer.succeed(DiscordConfig, make(opts))
|
|
55
56
|
export const makeFromConfig = (_: Config.Wrap<MakeOpts>) =>
|
|
56
|
-
Config.unwrap(_).config.map(make)
|
|
57
|
+
Layer.effect(DiscordConfig, Config.unwrap(_).config.map(make))
|
|
@@ -30,8 +30,8 @@ export const LiveJsonDiscordWSCodec = Layer.succeed(DiscordWSCodec, {
|
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
const make = Do($ => {
|
|
33
|
-
const ws = $(WS)
|
|
34
|
-
const encoding = $(DiscordWSCodec)
|
|
33
|
+
const ws = $(WS.accessWith(identity))
|
|
34
|
+
const encoding = $(DiscordWSCodec.accessWith(identity))
|
|
35
35
|
|
|
36
36
|
const connect = ({
|
|
37
37
|
url = "wss://gateway.discord.gg/",
|
|
@@ -69,4 +69,4 @@ const make = Do($ => {
|
|
|
69
69
|
|
|
70
70
|
export interface DiscordWS extends Effect.Success<typeof make> {}
|
|
71
71
|
export const DiscordWS = Tag<DiscordWS>()
|
|
72
|
-
export const LiveDiscordWS = LiveWS >>
|
|
72
|
+
export const LiveDiscordWS = LiveWS >> Layer.effect(DiscordWS, make)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as SendEvents from "./sendEvents.js"
|
|
2
2
|
import * as OS from "os"
|
|
3
|
+
import * as Option from "@effect/data/Option"
|
|
3
4
|
|
|
4
5
|
export interface Options {
|
|
5
6
|
token: string
|
|
@@ -42,11 +43,12 @@ export const identifyOrResume = (
|
|
|
42
43
|
const readyEvent = $(ready.get)
|
|
43
44
|
const seqNumber = $(seq.get)
|
|
44
45
|
|
|
45
|
-
return
|
|
46
|
+
return Option.all({
|
|
46
47
|
readyEvent,
|
|
47
48
|
seqNumber,
|
|
48
|
-
}).match(
|
|
49
|
-
() => identify(opts),
|
|
50
|
-
({ readyEvent, seqNumber }) =>
|
|
51
|
-
|
|
49
|
+
}).match({
|
|
50
|
+
onNone: () => identify(opts),
|
|
51
|
+
onSome: ({ readyEvent, seqNumber }) =>
|
|
52
|
+
resume(opts.token, readyEvent, seqNumber),
|
|
53
|
+
})
|
|
52
54
|
})
|
|
@@ -3,10 +3,13 @@ export const opCode =
|
|
|
3
3
|
<T = any>(code: Discord.GatewayOpcode) =>
|
|
4
4
|
source.filter((p): p is Discord.GatewayPayload<T> => p.op === code)
|
|
5
5
|
|
|
6
|
-
const maybeUpdateRef =
|
|
7
|
-
f: (p: Discord.GatewayPayload) => Maybe<T>,
|
|
8
|
-
|
|
9
|
-
)
|
|
6
|
+
const maybeUpdateRef =
|
|
7
|
+
<T>(f: (p: Discord.GatewayPayload) => Maybe<T>, ref: Ref<Maybe<T>>) =>
|
|
8
|
+
(_: Discord.GatewayPayload) =>
|
|
9
|
+
f(_).match({
|
|
10
|
+
onNone: () => Effect.unit,
|
|
11
|
+
onSome: a => ref.set(Maybe.some(a)),
|
|
12
|
+
})
|
|
10
13
|
|
|
11
14
|
export const latest = <T>(f: (p: Discord.GatewayPayload) => Maybe<T>) =>
|
|
12
15
|
Ref.make<Maybe<T>>(Maybe.none()).map(
|
|
@@ -15,10 +15,10 @@ const enum Phase {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export const make = Do($ => {
|
|
18
|
-
const { token, gateway } = $(DiscordConfig)
|
|
19
|
-
const limiter = $(RateLimiter)
|
|
20
|
-
const dws = $(DiscordWS)
|
|
21
|
-
const log = $(Log)
|
|
18
|
+
const { token, gateway } = $(DiscordConfig.accessWith(identity))
|
|
19
|
+
const limiter = $(RateLimiter.accessWith(identity))
|
|
20
|
+
const dws = $(DiscordWS.accessWith(identity))
|
|
21
|
+
const log = $(Log.accessWith(identity))
|
|
22
22
|
|
|
23
23
|
const connect = (
|
|
24
24
|
shard: [id: number, count: number],
|
|
@@ -94,10 +94,11 @@ export const make = Do($ => {
|
|
|
94
94
|
p.op === Discord.GatewayOpcode.DISPATCH && p.t === "READY",
|
|
95
95
|
)
|
|
96
96
|
.map(p => p.d!)
|
|
97
|
-
.match(
|
|
98
|
-
() => Effect.unit
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
.match({
|
|
98
|
+
onNone: () => Effect.unit,
|
|
99
|
+
onSome: ({ resume_gateway_url }) =>
|
|
100
|
+
socket.setUrl(resume_gateway_url),
|
|
101
|
+
})
|
|
101
102
|
|
|
102
103
|
const hellos = $(Queue.unbounded<Discord.GatewayPayload>())
|
|
103
104
|
const acks = $(Queue.unbounded<Discord.GatewayPayload>())
|
|
@@ -126,17 +127,19 @@ export const make = Do($ => {
|
|
|
126
127
|
Do($ => {
|
|
127
128
|
$(
|
|
128
129
|
updateLatestReady(p)
|
|
129
|
-
.
|
|
130
|
-
.
|
|
130
|
+
.zip(updateLatestSequence(p), { parallel: true })
|
|
131
|
+
.zip(maybeUpdateUrl(p)),
|
|
131
132
|
)
|
|
132
133
|
|
|
133
|
-
let effect = Effect.unit
|
|
134
|
+
let effect = Effect.unit
|
|
134
135
|
|
|
135
136
|
switch (p.op) {
|
|
136
137
|
case Discord.GatewayOpcode.HELLO:
|
|
137
138
|
effect = identify
|
|
138
139
|
.tap(prioritySend)
|
|
139
|
-
.
|
|
140
|
+
.zip(setPhase(Phase.Handshake).zipRight(hellos.offer(p)), {
|
|
141
|
+
parallel: true,
|
|
142
|
+
})
|
|
140
143
|
break
|
|
141
144
|
case Discord.GatewayOpcode.HEARTBEAT_ACK:
|
|
142
145
|
effect = acks.offer(p)
|
|
@@ -158,11 +161,13 @@ export const make = Do($ => {
|
|
|
158
161
|
|
|
159
162
|
const drainSendQueue = sendQueue.take().tap(send).forever
|
|
160
163
|
|
|
161
|
-
const run =
|
|
162
|
-
.flatMap(onPayload)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
const run = Effect.all(
|
|
165
|
+
socket.take.flatMap(onPayload).forever,
|
|
166
|
+
heartbeats,
|
|
167
|
+
drainSendQueue,
|
|
168
|
+
socket.run,
|
|
169
|
+
{ discard: true, concurrency: "unbounded" },
|
|
170
|
+
)
|
|
166
171
|
|
|
167
172
|
return { id: shard, send, run } as const
|
|
168
173
|
})
|
|
@@ -173,7 +178,7 @@ export const make = Do($ => {
|
|
|
173
178
|
export interface Shard extends Effect.Success<typeof make> {}
|
|
174
179
|
export const Shard = Tag<Shard>()
|
|
175
180
|
export const LiveShard =
|
|
176
|
-
(LiveDiscordWS + LiveRateLimiter) >>
|
|
181
|
+
(LiveDiscordWS + LiveRateLimiter) >> Layer.effect(Shard, make)
|
|
177
182
|
|
|
178
183
|
export interface RunningShard
|
|
179
184
|
extends Effect.Success<ReturnType<Shard["connect"]>> {}
|
|
@@ -12,11 +12,11 @@ const claimRepeatPolicy = Schedule.fixed(Duration.minutes(3)).whileInput(
|
|
|
12
12
|
).passthrough as Schedule<never, Maybe<number>, Some<number>>
|
|
13
13
|
|
|
14
14
|
const make = Do($ => {
|
|
15
|
-
const store = $(ShardStore)
|
|
16
|
-
const rest = $(DiscordREST)
|
|
17
|
-
const { gateway: config } = $(DiscordConfig)
|
|
18
|
-
const limiter = $(RateLimiter)
|
|
19
|
-
const shard = $(Shard)
|
|
15
|
+
const store = $(ShardStore.accessWith(identity))
|
|
16
|
+
const rest = $(DiscordREST.accessWith(identity))
|
|
17
|
+
const { gateway: config } = $(DiscordConfig.accessWith(identity))
|
|
18
|
+
const limiter = $(RateLimiter.accessWith(identity))
|
|
19
|
+
const shard = $(Shard.accessWith(identity))
|
|
20
20
|
const currentShards = $(Ref.make(HashSet.empty<RunningShard>()))
|
|
21
21
|
|
|
22
22
|
const takeConfig = (totalCount: number) =>
|
|
@@ -97,11 +97,11 @@ const make = Do($ => {
|
|
|
97
97
|
).map(() => spawner)
|
|
98
98
|
|
|
99
99
|
return $(
|
|
100
|
-
Effect.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
>,
|
|
100
|
+
Effect.all(
|
|
101
|
+
Effect.all(spawners, { concurrency: "unbounded", discard: true }),
|
|
102
|
+
deferred.await,
|
|
103
|
+
{ concurrency: "unbounded", discard: true },
|
|
104
|
+
) as Effect<never, WebSocketError | WebSocketCloseError, never>,
|
|
105
105
|
)
|
|
106
106
|
})
|
|
107
107
|
|
|
@@ -111,4 +111,4 @@ const make = Do($ => {
|
|
|
111
111
|
export interface Sharder extends Effect.Success<typeof make> {}
|
|
112
112
|
export const Sharder = Tag<Sharder>()
|
|
113
113
|
export const LiveSharder =
|
|
114
|
-
(LiveRateLimiter + LiveShard) >>
|
|
114
|
+
(LiveRateLimiter + LiveShard) >> Layer.effect(Sharder, make)
|
package/src/DiscordGateway/WS.ts
CHANGED
|
@@ -45,7 +45,7 @@ const offer = (
|
|
|
45
45
|
run(
|
|
46
46
|
queue
|
|
47
47
|
.offer(message.data)
|
|
48
|
-
.zipLeft(log.debug("WS", "offer", message.data)),
|
|
48
|
+
.zipLeft(log.debug("WS", "offer", message.data), {}),
|
|
49
49
|
)
|
|
50
50
|
})
|
|
51
51
|
|
|
@@ -62,15 +62,18 @@ const offer = (
|
|
|
62
62
|
const waitForOpen = (ws: globalThis.WebSocket, timeout: Duration) =>
|
|
63
63
|
Effect.suspend(() => {
|
|
64
64
|
if (ws.readyState === WebSocket.OPEN) {
|
|
65
|
-
return Effect.unit
|
|
65
|
+
return Effect.unit
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
return Effect.async<never, never, void>(resume => {
|
|
69
|
-
ws.addEventListener("open", () => resume(Effect.unit
|
|
69
|
+
ws.addEventListener("open", () => resume(Effect.unit), {
|
|
70
70
|
once: true,
|
|
71
71
|
})
|
|
72
72
|
})
|
|
73
|
-
}).timeoutFail(
|
|
73
|
+
}).timeoutFail({
|
|
74
|
+
onTimeout: () => new WebSocketError("open-timeout"),
|
|
75
|
+
duration: timeout,
|
|
76
|
+
})
|
|
74
77
|
|
|
75
78
|
const send = (
|
|
76
79
|
ws: globalThis.WebSocket,
|
|
@@ -93,12 +96,12 @@ const send = (
|
|
|
93
96
|
}).forever
|
|
94
97
|
|
|
95
98
|
const make = Do($ => {
|
|
96
|
-
const log = $(Log)
|
|
99
|
+
const log = $(Log.accessWith(identity))
|
|
97
100
|
|
|
98
101
|
const connect = (
|
|
99
102
|
url: Ref<string>,
|
|
100
103
|
takeOutbound: Effect<never, never, Message>,
|
|
101
|
-
onConnecting = Effect.unit
|
|
104
|
+
onConnecting = Effect.unit,
|
|
102
105
|
openTimeout = Duration.seconds(3),
|
|
103
106
|
) =>
|
|
104
107
|
Do($ => {
|
|
@@ -107,8 +110,9 @@ const make = Do($ => {
|
|
|
107
110
|
const run = onConnecting
|
|
108
111
|
.zipRight(socket(url))
|
|
109
112
|
.flatMap(ws =>
|
|
110
|
-
offer(ws, queue, log).
|
|
113
|
+
offer(ws, queue, log).zipLeft(
|
|
111
114
|
waitForOpen(ws, openTimeout).zipRight(send(ws, takeOutbound, log)),
|
|
115
|
+
{ parallel: true },
|
|
112
116
|
),
|
|
113
117
|
)
|
|
114
118
|
.scoped.retryWhile(isReconnect)
|
|
@@ -121,4 +125,4 @@ const make = Do($ => {
|
|
|
121
125
|
|
|
122
126
|
export interface WS extends Effect.Success<typeof make> {}
|
|
123
127
|
export const WS = Tag<WS>()
|
|
124
|
-
export const LiveWS =
|
|
128
|
+
export const LiveWS = Layer.effect(WS, make)
|
package/src/DiscordGateway.ts
CHANGED
|
@@ -17,11 +17,11 @@ const handleDispatchFactory =
|
|
|
17
17
|
if (_.t === event) {
|
|
18
18
|
return handle(_.d as any)
|
|
19
19
|
}
|
|
20
|
-
return Effect.unit
|
|
20
|
+
return Effect.unit
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
export const make = Do($ => {
|
|
24
|
-
const sharder = $(Sharder)
|
|
24
|
+
const sharder = $(Sharder.accessWith(identity))
|
|
25
25
|
const hub = $(Hub.unbounded<Discord.GatewayPayload<Discord.ReceiveEvent>>())
|
|
26
26
|
|
|
27
27
|
const sendQueue = $(
|
|
@@ -48,4 +48,5 @@ export const make = Do($ => {
|
|
|
48
48
|
|
|
49
49
|
export interface DiscordGateway extends Effect.Success<typeof make> {}
|
|
50
50
|
export const DiscordGateway = Tag<DiscordGateway>()
|
|
51
|
-
export const LiveDiscordGateway =
|
|
51
|
+
export const LiveDiscordGateway =
|
|
52
|
+
LiveSharder >> Layer.effect(DiscordGateway, make)
|
package/src/DiscordREST/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as Option from "@effect/data/Option"
|
|
2
|
+
|
|
1
3
|
const majorResources = ["channels", "guilds", "webhooks"] as const
|
|
2
4
|
|
|
3
5
|
export const routeFromConfig = (path: string, method: string) => {
|
|
@@ -24,7 +26,7 @@ export const retryAfter = (headers: Headers) =>
|
|
|
24
26
|
.map(Duration.seconds)
|
|
25
27
|
|
|
26
28
|
export const rateLimitFromHeaders = (headers: Headers) =>
|
|
27
|
-
|
|
29
|
+
Option.all({
|
|
28
30
|
bucket: Maybe.fromNullable(headers.get("x-ratelimit-bucket")),
|
|
29
31
|
retryAfter: retryAfter(headers),
|
|
30
32
|
limit: numberHeader(headers)("x-ratelimit-limit"),
|