dfx 0.126.1 → 1.0.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.
Files changed (342) hide show
  1. package/.babel.cjs.json +11 -0
  2. package/.babel.mjs.json +10 -0
  3. package/.envrc +1 -0
  4. package/.gitmodules +3 -0
  5. package/.husky/pre-commit +2 -0
  6. package/.oxlintrc.json +72 -0
  7. package/.prettierignore +0 -0
  8. package/.prettierrc.json +5 -0
  9. package/.tool-versions +1 -0
  10. package/.vscode/debug.cjs +8 -0
  11. package/.vscode/launch.json +23 -0
  12. package/.vscode/settings.json +29 -0
  13. package/.vscode/tasks.json +44 -0
  14. package/AGENTS.md +15 -0
  15. package/CHANGELOG.md +1554 -0
  16. package/examples/.env.example +5 -0
  17. package/examples/interactions.ts +79 -0
  18. package/examples/readme.ts +56 -0
  19. package/examples/registry.ts +66 -0
  20. package/flake.lock +27 -0
  21. package/flake.nix +21 -0
  22. package/lerna.json +12 -0
  23. package/package.json +79 -36
  24. package/pnpm-workspace.yaml +7 -0
  25. package/scripts/generate-client.sh +10 -0
  26. package/scripts/worktree-setup.sh +8 -0
  27. package/src/Cache/memory.ts +5 -5
  28. package/src/Cache/memoryTTL.ts +11 -7
  29. package/src/Cache/prelude.ts +10 -8
  30. package/src/Cache.ts +31 -35
  31. package/src/DiscordConfig.ts +12 -16
  32. package/src/DiscordGateway/DiscordWS.ts +58 -32
  33. package/src/DiscordGateway/Messaging.ts +13 -15
  34. package/src/DiscordGateway/Shard/StateStore.ts +30 -25
  35. package/src/DiscordGateway/Shard/heartbeats.ts +25 -28
  36. package/src/DiscordGateway/Shard/identify.ts +11 -6
  37. package/src/DiscordGateway/Shard/sendEvents.ts +1 -1
  38. package/src/DiscordGateway/Shard/utils.ts +1 -1
  39. package/src/DiscordGateway/Shard.ts +39 -35
  40. package/src/DiscordGateway/ShardStore.ts +6 -7
  41. package/src/DiscordGateway/Sharder.ts +31 -29
  42. package/src/DiscordGateway.ts +15 -14
  43. package/src/DiscordREST/Generated.ts +660 -341
  44. package/src/DiscordREST/utils.ts +6 -3
  45. package/src/DiscordREST.ts +37 -41
  46. package/src/Helpers/flags.ts +10 -5
  47. package/src/Helpers/intents.ts +2 -2
  48. package/src/Helpers/interactions.ts +16 -14
  49. package/src/Helpers/members.ts +3 -3
  50. package/src/Helpers/permissions.ts +5 -5
  51. package/src/Helpers/ui.ts +16 -16
  52. package/src/Interactions/builder.ts +10 -10
  53. package/src/Interactions/commandHelper.ts +18 -29
  54. package/src/Interactions/context.ts +51 -65
  55. package/src/Interactions/definitions.ts +3 -3
  56. package/src/Interactions/gateway.ts +33 -45
  57. package/src/Interactions/handlers.ts +8 -5
  58. package/src/Interactions/index.ts +5 -5
  59. package/src/Interactions/utils.ts +6 -6
  60. package/src/Interactions/webhook.ts +31 -38
  61. package/src/RateLimit/memory.ts +3 -3
  62. package/src/RateLimit.ts +18 -15
  63. package/src/gateway.ts +21 -21
  64. package/src/index.ts +17 -17
  65. package/src/types.ts +18 -16
  66. package/src/utils/Effect.ts +38 -27
  67. package/src/webhooks.ts +7 -7
  68. package/test/index.test.ts +5 -0
  69. package/tsconfig.base.json +12 -6
  70. package/tsconfig.examples.json +0 -1
  71. package/vitest.config.ts +22 -0
  72. package/Cache/driver.d.ts +0 -24
  73. package/Cache/driver.d.ts.map +0 -1
  74. package/Cache/driver.js +0 -11
  75. package/Cache/driver.js.map +0 -1
  76. package/Cache/memory.d.ts +0 -5
  77. package/Cache/memory.d.ts.map +0 -1
  78. package/Cache/memory.js +0 -57
  79. package/Cache/memory.js.map +0 -1
  80. package/Cache/memoryTTL.d.ts +0 -23
  81. package/Cache/memoryTTL.d.ts.map +0 -1
  82. package/Cache/memoryTTL.js +0 -128
  83. package/Cache/memoryTTL.js.map +0 -1
  84. package/Cache/prelude.d.ts +0 -32
  85. package/Cache/prelude.d.ts.map +0 -1
  86. package/Cache/prelude.js +0 -143
  87. package/Cache/prelude.js.map +0 -1
  88. package/Cache.d.ts +0 -82
  89. package/Cache.d.ts.map +0 -1
  90. package/Cache.js +0 -144
  91. package/Cache.js.map +0 -1
  92. package/DiscordConfig.d.ts +0 -35
  93. package/DiscordConfig.d.ts.map +0 -1
  94. package/DiscordConfig.js +0 -42
  95. package/DiscordConfig.js.map +0 -1
  96. package/DiscordGateway/DiscordWS.d.ts +0 -37
  97. package/DiscordGateway/DiscordWS.d.ts.map +0 -1
  98. package/DiscordGateway/DiscordWS.js +0 -73
  99. package/DiscordGateway/DiscordWS.js.map +0 -1
  100. package/DiscordGateway/Messaging.d.ts +0 -393
  101. package/DiscordGateway/Messaging.d.ts.map +0 -1
  102. package/DiscordGateway/Messaging.js +0 -40
  103. package/DiscordGateway/Messaging.js.map +0 -1
  104. package/DiscordGateway/Shard/StateStore.d.ts +0 -24
  105. package/DiscordGateway/Shard/StateStore.d.ts.map +0 -1
  106. package/DiscordGateway/Shard/StateStore.js +0 -48
  107. package/DiscordGateway/Shard/StateStore.js.map +0 -1
  108. package/DiscordGateway/Shard/heartbeats.d.ts +0 -8
  109. package/DiscordGateway/Shard/heartbeats.d.ts.map +0 -1
  110. package/DiscordGateway/Shard/heartbeats.js +0 -28
  111. package/DiscordGateway/Shard/heartbeats.js.map +0 -1
  112. package/DiscordGateway/Shard/identify.d.ts +0 -12
  113. package/DiscordGateway/Shard/identify.d.ts.map +0 -1
  114. package/DiscordGateway/Shard/identify.js +0 -38
  115. package/DiscordGateway/Shard/identify.js.map +0 -1
  116. package/DiscordGateway/Shard/sendEvents.d.ts +0 -8
  117. package/DiscordGateway/Shard/sendEvents.d.ts.map +0 -1
  118. package/DiscordGateway/Shard/sendEvents.js +0 -39
  119. package/DiscordGateway/Shard/sendEvents.js.map +0 -1
  120. package/DiscordGateway/Shard/utils.d.ts +0 -6
  121. package/DiscordGateway/Shard/utils.d.ts.map +0 -1
  122. package/DiscordGateway/Shard/utils.js +0 -11
  123. package/DiscordGateway/Shard/utils.js.map +0 -1
  124. package/DiscordGateway/Shard.d.ts +0 -28
  125. package/DiscordGateway/Shard.d.ts.map +0 -1
  126. package/DiscordGateway/Shard.js +0 -149
  127. package/DiscordGateway/Shard.js.map +0 -1
  128. package/DiscordGateway/ShardStore.d.ts +0 -18
  129. package/DiscordGateway/ShardStore.d.ts.map +0 -1
  130. package/DiscordGateway/ShardStore.js +0 -31
  131. package/DiscordGateway/ShardStore.js.map +0 -1
  132. package/DiscordGateway/Sharder.d.ts +0 -13
  133. package/DiscordGateway/Sharder.d.ts.map +0 -1
  134. package/DiscordGateway/Sharder.js +0 -73
  135. package/DiscordGateway/Sharder.js.map +0 -1
  136. package/DiscordGateway.d.ts +0 -32
  137. package/DiscordGateway.d.ts.map +0 -1
  138. package/DiscordGateway.js +0 -28
  139. package/DiscordGateway.js.map +0 -1
  140. package/DiscordREST/Generated.d.ts +0 -5399
  141. package/DiscordREST/Generated.d.ts.map +0 -1
  142. package/DiscordREST/Generated.js +0 -2405
  143. package/DiscordREST/Generated.js.map +0 -1
  144. package/DiscordREST/utils.d.ts +0 -14
  145. package/DiscordREST/utils.d.ts.map +0 -1
  146. package/DiscordREST/utils.js +0 -31
  147. package/DiscordREST/utils.js.map +0 -1
  148. package/DiscordREST.d.ts +0 -23
  149. package/DiscordREST.d.ts.map +0 -1
  150. package/DiscordREST.js +0 -132
  151. package/DiscordREST.js.map +0 -1
  152. package/Helpers/flags.d.ts +0 -28
  153. package/Helpers/flags.d.ts.map +0 -1
  154. package/Helpers/flags.js +0 -48
  155. package/Helpers/flags.js.map +0 -1
  156. package/Helpers/intents.d.ts +0 -25
  157. package/Helpers/intents.d.ts.map +0 -1
  158. package/Helpers/intents.js +0 -34
  159. package/Helpers/intents.js.map +0 -1
  160. package/Helpers/interactions.d.ts +0 -116
  161. package/Helpers/interactions.d.ts.map +0 -1
  162. package/Helpers/interactions.js +0 -143
  163. package/Helpers/interactions.js.map +0 -1
  164. package/Helpers/members.d.ts +0 -10
  165. package/Helpers/members.d.ts.map +0 -1
  166. package/Helpers/members.js +0 -17
  167. package/Helpers/members.js.map +0 -1
  168. package/Helpers/permissions.d.ts +0 -42
  169. package/Helpers/permissions.d.ts.map +0 -1
  170. package/Helpers/permissions.js +0 -97
  171. package/Helpers/permissions.js.map +0 -1
  172. package/Helpers/ui.d.ts +0 -105
  173. package/Helpers/ui.d.ts.map +0 -1
  174. package/Helpers/ui.js +0 -162
  175. package/Helpers/ui.js.map +0 -1
  176. package/Interactions/builder.d.ts +0 -48
  177. package/Interactions/builder.d.ts.map +0 -1
  178. package/Interactions/builder.js +0 -64
  179. package/Interactions/builder.js.map +0 -1
  180. package/Interactions/commandHelper.d.ts +0 -99
  181. package/Interactions/commandHelper.d.ts.map +0 -1
  182. package/Interactions/commandHelper.js +0 -53
  183. package/Interactions/commandHelper.js.map +0 -1
  184. package/Interactions/context.d.ts +0 -54
  185. package/Interactions/context.d.ts.map +0 -1
  186. package/Interactions/context.js +0 -42
  187. package/Interactions/context.js.map +0 -1
  188. package/Interactions/definitions.d.ts +0 -44
  189. package/Interactions/definitions.d.ts.map +0 -1
  190. package/Interactions/definitions.js +0 -67
  191. package/Interactions/definitions.js.map +0 -1
  192. package/Interactions/error.d.ts +0 -2
  193. package/Interactions/error.d.ts.map +0 -1
  194. package/Interactions/error.js +0 -8
  195. package/Interactions/error.js.map +0 -1
  196. package/Interactions/gateway.d.ts +0 -21
  197. package/Interactions/gateway.d.ts.map +0 -1
  198. package/Interactions/gateway.js +0 -90
  199. package/Interactions/gateway.js.map +0 -1
  200. package/Interactions/handlers.d.ts +0 -15
  201. package/Interactions/handlers.d.ts.map +0 -1
  202. package/Interactions/handlers.js +0 -72
  203. package/Interactions/handlers.js.map +0 -1
  204. package/Interactions/index.d.ts +0 -16
  205. package/Interactions/index.d.ts.map +0 -1
  206. package/Interactions/index.js +0 -94
  207. package/Interactions/index.js.map +0 -1
  208. package/Interactions/utils.d.ts +0 -61
  209. package/Interactions/utils.d.ts.map +0 -1
  210. package/Interactions/utils.js +0 -35
  211. package/Interactions/utils.js.map +0 -1
  212. package/Interactions/webhook.d.ts +0 -73
  213. package/Interactions/webhook.d.ts.map +0 -1
  214. package/Interactions/webhook.js +0 -89
  215. package/Interactions/webhook.js.map +0 -1
  216. package/RateLimit/memory.d.ts +0 -3
  217. package/RateLimit/memory.d.ts.map +0 -1
  218. package/RateLimit/memory.js +0 -47
  219. package/RateLimit/memory.js.map +0 -1
  220. package/RateLimit/utils.d.ts +0 -3
  221. package/RateLimit/utils.d.ts.map +0 -1
  222. package/RateLimit/utils.js +0 -25
  223. package/RateLimit/utils.js.map +0 -1
  224. package/RateLimit.d.ts +0 -30
  225. package/RateLimit.d.ts.map +0 -1
  226. package/RateLimit.js +0 -35
  227. package/RateLimit.js.map +0 -1
  228. package/gateway.d.ts +0 -19
  229. package/gateway.d.ts.map +0 -1
  230. package/gateway.js +0 -72
  231. package/gateway.js.map +0 -1
  232. package/index.d.ts +0 -18
  233. package/index.d.ts.map +0 -1
  234. package/index.js +0 -71
  235. package/index.js.map +0 -1
  236. package/mjs/Cache/driver.mjs +0 -3
  237. package/mjs/Cache/driver.mjs.map +0 -1
  238. package/mjs/Cache/memory.mjs +0 -48
  239. package/mjs/Cache/memory.mjs.map +0 -1
  240. package/mjs/Cache/memoryTTL.mjs +0 -119
  241. package/mjs/Cache/memoryTTL.mjs.map +0 -1
  242. package/mjs/Cache/prelude.mjs +0 -131
  243. package/mjs/Cache/prelude.mjs.map +0 -1
  244. package/mjs/Cache.mjs +0 -89
  245. package/mjs/Cache.mjs.map +0 -1
  246. package/mjs/DiscordConfig.mjs +0 -32
  247. package/mjs/DiscordConfig.mjs.map +0 -1
  248. package/mjs/DiscordGateway/DiscordWS.mjs +0 -66
  249. package/mjs/DiscordGateway/DiscordWS.mjs.map +0 -1
  250. package/mjs/DiscordGateway/Messaging.mjs +0 -33
  251. package/mjs/DiscordGateway/Messaging.mjs.map +0 -1
  252. package/mjs/DiscordGateway/Shard/StateStore.mjs +0 -40
  253. package/mjs/DiscordGateway/Shard/StateStore.mjs.map +0 -1
  254. package/mjs/DiscordGateway/Shard/heartbeats.mjs +0 -20
  255. package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +0 -1
  256. package/mjs/DiscordGateway/Shard/identify.mjs +0 -30
  257. package/mjs/DiscordGateway/Shard/identify.mjs.map +0 -1
  258. package/mjs/DiscordGateway/Shard/sendEvents.mjs +0 -26
  259. package/mjs/DiscordGateway/Shard/sendEvents.mjs.map +0 -1
  260. package/mjs/DiscordGateway/Shard/utils.mjs +0 -3
  261. package/mjs/DiscordGateway/Shard/utils.mjs.map +0 -1
  262. package/mjs/DiscordGateway/Shard.mjs +0 -142
  263. package/mjs/DiscordGateway/Shard.mjs.map +0 -1
  264. package/mjs/DiscordGateway/ShardStore.mjs +0 -24
  265. package/mjs/DiscordGateway/ShardStore.mjs.map +0 -1
  266. package/mjs/DiscordGateway/Sharder.mjs +0 -66
  267. package/mjs/DiscordGateway/Sharder.mjs.map +0 -1
  268. package/mjs/DiscordGateway.mjs +0 -21
  269. package/mjs/DiscordGateway.mjs.map +0 -1
  270. package/mjs/DiscordREST/Generated.mjs +0 -2396
  271. package/mjs/DiscordREST/Generated.mjs.map +0 -1
  272. package/mjs/DiscordREST/utils.mjs +0 -20
  273. package/mjs/DiscordREST/utils.mjs.map +0 -1
  274. package/mjs/DiscordREST.mjs +0 -124
  275. package/mjs/DiscordREST.mjs.map +0 -1
  276. package/mjs/Helpers/flags.mjs +0 -36
  277. package/mjs/Helpers/flags.mjs.map +0 -1
  278. package/mjs/Helpers/intents.mjs +0 -27
  279. package/mjs/Helpers/intents.mjs.map +0 -1
  280. package/mjs/Helpers/interactions.mjs +0 -115
  281. package/mjs/Helpers/interactions.mjs.map +0 -1
  282. package/mjs/Helpers/members.mjs +0 -9
  283. package/mjs/Helpers/members.mjs.map +0 -1
  284. package/mjs/Helpers/permissions.mjs +0 -84
  285. package/mjs/Helpers/permissions.mjs.map +0 -1
  286. package/mjs/Helpers/ui.mjs +0 -137
  287. package/mjs/Helpers/ui.mjs.map +0 -1
  288. package/mjs/Interactions/builder.mjs +0 -56
  289. package/mjs/Interactions/builder.mjs.map +0 -1
  290. package/mjs/Interactions/commandHelper.mjs +0 -45
  291. package/mjs/Interactions/commandHelper.mjs.map +0 -1
  292. package/mjs/Interactions/context.mjs +0 -29
  293. package/mjs/Interactions/context.mjs.map +0 -1
  294. package/mjs/Interactions/definitions.mjs +0 -51
  295. package/mjs/Interactions/definitions.mjs.map +0 -1
  296. package/mjs/Interactions/error.mjs +0 -2
  297. package/mjs/Interactions/error.mjs.map +0 -1
  298. package/mjs/Interactions/gateway.mjs +0 -81
  299. package/mjs/Interactions/gateway.mjs.map +0 -1
  300. package/mjs/Interactions/handlers.mjs +0 -63
  301. package/mjs/Interactions/handlers.mjs.map +0 -1
  302. package/mjs/Interactions/index.mjs +0 -11
  303. package/mjs/Interactions/index.mjs.map +0 -1
  304. package/mjs/Interactions/utils.mjs +0 -26
  305. package/mjs/Interactions/utils.mjs.map +0 -1
  306. package/mjs/Interactions/webhook.mjs +0 -76
  307. package/mjs/Interactions/webhook.mjs.map +0 -1
  308. package/mjs/RateLimit/memory.mjs +0 -39
  309. package/mjs/RateLimit/memory.mjs.map +0 -1
  310. package/mjs/RateLimit/utils.mjs +0 -18
  311. package/mjs/RateLimit/utils.mjs.map +0 -1
  312. package/mjs/RateLimit.mjs +0 -28
  313. package/mjs/RateLimit.mjs.map +0 -1
  314. package/mjs/gateway.mjs +0 -19
  315. package/mjs/gateway.mjs.map +0 -1
  316. package/mjs/index.mjs +0 -18
  317. package/mjs/index.mjs.map +0 -1
  318. package/mjs/types.mjs +0 -356
  319. package/mjs/types.mjs.map +0 -1
  320. package/mjs/utils/Effect.mjs +0 -18
  321. package/mjs/utils/Effect.mjs.map +0 -1
  322. package/mjs/version.mjs +0 -2
  323. package/mjs/version.mjs.map +0 -1
  324. package/mjs/webhooks.mjs +0 -6
  325. package/mjs/webhooks.mjs.map +0 -1
  326. package/src/version.ts +0 -1
  327. package/types.d.ts +0 -2457
  328. package/types.d.ts.map +0 -1
  329. package/types.js +0 -408
  330. package/types.js.map +0 -1
  331. package/utils/Effect.d.ts +0 -5
  332. package/utils/Effect.d.ts.map +0 -1
  333. package/utils/Effect.js +0 -27
  334. package/utils/Effect.js.map +0 -1
  335. package/version.d.ts +0 -2
  336. package/version.d.ts.map +0 -1
  337. package/version.js +0 -8
  338. package/version.js.map +0 -1
  339. package/webhooks.d.ts +0 -8
  340. package/webhooks.d.ts.map +0 -1
  341. package/webhooks.js +0 -55
  342. package/webhooks.js.map +0 -1
