dfx 0.91.2 → 0.92.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 (51) hide show
  1. package/Interactions/context.d.ts +1 -4
  2. package/Interactions/context.d.ts.map +1 -1
  3. package/Interactions/context.js +1 -1
  4. package/Interactions/context.js.map +1 -1
  5. package/Interactions/definitions.d.ts +12 -15
  6. package/Interactions/definitions.d.ts.map +1 -1
  7. package/Interactions/definitions.js.map +1 -1
  8. package/Interactions/gateway.d.ts.map +1 -1
  9. package/Interactions/gateway.js +6 -2
  10. package/Interactions/gateway.js.map +1 -1
  11. package/Interactions/handlers.d.ts +2 -1
  12. package/Interactions/handlers.d.ts.map +1 -1
  13. package/Interactions/handlers.js +25 -23
  14. package/Interactions/handlers.js.map +1 -1
  15. package/Interactions/index.d.ts +5 -6
  16. package/Interactions/index.d.ts.map +1 -1
  17. package/Interactions/index.js +5 -8
  18. package/Interactions/index.js.map +1 -1
  19. package/Interactions/utils.d.ts +26 -25
  20. package/Interactions/utils.d.ts.map +1 -1
  21. package/Interactions/utils.js +18 -20
  22. package/Interactions/utils.js.map +1 -1
  23. package/Interactions/webhook.d.ts.map +1 -1
  24. package/Interactions/webhook.js +5 -1
  25. package/Interactions/webhook.js.map +1 -1
  26. package/mjs/Interactions/context.mjs +1 -1
  27. package/mjs/Interactions/context.mjs.map +1 -1
  28. package/mjs/Interactions/definitions.mjs.map +1 -1
  29. package/mjs/Interactions/gateway.mjs +6 -2
  30. package/mjs/Interactions/gateway.mjs.map +1 -1
  31. package/mjs/Interactions/handlers.mjs +25 -23
  32. package/mjs/Interactions/handlers.mjs.map +1 -1
  33. package/mjs/Interactions/index.mjs +5 -6
  34. package/mjs/Interactions/index.mjs.map +1 -1
  35. package/mjs/Interactions/utils.mjs +18 -20
  36. package/mjs/Interactions/utils.mjs.map +1 -1
  37. package/mjs/Interactions/webhook.mjs +5 -1
  38. package/mjs/Interactions/webhook.mjs.map +1 -1
  39. package/mjs/version.mjs +1 -1
  40. package/package.json +2 -2
  41. package/src/Interactions/builder.ts +1 -1
  42. package/src/Interactions/context.ts +2 -5
  43. package/src/Interactions/definitions.ts +30 -40
  44. package/src/Interactions/gateway.ts +8 -3
  45. package/src/Interactions/handlers.ts +44 -69
  46. package/src/Interactions/index.ts +5 -7
  47. package/src/Interactions/utils.ts +51 -42
  48. package/src/Interactions/webhook.ts +8 -4
  49. package/src/version.ts +1 -1
  50. package/version.d.ts +1 -1
  51. package/version.js +1 -1
@@ -10,6 +10,7 @@ import type {
10
10
  } from "dfx/Interactions/context"
11
11
  import type * as Discord from "dfx/types"
12
12
  import type { NoSuchElementException } from "effect/Cause"
13
+ import type { Scope } from "effect/Scope"
13
14
 
14
15
  export type InteractionDefinition<R, E> =
15
16
  | GlobalApplicationCommand<R, E>
