@shivaedev/discord 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +6 -7
- package/dist/{gatewayConnection.d.ts → adapters/gatewayConnection.d.ts} +1 -1
- package/dist/adapters/gatewayConnection.d.ts.map +1 -0
- package/dist/adapters/gatewayConnection.js.map +1 -0
- package/dist/gateway/run.d.ts +6 -0
- package/dist/gateway/run.d.ts.map +1 -0
- package/dist/{runGateway.js → gateway/run.js} +3 -3
- package/dist/gateway/run.js.map +1 -0
- package/dist/{DiscordGateway.d.ts → gateway/service.d.ts} +2 -2
- package/dist/gateway/service.d.ts.map +1 -0
- package/dist/{DiscordGateway.js → gateway/service.js} +3 -3
- package/dist/gateway/service.js.map +1 -0
- package/dist/request.js +1 -1
- package/dist/request.js.map +1 -1
- package/dist/rest/initialize.d.ts +3 -0
- package/dist/rest/initialize.d.ts.map +1 -0
- package/dist/rest/initialize.js +3 -0
- package/dist/rest/initialize.js.map +1 -0
- package/dist/rest/layer.d.ts +3 -0
- package/dist/rest/layer.d.ts.map +1 -0
- package/dist/rest/layer.js +5 -0
- package/dist/rest/layer.js.map +1 -0
- package/dist/rest/request.d.ts +8 -0
- package/dist/rest/request.d.ts.map +1 -0
- package/dist/{restClient.js → rest/request.js} +12 -17
- package/dist/rest/request.js.map +1 -0
- package/dist/rest/service.d.ts +8 -0
- package/dist/rest/service.d.ts.map +1 -0
- package/dist/{DiscordRest.js → rest/service.js} +7 -5
- package/dist/rest/service.js.map +1 -0
- package/dist/rest-limits/initialize.d.ts +7 -0
- package/dist/rest-limits/initialize.d.ts.map +1 -0
- package/dist/rest-limits/initialize.js +9 -0
- package/dist/rest-limits/initialize.js.map +1 -0
- package/dist/rest-limits/observe.d.ts +5 -0
- package/dist/rest-limits/observe.d.ts.map +1 -0
- package/dist/rest-limits/observe.js +13 -0
- package/dist/rest-limits/observe.js.map +1 -0
- package/dist/rest-limits/refuse.d.ts +4 -0
- package/dist/rest-limits/refuse.d.ts.map +1 -0
- package/dist/rest-limits/refuse.js +13 -0
- package/dist/rest-limits/refuse.js.map +1 -0
- package/dist/rest-limits/service.d.ts +8 -0
- package/dist/rest-limits/service.d.ts.map +1 -0
- package/dist/rest-limits/service.js +12 -0
- package/dist/rest-limits/service.js.map +1 -0
- package/dist/rest-limits/wait.d.ts +4 -0
- package/dist/rest-limits/wait.d.ts.map +1 -0
- package/dist/rest-limits/wait.js +11 -0
- package/dist/rest-limits/wait.js.map +1 -0
- package/package.json +8 -8
- package/src/{runGateway.ts → gateway/run.ts} +2 -2
- package/src/{DiscordGateway.ts → gateway/service.ts} +2 -2
- package/src/request.ts +1 -1
- package/src/rest/initialize.ts +3 -0
- package/src/rest/layer.ts +5 -0
- package/src/{restClient.ts → rest/request.ts} +28 -35
- package/src/rest/service.ts +14 -0
- package/src/rest-limits/initialize.ts +9 -0
- package/src/rest-limits/observe.ts +18 -0
- package/src/rest-limits/refuse.ts +13 -0
- package/src/rest-limits/service.ts +12 -0
- package/src/rest-limits/wait.ts +12 -0
- package/dist/DiscordGateway.d.ts.map +0 -1
- package/dist/DiscordGateway.js.map +0 -1
- package/dist/DiscordRest.d.ts +0 -8
- package/dist/DiscordRest.d.ts.map +0 -1
- package/dist/DiscordRest.js.map +0 -1
- package/dist/gatewayConnection.d.ts.map +0 -1
- package/dist/gatewayConnection.js.map +0 -1
- package/dist/rateLimits.d.ts +0 -8
- package/dist/rateLimits.d.ts.map +0 -1
- package/dist/rateLimits.js +0 -36
- package/dist/rateLimits.js.map +0 -1
- package/dist/restClient.d.ts +0 -11
- package/dist/restClient.d.ts.map +0 -1
- package/dist/restClient.js.map +0 -1
- package/dist/runGateway.d.ts +0 -6
- package/dist/runGateway.d.ts.map +0 -1
- package/dist/runGateway.js.map +0 -1
- package/src/DiscordRest.ts +0 -12
- package/src/rateLimits.ts +0 -39
- /package/dist/{gatewayConnection.js → adapters/gatewayConnection.js} +0 -0
- /package/src/{gatewayConnection.ts → adapters/gatewayConnection.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.1 - 2026-11-07
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Require Effect 4.1.1 and its matching platform packages.
|
|
8
|
+
|
|
9
|
+
## 0.4.0 - 2026-11-05
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- REST operations yield their declared dependencies; a dedicated rate-limit service owns pacing state for the registered Layer's lifetime. REST and gateway operations have named tracing spans.
|
|
14
|
+
|
|
15
|
+
### Breaking
|
|
16
|
+
|
|
17
|
+
- Import `DiscordRest` from `@shivaedev/discord/rest/service.ts` and provide `layer` from `@shivaedev/discord/rest/layer.ts` in place of `DiscordRest.layer`. The composed Layer supplies the rate-limit service; continue supplying the native HTTP client, bot token and optional config once at registration.
|
|
18
|
+
- Import `DiscordGateway` from `@shivaedev/discord/gateway/service.ts`. Its Layer and `run(handler)` signature stay the same.
|
|
19
|
+
- Replace direct uses of the removed `restClient.ts` and `rateLimits.ts` factories with the composed REST Layer and `DiscordRest.request`. Direct gateway integrations import `run` from `gateway/run.ts` and `gatewayConnection` from `adapters/gatewayConnection.ts` instead of `runGateway.ts` and `gatewayConnection.ts`.
|
|
20
|
+
|
|
3
21
|
## 0.3.0 - 2026-11-05
|
|
4
22
|
|
|
5
23
|
### Breaking
|
package/README.md
CHANGED
|
@@ -19,20 +19,19 @@ REST and gateway are independent services sharing a redacted `DiscordToken`. Pro
|
|
|
19
19
|
|
|
20
20
|
### Bot REST
|
|
21
21
|
|
|
22
|
-
Provide `
|
|
22
|
+
Provide `layer` from `rest/layer.ts`, a native `HttpClient` and the token:
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import { Layer, Redacted } from "effect";
|
|
26
26
|
import { FetchHttpClient } from "effect/http";
|
|
27
|
-
import {
|
|
27
|
+
import { layer } from "@shivaedev/discord/rest/layer.ts";
|
|
28
28
|
import { DiscordToken } from "@shivaedev/discord/DiscordToken.ts";
|
|
29
29
|
|
|
30
|
-
const restLayer =
|
|
31
|
-
Layer.provide(FetchHttpClient.layer),
|
|
32
|
-
Layer.provide(Layer.succeed(DiscordToken)(Redacted.make("bot-token"))),
|
|
33
|
-
);
|
|
30
|
+
const restLayer = layer.pipe(Layer.provide(FetchHttpClient.layer), Layer.provide(Layer.succeed(DiscordToken)(Redacted.make("bot-token"))));
|
|
34
31
|
```
|
|
35
32
|
|
|
33
|
+
The composed REST Layer provides `DiscordRest` from `rest/service.ts` and its `DiscordRestLimits` dependency. Its registration chooses their lifetime: share one build for a bot, or build a fresh Layer for independent pacing state. Operations yield the HTTP client, token, config and limits from the environment; REST initializer state owns only a semaphore, and the limits service owns the bucket maps and reset times.
|
|
34
|
+
|
|
36
35
|
`request(method, path, schema, body?)` reads the service and decodes the result. `DiscordRest.request(method, path, body?)` returns decoded JSON as `unknown`; a 204 response returns `undefined`. Paths start with `/` and are relative to Discord's API v10 base. Request bodies use native HTTP JSON encoding, and response reads use `@shivaedev/http` with a 1 MiB limit.
|
|
37
36
|
|
|
38
37
|
One service instance serializes calls for its bot. It tracks Discord's bucket ids, major channel/guild identifiers, remaining count and relative reset time. An exhausted bucket delays the next matching call. A 429 reads Discord's `retry_after` seconds and `global` flag, releases the response, waits on Effect's clock and retries up to three times. Exhaustion fails with `DiscordRateLimited`, carrying the final delay in seconds. Transport failures become `DiscordTransportError`; other HTTP statuses retain `@shivaedev/http`'s typed failures. Schema decoding failures remain in the error channel.
|
|
@@ -43,7 +42,7 @@ Provide `DiscordGateway.layer`, the same token, `DiscordConfig` with your intent
|
|
|
43
42
|
|
|
44
43
|
```ts
|
|
45
44
|
import { Effect } from "effect";
|
|
46
|
-
import { DiscordGateway } from "@shivaedev/discord/
|
|
45
|
+
import { DiscordGateway } from "@shivaedev/discord/gateway/service.ts";
|
|
47
46
|
|
|
48
47
|
const listen = Effect.gen(function* () {
|
|
49
48
|
const gateway = yield* DiscordGateway;
|
|
@@ -2,5 +2,5 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { Socket } from "effect/socket";
|
|
3
3
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
4
4
|
import { type GatewayDispatch, type GatewaySession } from "#gatewayProtocol.ts";
|
|
5
|
-
export declare function gatewayConnection(session: GatewaySession, dispatch: (event: GatewayDispatch) => Effect.Effect<void>): Effect.Effect<never, import("
|
|
5
|
+
export declare function gatewayConnection(session: GatewaySession, dispatch: (event: GatewayDispatch) => Effect.Effect<void>): Effect.Effect<never, import("../errors.ts").DiscordGatewayProtocolError | Socket.SocketError, DiscordToken | Socket.Socket>;
|
|
6
6
|
//# sourceMappingURL=gatewayConnection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatewayConnection.d.ts","sourceRoot":"","sources":["../../src/adapters/gatewayConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAA2B,KAAK,eAAe,EAAqB,KAAK,cAAc,EAA2B,MAAM,qBAAqB,CAAC;AAErJ,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,+HAkFnH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatewayConnection.js","sourceRoot":"","sources":["../../src/adapters/gatewayConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAgE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErJ,MAAM,UAAU,iBAAiB,CAAC,OAAuB,EAAE,QAAyD;IACnH,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC;QAClC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;QACzC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAA6B,CAAC;QACjE,IAAI,YAAY,GAAG,IAAI,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAU,EAAE,CAAU;YAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9G,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAgB;YACnE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;gBACjC,OAAO,IAAI,EAAE,CAAC;oBACb,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAC9B,IAAI,CAAC,YAAY,EAAE,CAAC;wBACnB,OAAO,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;oBAC3B,CAAC;oBACD,YAAY,GAAG,KAAK,CAAC;oBACrB,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAClC,CAAC;YACF,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAChB,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EACrD,MAAM,CAAC,UAAU,CACjB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAa;YACvD,MAAM,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7D,MAAM,OAAO,GACZ,OAAO,CAAC,SAAS,KAAK,SAAS;gBAC9B,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACjH,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7F,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,KAAK,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAmB;YAC/D,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;gBAChD,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;gBACpC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YACrC,CAAC;YACD,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC5F,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YACtE,CAAC;QACF,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAmB;YAC9D,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/C,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;YAC5B,CAAC;YACD,QAAQ,KAAK,CAAC,EAAE,EAAE,CAAC;gBAClB,KAAK,EAAE;oBACN,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC9B,KAAK,EAAE;oBACN,YAAY,GAAG,IAAI,CAAC;oBACpB,OAAO;gBACR,KAAK,CAAC;oBACL,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzC,KAAK,CAAC;oBACL,OAAO,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;gBAC3B,KAAK,CAAC;oBACL,IAAI,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;wBACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;wBAC9B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;wBAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;oBACzB,CAAC;oBACD,OAAO,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;gBAC3B,KAAK,CAAC;oBACL,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnC,OAAO,IAAI,EAAE,CAAC;gBACb,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBACtC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxC,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { DiscordGatewayClosed } from "#errors.ts";
|
|
3
|
+
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
4
|
+
import type { GatewayDispatch } from "#gatewayProtocol.ts";
|
|
5
|
+
export declare const run: (dispatch: (event: GatewayDispatch) => Effect.Effect<void>) => Effect.Effect<never, DiscordGatewayClosed | import("#errors.ts").DiscordGatewayProtocolError, import("../DiscordToken.ts").DiscordToken | GatewayTransport>;
|
|
6
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/gateway/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,qBAAqB,CAAC;AAE3E,eAAO,MAAM,GAAG,qBAAgE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gKAuBrH,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { Socket } from "effect/socket";
|
|
3
|
+
import { gatewayConnection } from "#adapters/gatewayConnection.ts";
|
|
3
4
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
5
|
import { DiscordGatewayClosed } from "#errors.ts";
|
|
5
6
|
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
6
|
-
|
|
7
|
-
export const runGateway = Effect.fnUntraced(function* (dispatch) {
|
|
7
|
+
export const run = Effect.fn("DiscordGateway.run")(function* (dispatch) {
|
|
8
8
|
const config = yield* DiscordConfig;
|
|
9
9
|
const transport = yield* GatewayTransport;
|
|
10
10
|
const session = { resumeUrl: undefined, sequence: null, sessionId: undefined };
|
|
@@ -26,4 +26,4 @@ export const runGateway = Effect.fnUntraced(function* (dispatch) {
|
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
|
-
//# sourceMappingURL=
|
|
29
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/gateway/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAyD;IACtH,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC;IAC1C,MAAM,OAAO,GAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAC/F,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,sBAAsB,CAAC,CAAC;QACtG,KAAK,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC;aACzC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aAClD,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACtF,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;gBAC3E,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACpC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC9B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC,CAAC,CACF,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC"}
|
|
@@ -2,8 +2,8 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
3
3
|
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
4
4
|
export declare const DiscordGateway: import("effect/Context").Service<"@shivaedev/discord/DiscordGateway", Readonly<{
|
|
5
|
-
readonly run: (dispatch: (event: import("
|
|
5
|
+
readonly run: (dispatch: (event: import("../gatewayProtocol.ts").GatewayDispatch) => Effect.Effect<void>) => Effect.Effect<never, import("../errors.ts").DiscordGatewayClosed | import("../errors.ts").DiscordGatewayProtocolError, never>;
|
|
6
6
|
}>> & {
|
|
7
7
|
readonly layer: import("effect/Layer").Layer<"@shivaedev/discord/DiscordGateway", never, DiscordToken | GatewayTransport>;
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=
|
|
9
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/gateway/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,eAAO,MAAM,cAAc;;;;CAKzB,CAAC"}
|
|
@@ -3,11 +3,11 @@ import { defineService } from "@shivaedev/service/defineService.ts";
|
|
|
3
3
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
4
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
5
|
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { run } from "#gateway/run.ts";
|
|
7
7
|
export const DiscordGateway = defineService({
|
|
8
8
|
id: "@shivaedev/discord/DiscordGateway",
|
|
9
9
|
initialize: Effect.void,
|
|
10
|
-
methods: () => ({ run
|
|
10
|
+
methods: () => ({ run }),
|
|
11
11
|
requires: [DiscordConfig, DiscordToken, GatewayTransport],
|
|
12
12
|
});
|
|
13
|
-
//# sourceMappingURL=
|
|
13
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/gateway/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;IAC3C,EAAE,EAAE,mCAAmC;IACvC,UAAU,EAAE,MAAM,CAAC,IAAI;IACvB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,gBAAgB,CAAC;CACzD,CAAC,CAAC"}
|
package/dist/request.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
|
-
import { DiscordRest } from "#
|
|
2
|
+
import { DiscordRest } from "#rest/service.ts";
|
|
3
3
|
export function request(method, path, schema, body) {
|
|
4
4
|
return Effect.flatMap(DiscordRest, (rest) => rest.request(method, path, body)).pipe(Effect.flatMap(Schema.decodeUnknownEffect(schema)));
|
|
5
5
|
}
|
package/dist/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,UAAU,OAAO,CAAoD,MAAkB,EAAE,IAAY,EAAE,MAAe,EAAE,IAAc;IAC3I,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/rest/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,eAAO,MAAM,UAAU,mEAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.js","sourceRoot":"","sources":["../../src/rest/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../../src/rest/layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAI/B,eAAO,MAAM,KAAK,+IAAiE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../../src/rest/layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { HttpClient } from "effect/http";
|
|
3
|
+
import type { HttpMethod } from "effect/http/HttpMethod";
|
|
4
|
+
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
|
+
import { DiscordRateLimited, DiscordTransportError } from "#errors.ts";
|
|
6
|
+
import type { initialize } from "#rest/initialize.ts";
|
|
7
|
+
export declare function request(lock: Effect.Success<typeof initialize>): (method: HttpMethod, path: string, body?: unknown) => Effect.Effect<unknown, DiscordRateLimited | DiscordTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").InvalidBodyLimit | import("@shivaedev/http/errors.ts").RemoteGone | import("@shivaedev/http/errors.ts").RemoteHttpError | import("@shivaedev/http/errors.ts").RemoteNotFound | import("@shivaedev/http/errors.ts").RemoteRateLimited | import("@shivaedev/http/errors.ts").RemoteUnauthorized | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | Schema.SchemaError, "@shivaedev/discord/DiscordRestLimits" | DiscordToken | HttpClient.HttpClient>;
|
|
8
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/rest/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAMzD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAOtD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,UAAU,CAAC,8oBAuC9D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Redacted, Schema
|
|
1
|
+
import { Effect, Redacted, Schema } from "effect";
|
|
2
2
|
import { HttpClient, HttpClientRequest } from "effect/http";
|
|
3
3
|
import { readBoundedJson } from "@shivaedev/http/body.ts";
|
|
4
4
|
import { checkStatus } from "@shivaedev/http/checkStatus.ts";
|
|
@@ -7,15 +7,14 @@ import { routeKey } from "#adapters/routeKey.ts";
|
|
|
7
7
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
8
8
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
9
9
|
import { DiscordRateLimited, DiscordTransportError } from "#errors.ts";
|
|
10
|
-
import {
|
|
10
|
+
import { DiscordRestLimits } from "#rest-limits/service.ts";
|
|
11
11
|
const Limited = Schema.Struct({ global: Schema.optional(Schema.Boolean), retryAfter: Schema.Number }).pipe(Schema.encodeKeys({ retryAfter: "retry_after" }));
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const request = Effect.fnUntraced(function* (method, path, body) {
|
|
12
|
+
export function request(lock) {
|
|
13
|
+
return Effect.fn("DiscordRest.request")(function* (method, path, body) {
|
|
14
|
+
const client = HttpClient.withScope(yield* HttpClient.HttpClient);
|
|
15
|
+
const token = yield* DiscordToken;
|
|
16
|
+
const config = yield* DiscordConfig;
|
|
17
|
+
const rates = yield* DiscordRestLimits;
|
|
19
18
|
const { major, route } = routeKey(method, path);
|
|
20
19
|
let input = HttpClientRequest.make(method)(`${config.apiUrl}${path}`).pipe(HttpClientRequest.setHeader("Authorization", `Bot ${Redacted.value(token)}`));
|
|
21
20
|
if (body !== undefined) {
|
|
@@ -23,7 +22,7 @@ export const initializeRest = Effect.gen(function* () {
|
|
|
23
22
|
}
|
|
24
23
|
for (let attempt = 0;; attempt += 1) {
|
|
25
24
|
yield* rates.wait(route, major);
|
|
26
|
-
const answer = yield* Effect.
|
|
25
|
+
const answer = yield* Effect.gen(function* () {
|
|
27
26
|
const response = yield* client.execute(input);
|
|
28
27
|
yield* rates.observe(route, major, response.headers);
|
|
29
28
|
if (isRateLimited(response.status)) {
|
|
@@ -37,15 +36,11 @@ export const initializeRest = Effect.gen(function* () {
|
|
|
37
36
|
yield* checkStatus(response);
|
|
38
37
|
const value = isEmpty(response.status) ? undefined : yield* readBoundedJson(response, 1024 * 1024, Schema.Unknown);
|
|
39
38
|
return { retry: false, value };
|
|
40
|
-
}));
|
|
39
|
+
}).pipe(Effect.scoped);
|
|
41
40
|
if (!answer.retry) {
|
|
42
41
|
return answer.value;
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
|
-
});
|
|
46
|
-
return { lock, request };
|
|
47
|
-
});
|
|
48
|
-
export function restRequest(state) {
|
|
49
|
-
return (method, path, body) => state.request(method, path, body).pipe(state.lock.withPermit, Effect.catchTag("HttpClientError", () => Effect.fail(new DiscordTransportError({}))));
|
|
44
|
+
}, lock.withPermit, Effect.catchTag("HttpClientError", () => Effect.fail(new DiscordTransportError({}))));
|
|
50
45
|
}
|
|
51
|
-
//# sourceMappingURL=
|
|
46
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/rest/request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HttpClient } from "effect/http";
|
|
2
|
+
import { DiscordToken } from "#DiscordToken.ts";
|
|
3
|
+
export declare const DiscordRest: import("effect/Context").Service<"@shivaedev/discord/DiscordRest", Readonly<{
|
|
4
|
+
readonly request: (method: import("effect/http/HttpMethod").HttpMethod, path: string, body?: unknown) => import("effect/Effect").Effect<unknown, import("../errors.ts").DiscordRateLimited | import("../errors.ts").DiscordTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").InvalidBodyLimit | import("@shivaedev/http/errors.ts").RemoteGone | import("@shivaedev/http/errors.ts").RemoteHttpError | import("@shivaedev/http/errors.ts").RemoteNotFound | import("@shivaedev/http/errors.ts").RemoteRateLimited | import("@shivaedev/http/errors.ts").RemoteUnauthorized | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | import("effect/Schema").SchemaError, never>;
|
|
5
|
+
}>> & {
|
|
6
|
+
readonly layer: import("effect/Layer").Layer<"@shivaedev/discord/DiscordRest", never, "@shivaedev/discord/DiscordRestLimits" | DiscordToken | HttpClient.HttpClient>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/rest/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKhD,eAAO,MAAM,WAAW;;;;CAKtB,CAAC"}
|
|
@@ -2,11 +2,13 @@ import { HttpClient } from "effect/http";
|
|
|
2
2
|
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
3
3
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
4
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
|
-
import {
|
|
5
|
+
import { initialize } from "#rest/initialize.ts";
|
|
6
|
+
import { request } from "#rest/request.ts";
|
|
7
|
+
import { DiscordRestLimits } from "#rest-limits/service.ts";
|
|
6
8
|
export const DiscordRest = defineService({
|
|
7
9
|
id: "@shivaedev/discord/DiscordRest",
|
|
8
|
-
initialize
|
|
9
|
-
methods: (state) => ({ request:
|
|
10
|
-
requires: [HttpClient.HttpClient, DiscordToken, DiscordConfig],
|
|
10
|
+
initialize,
|
|
11
|
+
methods: (state) => ({ request: request(state) }),
|
|
12
|
+
requires: [HttpClient.HttpClient, DiscordToken, DiscordConfig, DiscordRestLimits],
|
|
11
13
|
});
|
|
12
|
-
//# sourceMappingURL=
|
|
14
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/rest/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACxC,EAAE,EAAE,gCAAgC;IACpC,UAAU;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IACjD,QAAQ,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC;CACjF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../src/rest-limits/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAErC,eAAO,MAAM,UAAU;;;;gBAMrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize.js","sourceRoot":"","sources":["../../src/rest-limits/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC7C,OAAO;QACN,OAAO,EAAE,IAAI,GAAG,EAAkB;QAClC,WAAW,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,IAAI,GAAG,EAAkB;KACjC,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { Headers } from "effect/http";
|
|
3
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
4
|
+
export declare function observe(state: Effect.Success<typeof initialize>): (route: string, major: string, headers: Headers.Headers) => Effect.Effect<void, never, never>;
|
|
5
|
+
//# sourceMappingURL=observe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/rest-limits/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,UAAU,CAAC,iGAa/D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
export function observe(state) {
|
|
3
|
+
return Effect.fn("DiscordRestLimits.observe")(function* (route, major, headers) {
|
|
4
|
+
const bucket = headers["x-ratelimit-bucket"];
|
|
5
|
+
if (bucket !== undefined) {
|
|
6
|
+
state.routes.set(route, bucket);
|
|
7
|
+
}
|
|
8
|
+
if (headers["x-ratelimit-remaining"] === "0") {
|
|
9
|
+
state.blocked.set(`${state.routes.get(route) ?? route}:${major}`, (yield* Clock.currentTimeMillis) + Number(headers["x-ratelimit-reset-after"] ?? 0) * 1000);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=observe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/rest-limits/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIvC,MAAM,UAAU,OAAO,CAAC,KAAwC;IAC/D,OAAO,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAa,EAAE,KAAa,EAAE,OAAwB;QAC9G,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,OAAO,CAAC,uBAAuB,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9C,KAAK,CAAC,OAAO,CAAC,GAAG,CAChB,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE,EAC9C,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CACzF,CAAC;QACH,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
export declare function refuse(state: Effect.Success<typeof initialize>): (route: string, major: string, seconds: number, global: boolean) => Effect.Effect<void, never, never>;
|
|
4
|
+
//# sourceMappingURL=refuse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refuse.d.ts","sourceRoot":"","sources":["../../src/rest-limits/refuse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,UAAU,CAAC,yGAS9D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Clock, Effect, Ref } from "effect";
|
|
2
|
+
export function refuse(state) {
|
|
3
|
+
return Effect.fn("DiscordRestLimits.refuse")(function* (route, major, seconds, global) {
|
|
4
|
+
const reset = (yield* Clock.currentTimeMillis) + seconds * 1000;
|
|
5
|
+
if (global) {
|
|
6
|
+
yield* Ref.update(state.globalReset, (previous) => Math.max(previous, reset));
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
state.blocked.set(`${state.routes.get(route) ?? route}:${major}`, reset);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=refuse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refuse.js","sourceRoot":"","sources":["../../src/rest-limits/refuse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG5C,MAAM,UAAU,MAAM,CAAC,KAAwC;IAC9D,OAAO,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAa,EAAE,KAAa,EAAE,OAAe,EAAE,MAAe;QACrH,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;QAChE,IAAI,MAAM,EAAE,CAAC;YACZ,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;QAC/E,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DiscordRestLimits: import("effect/Context").Service<"@shivaedev/discord/DiscordRestLimits", Readonly<{
|
|
2
|
+
readonly observe: (route: string, major: string, headers: import("effect/http/Headers").Headers) => import("effect/Effect").Effect<void, never, never>;
|
|
3
|
+
readonly refuse: (route: string, major: string, seconds: number, global: boolean) => import("effect/Effect").Effect<void, never, never>;
|
|
4
|
+
readonly wait: (route: string, major: string) => import("effect/Effect").Effect<void, never, never>;
|
|
5
|
+
}>> & {
|
|
6
|
+
readonly layer: import("effect/Layer").Layer<"@shivaedev/discord/DiscordRestLimits", never, never>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/rest-limits/service.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB;;;;;;CAK5B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
2
|
+
import { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
import { observe } from "#rest-limits/observe.ts";
|
|
4
|
+
import { refuse } from "#rest-limits/refuse.ts";
|
|
5
|
+
import { wait } from "#rest-limits/wait.ts";
|
|
6
|
+
export const DiscordRestLimits = defineService({
|
|
7
|
+
id: "@shivaedev/discord/DiscordRestLimits",
|
|
8
|
+
initialize,
|
|
9
|
+
methods: (state) => ({ observe: observe(state), refuse: refuse(state), wait: wait(state) }),
|
|
10
|
+
requires: [],
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/rest-limits/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;IAC9C,EAAE,EAAE,sCAAsC;IAC1C,UAAU;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3F,QAAQ,EAAE,EAAE;CACZ,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
export declare function wait(state: Effect.Success<typeof initialize>): (route: string, major: string) => Effect.Effect<void, never, never>;
|
|
4
|
+
//# sourceMappingURL=wait.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../src/rest-limits/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,UAAU,CAAC,uEAQ5D"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Clock, Effect, Ref } from "effect";
|
|
2
|
+
export function wait(state) {
|
|
3
|
+
return Effect.fn("DiscordRestLimits.wait")(function* (route, major) {
|
|
4
|
+
const reset = Math.max(yield* Ref.get(state.globalReset), state.blocked.get(`${state.routes.get(route) ?? route}:${major}`) ?? 0);
|
|
5
|
+
const delay = reset - (yield* Clock.currentTimeMillis);
|
|
6
|
+
if (delay > 0) {
|
|
7
|
+
yield* Effect.sleep(delay);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=wait.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/rest-limits/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG5C,MAAM,UAAU,IAAI,CAAC,KAAwC;IAC5D,OAAO,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAa,EAAE,KAAa;QACjF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAClI,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACvD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/discord",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Discord integrations for Effect applications",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/discord#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -40,20 +40,20 @@
|
|
|
40
40
|
"README.md"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@shivaedev/http": "0.8.
|
|
44
|
-
"@shivaedev/service": "0.8.
|
|
43
|
+
"@shivaedev/http": "0.8.1",
|
|
44
|
+
"@shivaedev/service": "0.8.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@shivaedev/quality": "0.
|
|
48
|
-
"@shivaedev/test-kits": "0.
|
|
49
|
-
"@shivaedev/test-story": "0.
|
|
47
|
+
"@shivaedev/quality": "0.70.1",
|
|
48
|
+
"@shivaedev/test-kits": "0.10.2",
|
|
49
|
+
"@shivaedev/test-story": "0.45.2",
|
|
50
50
|
"@types/node": "24.19.2",
|
|
51
|
-
"effect": "4.1.
|
|
51
|
+
"effect": "4.1.1",
|
|
52
52
|
"typescript": "7.0.2",
|
|
53
53
|
"vitest": "5.0.5"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"effect": "4.1.
|
|
56
|
+
"effect": "4.1.1"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=24"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { Socket } from "effect/socket";
|
|
3
|
+
import { gatewayConnection } from "#adapters/gatewayConnection.ts";
|
|
3
4
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
5
|
import { DiscordGatewayClosed } from "#errors.ts";
|
|
5
6
|
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
6
|
-
import { gatewayConnection } from "#gatewayConnection.ts";
|
|
7
7
|
import type { GatewayDispatch, GatewaySession } from "#gatewayProtocol.ts";
|
|
8
8
|
|
|
9
|
-
export const
|
|
9
|
+
export const run = Effect.fn("DiscordGateway.run")(function* (dispatch: (event: GatewayDispatch) => Effect.Effect<void>) {
|
|
10
10
|
const config = yield* DiscordConfig;
|
|
11
11
|
const transport = yield* GatewayTransport;
|
|
12
12
|
const session: GatewaySession = { resumeUrl: undefined, sequence: null, sessionId: undefined };
|
|
@@ -3,11 +3,11 @@ import { defineService } from "@shivaedev/service/defineService.ts";
|
|
|
3
3
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
4
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
5
|
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { run } from "#gateway/run.ts";
|
|
7
7
|
|
|
8
8
|
export const DiscordGateway = defineService({
|
|
9
9
|
id: "@shivaedev/discord/DiscordGateway",
|
|
10
10
|
initialize: Effect.void,
|
|
11
|
-
methods: () => ({ run
|
|
11
|
+
methods: () => ({ run }),
|
|
12
12
|
requires: [DiscordConfig, DiscordToken, GatewayTransport],
|
|
13
13
|
});
|
package/src/request.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import type { HttpMethod } from "effect/http/HttpMethod";
|
|
3
|
-
import { DiscordRest } from "#
|
|
3
|
+
import { DiscordRest } from "#rest/service.ts";
|
|
4
4
|
|
|
5
5
|
export function request<TSchema extends Schema.ConstraintDecoder<unknown>>(method: HttpMethod, path: string, schema: TSchema, body?: unknown) {
|
|
6
6
|
return Effect.flatMap(DiscordRest, (rest) => rest.request(method, path, body)).pipe(Effect.flatMap(Schema.decodeUnknownEffect(schema)));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Redacted, Schema
|
|
1
|
+
import { Effect, Redacted, Schema } from "effect";
|
|
2
2
|
import { HttpClient, HttpClientRequest } from "effect/http";
|
|
3
3
|
import type { HttpMethod } from "effect/http/HttpMethod";
|
|
4
4
|
import { readBoundedJson } from "@shivaedev/http/body.ts";
|
|
@@ -8,30 +8,30 @@ import { routeKey } from "#adapters/routeKey.ts";
|
|
|
8
8
|
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
9
9
|
import { DiscordToken } from "#DiscordToken.ts";
|
|
10
10
|
import { DiscordRateLimited, DiscordTransportError } from "#errors.ts";
|
|
11
|
-
import {
|
|
11
|
+
import type { initialize } from "#rest/initialize.ts";
|
|
12
|
+
import { DiscordRestLimits } from "#rest-limits/service.ts";
|
|
12
13
|
|
|
13
14
|
const Limited = Schema.Struct({ global: Schema.optional(Schema.Boolean), retryAfter: Schema.Number }).pipe(
|
|
14
15
|
Schema.encodeKeys({ retryAfter: "retry_after" }),
|
|
15
16
|
);
|
|
16
17
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Effect.gen(function* () {
|
|
18
|
+
export function request(lock: Effect.Success<typeof initialize>) {
|
|
19
|
+
return Effect.fn("DiscordRest.request")(
|
|
20
|
+
function* (method: HttpMethod, path: string, body?: unknown) {
|
|
21
|
+
const client = HttpClient.withScope(yield* HttpClient.HttpClient);
|
|
22
|
+
const token = yield* DiscordToken;
|
|
23
|
+
const config = yield* DiscordConfig;
|
|
24
|
+
const rates = yield* DiscordRestLimits;
|
|
25
|
+
const { major, route } = routeKey(method, path);
|
|
26
|
+
let input = HttpClientRequest.make(method)(`${config.apiUrl}${path}`).pipe(
|
|
27
|
+
HttpClientRequest.setHeader("Authorization", `Bot ${Redacted.value(token)}`),
|
|
28
|
+
);
|
|
29
|
+
if (body !== undefined) {
|
|
30
|
+
input = yield* HttpClientRequest.bodyJson(input, body);
|
|
31
|
+
}
|
|
32
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
33
|
+
yield* rates.wait(route, major);
|
|
34
|
+
const answer = yield* Effect.gen(function* () {
|
|
35
35
|
const response = yield* client.execute(input);
|
|
36
36
|
yield* rates.observe(route, major, response.headers);
|
|
37
37
|
if (isRateLimited(response.status)) {
|
|
@@ -45,20 +45,13 @@ export const initializeRest = Effect.gen(function* () {
|
|
|
45
45
|
yield* checkStatus(response);
|
|
46
46
|
const value = isEmpty(response.status) ? undefined : yield* readBoundedJson(response, 1024 * 1024, Schema.Unknown);
|
|
47
47
|
return { retry: false, value };
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
}).pipe(Effect.scoped);
|
|
49
|
+
if (!answer.retry) {
|
|
50
|
+
return answer.value;
|
|
51
|
+
}
|
|
52
52
|
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
export function restRequest(state: Effect.Success<typeof initializeRest>) {
|
|
59
|
-
return (method: HttpMethod, path: string, body?: unknown) =>
|
|
60
|
-
state.request(method, path, body).pipe(
|
|
61
|
-
state.lock.withPermit,
|
|
62
|
-
Effect.catchTag("HttpClientError", () => Effect.fail(new DiscordTransportError({}))),
|
|
63
|
-
);
|
|
53
|
+
},
|
|
54
|
+
lock.withPermit,
|
|
55
|
+
Effect.catchTag("HttpClientError", () => Effect.fail(new DiscordTransportError({}))),
|
|
56
|
+
);
|
|
64
57
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpClient } from "effect/http";
|
|
2
|
+
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
3
|
+
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
|
+
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
|
+
import { initialize } from "#rest/initialize.ts";
|
|
6
|
+
import { request } from "#rest/request.ts";
|
|
7
|
+
import { DiscordRestLimits } from "#rest-limits/service.ts";
|
|
8
|
+
|
|
9
|
+
export const DiscordRest = defineService({
|
|
10
|
+
id: "@shivaedev/discord/DiscordRest",
|
|
11
|
+
initialize,
|
|
12
|
+
methods: (state) => ({ request: request(state) }),
|
|
13
|
+
requires: [HttpClient.HttpClient, DiscordToken, DiscordConfig, DiscordRestLimits],
|
|
14
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
import type { Headers } from "effect/http";
|
|
3
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
4
|
+
|
|
5
|
+
export function observe(state: Effect.Success<typeof initialize>) {
|
|
6
|
+
return Effect.fn("DiscordRestLimits.observe")(function* (route: string, major: string, headers: Headers.Headers) {
|
|
7
|
+
const bucket = headers["x-ratelimit-bucket"];
|
|
8
|
+
if (bucket !== undefined) {
|
|
9
|
+
state.routes.set(route, bucket);
|
|
10
|
+
}
|
|
11
|
+
if (headers["x-ratelimit-remaining"] === "0") {
|
|
12
|
+
state.blocked.set(
|
|
13
|
+
`${state.routes.get(route) ?? route}:${major}`,
|
|
14
|
+
(yield* Clock.currentTimeMillis) + Number(headers["x-ratelimit-reset-after"] ?? 0) * 1000,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Clock, Effect, Ref } from "effect";
|
|
2
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
|
|
4
|
+
export function refuse(state: Effect.Success<typeof initialize>) {
|
|
5
|
+
return Effect.fn("DiscordRestLimits.refuse")(function* (route: string, major: string, seconds: number, global: boolean) {
|
|
6
|
+
const reset = (yield* Clock.currentTimeMillis) + seconds * 1000;
|
|
7
|
+
if (global) {
|
|
8
|
+
yield* Ref.update(state.globalReset, (previous) => Math.max(previous, reset));
|
|
9
|
+
} else {
|
|
10
|
+
state.blocked.set(`${state.routes.get(route) ?? route}:${major}`, reset);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
2
|
+
import { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
import { observe } from "#rest-limits/observe.ts";
|
|
4
|
+
import { refuse } from "#rest-limits/refuse.ts";
|
|
5
|
+
import { wait } from "#rest-limits/wait.ts";
|
|
6
|
+
|
|
7
|
+
export const DiscordRestLimits = defineService({
|
|
8
|
+
id: "@shivaedev/discord/DiscordRestLimits",
|
|
9
|
+
initialize,
|
|
10
|
+
methods: (state) => ({ observe: observe(state), refuse: refuse(state), wait: wait(state) }),
|
|
11
|
+
requires: [],
|
|
12
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Clock, Effect, Ref } from "effect";
|
|
2
|
+
import type { initialize } from "#rest-limits/initialize.ts";
|
|
3
|
+
|
|
4
|
+
export function wait(state: Effect.Success<typeof initialize>) {
|
|
5
|
+
return Effect.fn("DiscordRestLimits.wait")(function* (route: string, major: string) {
|
|
6
|
+
const reset = Math.max(yield* Ref.get(state.globalReset), state.blocked.get(`${state.routes.get(route) ?? route}:${major}`) ?? 0);
|
|
7
|
+
const delay = reset - (yield* Clock.currentTimeMillis);
|
|
8
|
+
if (delay > 0) {
|
|
9
|
+
yield* Effect.sleep(delay);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiscordGateway.d.ts","sourceRoot":"","sources":["../src/DiscordGateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxD,eAAO,MAAM,cAAc;;;;CAKzB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiscordGateway.js","sourceRoot":"","sources":["../src/DiscordGateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;IAC3C,EAAE,EAAE,mCAAmC;IACvC,UAAU,EAAE,MAAM,CAAC,IAAI;IACvB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,gBAAgB,CAAC;CACzD,CAAC,CAAC"}
|
package/dist/DiscordRest.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from "effect/http";
|
|
2
|
-
import { DiscordToken } from "#DiscordToken.ts";
|
|
3
|
-
export declare const DiscordRest: import("effect/Context").Service<"@shivaedev/discord/DiscordRest", Readonly<{
|
|
4
|
-
readonly request: (method: import("effect/http/HttpMethod").HttpMethod, path: string, body?: unknown) => import("effect/Effect").Effect<unknown, import("./errors.ts").DiscordRateLimited | import("./errors.ts").DiscordTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").InvalidBodyLimit | import("@shivaedev/http/errors.ts").RemoteGone | import("@shivaedev/http/errors.ts").RemoteHttpError | import("@shivaedev/http/errors.ts").RemoteNotFound | import("@shivaedev/http/errors.ts").RemoteRateLimited | import("@shivaedev/http/errors.ts").RemoteUnauthorized | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | import("effect/Schema").SchemaError, never>;
|
|
5
|
-
}>> & {
|
|
6
|
-
readonly layer: import("effect/Layer").Layer<"@shivaedev/discord/DiscordRest", never, DiscordToken | HttpClient.HttpClient>;
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=DiscordRest.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiscordRest.d.ts","sourceRoot":"","sources":["../src/DiscordRest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,eAAO,MAAM,WAAW;;;;CAKtB,CAAC"}
|
package/dist/DiscordRest.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DiscordRest.js","sourceRoot":"","sources":["../src/DiscordRest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACxC,EAAE,EAAE,gCAAgC;IACpC,UAAU,EAAE,cAAc;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;IACrD,QAAQ,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC;CAC9D,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gatewayConnection.d.ts","sourceRoot":"","sources":["../src/gatewayConnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAA2B,KAAK,eAAe,EAAqB,KAAK,cAAc,EAA2B,MAAM,qBAAqB,CAAC;AAErJ,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,8HAkFnH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gatewayConnection.js","sourceRoot":"","sources":["../src/gatewayConnection.ts"],"names":[],"mappings":"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"}
|
package/dist/rateLimits.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { Headers } from "effect/http";
|
|
3
|
-
export declare function rateLimits(): {
|
|
4
|
-
observe: (route: string, major: string, headers: Headers.Headers) => Effect.Effect<void, never, never>;
|
|
5
|
-
refuse: (route: string, major: string, seconds: number, global: boolean) => Effect.Effect<void, never, never>;
|
|
6
|
-
wait: (route: string, major: string) => Effect.Effect<void, never, never>;
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=rateLimits.d.ts.map
|
package/dist/rateLimits.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimits.d.ts","sourceRoot":"","sources":["../src/rateLimits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,UAAU;IAQxB,OAAO,UAAU,MAAM,SAAS,MAAM,WAAW,OAAO,CAAC,OAAO;IAUhE,MAAM,UAAU,MAAM,SAAS,MAAM,WAAW,MAAM,UAAU,OAAO;IASvE,IAAI,UAAU,MAAM,SAAS,MAAM;EAQpC"}
|
package/dist/rateLimits.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Clock, Effect } from "effect";
|
|
2
|
-
export function rateLimits() {
|
|
3
|
-
const routes = new Map();
|
|
4
|
-
const blocked = new Map();
|
|
5
|
-
let globalReset = 0;
|
|
6
|
-
function key(route, major) {
|
|
7
|
-
return `${routes.get(route) ?? route}:${major}`;
|
|
8
|
-
}
|
|
9
|
-
return {
|
|
10
|
-
observe: (route, major, headers) => Effect.gen(function* () {
|
|
11
|
-
const bucket = headers["x-ratelimit-bucket"];
|
|
12
|
-
if (bucket !== undefined) {
|
|
13
|
-
routes.set(route, bucket);
|
|
14
|
-
}
|
|
15
|
-
if (headers["x-ratelimit-remaining"] === "0") {
|
|
16
|
-
blocked.set(key(route, major), (yield* Clock.currentTimeMillis) + Number(headers["x-ratelimit-reset-after"] ?? 0) * 1000);
|
|
17
|
-
}
|
|
18
|
-
}),
|
|
19
|
-
refuse: (route, major, seconds, global) => Effect.gen(function* () {
|
|
20
|
-
const reset = (yield* Clock.currentTimeMillis) + seconds * 1000;
|
|
21
|
-
if (global) {
|
|
22
|
-
globalReset = Math.max(globalReset, reset);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
blocked.set(key(route, major), reset);
|
|
26
|
-
}
|
|
27
|
-
}),
|
|
28
|
-
wait: (route, major) => Effect.gen(function* () {
|
|
29
|
-
const delay = Math.max(globalReset, blocked.get(key(route, major)) ?? 0) - (yield* Clock.currentTimeMillis);
|
|
30
|
-
if (delay > 0) {
|
|
31
|
-
yield* Effect.sleep(delay);
|
|
32
|
-
}
|
|
33
|
-
}),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=rateLimits.js.map
|
package/dist/rateLimits.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimits.js","sourceRoot":"","sources":["../src/rateLimits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvC,MAAM,UAAU,UAAU;IACzB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,SAAS,GAAG,CAAC,KAAa,EAAE,KAAa;QACxC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;IACjD,CAAC;IACD,OAAO;QACN,OAAO,EAAE,CAAC,KAAa,EAAE,KAAa,EAAE,OAAwB,EAAE,EAAE,CACnE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;YAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3B,CAAC;YACD,IAAI,OAAO,CAAC,uBAAuB,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3H,CAAC;QACF,CAAC,CAAC;QACH,MAAM,EAAE,CAAC,KAAa,EAAE,KAAa,EAAE,OAAe,EAAE,MAAe,EAAE,EAAE,CAC1E,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;YAChE,IAAI,MAAM,EAAE,CAAC;gBACZ,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;YACvC,CAAC;QACF,CAAC,CAAC;QACH,IAAI,EAAE,CAAC,KAAa,EAAE,KAAa,EAAE,EAAE,CACtC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC5G,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACf,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACF,CAAC,CAAC;KACH,CAAC;AACH,CAAC"}
|
package/dist/restClient.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Effect, Schema, Semaphore } from "effect";
|
|
2
|
-
import { HttpClient } from "effect/http";
|
|
3
|
-
import type { HttpMethod } from "effect/http/HttpMethod";
|
|
4
|
-
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
|
-
import { DiscordRateLimited, DiscordTransportError } from "#errors.ts";
|
|
6
|
-
export declare const initializeRest: Effect.Effect<{
|
|
7
|
-
lock: Semaphore.Semaphore;
|
|
8
|
-
request: (method: HttpMethod, path: string, body?: unknown) => Effect.Effect<unknown, DiscordRateLimited | import("effect/http/HttpBody").HttpBodyError | import("effect/http/HttpClientError").HttpClientError | import("@shivaedev/http/errors.ts").InvalidBodyLimit | import("@shivaedev/http/errors.ts").RemoteGone | import("@shivaedev/http/errors.ts").RemoteHttpError | import("@shivaedev/http/errors.ts").RemoteNotFound | import("@shivaedev/http/errors.ts").RemoteRateLimited | import("@shivaedev/http/errors.ts").RemoteUnauthorized | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | Schema.SchemaError, never>;
|
|
9
|
-
}, never, DiscordToken | HttpClient.HttpClient>;
|
|
10
|
-
export declare function restRequest(state: Effect.Success<typeof initializeRest>): (method: HttpMethod, path: string, body?: unknown) => Effect.Effect<unknown, DiscordRateLimited | DiscordTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").InvalidBodyLimit | import("@shivaedev/http/errors.ts").RemoteGone | import("@shivaedev/http/errors.ts").RemoteHttpError | import("@shivaedev/http/errors.ts").RemoteNotFound | import("@shivaedev/http/errors.ts").RemoteRateLimited | import("@shivaedev/http/errors.ts").RemoteUnauthorized | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | Schema.SchemaError, never>;
|
|
11
|
-
//# sourceMappingURL=restClient.d.ts.map
|
package/dist/restClient.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restClient.d.ts","sourceRoot":"","sources":["../src/restClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAMzD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOvE,eAAO,MAAM,cAAc;;;+CAuCzB,CAAC;AAEH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,cAAc,CAAC,YACvD,UAAU,QAAQ,MAAM,SAAS,OAAO,khBAKxD"}
|
package/dist/restClient.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"restClient.js","sourceRoot":"","sources":["../src/restClient.ts"],"names":[],"mappings":"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"}
|
package/dist/runGateway.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { DiscordGatewayClosed } from "#errors.ts";
|
|
3
|
-
import { GatewayTransport } from "#GatewayTransport.ts";
|
|
4
|
-
import type { GatewayDispatch } from "#gatewayProtocol.ts";
|
|
5
|
-
export declare const runGateway: (dispatch: (event: GatewayDispatch) => Effect.Effect<void>) => Effect.Effect<never, DiscordGatewayClosed | import("#errors.ts").DiscordGatewayProtocolError, import("./DiscordToken.ts").DiscordToken | GatewayTransport>;
|
|
6
|
-
//# sourceMappingURL=runGateway.d.ts.map
|
package/dist/runGateway.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runGateway.d.ts","sourceRoot":"","sources":["../src/runGateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,qBAAqB,CAAC;AAE3E,eAAO,MAAM,UAAU,qBAAkD,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,+JAuB9G,CAAC"}
|
package/dist/runGateway.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runGateway.js","sourceRoot":"","sources":["../src/runGateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1D,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAyD;IAC/G,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC;IAC1C,MAAM,OAAO,GAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAC/F,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,sBAAsB,CAAC,CAAC;QACtG,KAAK,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC;aACzC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aAClD,IAAI,CACJ,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YACtF,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;gBAC3E,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACpC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC9B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC,CAAC,CACF,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC"}
|
package/src/DiscordRest.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from "effect/http";
|
|
2
|
-
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
3
|
-
import { DiscordConfig } from "#DiscordConfig.ts";
|
|
4
|
-
import { DiscordToken } from "#DiscordToken.ts";
|
|
5
|
-
import { initializeRest, restRequest } from "#restClient.ts";
|
|
6
|
-
|
|
7
|
-
export const DiscordRest = defineService({
|
|
8
|
-
id: "@shivaedev/discord/DiscordRest",
|
|
9
|
-
initialize: initializeRest,
|
|
10
|
-
methods: (state) => ({ request: restRequest(state) }),
|
|
11
|
-
requires: [HttpClient.HttpClient, DiscordToken, DiscordConfig],
|
|
12
|
-
});
|
package/src/rateLimits.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Clock, Effect } from "effect";
|
|
2
|
-
import type { Headers } from "effect/http";
|
|
3
|
-
|
|
4
|
-
export function rateLimits() {
|
|
5
|
-
const routes = new Map<string, string>();
|
|
6
|
-
const blocked = new Map<string, number>();
|
|
7
|
-
let globalReset = 0;
|
|
8
|
-
function key(route: string, major: string) {
|
|
9
|
-
return `${routes.get(route) ?? route}:${major}`;
|
|
10
|
-
}
|
|
11
|
-
return {
|
|
12
|
-
observe: (route: string, major: string, headers: Headers.Headers) =>
|
|
13
|
-
Effect.gen(function* () {
|
|
14
|
-
const bucket = headers["x-ratelimit-bucket"];
|
|
15
|
-
if (bucket !== undefined) {
|
|
16
|
-
routes.set(route, bucket);
|
|
17
|
-
}
|
|
18
|
-
if (headers["x-ratelimit-remaining"] === "0") {
|
|
19
|
-
blocked.set(key(route, major), (yield* Clock.currentTimeMillis) + Number(headers["x-ratelimit-reset-after"] ?? 0) * 1000);
|
|
20
|
-
}
|
|
21
|
-
}),
|
|
22
|
-
refuse: (route: string, major: string, seconds: number, global: boolean) =>
|
|
23
|
-
Effect.gen(function* () {
|
|
24
|
-
const reset = (yield* Clock.currentTimeMillis) + seconds * 1000;
|
|
25
|
-
if (global) {
|
|
26
|
-
globalReset = Math.max(globalReset, reset);
|
|
27
|
-
} else {
|
|
28
|
-
blocked.set(key(route, major), reset);
|
|
29
|
-
}
|
|
30
|
-
}),
|
|
31
|
-
wait: (route: string, major: string) =>
|
|
32
|
-
Effect.gen(function* () {
|
|
33
|
-
const delay = Math.max(globalReset, blocked.get(key(route, major)) ?? 0) - (yield* Clock.currentTimeMillis);
|
|
34
|
-
if (delay > 0) {
|
|
35
|
-
yield* Effect.sleep(delay);
|
|
36
|
-
}
|
|
37
|
-
}),
|
|
38
|
-
};
|
|
39
|
-
}
|
|
File without changes
|
|
File without changes
|