@@ -19,14 +19,97 @@ import type {
19
19
import type { CommandType , EventType } from '../core/structures/enums' ;
20
20
import { Context } from '../core/structures/context'
21
21
import { ControlPlugin , InitPlugin , Plugin } from './core-plugin' ;
22
- import { Awaitable , SernEventsMapping , UnpackedDependencies } from './utility' ;
22
+ import { Awaitable , SernEventsMapping , UnpackedDependencies , Dictionary } from './utility' ;
23
23
24
- //state, deps, type (very original)
24
+ /**
25
+ * SDT (State, Dependencies, Type) interface represents the core data structure
26
+ * passed through the plugin pipeline to command modules.
27
+ *
28
+ * @interface SDT
29
+ * @template TState - Type parameter for the state object's structure
30
+ * @template TDeps - Type parameter for dependencies interface
31
+ *
32
+ * @property {Record<string, unknown> } state - Accumulated state data passed between plugins
33
+ * @property {TDeps } deps - Instance of application dependencies
34
+ * @property {CommandType } type - Command type identifier
35
+ * @property {string } [params] - Optional parameters passed to the command
36
+ *
37
+ * @example
38
+ * // Example of a plugin using SDT
39
+ * const loggingPlugin = CommandControlPlugin((ctx, sdt: SDT) => {
40
+ * console.log(`User ${ctx.user.id} executed command`);
41
+ * return controller.next({ 'logging/timestamp': Date.now() });
42
+ * });
43
+ *
44
+ * @example
45
+ * // Example of state accumulation through multiple plugins
46
+ * const plugin1 = CommandControlPlugin((ctx, sdt: SDT) => {
47
+ * return controller.next({ 'plugin1/data': 'value1' });
48
+ * });
49
+ *
50
+ * const plugin2 = CommandControlPlugin((ctx, sdt: SDT) => {
51
+ * // Access previous state
52
+ * const prevData = sdt.state['plugin1/data'];
53
+ * return controller.next({ 'plugin2/data': 'value2' });
54
+ * });
55
+ *
56
+ * @remarks
57
+ * - State is immutable and accumulated through the plugin chain
58
+ * - Keys in state should be namespaced to avoid collisions
59
+ * - Dependencies are injected and available throughout the pipeline
60
+ * - Type information helps plugins make type-safe decisions
61
+ *
62
+ * @see {@link CommandControlPlugin } for plugin implementation
63
+ * @see {@link CommandType } for available command types
64
+ * @see {@link Dependencies } for dependency injection interface
65
+ */
25
66
export type SDT = {
26
- state : Record < string , unknown > ;
67
+ /**
68
+ * Accumulated state passed between plugins in the pipeline.
69
+ * Each plugin can add to or modify this state using controller.next().
70
+ *
71
+ * @type {Record<string, unknown> }
72
+ * @example
73
+ * // Good: Namespaced state key
74
+ * { 'myPlugin/userData': { id: '123', name: 'User' } }
75
+ *
76
+ * // Avoid: Non-namespaced keys that might collide
77
+ * { userData: { id: '123' } }
78
+ */
79
+ state : Record < string , unknown > ;
80
+
81
+ /**
82
+ * Application dependencies available to plugins and command modules.
83
+ * Typically includes services, configurations, and utilities.
84
+ *
85
+ * @type {Dependencies }
86
+ */
27
87
deps : Dependencies ;
28
- type : CommandType ,
29
- params ?: string
88
+
89
+ /**
90
+ * Identifies the type of command being processed.
91
+ * Used by plugins to apply type-specific logic.
92
+ *
93
+ * @type {CommandType }
94
+ */
95
+ type : CommandType ;
96
+
97
+ /**
98
+ * Optional parameters passed to the command.
99
+ * May contain additional configuration or runtime data.
100
+ *
101
+ * @type {string }
102
+ * @optional
103
+ */
104
+ params ?: string ;
105
+
106
+ /**
107
+ * A copy of the current module that the plugin is running in.
108
+ */
109
+ module : { name : string ;
110
+ description : string ;
111
+ meta : Dictionary ;
112
+ locals : Dictionary ; }
30
113
} ;
31
114
32
115
export type Processed < T > = T & { name : string ; description : string } ;
@@ -41,7 +124,75 @@ export interface Module {
41
124
id : string ;
42
125
absPath : string ;
43
126
}
44
- locals : Record < string , unknown >
127
+
128
+ /**
129
+ * Custom data storage object for module-specific information.
130
+ * Plugins and module code can use this to store and retrieve metadata,
131
+ * configuration, or any other module-specific information.
132
+ *
133
+ * @type {Dictionary }
134
+ * @description A key-value store that allows plugins and module code to persist
135
+ * data at the module level. This is especially useful for InitPlugins that need
136
+ * to attach metadata or configuration to modules.
137
+ *
138
+ * @example
139
+ * // In a plugin
140
+ * module.locals.registrationDate = Date.now();
141
+ * module.locals.version = "1.0.0";
142
+ * module.locals.permissions = ["ADMIN", "MODERATE"];
143
+ *
144
+ * @example
145
+ * // In module execution
146
+ * console.log(`Command registered on: ${new Date(module.locals.registrationDate)}`);
147
+ *
148
+ * @example
149
+ * // Storing localization data
150
+ * module.locals.translations = {
151
+ * en: "Hello",
152
+ * es: "Hola",
153
+ * fr: "Bonjour"
154
+ * };
155
+ *
156
+ * @example
157
+ * // Storing command metadata
158
+ * module.locals.metadata = {
159
+ * category: "admin",
160
+ * cooldown: 5000,
161
+ * requiresPermissions: true
162
+ * };
163
+ *
164
+ * @remarks
165
+ * - The locals object is initialized as an empty object ({}) by default
166
+ * - Keys should be namespaced to avoid collisions between plugins
167
+ * - Values can be of any type
168
+ * - Data persists for the lifetime of the module
169
+ * - Commonly used by InitPlugins during module initialization
170
+ *
171
+ * @best -practices
172
+ * 1. Namespace your keys to avoid conflicts:
173
+ * ```typescript
174
+ * module.locals['myPlugin:data'] = value;
175
+ * ```
176
+ *
177
+ * 2. Document the data structure you're storing:
178
+ * ```typescript
179
+ * interface MyPluginData {
180
+ * version: string;
181
+ * timestamp: number;
182
+ * }
183
+ * module.locals['myPlugin:data'] = {
184
+ * version: '1.0.0',
185
+ * timestamp: Date.now()
186
+ * } as MyPluginData;
187
+ * ```
188
+ *
189
+ * 3. Use type-safe accessors when possible:
190
+ * ```typescript
191
+ * const getPluginData = (module: Module): MyPluginData =>
192
+ * module.locals['myPlugin:data'];
193
+ * ```
194
+ */
195
+ locals : Dictionary ;
45
196
execute ( ...args : any [ ] ) : Awaitable < any > ;
46
197
}
47
198
0 commit comments