@@ -29,14 +30,13 @@ export class GlobalApplicationCommand<R, E> {
29
30
  export const global = <
30
31
  R,
31
32
  E,
32
- const A extends
33
- DeepReadonlyObject<Discord.CreateGlobalApplicationCommandParams>,
33
+ const A extends Discord.CreateGlobalApplicationCommandParams,
34
34
  >(
35
35
  command: A,
36
36
  handle: CommandHandler<R, E, A>,
37
37
  ) =>
38
38
  new GlobalApplicationCommand<
39
- Exclude<R, DiscordInteraction | DiscordApplicationCommand>,
39
+ Exclude<R, DiscordInteraction | DiscordApplicationCommand | Scope>,
40
40
  E
41
41
  >(command as any, handle as any)
42
42
 
@@ -51,50 +51,49 @@ export class GuildApplicationCommand<R, E> {
51
51
  export const guild = <
52
52
  R,
53
53
  E,
54
- const A extends
55
- DeepReadonlyObject<Discord.CreateGuildApplicationCommandParams>,
54
+ const A extends Discord.CreateGuildApplicationCommandParams,
56
55
  >(
57
56
  command: A,
58
57
  handle: CommandHandler<R, E, A>,
59
58
  ) =>
60
59
  new GuildApplicationCommand<
61
- Exclude<R, DiscordInteraction | DiscordApplicationCommand>,
60
+ Exclude<R, DiscordInteraction | DiscordApplicationCommand | Scope>,
62
61
  E
63
62
  >(command as any, handle as any)
64
63
 
65
64
  export class MessageComponent<R, E> {
66
65
  readonly _tag = "MessageComponent"
67
66
  constructor(
68
- readonly predicate: (customId: string) => Effect.Effect<boolean, E, R>,
67
+ readonly predicate: (customId: string) => boolean,
69
68
  readonly handle: Effect.Effect<Discord.InteractionResponse, E, R>,
70
69
  ) {}
71
70
  }
72
71
 
73
- export const messageComponent = <R1, R2, E1, E2>(
74
- pred: (customId: string) => Effect.Effect<boolean, E1, R1>,
75
- handle: CommandHandler<R2, E2, Discord.InteractionResponse>,
72
+ export const messageComponent = <R, E>(
73
+ pred: (customId: string) => boolean,
74
+ handle: CommandHandler<R, E, Discord.InteractionResponse>,
76
75
  ) =>
77
76
  new MessageComponent<
78
- Exclude<R1 | R2, DiscordInteraction | DiscordMessageComponent>,
79
- E1 | E2
80
- >(pred as any, handle as any)
77
+ Exclude<R, DiscordInteraction | DiscordMessageComponent | Scope>,
78
+ E
79
+ >(pred, handle as any)
81
80
 
82
81
  export class ModalSubmit<R, E> {
83
82
  readonly _tag = "ModalSubmit"
84
83
  constructor(
85
- readonly predicate: (customId: string) => Effect.Effect<boolean, E, R>,
84
+ readonly predicate: (customId: string) => boolean,
86
85
  readonly handle: Effect.Effect<Discord.InteractionResponse, E, R>,
87
86
  ) {}
88
87
  }
89
88
 
90
- export const modalSubmit = <R1, R2, E1, E2>(
91
- pred: (customId: string) => Effect.Effect<boolean, E1, R1>,
92
- handle: Effect.Effect<Discord.InteractionResponse, E2, R2>,
89
+ export const modalSubmit = <R, E>(
90
+ pred: (customId: string) => boolean,
91
+ handle: Effect.Effect<Discord.InteractionResponse, E, R>,
93
92
  ) =>
94
93
  new ModalSubmit<
95
- Exclude<R1 | R2, DiscordInteraction | DiscordModalSubmit>,
96
- E1 | E2
97
- >(pred as any, handle as any)
94
+ Exclude<R, DiscordInteraction | DiscordModalSubmit | Scope>,
95
+ E
96
+ >(pred, handle as any)
98
97
 
99
98
  export class Autocomplete<R, E> {
100
99
  readonly _tag = "Autocomplete"
@@ -102,39 +101,30 @@ export class Autocomplete<R, E> {
102
101
  readonly predicate: (
103
102
  data: Discord.ApplicationCommandDatum,
104
103
  focusedOption: Discord.ApplicationCommandInteractionDataOption,
105
- ) => Effect.Effect<boolean, E, R>,
104
+ ) => boolean,
106
105
  readonly handle: Effect.Effect<Discord.InteractionResponse, E, R>,
107
106
  ) {}
108
107
  }
109
108
 
110
- export const autocomplete = <R1, R2, E1, E2>(
109
+ export const autocomplete = <R, E>(
111
110
  pred: (
112
111
  data: Discord.ApplicationCommandDatum,
113
112
  focusedOption: Discord.ApplicationCommandInteractionDataOption,
114
- ) => Effect.Effect<boolean, E1, R1>,
115
- handle: Effect.Effect<Discord.InteractionResponse, E2, R2>,
113
+ ) => boolean,
114
+ handle: Effect.Effect<Discord.InteractionResponse, E, R>,
116
115
  ) =>
117
116
  new Autocomplete<
118
117
  Exclude<
119
- R1 | R2,
120
- DiscordInteraction | DiscordApplicationCommand | DiscordFocusedOption
118
+ R,
119
+ | DiscordInteraction
120
+ | DiscordApplicationCommand
121
+ | DiscordFocusedOption
122
+ | Scope
121
123
  >,
122
- E1 | E2
123
- >(pred as any, handle as any)
124
+ E
125
+ >(pred, handle as any)
124
126
 
125
127
  // ==== Command handler helpers
126
- type DeepReadonly<T> =
127
- T extends Array<infer R>
128
- ? ReadonlyArray<DeepReadonly<R>>
129
- : T extends Function
130
- ? T
131
- : T extends object
132
- ? DeepReadonlyObject<T>
133
- : T
134
- type DeepReadonlyObject<T> = {
135
- readonly [P in keyof T]: DeepReadonly<T[P]>
136
- }
137
-
138
128
  export type CommandHandler<R, E, A = any> =
139
129
  | Effect.Effect<Discord.InteractionResponse, E, R>
140
130
  | CommandHandlerFn<R, E, A>
@@ -95,12 +95,17 @@ export const run =
95
95
  )
96
96
  : Effect.never
97
97
 
98
- const handle = handlers(ix.definitions, (i, r) =>
99
- rest.createInteractionResponse(i.id, i.token, r).pipe(Effect.scoped),
98
+ const handle = handlers(
99
+ ix.definitions,
100
+ (i, r) => rest.createInteractionResponse(i.id, i.token, r).effect,
100
101
  )
101
102
 
102
103
  const run = gateway.handleDispatch("INTERACTION_CREATE", i =>
103
- Effect.provideService(postHandler(handle[i.type](i)), Interaction, i),
104
+ Effect.withSpan(
105
+ Effect.provideService(postHandler(handle[i.type](i)), Interaction, i),
106
+ "dfx.Interaction",
107
+ { attributes: { interactionId: i.id } },
108
+ ),
104
109
  )
105
110
 
106
111
  const sync = yield* _(FiberRef.get(interactionsSync))
@@ -1,11 +1,11 @@
1
1
  import type * as Chunk from "effect/Chunk"
2
- import * as Option from "effect/Option"
3
2
  import * as Effect from "effect/Effect"
4
3
  import * as IxHelpers from "dfx/Helpers/interactions"
5
4
  import * as Ctx from "dfx/Interactions/context"
6
5
  import type * as D from "dfx/Interactions/definitions"
7
6
  import { flattenDefinitions, splitDefinitions } from "dfx/Interactions/utils"
8
7
  import * as Discord from "dfx/types"
8
+ import type { Scope } from "effect/Scope"
9
9
 
10
10
  export class DefinitionNotFound {
11
11
  readonly _tag = "DefinitionNotFound"
@@ -31,7 +31,7 @@ export const handlers = <R, E, TE, A, B>(
31
31
  ) => Effect.Effect<A, E, R>,
32
32
  ): Record<
33
33
  Discord.InteractionType,
34
- (i: Discord.Interaction) => Handler<R, E, B>
34
+ (i: Discord.Interaction) => Handler<Exclude<R, Scope>, E, B>
35
35
  > => {
36
36
  const flattened = flattenDefinitions(definitions, handleResponse)
37
37
 
@@ -39,91 +39,66 @@ export const handlers = <R, E, TE, A, B>(
39
39
  splitDefinitions(flattened)
40
40
 
41
41
  return {
42
- [Discord.InteractionType.PING]: () =>
42
+ [Discord.InteractionType.PING]: _ =>
43
43
  Effect.succeed({
44
44
  type: Discord.InteractionCallbackType.PONG,
45
45
  } as any),
46
46
 
47
47
  [Discord.InteractionType.APPLICATION_COMMAND]: i => {
48
48
  const data = i.data as Discord.ApplicationCommandDatum
49
-
50
- return Option.match(Option.fromNullable(Commands[data.name]), {
51
- onNone: () => Effect.fail(new DefinitionNotFound(i)),
52
- onSome: command =>
53
- Effect.provideService(
54
- command.handle(i),
55
- Ctx.ApplicationCommand,
56
- data,
57
- ) as Handler<R, E, B>,
58
- })
49
+ const command = Commands[data.name]
50
+ if (command === undefined) {
51
+ return Effect.fail(new DefinitionNotFound(i))
52
+ }
53
+ return Effect.provideService(
54
+ command.handle(i),
55
+ Ctx.ApplicationCommand,
56
+ data,
57
+ ) as Handler<Exclude<R, Scope>, E, B>
59
58
  },
60
59
 
61
60
  [Discord.InteractionType.MODAL_SUBMIT]: i => {
62
61
  const data = i.data as Discord.ModalSubmitDatum
63
-
64
- return Effect.findFirst(ModalSubmit, _ =>
65
- _.predicate(data.custom_id),
66
- ).pipe(
67
- Effect.flatMap(
68
- Option.match({
69
- onNone: () => Effect.fail(new DefinitionNotFound(i)),
70
- onSome: match =>
71
- Effect.provideService(
72
- match.handle(i),
73
- Ctx.ModalSubmitData,
74
- data,
75
- ) as Handler<R, E, B>,
76
- }),
77
- ),
78
- )
62
+ const match = ModalSubmit.find(_ => _.predicate(data.custom_id))
63
+ if (match === undefined) {
64
+ return Effect.fail(new DefinitionNotFound(i))
65
+ }
66
+ return Effect.provideService(
67
+ match.handle(i),
68
+ Ctx.ModalSubmitData,
69
+ data,
70
+ ) as Handler<Exclude<R, Scope>, E, B>
79
71
  },
80
72
 
81
73
  [Discord.InteractionType.MESSAGE_COMPONENT]: i => {
82
74
  const data = i.data as Discord.MessageComponentDatum
83
-
84
- return Effect.findFirst(MessageComponent, _ =>
85
- _.predicate(data.custom_id),
86
- ).pipe(
87
- Effect.flatMap(
88
- Option.match({
89
- onNone: () => Effect.fail(new DefinitionNotFound(i)),
90
- onSome: match =>
91
- Effect.provideService(
92
- match.handle(i),
93
- Ctx.MessageComponentData,
94
- data,
95
- ) as Handler<R, E, B>,
96
- }),
97
- ),
98
- )
75
+ const match = MessageComponent.find(_ => _.predicate(data.custom_id))
76
+ if (match === undefined) {
77
+ return Effect.fail(new DefinitionNotFound(i))
78
+ }
79
+ return Effect.provideService(
80
+ match.handle(i),
81
+ Ctx.MessageComponentData,
82
+ data,
83
+ ) as Handler<Exclude<R, Scope>, E, B>
99
84
  },
100
85
 
101
86
  [Discord.InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE]: i => {
102
87
  const data = i.data as Discord.ApplicationCommandDatum
103
-
104
- return Option.match(IxHelpers.focusedOption(data), {
105
- onNone: () => Effect.fail(new DefinitionNotFound(i)),
106
- onSome: focusedOption =>
107
- Effect.findFirst(Autocomplete, _ =>
108
- _.predicate(data, focusedOption),
109
- ).pipe(
110
- Effect.flatMap(
111
- Option.match({
112
- onNone: () => Effect.fail(new DefinitionNotFound(i)),
113
- onSome: match =>
114
- Effect.provideService(
115
- match.handle(i),
116
- Ctx.ApplicationCommand,
117
- data,
118
- ).pipe(
119
- Effect.provideService(Ctx.FocusedOptionContext, {
120
- focusedOption,
121
- }),
122
- ) as Handler<R, E, B>,
123
- }),
124
- ),
125
- ),
126
- })
88
+ const option = IxHelpers.focusedOption(data)
89
+ if (option._tag === "None") {
90
+ return Effect.fail(new DefinitionNotFound(i))
91
+ }
92
+ const match = Autocomplete.find(_ => _.predicate(data, option.value))
93
+ if (match === undefined) {
94
+ return Effect.fail(new DefinitionNotFound(i))
95
+ }
96
+ return match
97
+ .handle(i)
98
+ .pipe(
99
+ Effect.provideService(Ctx.ApplicationCommand, data),
100
+ Effect.provideService(Ctx.FocusedOptionContext, option.value),
101
+ ) as Handler<Exclude<R, Scope>, E, B>
127
102
  },
128
103
  }
129
104
  }
@@ -1,4 +1,3 @@
1
- import * as Effect from "effect/Effect"
2
1
  import type * as Discord from "dfx/types"
3
2
 
4
3
  export { response } from "dfx/Helpers/interactions"
@@ -14,14 +13,13 @@ export {
14
13
  } from "dfx/Interactions/definitions"
15
14
 
16
15
  // Filters
17
- export const id = (query: string) => (customId: string) =>
18
- Effect.succeed(query === customId)
16
+ export const id = (query: string) => (customId: string) => query === customId
19
17
 
20
18
  export const idStartsWith = (query: string) => (customId: string) =>
21
- Effect.succeed(customId.startsWith(query))
19
+ customId.startsWith(query)
22
20
 
23
21
  export const idRegex = (query: RegExp) => (customId: string) =>
24
- Effect.succeed(query.test(customId))
22
+ query.test(customId)
25
23
 
26
24
  export const option =
27
25
  (command: string, optionName: string) =>
@@ -32,7 +30,7 @@ export const option =
32
30
  "name"
33
31
  >,
34
32
  ) =>
35
- Effect.succeed(data.name === command && focusedOption.name === optionName)
33
+ data.name === command && focusedOption.name === optionName
36
34
 
37
35
  export const optionOnly =
38
36
  (optionName: string) =>
@@ -43,4 +41,4 @@ export const optionOnly =
43
41
  "name"
44
42
  >,
45
43
  ) =>
46
- Effect.succeed(focusedOption.name === optionName)
44
+ focusedOption.name === optionName
@@ -3,6 +3,7 @@ import * as Effect from "effect/Effect"
3
3
  import * as Ctx from "dfx/Interactions/context"
4
4
  import type * as D from "dfx/Interactions/definitions"
5
5
  import type * as Discord from "dfx/types"
6
+ import * as ReadonlyArray from "effect/ReadonlyArray"
6
7
 
7
8
  export type DefinitionFlattened<R, E, TE, A> =
8
9
  D.InteractionDefinition<R, E> extends infer D
@@ -38,58 +39,66 @@ export const flattenDefinitions = <R, E, TE, A, B>(
38
39
  _: Discord.InteractionResponse,
39
40
  ) => Effect.Effect<A, E, R>,
40
41
  ) =>
41
- Chunk.map(definitions, ([definition, transform]) => ({
42
- ...definition,
43
- handle: (i: Discord.Interaction) =>
44
- Effect.isEffect(definition.handle)
45
- ? transform(
46
- Effect.flatMap(definition.handle, _ => handleResponse(i, _)),
47
- )
48
- : transform(
49
- Effect.flatMap(definition.handle(context), _ =>
50
- handleResponse(i, _),
42
+ ReadonlyArray.map(
43
+ Chunk.toReadonlyArray(definitions),
44
+ ([definition, transform]) => ({
45
+ ...definition,
46
+ handle: Effect.isEffect(definition.handle)
47
+ ? (i: Discord.Interaction) =>
48
+ Effect.scoped(
49
+ transform(
50
+ Effect.flatMap(
51
+ definition.handle as Effect.Effect<Discord.InteractionResponse>,
52
+ _ => handleResponse(i, _),
53
+ ),
54
+ ),
55
+ )
56
+ : (i: Discord.Interaction) =>
57
+ Effect.scoped(
58
+ transform(
59
+ Effect.flatMap(
60
+ (
61
+ definition.handle as (
62
+ _: any,
63
+ ) => Effect.Effect<Discord.InteractionResponse>
64
+ )(context),
65
+ _ => handleResponse(i, _),
66
+ ),
67
+ ),
51
68
  ),
52
- ),
53
- }))
69
+ }),
70
+ )
54
71
 
55
72
  export const splitDefinitions = <R, E, TE, A>(
56
- definitions: Chunk.Chunk<DefinitionFlattened<R, E, TE, A>>,
73
+ definitions: ReadonlyArray<DefinitionFlattened<R, E, TE, A>>,
57
74
  ) => {
58
- const grouped = Chunk.reduce(
75
+ const grouped = ReadonlyArray.reduce(
59
76
  definitions,
60
77
  {
61
- Autocomplete: Chunk.empty(),
62
- GlobalApplicationCommand: Chunk.empty(),
63
- GuildApplicationCommand: Chunk.empty(),
64
- MessageComponent: Chunk.empty(),
65
- ModalSubmit: Chunk.empty(),
78
+ Autocomplete: [],
79
+ GlobalApplicationCommand: [],
80
+ GuildApplicationCommand: [],
81
+ MessageComponent: [],
82
+ ModalSubmit: [],
83
+ Commands: {},
66
84
  } as {
67
- [K in D.InteractionDefinition<R, E>["_tag"]]: Chunk.Chunk<
85
+ [K in D.InteractionDefinition<R, E>["_tag"]]: Array<
68
86
  Extract<DefinitionFlattened<R, E, TE, A>, { _tag: K }>
69
87
  >
88
+ } & {
89
+ readonly Commands: Record<string, DefinitionFlattenedCommand<R, E, TE, A>>
90
+ },
91
+ (acc, d) => {
92
+ acc[d._tag].push(d as any)
93
+ if (
94
+ d._tag === "GlobalApplicationCommand" ||
95
+ d._tag === "GuildApplicationCommand"
96
+ ) {
97
+ acc.Commands[d.command.name] = d as any
98
+ }
99
+ return acc
70
100
  },
71
- (acc, d) => ({
72
- ...acc,
73
- [d._tag]: Chunk.append(acc[d._tag] as Chunk.Chunk<any>, d),
74
- }),
75
- )
76
-
77
- const Commands = Chunk.appendAll(
78
- grouped.GlobalApplicationCommand,
79
- grouped.GuildApplicationCommand,
80
- ).pipe(
81
- Chunk.reduce(
82
- {} as Record<string, DefinitionFlattenedCommand<R, E, TE, A>>,
83
- (acc, d) =>
84
- (({
85
- ...acc,
86
- [d.command.name]: d
87
- }) as any),
88
- ),
89
101
  )
90
102
 
91
- return {
92
- ...grouped,
93
- Commands,
94
- }
103
+ return grouped
95
104
  }
@@ -131,10 +131,14 @@ const run = <R, E>(
131
131
  WebhookConfig | Exclude<R, DiscordInteraction>
132
132
  > =>
133
133
  Effect.flatMap(fromHeadersAndBody(headers, body), interaction =>
134
- Effect.provideService(
135
- handler[interaction.type](interaction),
136
- Interaction,
137
- interaction,
134
+ Effect.withSpan(
135
+ Effect.provideService(
136
+ handler[interaction.type](interaction),
137
+ Interaction,
138
+ interaction,
139
+ ),
140
+ "dfx.Interaction",
141
+ { attributes: { interactionId: interaction.id } },
138
142
  ),
139
143
  )
140
144
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const LIB_VERSION = "0.91.2";
1
+ export const LIB_VERSION = "0.92.0";
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const LIB_VERSION = "0.91.2";
1
+ export declare const LIB_VERSION = "0.92.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.LIB_VERSION = void 0;
7
- const LIB_VERSION = exports.LIB_VERSION = "0.91.2";
7
+ const LIB_VERSION = exports.LIB_VERSION = "0.92.0";
8
8
  //# sourceMappingURL=version.js.map