@evitcastudio/kit 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.
- package/CONTRIBUTING.md +0 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/bin/cli.ts +71 -0
- package/bin/index.ts +11 -0
- package/bin/resource-builder.ts +196 -0
- package/bin/types/shared-types.ts +10 -0
- package/bun-build.ts +56 -0
- package/bun.lockb +0 -0
- package/bunfig.toml +4 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +78 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1610 -0
- package/docs/classes/index.Kit.html +23 -0
- package/docs/index.html +15 -0
- package/docs/modules/index.html +1 -0
- package/docs/modules/types_shared-types.html +1 -0
- package/docs/modules.html +1 -0
- package/docs/types/types_shared-types.EmitterEvent.html +4 -0
- package/docs/types/types_shared-types.Listener.html +1 -0
- package/lib/bundle/cli/cli.js +2659 -0
- package/lib/event-system.d.ts +12 -0
- package/lib/event-system.d.ts.map +1 -0
- package/lib/event-system.js +25 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1 -0
- package/lib/kit.d.ts +54 -0
- package/lib/kit.d.ts.map +1 -0
- package/lib/kit.js +91 -0
- package/lib/types/shared-types.d.ts +18 -0
- package/lib/types/shared-types.d.ts.map +1 -0
- package/lib/types/shared-types.js +1 -0
- package/package.json +53 -0
- package/src/event-system.ts +29 -0
- package/src/index.ts +1 -0
- package/src/kit.ts +106 -0
- package/src/types/shared-types.ts +19 -0
- package/tests/kit-cli.test.ts +75 -0
- package/tests/kit.test.ts +33 -0
- package/tsconfig.json +37 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EmitterEvent, Listener } from './types/shared-types';
|
|
2
|
+
export declare class EventEmitter {
|
|
3
|
+
private listener;
|
|
4
|
+
private plugin;
|
|
5
|
+
constructor(pListener: Listener, pPlugin: any);
|
|
6
|
+
/**
|
|
7
|
+
* Emit an event to all listeners.
|
|
8
|
+
* @param pEvent - The event to emit.
|
|
9
|
+
*/
|
|
10
|
+
emit(pEvent: EmitterEvent): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=event-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-system.d.ts","sourceRoot":"","sources":["../src/event-system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACnE,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,MAAM,CAAmB;gBAErB,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAe,GAAG;IAK1D;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;CAcnC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export class EventEmitter {
|
|
2
|
+
listener;
|
|
3
|
+
plugin;
|
|
4
|
+
constructor(pListener, pPlugin) {
|
|
5
|
+
this.listener = pListener;
|
|
6
|
+
this.plugin = pPlugin;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Emit an event to all listeners.
|
|
10
|
+
* @param pEvent - The event to emit.
|
|
11
|
+
*/
|
|
12
|
+
emit(pEvent) {
|
|
13
|
+
if (pEvent.plugin && pEvent.plugin !== this.plugin.name) {
|
|
14
|
+
throw new Error(`Event mismatch: ${this.plugin.name} tried to emit an event from the ${pEvent.plugin} namespace.`);
|
|
15
|
+
}
|
|
16
|
+
const event = {
|
|
17
|
+
plugin: this.plugin.name,
|
|
18
|
+
event: pEvent.event,
|
|
19
|
+
data: pEvent?.data,
|
|
20
|
+
timestamp: Date.now()
|
|
21
|
+
};
|
|
22
|
+
Object.freeze(event);
|
|
23
|
+
this.listener(event);
|
|
24
|
+
}
|
|
25
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Kit } from './kit';
|
package/lib/kit.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EmitterEvent, Listener } from './types/shared-types';
|
|
2
|
+
export declare class Kit {
|
|
3
|
+
/**
|
|
4
|
+
* A record of all plugins registered with the Kit class.
|
|
5
|
+
*/
|
|
6
|
+
private static plugins;
|
|
7
|
+
/**
|
|
8
|
+
* A set of all plugin emitters.
|
|
9
|
+
*/
|
|
10
|
+
private static emitters;
|
|
11
|
+
/**
|
|
12
|
+
* A record of all event listeners.
|
|
13
|
+
*/
|
|
14
|
+
private static events;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the Kit class with plugins.
|
|
17
|
+
* @param pPlugins - An array of plugins to initialize.
|
|
18
|
+
*/
|
|
19
|
+
static init(pPlugins: any[]): void;
|
|
20
|
+
/**
|
|
21
|
+
* Register a plugin with the Kit class.
|
|
22
|
+
* @param pPlugin - The plugin to register.
|
|
23
|
+
*/
|
|
24
|
+
static registerPlugin(pPlugin: any): void;
|
|
25
|
+
/**
|
|
26
|
+
* Gets a plugin by name.
|
|
27
|
+
* @param pName - String name of the plugin to retrieve.
|
|
28
|
+
*/
|
|
29
|
+
static getPlugin<T>(pName: string): T | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Lists all registered plugins.
|
|
32
|
+
*/
|
|
33
|
+
static getPlugins(): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Emit an event to all listeners.
|
|
36
|
+
* @param pEvent - The event to emit.
|
|
37
|
+
*/
|
|
38
|
+
private static emit;
|
|
39
|
+
/**
|
|
40
|
+
* Listen for an event.
|
|
41
|
+
* @param pPluginName - The plugin namespace.
|
|
42
|
+
* @param pEventName - The event name.
|
|
43
|
+
* @param pListener - The listener to call when the event is emitted.
|
|
44
|
+
*/
|
|
45
|
+
static on(pPluginName: string, pEventName: string, pListener: Listener): void;
|
|
46
|
+
/**
|
|
47
|
+
* Removes an event listener.
|
|
48
|
+
* @param pPluginName - The plugin namespace.
|
|
49
|
+
* @param pEventName - The event name.
|
|
50
|
+
* @param pListener - The listener to remove.
|
|
51
|
+
*/
|
|
52
|
+
static off(pPluginName: string, pEventName: string, pListener: (pData: EmitterEvent) => void): void;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=kit.d.ts.map
|
package/lib/kit.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEnE,qBAAa,GAAG;IACZ;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,OAAO,CAAwC;IAC9D;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmC;IAC1D;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,MAAM,CAAmD;IAExE;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAkB,GAAG,EAAE,GAAG,IAAI;IAMlD;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAkB,GAAG,GAAG,IAAI;IAkBzD;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,CAAC,EAA0B,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIzE;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,EAAE;IAI7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,IAAI;IAWlB;;;;;MAKE;IACH,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI;IAQ7E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;CAMtG"}
|
package/lib/kit.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { EventEmitter } from './event-system';
|
|
2
|
+
export class Kit {
|
|
3
|
+
/**
|
|
4
|
+
* A record of all plugins registered with the Kit class.
|
|
5
|
+
*/
|
|
6
|
+
static plugins = {};
|
|
7
|
+
/**
|
|
8
|
+
* A set of all plugin emitters.
|
|
9
|
+
*/
|
|
10
|
+
static emitters = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* A record of all event listeners.
|
|
13
|
+
*/
|
|
14
|
+
static events = {};
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the Kit class with plugins.
|
|
17
|
+
* @param pPlugins - An array of plugins to initialize.
|
|
18
|
+
*/
|
|
19
|
+
static init(pPlugins) {
|
|
20
|
+
pPlugins.forEach(pPlugin => {
|
|
21
|
+
this.registerPlugin(pPlugin);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Register a plugin with the Kit class.
|
|
26
|
+
* @param pPlugin - The plugin to register.
|
|
27
|
+
*/
|
|
28
|
+
static registerPlugin(pPlugin) {
|
|
29
|
+
const plugin = new pPlugin();
|
|
30
|
+
if (Kit.plugins[plugin.name]) {
|
|
31
|
+
throw new Error(`[Kit] plugin with name '${plugin.name}' is already registered.`);
|
|
32
|
+
}
|
|
33
|
+
const listener = (pEvent) => {
|
|
34
|
+
Kit.emit(pEvent);
|
|
35
|
+
};
|
|
36
|
+
const emitter = new EventEmitter(listener, plugin);
|
|
37
|
+
Kit.emitters.set(plugin.name, emitter);
|
|
38
|
+
Kit.plugins[plugin.name] = plugin;
|
|
39
|
+
plugin._register(emitter);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets a plugin by name.
|
|
43
|
+
* @param pName - String name of the plugin to retrieve.
|
|
44
|
+
*/
|
|
45
|
+
static getPlugin(pName) {
|
|
46
|
+
return Kit.plugins[pName];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Lists all registered plugins.
|
|
50
|
+
*/
|
|
51
|
+
static getPlugins() {
|
|
52
|
+
return Object.keys(Kit.plugins);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Emit an event to all listeners.
|
|
56
|
+
* @param pEvent - The event to emit.
|
|
57
|
+
*/
|
|
58
|
+
static emit(pEvent) {
|
|
59
|
+
const { plugin, event } = pEvent;
|
|
60
|
+
const eventScope = `${plugin}-${event}`;
|
|
61
|
+
if (!Kit.events[eventScope]) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
Kit.events[eventScope].forEach(pListener => pListener(pEvent));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Listen for an event.
|
|
68
|
+
* @param pPluginName - The plugin namespace.
|
|
69
|
+
* @param pEventName - The event name.
|
|
70
|
+
* @param pListener - The listener to call when the event is emitted.
|
|
71
|
+
*/
|
|
72
|
+
static on(pPluginName, pEventName, pListener) {
|
|
73
|
+
const eventScope = `${pPluginName}-${pEventName}`;
|
|
74
|
+
if (!Kit.events[eventScope]) {
|
|
75
|
+
Kit.events[eventScope] = [];
|
|
76
|
+
}
|
|
77
|
+
Kit.events[eventScope].push(pListener);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Removes an event listener.
|
|
81
|
+
* @param pPluginName - The plugin namespace.
|
|
82
|
+
* @param pEventName - The event name.
|
|
83
|
+
* @param pListener - The listener to remove.
|
|
84
|
+
*/
|
|
85
|
+
static off(pPluginName, pEventName, pListener) {
|
|
86
|
+
const eventScope = `${pPluginName}-${pEventName}`;
|
|
87
|
+
if (Kit.events[eventScope].includes(pListener)) {
|
|
88
|
+
Kit.events[eventScope].splice(Kit.events[eventScope].indexOf(pListener), 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
/**
|
|
3
|
+
* The EmitterEvent type is used to define the shape of the data that is passed to the event listeners.
|
|
4
|
+
*/
|
|
5
|
+
type EmitterEvent = {
|
|
6
|
+
/**
|
|
7
|
+
* The event name, e.g., "draw-frame".
|
|
8
|
+
*/
|
|
9
|
+
event: string;
|
|
10
|
+
/**
|
|
11
|
+
* The data associated with the event.
|
|
12
|
+
*/
|
|
13
|
+
data?: Record<string, any>;
|
|
14
|
+
} & Record<string, any>;
|
|
15
|
+
type Listener = (pData: EmitterEvent) => void;
|
|
16
|
+
}
|
|
17
|
+
export type { EmitterEvent, Listener };
|
|
18
|
+
//# sourceMappingURL=shared-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-types.d.ts","sourceRoot":"","sources":["../../src/types/shared-types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACX;;OAEG;IACH,KAAK,YAAY,GAAG;QAChB;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC9B,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAExB,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CACjD;AAED,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@evitcastudio/kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "doubleactii 56242467+doubleactii@users.noreply.github.com (https://evitcastudio.com)",
|
|
5
|
+
"main": "./lib/src/index.js",
|
|
6
|
+
"types": "./lib/src/index.d.ts",
|
|
7
|
+
"module": "lib/src/index.js",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"description": "A single-player/multiplayer framework for the Vylocity Game Engine.",
|
|
10
|
+
"cli-description": "CLI for handling building resources and running | testing | publishing games.",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"framework",
|
|
13
|
+
"multiplayer",
|
|
14
|
+
"single-player",
|
|
15
|
+
"toolkit",
|
|
16
|
+
"kit"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/EvitcaStudio/Kit.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/EvitcaStudio/Kit/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/EvitcaStudio/Kit",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"prepublishOnly": "bun run build-all",
|
|
29
|
+
"test": "bun test ./tests",
|
|
30
|
+
"build-types": "bun tsc",
|
|
31
|
+
"build-dist": "bun bun-build.ts",
|
|
32
|
+
"build-docs": "bun typedoc ./src/index.ts ./src/types/shared-types.ts",
|
|
33
|
+
"build-all": "bun run build-types && bun run build-dist && bun run build-docs"
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"kit": "./lib/bundle/cli/cli.js"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/bun": "latest",
|
|
40
|
+
"@types/node": "^22.10.2",
|
|
41
|
+
"bun": "^1.1.42",
|
|
42
|
+
"typedoc": "^0.27.5",
|
|
43
|
+
"typescript": "^5.7.2"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"chalk": "^5.4.0",
|
|
47
|
+
"commander": "^12.1.0",
|
|
48
|
+
"uuid": "^11.0.3"
|
|
49
|
+
},
|
|
50
|
+
"directories": {
|
|
51
|
+
"test": "tests"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EmitterEvent, Listener } from './types/shared-types';
|
|
2
|
+
export class EventEmitter {
|
|
3
|
+
private listener: Listener;
|
|
4
|
+
private plugin: /*KitPlugin*/any;
|
|
5
|
+
|
|
6
|
+
constructor(pListener: Listener, pPlugin: /*KitPlugin*/any) {
|
|
7
|
+
this.listener = pListener;
|
|
8
|
+
this.plugin = pPlugin;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Emit an event to all listeners.
|
|
13
|
+
* @param pEvent - The event to emit.
|
|
14
|
+
*/
|
|
15
|
+
emit(pEvent: EmitterEvent): void {
|
|
16
|
+
if (pEvent.plugin && pEvent.plugin !== this.plugin.name) {
|
|
17
|
+
throw new Error(`Event mismatch: ${this.plugin.name} tried to emit an event from the ${pEvent.plugin} namespace.`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const event: EmitterEvent = {
|
|
21
|
+
plugin: this.plugin.name,
|
|
22
|
+
event: pEvent.event,
|
|
23
|
+
data: pEvent?.data,
|
|
24
|
+
timestamp: Date.now()
|
|
25
|
+
}
|
|
26
|
+
Object.freeze(event);
|
|
27
|
+
this.listener(event);
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Kit } from './kit';
|
package/src/kit.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { EventEmitter } from './event-system';
|
|
2
|
+
import type { EmitterEvent, Listener } from './types/shared-types';
|
|
3
|
+
|
|
4
|
+
export class Kit {
|
|
5
|
+
/**
|
|
6
|
+
* A record of all plugins registered with the Kit class.
|
|
7
|
+
*/
|
|
8
|
+
private static plugins: Record<string, /*KitPlugin*/any> = {};
|
|
9
|
+
/**
|
|
10
|
+
* A set of all plugin emitters.
|
|
11
|
+
*/
|
|
12
|
+
private static emitters = new Map<string, EventEmitter>();
|
|
13
|
+
/**
|
|
14
|
+
* A record of all event listeners.
|
|
15
|
+
*/
|
|
16
|
+
private static events: Record<string, Array<(pData: any) => void>> = {};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the Kit class with plugins.
|
|
20
|
+
* @param pPlugins - An array of plugins to initialize.
|
|
21
|
+
*/
|
|
22
|
+
static init(pPlugins: /* KitPlugin[]*/any[]): void {
|
|
23
|
+
pPlugins.forEach(pPlugin => {
|
|
24
|
+
this.registerPlugin(pPlugin);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Register a plugin with the Kit class.
|
|
30
|
+
* @param pPlugin - The plugin to register.
|
|
31
|
+
*/
|
|
32
|
+
static registerPlugin(pPlugin: /* KitPlugin[]*/any): void {
|
|
33
|
+
const plugin = new pPlugin();
|
|
34
|
+
|
|
35
|
+
if (Kit.plugins[plugin.name]) {
|
|
36
|
+
throw new Error(`[Kit] plugin with name '${plugin.name}' is already registered.`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const listener: Listener = (pEvent: EmitterEvent) => {
|
|
40
|
+
Kit.emit(pEvent);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const emitter = new EventEmitter(listener, plugin);
|
|
44
|
+
Kit.emitters.set(plugin.name, emitter);
|
|
45
|
+
|
|
46
|
+
Kit.plugins[plugin.name] = plugin;
|
|
47
|
+
plugin._register(emitter);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gets a plugin by name.
|
|
52
|
+
* @param pName - String name of the plugin to retrieve.
|
|
53
|
+
*/
|
|
54
|
+
static getPlugin<T /* extends KitPlugin */>(pName: string): T | undefined {
|
|
55
|
+
return Kit.plugins[pName] as T;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Lists all registered plugins.
|
|
60
|
+
*/
|
|
61
|
+
static getPlugins(): string[] {
|
|
62
|
+
return Object.keys(Kit.plugins);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Emit an event to all listeners.
|
|
67
|
+
* @param pEvent - The event to emit.
|
|
68
|
+
*/
|
|
69
|
+
private static emit(pEvent: EmitterEvent): void {
|
|
70
|
+
const { plugin, event } = pEvent;
|
|
71
|
+
const eventScope = `${plugin}-${event}`;
|
|
72
|
+
|
|
73
|
+
if (!Kit.events[eventScope]) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Kit.events[eventScope].forEach(pListener => pListener(pEvent));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Listen for an event.
|
|
82
|
+
* @param pPluginName - The plugin namespace.
|
|
83
|
+
* @param pEventName - The event name.
|
|
84
|
+
* @param pListener - The listener to call when the event is emitted.
|
|
85
|
+
*/
|
|
86
|
+
static on(pPluginName: string, pEventName: string, pListener: Listener): void {
|
|
87
|
+
const eventScope = `${pPluginName}-${pEventName}`;
|
|
88
|
+
if (!Kit.events[eventScope]) {
|
|
89
|
+
Kit.events[eventScope] = [];
|
|
90
|
+
}
|
|
91
|
+
Kit.events[eventScope].push(pListener);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Removes an event listener.
|
|
96
|
+
* @param pPluginName - The plugin namespace.
|
|
97
|
+
* @param pEventName - The event name.
|
|
98
|
+
* @param pListener - The listener to remove.
|
|
99
|
+
*/
|
|
100
|
+
static off(pPluginName: string, pEventName: string, pListener: (pData: EmitterEvent) => void): void {
|
|
101
|
+
const eventScope = `${pPluginName}-${pEventName}`;
|
|
102
|
+
if (Kit.events[eventScope].includes(pListener)) {
|
|
103
|
+
Kit.events[eventScope].splice(Kit.events[eventScope].indexOf(pListener), 1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
/**
|
|
3
|
+
* The EmitterEvent type is used to define the shape of the data that is passed to the event listeners.
|
|
4
|
+
*/
|
|
5
|
+
type EmitterEvent = {
|
|
6
|
+
/**
|
|
7
|
+
* The event name, e.g., "draw-frame".
|
|
8
|
+
*/
|
|
9
|
+
event: string;
|
|
10
|
+
/**
|
|
11
|
+
* The data associated with the event.
|
|
12
|
+
*/
|
|
13
|
+
data?: Record<string, any>;
|
|
14
|
+
} & Record<string, any>;
|
|
15
|
+
|
|
16
|
+
type Listener = (pData: EmitterEvent) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type { EmitterEvent, Listener };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, beforeEach, afterEach, test, expect } from 'bun:test';
|
|
2
|
+
import { writeFile, rm, readdir, mkdir } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { KitCLI } from '../bin/kit';
|
|
5
|
+
|
|
6
|
+
const tempDir = join(process.cwd(), 'tests/temp');
|
|
7
|
+
const outDir = join(process.cwd(), 'tests/temp/dist');
|
|
8
|
+
|
|
9
|
+
async function createFile(pName: string, pExtension: string): Promise<string> {
|
|
10
|
+
const filePath = join(tempDir, `${pName}.${pExtension}`);
|
|
11
|
+
await writeFile(filePath, '');
|
|
12
|
+
return filePath;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function cleanUpDirectory(pDirectory: string): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
await rm(pDirectory, { recursive: true, force: true });
|
|
18
|
+
} catch (pError) {
|
|
19
|
+
console.error(`Error cleaning up directory: ${pError}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function ensureDirectoryExists(pDirectory: string): Promise<void> {
|
|
24
|
+
try {
|
|
25
|
+
await mkdir(pDirectory, { recursive: true });
|
|
26
|
+
} catch (pError) {
|
|
27
|
+
console.error(`Error creating directory: ${pError}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('Kit CLI', () => {
|
|
32
|
+
const testFiles = [
|
|
33
|
+
{ name: 'file1', extension: 'txt' },
|
|
34
|
+
{ name: 'file2', extension: 'json' },
|
|
35
|
+
{ name: 'file3', extension: 'vyint' },
|
|
36
|
+
{ name: 'file4', extension: 'vyi' },
|
|
37
|
+
{ name: 'file5', extension: 'vym' },
|
|
38
|
+
{ name: 'file6', extension: 'vymac' },
|
|
39
|
+
{ name: 'file7', extension: 'mp3' },
|
|
40
|
+
{ name: 'file8', extension: 'wav' },
|
|
41
|
+
{ name: 'file9', extension: 'm4a' },
|
|
42
|
+
{ name: 'file10', extension: 'ogg' },
|
|
43
|
+
{ name: 'file11', extension: 'aac' },
|
|
44
|
+
{ name: 'file12', extension: 'flac' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
beforeEach(async () => {
|
|
48
|
+
await cleanUpDirectory(tempDir);
|
|
49
|
+
await ensureDirectoryExists(tempDir);
|
|
50
|
+
await ensureDirectoryExists(outDir);
|
|
51
|
+
await Promise.all(
|
|
52
|
+
testFiles.map(({ name, extension }) => createFile(name, extension))
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
afterEach(async () => {
|
|
57
|
+
await cleanUpDirectory(tempDir);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('should process resources with KitCLI', async () => {
|
|
61
|
+
await KitCLI.processResources({
|
|
62
|
+
inDirectory: tempDir,
|
|
63
|
+
outDirectory: outDir,
|
|
64
|
+
ignoreSound: false,
|
|
65
|
+
verbose: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const filesAfterBuild = await readdir(join(outDir, 'resources'));
|
|
69
|
+
const expectedFiles = ['icon', 'interface', 'macros', 'map', 'sound'];
|
|
70
|
+
|
|
71
|
+
expectedFiles.forEach((expectedFile) => {
|
|
72
|
+
expect(filesAfterBuild).toContain(expectedFile);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, test, beforeEach, mock } from "bun:test";
|
|
2
|
+
import { Kit } from '../src/kit';
|
|
3
|
+
|
|
4
|
+
describe('Kit Framework', () => {
|
|
5
|
+
let kit: typeof Kit;
|
|
6
|
+
|
|
7
|
+
// Reset Kit for each test
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
kit = Kit;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('should listen for an event and remove the listener', () => {
|
|
13
|
+
const mockListener = mock(() => {});
|
|
14
|
+
const pluginName = 'FakePlugin';
|
|
15
|
+
const eventName = 'testEvent';
|
|
16
|
+
|
|
17
|
+
kit.on(pluginName, eventName, mockListener);
|
|
18
|
+
kit.off(pluginName, eventName, mockListener);
|
|
19
|
+
/** @ts-ignore (accessing private field)*/
|
|
20
|
+
expect(kit.events[`${pluginName}-${eventName}`].length).toBe(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('should listen for an event and should not remove the listener due to a different func being passed.', () => {
|
|
24
|
+
const mockListener = mock(() => {});
|
|
25
|
+
const pluginName = 'FakePlugin';
|
|
26
|
+
const eventName = 'testEvent';
|
|
27
|
+
|
|
28
|
+
kit.on(pluginName, eventName, mockListener);
|
|
29
|
+
kit.off(pluginName, eventName, ()=>{});
|
|
30
|
+
/** @ts-ignore (accessing private field)*/
|
|
31
|
+
expect(kit.events[`${pluginName}-${eventName}`].length).toBe(1);
|
|
32
|
+
});
|
|
33
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"forceConsistentCasingInFileNames": true,
|
|
4
|
+
"declaration": true, // Generate .d.ts files
|
|
5
|
+
"declarationMap": true, // Generate .d.ts.map files for debugging
|
|
6
|
+
"emitDeclarationOnly": false, // Only emit type declarations
|
|
7
|
+
"outDir": "./lib", // Output folder for compiled files
|
|
8
|
+
"baseUrl": ".", // Base URL for module resolution
|
|
9
|
+
"esModuleInterop": true, // Enable ES module interop
|
|
10
|
+
// Enable latest features
|
|
11
|
+
"lib": ["ESNext", "DOM"],
|
|
12
|
+
"target": "ESNext",
|
|
13
|
+
"module": "ESNext",
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
"allowJs": true,
|
|
17
|
+
"resolveJsonModule": true,
|
|
18
|
+
|
|
19
|
+
// Bundler mode
|
|
20
|
+
"moduleResolution": "bundler",
|
|
21
|
+
// "allowImportingTsExtensions": true,
|
|
22
|
+
"verbatimModuleSyntax": true,
|
|
23
|
+
// "noEmit": true,
|
|
24
|
+
|
|
25
|
+
// Best practices
|
|
26
|
+
"strict": true,
|
|
27
|
+
"skipLibCheck": true,
|
|
28
|
+
"noFallthroughCasesInSwitch": true,
|
|
29
|
+
|
|
30
|
+
// Some stricter flags (disabled by default)
|
|
31
|
+
"noUnusedLocals": false,
|
|
32
|
+
"noUnusedParameters": false,
|
|
33
|
+
"noPropertyAccessFromIndexSignature": false
|
|
34
|
+
},
|
|
35
|
+
"include": ["src/**/*"],
|
|
36
|
+
"exclude": ["node_modules", "lib", "dist"]
|
|
37
|
+
}
|