package/src/Cache.ts CHANGED
@@ -1,20 +1,20 @@
1
- import { TypeIdError } from "@effect/platform/Error"
2
- import type { CacheDriver, ParentCacheDriver } from "dfx/Cache/driver"
1
+ import type { CacheDriver, ParentCacheDriver } from "./Cache/driver.ts"
2
+ import * as Data from "effect/Data"
3
3
  import * as Effect from "effect/Effect"
4
4
  import * as Option from "effect/Option"
5
5
  import * as Schedule from "effect/Schedule"
6
6
  import type * as Scope from "effect/Scope"
7
7
  import * as Stream from "effect/Stream"
8
8
 
9
- export * from "dfx/Cache/driver"
9
+ export * from "./Cache/driver.ts"
10
10
  export {
11
11
  create as memoryDriver,
12
12
  createWithParent as memoryParentDriver,
13
- } from "dfx/Cache/memory"
13
+ } from "./Cache/memory.ts"
14
14
  export {
15
15
  create as memoryTTLDriver,
16
16
  createWithParent as memoryTTLParentDriver,
17
- } from "dfx/Cache/memoryTTL"
17
+ } from "./Cache/memoryTTL.ts"
18
18
 
19
19
  export type ParentCacheOp<T> =
20
20
  | { op: "create"; parentId: string; resourceId: string; resource: T }
