dreaction-client-core 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core.d.ts +30 -0
- package/lib/core.d.ts.map +1 -0
- package/lib/core.js +317 -0
- package/lib/index.d.ts +14 -194
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +20 -461
- package/lib/plugins/api-response.d.ts +1 -1
- package/lib/plugins/api-response.d.ts.map +1 -1
- package/lib/plugins/benchmark.d.ts +1 -1
- package/lib/plugins/benchmark.d.ts.map +1 -1
- package/lib/plugins/clear.d.ts +1 -1
- package/lib/plugins/clear.d.ts.map +1 -1
- package/lib/plugins/image.d.ts +1 -1
- package/lib/plugins/image.d.ts.map +1 -1
- package/lib/plugins/index.d.ts +53 -0
- package/lib/plugins/index.d.ts.map +1 -0
- package/lib/plugins/index.js +36 -0
- package/lib/plugins/issue.d.ts +19 -0
- package/lib/plugins/issue.d.ts.map +1 -0
- package/lib/plugins/issue.js +20 -0
- package/lib/plugins/logger.d.ts +21 -5
- package/lib/plugins/logger.d.ts.map +1 -1
- package/lib/plugins/logger.js +11 -23
- package/lib/plugins/repl.d.ts +1 -1
- package/lib/plugins/repl.d.ts.map +1 -1
- package/lib/plugins/state-responses.d.ts +17 -5
- package/lib/plugins/state-responses.d.ts.map +1 -1
- package/lib/plugins/state-responses.js +10 -19
- package/lib/types.d.ts +73 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/lib/utils/plugin-guard.d.ts +12 -0
- package/lib/utils/plugin-guard.d.ts.map +1 -0
- package/lib/utils/plugin-guard.js +19 -0
- package/package.json +2 -2
- package/src/core.ts +428 -0
- package/src/index.ts +36 -720
- package/src/plugins/api-response.ts +1 -1
- package/src/plugins/benchmark.ts +1 -1
- package/src/plugins/clear.ts +1 -1
- package/src/plugins/image.ts +1 -1
- package/src/plugins/index.ts +26 -0
- package/src/plugins/issue.ts +25 -0
- package/src/plugins/logger.ts +19 -35
- package/src/plugins/state-responses.ts +19 -29
- package/src/types.ts +127 -0
- package/src/utils/plugin-guard.ts +31 -0
- package/src/plugins/repl.ts +0 -63
package/src/plugins/benchmark.ts
CHANGED
package/src/plugins/clear.ts
CHANGED
package/src/plugins/image.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DReactionCore, PluginCreator } from '../types';
|
|
2
|
+
import logger from './logger';
|
|
3
|
+
import image from './image';
|
|
4
|
+
import benchmark from './benchmark';
|
|
5
|
+
import stateResponses from './state-responses';
|
|
6
|
+
import apiResponse from './api-response';
|
|
7
|
+
import clear from './clear';
|
|
8
|
+
import issue from './issue';
|
|
9
|
+
|
|
10
|
+
export { default as logger } from './logger';
|
|
11
|
+
export { default as image } from './image';
|
|
12
|
+
export { default as benchmark } from './benchmark';
|
|
13
|
+
export { default as stateResponses } from './state-responses';
|
|
14
|
+
export { default as apiResponse } from './api-response';
|
|
15
|
+
export { default as clear } from './clear';
|
|
16
|
+
export { default as issue } from './issue';
|
|
17
|
+
|
|
18
|
+
export const corePlugins = [
|
|
19
|
+
image(),
|
|
20
|
+
logger(),
|
|
21
|
+
benchmark(),
|
|
22
|
+
stateResponses(),
|
|
23
|
+
apiResponse(),
|
|
24
|
+
clear(),
|
|
25
|
+
issue(),
|
|
26
|
+
] satisfies PluginCreator<DReactionCore>[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DReactionCore, Plugin, InferFeatures } from '../types';
|
|
2
|
+
import { createPluginGuard } from '../utils/plugin-guard';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Provides issue reporting feature
|
|
6
|
+
*/
|
|
7
|
+
const issue = () => (dreaction: DReactionCore) => {
|
|
8
|
+
return {
|
|
9
|
+
features: {
|
|
10
|
+
reportIssue: (id: string, name?: string, description?: string) => {
|
|
11
|
+
dreaction.send('report.issue', { id, name, description }, true);
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
} satisfies Plugin<DReactionCore>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default issue;
|
|
18
|
+
|
|
19
|
+
export type IssuePlugin = ReturnType<typeof issue>;
|
|
20
|
+
export type IssueFeatures = InferFeatures<ReturnType<typeof issue>>;
|
|
21
|
+
|
|
22
|
+
const issueGuard = createPluginGuard<IssueFeatures>(['reportIssue'], 'issue');
|
|
23
|
+
|
|
24
|
+
export const hasIssuePlugin = issueGuard.has;
|
|
25
|
+
export const assertHasIssuePlugin = issueGuard.assert;
|
package/src/plugins/logger.ts
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
import type { DReactionCore, Plugin, InferFeatures } from '../';
|
|
1
|
+
import type { DReactionCore, Plugin, InferFeatures } from '../types';
|
|
2
|
+
import { createPluginGuard } from '../utils/plugin-guard';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* Provides
|
|
5
|
+
* Provides logging features: log, info, debug, warn, error
|
|
5
6
|
*/
|
|
6
7
|
const logger = () => (dreaction: DReactionCore) => {
|
|
7
8
|
return {
|
|
8
9
|
features: {
|
|
9
|
-
log: (...args) => {
|
|
10
|
-
const content = args
|
|
10
|
+
log: (...args: any[]) => {
|
|
11
|
+
const content = args.length === 1 ? args[0] : args;
|
|
11
12
|
dreaction.send('log', { level: 'debug', message: content }, false);
|
|
12
13
|
},
|
|
13
|
-
|
|
14
|
-
const content = args
|
|
14
|
+
info: (...args: any[]) => {
|
|
15
|
+
const content = args.length === 1 ? args[0] : args;
|
|
16
|
+
dreaction.send('log', { level: 'debug', message: content }, false);
|
|
17
|
+
},
|
|
18
|
+
logImportant: (...args: any[]) => {
|
|
19
|
+
const content = args.length === 1 ? args[0] : args;
|
|
15
20
|
dreaction.send('log', { level: 'debug', message: content }, true);
|
|
16
21
|
},
|
|
17
22
|
debug: (message, important = false) =>
|
|
18
23
|
dreaction.send('log', { level: 'debug', message }, !!important),
|
|
19
24
|
warn: (message) =>
|
|
20
25
|
dreaction.send('log', { level: 'warn', message }, true),
|
|
21
|
-
error: (message, stack) =>
|
|
26
|
+
error: (message, stack?) =>
|
|
22
27
|
dreaction.send('log', { level: 'error', message, stack }, true),
|
|
23
28
|
},
|
|
24
29
|
} satisfies Plugin<DReactionCore>;
|
|
@@ -27,33 +32,12 @@ const logger = () => (dreaction: DReactionCore) => {
|
|
|
27
32
|
export default logger;
|
|
28
33
|
|
|
29
34
|
export type LoggerPlugin = ReturnType<typeof logger>;
|
|
35
|
+
export type LoggerFeatures = InferFeatures<ReturnType<typeof logger>>;
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
dreaction &&
|
|
37
|
-
'log' in dreaction &&
|
|
38
|
-
typeof dreaction.log === 'function' &&
|
|
39
|
-
'logImportant' in dreaction &&
|
|
40
|
-
typeof dreaction.logImportant === 'function' &&
|
|
41
|
-
'debug' in dreaction &&
|
|
42
|
-
typeof dreaction.debug === 'function' &&
|
|
43
|
-
'warn' in dreaction &&
|
|
44
|
-
typeof dreaction.warn === 'function' &&
|
|
45
|
-
'error' in dreaction &&
|
|
46
|
-
typeof dreaction.error === 'function'
|
|
47
|
-
);
|
|
48
|
-
};
|
|
37
|
+
const loggerGuard = createPluginGuard<LoggerFeatures>(
|
|
38
|
+
['log', 'info', 'logImportant', 'debug', 'warn', 'error'],
|
|
39
|
+
'logger'
|
|
40
|
+
);
|
|
49
41
|
|
|
50
|
-
export const
|
|
51
|
-
|
|
52
|
-
): asserts dreaction is DReactionCore &
|
|
53
|
-
InferFeatures<DReactionCore, ReturnType<typeof logger>> => {
|
|
54
|
-
if (!hasLoggerPlugin(dreaction)) {
|
|
55
|
-
throw new Error(
|
|
56
|
-
'This DReaction client has not had the logger plugin applied to it. Make sure that you add `use(logger())` before adding this plugin.'
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
42
|
+
export const hasLoggerPlugin = loggerGuard.has;
|
|
43
|
+
export const assertHasLoggerPlugin = loggerGuard.assert;
|
|
@@ -5,7 +5,8 @@ import type {
|
|
|
5
5
|
StateValuesChangePayload,
|
|
6
6
|
StateValuesResponsePayload,
|
|
7
7
|
} from 'dreaction-protocol';
|
|
8
|
-
import type { DReactionCore, Plugin, InferFeatures } from '../';
|
|
8
|
+
import type { DReactionCore, Plugin, InferFeatures } from '../types';
|
|
9
|
+
import { createPluginGuard } from '../utils/plugin-guard';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Provides helper functions for send state responses.
|
|
@@ -36,40 +37,29 @@ const stateResponse = () => (dreaction: DReactionCore) => {
|
|
|
36
37
|
changes.length > 0 &&
|
|
37
38
|
dreaction.send('state.values.change', { changes }),
|
|
38
39
|
|
|
39
|
-
/** sends the state backup over to the server */
|
|
40
40
|
stateBackupResponse: (state: StateBackupResponsePayload['state']) =>
|
|
41
41
|
dreaction.send('state.backup.response', { state }),
|
|
42
42
|
},
|
|
43
43
|
} satisfies Plugin<DReactionCore>;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
export type StateResponsePlugin = ReturnType<typeof stateResponse>;
|
|
47
|
-
|
|
48
46
|
export default stateResponse;
|
|
49
47
|
|
|
50
|
-
export
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
dreaction &&
|
|
55
|
-
'stateActionComplete' in dreaction &&
|
|
56
|
-
typeof dreaction.stateActionComplete === 'function' &&
|
|
57
|
-
'stateValuesResponse' in dreaction &&
|
|
58
|
-
typeof dreaction.stateValuesResponse === 'function' &&
|
|
59
|
-
'stateKeysResponse' in dreaction &&
|
|
60
|
-
typeof dreaction.stateKeysResponse === 'function' &&
|
|
61
|
-
'stateValuesChange' in dreaction &&
|
|
62
|
-
typeof dreaction.stateValuesChange === 'function' &&
|
|
63
|
-
'stateBackupResponse' in dreaction &&
|
|
64
|
-
typeof dreaction.stateBackupResponse === 'function';
|
|
48
|
+
export type StateResponsePlugin = ReturnType<typeof stateResponse>;
|
|
49
|
+
export type StateResponseFeatures = InferFeatures<
|
|
50
|
+
ReturnType<typeof stateResponse>
|
|
51
|
+
>;
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
const stateResponseGuard = createPluginGuard<StateResponseFeatures>(
|
|
54
|
+
[
|
|
55
|
+
'stateActionComplete',
|
|
56
|
+
'stateValuesResponse',
|
|
57
|
+
'stateKeysResponse',
|
|
58
|
+
'stateValuesChange',
|
|
59
|
+
'stateBackupResponse',
|
|
60
|
+
],
|
|
61
|
+
'state responses'
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
export const hasStateResponsePlugin = stateResponseGuard.has;
|
|
65
|
+
export const assertHasStateResponsePlugin = stateResponseGuard.assert;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Command,
|
|
3
|
+
CommandMap,
|
|
4
|
+
CustomCommandArg,
|
|
5
|
+
CustomCommandRegisterPayload,
|
|
6
|
+
} from 'dreaction-protocol';
|
|
7
|
+
import type { ClientOptions } from './client-options';
|
|
8
|
+
|
|
9
|
+
// #region Basic Types
|
|
10
|
+
type AnyFunction = (...args: any[]) => any;
|
|
11
|
+
|
|
12
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
13
|
+
k: infer I
|
|
14
|
+
) => void
|
|
15
|
+
? I
|
|
16
|
+
: never;
|
|
17
|
+
|
|
18
|
+
export interface DisplayConfig {
|
|
19
|
+
name: string;
|
|
20
|
+
value?: object | string | number | boolean | null | undefined;
|
|
21
|
+
preview?: string;
|
|
22
|
+
image?: string | { uri: string };
|
|
23
|
+
important?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ArgTypeMap {
|
|
27
|
+
string: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type CustomCommandArgs<Args extends CustomCommandArg[]> =
|
|
31
|
+
UnionToIntersection<
|
|
32
|
+
Args extends Array<infer U>
|
|
33
|
+
? U extends CustomCommandArg
|
|
34
|
+
? { [K in U as U['name']]: ArgTypeMap[U['type']] }
|
|
35
|
+
: never
|
|
36
|
+
: never
|
|
37
|
+
>;
|
|
38
|
+
|
|
39
|
+
export interface CustomCommand<
|
|
40
|
+
Args extends CustomCommandArg[] = CustomCommandArg[]
|
|
41
|
+
> extends Omit<CustomCommandRegisterPayload, 'id' | 'args'> {
|
|
42
|
+
id?: number;
|
|
43
|
+
handler: (args: CustomCommandArgs<Args>) => any | Promise<any>;
|
|
44
|
+
args?: Args;
|
|
45
|
+
}
|
|
46
|
+
// #endregion
|
|
47
|
+
|
|
48
|
+
// #region Plugin Types
|
|
49
|
+
export interface LifeCycleMethods {
|
|
50
|
+
onCommand?: (command: Command) => void;
|
|
51
|
+
onConnect?: () => void;
|
|
52
|
+
onDisconnect?: () => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface Plugin<Client> extends LifeCycleMethods {
|
|
56
|
+
features?: {
|
|
57
|
+
[key: string]: AnyFunction;
|
|
58
|
+
};
|
|
59
|
+
onPlugin?: (client: Client) => void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type PluginCreator<Client> = (client: Client) => Plugin<Client>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extract features from a single PluginCreator
|
|
66
|
+
*/
|
|
67
|
+
type ExtractPluginFeatures<P> = P extends PluginCreator<any>
|
|
68
|
+
? ReturnType<P> extends { features: infer F }
|
|
69
|
+
? F
|
|
70
|
+
: {}
|
|
71
|
+
: {};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Extract features type from a plugin or array of plugins.
|
|
75
|
+
* Supports:
|
|
76
|
+
* - Single PluginCreator: InferFeatures<typeof myPlugin>
|
|
77
|
+
* - Array of PluginCreators: InferFeatures<typeof plugins>
|
|
78
|
+
* - Legacy format: InferFeatures<Client, PluginCreator> (second param is the plugin)
|
|
79
|
+
*/
|
|
80
|
+
export type InferFeatures<ClientOrPlugin, LegacyPluginCreator = never> = [
|
|
81
|
+
LegacyPluginCreator
|
|
82
|
+
] extends [never]
|
|
83
|
+
? ClientOrPlugin extends PluginCreator<any>[]
|
|
84
|
+
? UnionToIntersection<ExtractPluginFeatures<ClientOrPlugin[number]>>
|
|
85
|
+
: ExtractPluginFeatures<ClientOrPlugin>
|
|
86
|
+
: ExtractPluginFeatures<LegacyPluginCreator>;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @deprecated Use InferFeatures instead
|
|
90
|
+
*/
|
|
91
|
+
export type InferFeaturesFromPlugins<
|
|
92
|
+
_Client,
|
|
93
|
+
Plugins extends PluginCreator<any>[]
|
|
94
|
+
> = UnionToIntersection<ExtractPluginFeatures<Plugins[number]>>;
|
|
95
|
+
// #endregion
|
|
96
|
+
|
|
97
|
+
// #region Core Interface
|
|
98
|
+
export interface DReactionCore {
|
|
99
|
+
connected: boolean;
|
|
100
|
+
isReady: boolean;
|
|
101
|
+
options: ClientOptions<this>;
|
|
102
|
+
plugins: Plugin<this>[];
|
|
103
|
+
startTimer: () => () => number;
|
|
104
|
+
close: () => this;
|
|
105
|
+
send: <Type extends keyof CommandMap>(
|
|
106
|
+
type: Type,
|
|
107
|
+
payload?: CommandMap[Type],
|
|
108
|
+
important?: boolean
|
|
109
|
+
) => void;
|
|
110
|
+
display: (config: DisplayConfig) => void;
|
|
111
|
+
registerCustomCommand: <
|
|
112
|
+
Args extends CustomCommandArg[] = Exclude<CustomCommand['args'], undefined>
|
|
113
|
+
>(
|
|
114
|
+
config: CustomCommand<Args>
|
|
115
|
+
) => () => void | ((config: string, optHandler?: () => void) => () => void);
|
|
116
|
+
configure: (
|
|
117
|
+
options?: ClientOptions<this>
|
|
118
|
+
) => ClientOptions<this>['plugins'] extends PluginCreator<this>[]
|
|
119
|
+
? this & InferFeatures<ClientOptions<this>['plugins']>
|
|
120
|
+
: this;
|
|
121
|
+
use: <P extends PluginCreator<this>>(
|
|
122
|
+
pluginCreator: P
|
|
123
|
+
) => this & InferFeatures<P>;
|
|
124
|
+
connect: () => this;
|
|
125
|
+
waitForConnect: () => Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
// #endregion
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DReactionCore } from '../types';
|
|
2
|
+
|
|
3
|
+
type AnyFunction = (...args: any[]) => any;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create type guard functions for plugin features.
|
|
7
|
+
* Reduces boilerplate for hasXxxPlugin and assertHasXxxPlugin patterns.
|
|
8
|
+
*/
|
|
9
|
+
export function createPluginGuard<T extends Record<string, AnyFunction>>(
|
|
10
|
+
featureNames: (keyof T)[],
|
|
11
|
+
pluginName: string
|
|
12
|
+
) {
|
|
13
|
+
const has = (client: DReactionCore): client is DReactionCore & T => {
|
|
14
|
+
return featureNames.every(
|
|
15
|
+
(name) => name in client && typeof (client as any)[name] === 'function'
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const assert = (
|
|
20
|
+
client: DReactionCore
|
|
21
|
+
): asserts client is DReactionCore & T => {
|
|
22
|
+
if (!has(client)) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`This DReaction client has not had the ${pluginName} plugin applied to it. ` +
|
|
25
|
+
`Make sure that you add the plugin before using these features.`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return { has, assert };
|
|
31
|
+
}
|
package/src/plugins/repl.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { DReactionCore, Plugin } from '../';
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
4
|
-
export type AcceptableRepls = object | Function | string | number;
|
|
5
|
-
|
|
6
|
-
const repl = () => (dreaction: DReactionCore) => {
|
|
7
|
-
const myRepls: { [key: string]: AcceptableRepls } = {};
|
|
8
|
-
// let currentContext = null
|
|
9
|
-
return {
|
|
10
|
-
onCommand: ({ type, payload }) => {
|
|
11
|
-
if (type.substr(0, 5) !== 'repl.') return;
|
|
12
|
-
|
|
13
|
-
switch (type.substr(5)) {
|
|
14
|
-
case 'ls':
|
|
15
|
-
dreaction.send('repl.ls.response', Object.keys(myRepls));
|
|
16
|
-
break;
|
|
17
|
-
// case "cd":
|
|
18
|
-
// const changeTo = myRepls.find(r => r.name === payload)
|
|
19
|
-
// if (!changeTo) {
|
|
20
|
-
// dreaction.send("repl.cd.response", "That REPL does not exist")
|
|
21
|
-
// break
|
|
22
|
-
// }
|
|
23
|
-
// currentContext = payload
|
|
24
|
-
// dreaction.send("repl.cd.response", `Change REPL to "${payload}"`)
|
|
25
|
-
// break
|
|
26
|
-
case 'execute':
|
|
27
|
-
// if (!currentContext) {
|
|
28
|
-
// dreaction.send(
|
|
29
|
-
// "repl.execute.response",
|
|
30
|
-
// "You must first select the REPL to use. Try 'ls'"
|
|
31
|
-
// )
|
|
32
|
-
// break
|
|
33
|
-
// }
|
|
34
|
-
// const currentRepl = myRepls.find(r => r.name === currentContext)
|
|
35
|
-
// if (!currentRepl) {
|
|
36
|
-
// dreaction.send("repl.execute.response", "The selected REPL no longer exists.")
|
|
37
|
-
// break
|
|
38
|
-
// }
|
|
39
|
-
dreaction.send(
|
|
40
|
-
'repl.execute.response',
|
|
41
|
-
function () {
|
|
42
|
-
return eval(payload); // eslint-disable-line no-eval
|
|
43
|
-
}.call(myRepls)
|
|
44
|
-
);
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
features: {
|
|
49
|
-
repl: (name: string, value: AcceptableRepls) => {
|
|
50
|
-
if (!name) {
|
|
51
|
-
throw new Error('You must provide a name for your REPL');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (myRepls[name]) {
|
|
55
|
-
throw new Error('You are already REPLing an item with that name');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
myRepls[name] = value;
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
} satisfies Plugin<DReactionCore>;
|
|
62
|
-
};
|
|
63
|
-
export default repl;
|