@@ -28,7 +28,7 @@ export type CacheOp<T> =
28
28
  | { op: "delete"; resourceId: string }
29
29
 
30
30
  const retryPolicy = Schedule.exponential("500 millis").pipe(
31
- Schedule.union(Schedule.spaced("10 seconds")),
31
+ Schedule.either(Schedule.spaced("10 seconds")),
32
32
  )
33
33
 
34
34
  export interface ParentCache<EDriver, EMiss, EPMiss, A> {
@@ -65,7 +65,7 @@ export interface ParentCache<EDriver, EMiss, EPMiss, A> {
65
65
 
66
66
  export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
67
67
  driver,
68
- id,
68
+ id: identify,
69
69
  onMiss,
70
70
  onParentMiss,
71
71
  ops = Stream.empty,
@@ -94,14 +94,14 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
94
94
  }
95
95
  }),
96
96
  ).pipe(
97
- Effect.tapErrorCause(_ => Effect.logError("ops error, restarting", _)),
97
+ Effect.tapCause(cause => Effect.logError("ops error, restarting", cause)),
98
98
  Effect.retry(retryPolicy),
99
99
  Effect.forkScoped,
100
100
  Effect.interruptible,
101
101
  )
102
102
  yield* driver.run.pipe(
103
- Effect.tapErrorCause(_ =>
104
- Effect.logError("cache driver error, restarting", _),
103
+ Effect.tapCause(cause =>
104
+ Effect.logError("cache driver error, restarting", cause),
105
105
  ),
106
106
  Effect.retry(retryPolicy),
107
107
  Effect.forkScoped,
@@ -109,9 +109,8 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
109
109
  )
110
110
 
111
111
  const get = (parentId: string, id: string) =>
112
- Effect.flatMap(
113
- driver.get(parentId, id),
114
- Option.match({
112
+ Effect.flatMap(driver.get(parentId, id), option =>
113
+ Option.match(option, {
115
114
  onNone: () =>
116
115
  Effect.tap(onMiss(parentId, id), a => driver.set(parentId, id, a)),
117
116
  onSome: Effect.succeed,
@@ -119,16 +118,17 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
119
118
  )
120
119
 
121
120
  const put = (_: A) =>
122
- Effect.flatMap(id(_), ([parentId, id]) => driver.set(parentId, id, _))
121
+ Effect.flatMap(identify(_), ([parentId, id]) =>
122
+ driver.set(parentId, id, _),
123
+ )
123
124
 
124
125
  const update = <R, E>(
125
126
  parentId: string,
126
127
  id: string,
127
128
  f: (_: A) => Effect.Effect<A, E, R>,
128
129
  ) =>
129
- get(parentId, id).pipe(
130
- Effect.flatMap(f),
131
- Effect.tap(_ => driver.set(parentId, id, _)),
130
+ Effect.flatMap(get(parentId, id), a =>
131
+ Effect.tap(f(a), next => driver.set(parentId, id, next)),
132
132
  )
133
133
 
134
134
  return {
@@ -139,9 +139,8 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
139
139
  update,
140
140
 
141
141
  getForParent: (parentId: string) =>
142
- Effect.flatMap(
143
- driver.getForParent(parentId),
144
- Option.match({
142
+ Effect.flatMap(driver.getForParent(parentId), option =>
143
+ Option.match(option, {
145
144
  onNone: () =>
146
145
  onParentMiss(parentId).pipe(
147
146
  Effect.tap(entries =>
@@ -183,7 +182,7 @@ export interface Cache<EDriver, EMiss, A> {
183
182
 
184
183
  export const make = <EOps, EDriver, EMiss, A>({
185
184
  driver,
186
- id,
185
+ id: identify,
187
186
  onMiss,
188
187
  ops = Stream.empty,
189
188
  }: {
@@ -205,15 +204,15 @@ export const make = <EOps, EDriver, EMiss, A>({
205
204
  }
206
205
  }),
207
206
  ).pipe(
208
- Effect.tapErrorCause(_ => Effect.logError("ops error, restarting", _)),
207
+ Effect.tapCause(cause => Effect.logError("ops error, restarting", cause)),
209
208
  Effect.retry(retryPolicy),
210
209
  Effect.forkScoped,
211
210
  Effect.interruptible,
212
211
  )
213
212
 
214
213
  yield* driver.run.pipe(
215
- Effect.tapErrorCause(_ =>
216
- Effect.logError("cache driver error, restarting", _),
214
+ Effect.tapCause(cause =>
215
+ Effect.logError("cache driver error, restarting", cause),
217
216
  ),
218
217
  Effect.retry(retryPolicy),
219
218
  Effect.forkScoped,
@@ -221,20 +220,18 @@ export const make = <EOps, EDriver, EMiss, A>({
221
220
  )
222
221
 
223
222
  const get = (id: string) =>
224
- Effect.flatMap(
225
- driver.get(id),
226
- Option.match({
223
+ Effect.flatMap(driver.get(id), option =>
224
+ Option.match(option, {
227
225
  onNone: () => Effect.tap(onMiss(id), a => driver.set(id, a)),
228
226
  onSome: Effect.succeed,
229
227
  }),
230
228
  )
231
229
 
232
- const put = (_: A) => driver.set(id(_), _)
230
+ const put = (_: A) => driver.set(identify(_), _)
233
231
 
234
232
  const update = <R, E>(id: string, f: (_: A) => Effect.Effect<A, E, R>) =>
235
- get(id).pipe(
236
- Effect.flatMap(f),
237
- Effect.tap(_ => driver.set(id, _)),
233
+ Effect.flatMap(get(id), a =>
234
+ Effect.tap(f(a), next => driver.set(id, next)),
238
235
  )
239
236
 
240
237
  return {
@@ -252,13 +249,12 @@ export const make = <EOps, EDriver, EMiss, A>({
252
249
 
253
250
  export const CacheErrorTypeId = Symbol.for("dfx/Cache/CacheError")
254
251
 
255
- export class CacheMissError extends TypeIdError(
256
- CacheErrorTypeId,
257
- "CacheMissError",
258
- )<{
252
+ export class CacheMissError extends Data.Error<{
259
253
  cacheName: string
260
254
  id: string
261
255
  }> {
256
+ readonly _tag = "CacheMissError"
257
+
262
258
  get message() {
263
259
  return `Cache miss for "${this.cacheName}" with id: ${this.id}`
264
260
  }
@@ -1,18 +1,13 @@
1
- import * as Discord from "dfx/types"
1
+ import * as Discord from "./types.ts"
2
2
  import * as Config from "effect/Config"
3
- import type * as ConfigError from "effect/ConfigError"
4
- import { GenericTag } from "effect/Context"
5
3
  import * as Duration from "effect/Duration"
6
4
  import * as Effect from "effect/Effect"
7
5
  import * as Layer from "effect/Layer"
8
6
  import type * as Redacted from "effect/Redacted"
7
+ import * as ServiceMap from "effect/ServiceMap"
9
8
 
10
9
  const VERSION = 10
11
10
 
12
- export interface DiscordConfig {
13
- readonly _: unique symbol
14
- }
15
-
16
11
  export interface DiscordConfigService {
17
12
  readonly token: Redacted.Redacted
18
13
  readonly rest: {
@@ -30,9 +25,10 @@ export interface DiscordConfigService {
30
25
  readonly identifyRateLimit: readonly [window: number, limit: number]
31
26
  }
32
27
  }
33
- export const DiscordConfig = GenericTag<DiscordConfig, DiscordConfigService>(
34
- "dfx/DiscordConfig",
35
- )
28
+ export class DiscordConfig extends ServiceMap.Service<
29
+ DiscordConfig,
30
+ DiscordConfigService
31
+ >()("dfx/DiscordConfig") {}
36
32
 
37
33
  export interface MakeOpts {
38
34
  readonly token: Redacted.Redacted
@@ -48,17 +44,17 @@ export const make = ({
48
44
  token,
49
45
  rest: {
50
46
  baseUrl: `https://discord.com/api/v${VERSION}`,
51
- ...(rest ?? {}),
47
+ ...rest,
52
48
  globalRateLimit: {
53
49
  limit: 50,
54
50
  window: Duration.seconds(1),
55
- ...(rest?.globalRateLimit ?? {}),
51
+ ...rest?.globalRateLimit,
56
52
  },
57
53
  },
58
54
  gateway: {
59
55
  intents: Discord.GatewayIntentBits.Guilds,
60
56
  identifyRateLimit: [5000, 1],
61
- ...(gateway ?? {}),
57
+ ...gateway,
62
58
  },
63
59
  })
64
60
 
@@ -66,6 +62,6 @@ export const layer = (opts: MakeOpts): Layer.Layer<DiscordConfig> =>
66
62
  Layer.succeed(DiscordConfig, make(opts))
67
63
 
68
64
  export const layerConfig = (
69
- _: Config.Config.Wrap<MakeOpts>,
70
- ): Layer.Layer<DiscordConfig, ConfigError.ConfigError> =>
71
- Layer.effect(DiscordConfig, Effect.map(Config.unwrap(_), make))
65
+ _: Config.Wrap<MakeOpts>,
66
+ ): Layer.Layer<DiscordConfig, Config.ConfigError> =>
67
+ Layer.effect(DiscordConfig, Effect.map(Config.unwrap(_).asEffect(), make))
@@ -1,14 +1,16 @@
1
- import { GenericTag } from "effect/Context"
2
1
  import * as Effect from "effect/Effect"
3
2
  import * as Layer from "effect/Layer"
4
3
  import * as Ref from "effect/Ref"
5
- import type * as Discord from "dfx/types"
6
- import * as Socket from "@effect/platform/Socket"
7
- import * as Mailbox from "effect/Mailbox"
4
+ import type * as Discord from "../types.ts"
8
5
  import * as Schedule from "effect/Schedule"
9
6
  import * as Cause from "effect/Cause"
10
- import * as Option from "effect/Option"
7
+ import * as ServiceMap from "effect/ServiceMap"
8
+ import * as Queue from "effect/Queue"
9
+ import * as Socket from "effect/unstable/socket/Socket"
10
+ import type * as Scope from "effect/Scope"
11
+ import { CurrentLoggers } from "effect/Logger"
11
12
  import * as LogLevel from "effect/LogLevel"
13
+ import { MinimumLogLevel } from "effect/References"
12
14
 
13
15
  export type Message = Discord.GatewayReceivePayload
14
16
  export type MessageSend = Discord.GatewaySendPayload | Reconnect
@@ -28,16 +30,14 @@ export interface DiscordWSCodecService {
28
30
  encode: (p: Discord.GatewaySendPayload) => Uint8Array | string
29
31
  decode: (p: Uint8Array | string) => Discord.GatewayReceivePayload
30
32
  }
31
- export interface DiscordWSCodec {
32
- readonly _: unique symbol
33
- }
34
33
 
35
34
  const decoder = new TextDecoder()
36
- const logLevelTrace = Option.some(LogLevel.Trace)
37
35
 
38
- export const DiscordWSCodec = GenericTag<DiscordWSCodec, DiscordWSCodecService>(
39
- "dfx/DiscordGateway/DiscordWS/Codec",
40
- )
36
+ export class DiscordWSCodec extends ServiceMap.Service<
37
+ DiscordWSCodec,
38
+ DiscordWSCodecService
39
+ >()("dfx/DiscordGateway/DiscordWS/Codec") {}
40
+
41
41
  export const JsonDiscordWSCodecLive = Layer.succeed(DiscordWSCodec, {
42
42
  type: "json",
43
43
  encode: p => JSON.stringify(p),
@@ -56,9 +56,9 @@ const make = Effect.gen(function* () {
56
56
  const urlRef = yield* Ref.make(
57
57
  `${url}?v=${version}&encoding=${encoding.type}`,
58
58
  )
59
- const setUrl = (url: string) =>
60
- Ref.set(urlRef, `${url}?v=${version}&encoding=${encoding.type}`)
61
- const messages = yield* Mailbox.make<Message>()
59
+ const setUrl = (nextUrl: string) =>
60
+ Ref.set(urlRef, `${nextUrl}?v=${version}&encoding=${encoding.type}`)
61
+ const messages = yield* Queue.make<Message>()
62
62
  const socket = yield* Socket.makeWebSocket(Ref.get(urlRef), {
63
63
  closeCodeIsError: _ => true,
64
64
  openTimeout: 5000,
@@ -71,44 +71,58 @@ const make = Effect.gen(function* () {
71
71
  })
72
72
  const write = (message: MessageSend): Effect.Effect<void> => {
73
73
  if (message === Reconnect) {
74
- return Effect.catchAllCause(
74
+ return Effect.catchCause(
75
75
  writeRaw(new Socket.CloseEvent(3000, "reconnecting")),
76
76
  logWriteError,
77
77
  )
78
78
  }
79
- return Effect.catchAllCause(
79
+ return Effect.catchCause(
80
80
  writeRaw(encoding.encode(message)),
81
81
  logWriteError,
82
82
  )
83
83
  }
84
+ const traceEnabled = LogLevel.isLessThanOrEqualTo(
85
+ yield* MinimumLogLevel,
86
+ "Trace",
87
+ )
88
+ const loggers = yield* CurrentLoggers
84
89
  yield* onConnecting.pipe(
85
- Effect.zipRight(
86
- Effect.withFiberRuntime<void, Socket.SocketError>(fiber =>
90
+ Effect.andThen(
91
+ Effect.withFiber<void, Socket.SocketError>(fiber =>
87
92
  socket.runRaw(_ => {
88
93
  const message = encoding.decode(_)
89
- messages.unsafeOffer(message)
90
- ;(fiber as any).log([message], Cause.empty, logLevelTrace)
94
+ Queue.offerUnsafe(messages, message)
95
+ if (!traceEnabled) return
96
+ loggers.forEach(logger => {
97
+ logger.log({
98
+ message,
99
+ cause: Cause.empty,
100
+ fiber,
101
+ logLevel: "Trace",
102
+ date: new Date(),
103
+ })
104
+ })
91
105
  }),
92
106
  ),
93
107
  ),
94
108
  Effect.retry({
95
- while: e => e.reason === "Close" && e.code === 3000,
109
+ while: e =>
110
+ e.reason._tag === "SocketCloseError" && e.reason.code === 3000,
96
111
  }),
97
- Effect.catchAllCause(cause =>
112
+ Effect.catchCause(cause =>
98
113
  Effect.logDebug("Got socket error, reconnecting", cause),
99
114
  ),
100
115
  Effect.repeat(
101
116
  Schedule.exponential(500).pipe(
102
- Schedule.union(Schedule.spaced(10000)),
117
+ Schedule.either(Schedule.spaced(10000)),
103
118
  ),
104
119
  ),
105
120
  Effect.annotateLogs("channel", "inbound"),
106
121
  Effect.forkScoped,
107
- Effect.interruptible,
108
122
  )
109
123
 
110
124
  return {
111
- take: messages.take,
125
+ take: Queue.take(messages),
112
126
  setUrl,
113
127
  write,
114
128
  } as const
@@ -121,11 +135,23 @@ const make = Effect.gen(function* () {
121
135
  return { connect } as const
122
136
  })
123
137
 
124
- export interface DiscordWS {
125
- readonly _: unique symbol
126
- }
127
- export const DiscordWS = GenericTag<
138
+ export class DiscordWS extends ServiceMap.Service<
128
139
  DiscordWS,
129
- Effect.Effect.Success<typeof make>
130
- >("dfx/DiscordGateway/DiscordWS")
140
+ {
141
+ readonly connect: (args_0: OpenOpts) => Effect.Effect<
142
+ {
143
+ readonly take: Effect.Effect<
144
+ Discord.GatewayReceivePayload,
145
+ never,
146
+ never
147
+ >
148
+ readonly setUrl: (url: string) => Effect.Effect<void, never, never>
149
+ readonly write: (message: MessageSend) => Effect.Effect<void>
150
+ },
151
+ never,
152
+ Socket.WebSocketConstructor | Scope.Scope
153
+ >
154
+ }
155
+ >()("dfx/DiscordGateway/DiscordWS") {}
156
+
131
157
  export const DiscordWSLive = Layer.effect(DiscordWS, make)
@@ -1,11 +1,11 @@
1
- import { GenericTag } from "effect/Context"
2
1
  import * as Effect from "effect/Effect"
3
2
  import * as PubSub from "effect/PubSub"
4
3
  import * as Layer from "effect/Layer"
5
- import * as Mailbox from "effect/Mailbox"
6
4
  import * as Stream from "effect/Stream"
7
- import type * as Discord from "dfx/types"
8
- import * as EffectUtils from "dfx/utils/Effect"
5
+ import type * as Discord from "../types.ts"
6
+ import * as EffectUtils from "../utils/Effect.ts"
7
+ import * as Queue from "effect/Queue"
8
+ import * as ServiceMap from "effect/ServiceMap"
9
9
 
10
10
  const fromDispatchFactory =
11
11
  <R, E>(source: Stream.Stream<Discord.GatewayReceivePayload, E, R>) =>
@@ -43,11 +43,11 @@ export const make = Effect.gen(function* () {
43
43
  )
44
44
 
45
45
  const sendMailbox = yield* Effect.acquireRelease(
46
- Mailbox.make<Discord.GatewaySendPayload>(),
47
- _ => _.shutdown,
46
+ Queue.make<Discord.GatewaySendPayload>(),
47
+ Queue.shutdown,
48
48
  )
49
49
  const send = (payload: Discord.GatewaySendPayload) =>
50
- sendMailbox.offer(payload)
50
+ Queue.offer(sendMailbox, payload)
51
51
 
52
52
  const dispatch = Stream.fromPubSub(hub)
53
53
  const fromDispatch = fromDispatchFactory(dispatch)
@@ -63,11 +63,9 @@ export const make = Effect.gen(function* () {
63
63
  } as const
64
64
  })
65
65
 
66
- export interface Messsaging {
67
- readonly _: unique symbol
68
- }
69
- export const Messaging = GenericTag<
70
- Messsaging,
71
- Effect.Effect.Success<typeof make>
72
- >("dfx/DiscordGateway/Messaging")
73
- export const MesssagingLive = Layer.scoped(Messaging, make)
66
+ export class Messaging extends ServiceMap.Service<Messaging>()(
67
+ "dfx/DiscordGateway/Messaging",
68
+ { make },
69
+ ) {}
70
+ export type Messsaging = Messaging
71
+ export const MesssagingLive = Layer.effect(Messaging, make)
@@ -1,8 +1,9 @@
1
1
  import * as Effect from "effect/Effect"
2
2
  import * as Option from "effect/Option"
3
- import * as Context from "effect/Context"
4
3
  import * as Layer from "effect/Layer"
5
- import * as KVS from "@effect/platform/KeyValueStore"
4
+ import * as ServiceMap from "effect/ServiceMap"
5
+ import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
6
+ import { flow, pipe } from "effect/Function"
6
7
 
7
8
  export interface ShardState {
8
9
  readonly resumeUrl: string
@@ -16,10 +17,10 @@ export interface StateStore {
16
17
  readonly clear: Effect.Effect<void>
17
18
  }
18
19
 
19
- export class ShardStateStore extends Context.Tag("dfx/Shard/StateStore")<
20
+ export class ShardStateStore extends ServiceMap.Service<
20
21
  ShardStateStore,
21
22
  { readonly forShard: (id: [id: number, count: number]) => StateStore }
22
- >() {
23
+ >()("dfx/Shard/StateStore") {
23
24
  static MemoryLive: Layer.Layer<ShardStateStore> = Layer.sync(
24
25
  ShardStateStore,
25
26
  () => {
@@ -29,7 +30,7 @@ export class ShardStateStore extends Context.Tag("dfx/Shard/StateStore")<
29
30
  forShard: ([id, count]) => {
30
31
  const key = `${id}-${count}`
31
32
  return {
32
- get: Effect.sync(() => Option.fromNullable(store.get(key))),
33
+ get: Effect.sync(() => Option.fromUndefinedOr(store.get(key))),
33
34
  set(state) {
34
35
  return Effect.sync(() => {
35
36
  store.set(key, state)
@@ -44,24 +45,28 @@ export class ShardStateStore extends Context.Tag("dfx/Shard/StateStore")<
44
45
  },
45
46
  )
46
47
 
47
- static KVSLive: Layer.Layer<ShardStateStore, never, KVS.KeyValueStore> =
48
- Layer.effect(
49
- ShardStateStore,
50
- Effect.gen(function* () {
51
- const store = yield* KVS.KeyValueStore
52
- return ShardStateStore.of({
53
- forShard([id, count]) {
54
- const key = `dfx-shard-state-${id}-${count}`
55
- return {
56
- get: Effect.map(
57
- Effect.orDie(store.get(key)),
58
- Option.map(JSON.parse),
59
- ),
60
- set: state => Effect.orDie(store.set(key, JSON.stringify(state))),
61
- clear: Effect.orDie(store.remove(key)),
62
- }
63
- },
64
- })
65
- }),
66
- )
48
+ static KVSLive: Layer.Layer<
49
+ ShardStateStore,
50
+ never,
51
+ KeyValueStore.KeyValueStore
52
+ > = Layer.effect(
53
+ ShardStateStore,
54
+ Effect.gen(function* () {
55
+ const store = yield* KeyValueStore.KeyValueStore
56
+ return ShardStateStore.of({
57
+ forShard([id, count]) {
58
+ const key = `dfx-shard-state-${id}-${count}`
59
+ return {
60
+ get: pipe(
61
+ store.get(key),
62
+ Effect.orDie,
63
+ Effect.map(flow(Option.fromUndefinedOr, Option.map(JSON.parse))),
64
+ ),
65
+ set: state => Effect.orDie(store.set(key, JSON.stringify(state))),
66
+ clear: Effect.orDie(store.remove(key)),
67
+ }
68
+ },
69
+ })
70
+ }),
71
+ )
67
72
  }
@@ -1,18 +1,18 @@
1
- import * as Duration from "effect/Duration"
2
1
  import * as Option from "effect/Option"
3
2
  import * as Effect from "effect/Effect"
4
3
  import * as Ref from "effect/Ref"
5
- import * as Schedule from "effect/Schedule"
6
- import * as DiscordWS from "dfx/DiscordGateway/DiscordWS"
7
- import * as SendEvents from "dfx/DiscordGateway/Shard/sendEvents"
8
- import type * as Discord from "dfx/types"
9
- import * as EffectU from "dfx/utils/Effect"
10
- import type { ShardState } from "dfx/DiscordGateway/Shard/StateStore"
11
- import type * as Mailbox from "effect/Mailbox"
4
+ import * as DiscordWS from "../DiscordWS.ts"
5
+ import * as SendEvents from "./sendEvents.ts"
6
+ import type * as Discord from "../../types.ts"
7
+ import * as EffectU from "../../utils/Effect.ts"
8
+ import type { ShardState } from "./StateStore.ts"
9
+ import * as Queue from "effect/Queue"
12
10
 
13
11
  const payload = (state: Effect.Effect<Option.Option<ShardState>>) =>
14
- Effect.map(state, state =>
15
- SendEvents.heartbeat(Option.getOrNull(Option.map(state, s => s.sequence))),
12
+ Effect.map(state, shardState =>
13
+ SendEvents.heartbeat(
14
+ Option.getOrNull(Option.map(shardState, s => s.sequence)),
15
+ ),
16
16
  )
17
17
 
18
18
  const payloadOrReconnect = (
@@ -26,33 +26,30 @@ const payloadOrReconnect = (
26
26
  )
27
27
 
28
28
  export const send = (
29
- hellos: Mailbox.ReadonlyMailbox<Discord.GatewayHelloData>,
30
- acks: Mailbox.ReadonlyMailbox<void>,
29
+ hellos: Queue.Dequeue<Discord.GatewayHelloData>,
30
+ acks: Queue.Dequeue<void>,
31
31
  state: Effect.Effect<Option.Option<ShardState>>,
32
- send: (p: DiscordWS.MessageSend) => Effect.Effect<void>,
32
+ sendMessage: (p: DiscordWS.MessageSend) => Effect.Effect<void>,
33
33
  ) =>
34
34
  Effect.flatMap(Ref.make(true), ackedRef => {
35
35
  const sendPayload = payloadOrReconnect(ackedRef, state).pipe(
36
- Effect.zipLeft(Ref.set(ackedRef, false)),
37
- Effect.flatMap(send),
36
+ Effect.tap(Ref.set(ackedRef, false)),
37
+ Effect.flatMap(sendMessage),
38
38
  )
39
39
 
40
40
  const heartbeats = EffectU.foreverSwitch(
41
- Effect.zipLeft(hellos.take, Ref.set(ackedRef, true)),
42
- p =>
43
- Effect.schedule(
44
- sendPayload,
45
- Schedule.andThen(
46
- Schedule.duration(
47
- Duration.millis(p.heartbeat_interval * Math.random()),
48
- ),
49
- Schedule.spaced(Duration.millis(p.heartbeat_interval)),
50
- ),
51
- ),
41
+ Effect.tap(Queue.take(hellos), Ref.set(ackedRef, true)),
42
+ Effect.fnUntraced(function* (p) {
43
+ yield* Effect.sleep(p.heartbeat_interval * Math.random())
44
+ while (true) {
45
+ yield* sendPayload
46
+ yield* Effect.sleep(p.heartbeat_interval)
47
+ }
48
+ }),
52
49
  )
53
50
 
54
- const run = acks.take.pipe(
55
- Effect.zipLeft(Ref.set(ackedRef, true)),
51
+ const run = Queue.take(acks).pipe(
52
+ Effect.tap(Ref.set(ackedRef, true)),
56
53
  Effect.forever,
57
54
  )
58
55
 
@@ -1,9 +1,10 @@
1
1
  import * as Option from "effect/Option"
2
2
  import * as Effect from "effect/Effect"
3
- import * as SendEvents from "dfx/DiscordGateway/Shard/sendEvents"
4
- import type * as Discord from "dfx/types"
5
- import * as OS from "os"
6
- import type { ShardState } from "dfx/DiscordGateway/Shard/StateStore"
3
+ import * as SendEvents from "./sendEvents.ts"
4
+ import type * as Discord from "../../types.ts"
5
+ import type { ShardState } from "./StateStore.ts"
6
+
7
+ declare const process: { platform?: string | undefined } | undefined
7
8
 
8
9
  export interface Options {
9
10
  readonly token: string
@@ -17,7 +18,10 @@ const identify = ({ intents, presence, shard, token }: Options) =>
17
18
  token,
18
19
  intents,
19
20
  properties: {
20
- os: OS.platform(),
21
+ os:
22
+ typeof process !== "undefined"
23
+ ? (process.platform ?? "unknown")
24
+ : "unknown",
21
25
  browser: "dfx",
22
26
  device: "dfx",
23
27
  },
@@ -40,6 +44,7 @@ export const identifyOrResume = (
40
44
  state,
41
45
  Option.match({
42
46
  onNone: () => identify(opts),
43
- onSome: state => resume(opts.token, state.sessionId, state.sequence),
47
+ onSome: shardState =>
48
+ resume(opts.token, shardState.sessionId, shardState.sequence),
44
49
  }),
45
50
  )
@@ -1,4 +1,4 @@
1
- import * as Discord from "dfx/types"
1
+ import * as Discord from "../../types.ts"
2
2
 
3
3
  export const heartbeat = (
4
4
  d: Discord.GatewayHeartbeatData,
@@ -1,4 +1,4 @@
1
- import type * as Discord from "dfx/types"
1
+ import type * as Discord from "../../types.ts"
2
2
  import * as Stream from "effect/Stream"
3
3
 
4
4
  export const opCode =