feat: Enhance UserScript structure and functionality

- Updated package.json to include new scripts for development, production builds, linting, formatting, and cleaning.
- Added ESLint and Prettier for code quality and formatting.
- Refactored main application class to extend EventEmitter and manage modules.
- Introduced ExampleModule to demonstrate module structure and functionality.
- Created utility classes for DOM manipulation, event handling, and persistent storage.
- Added TypeScript definitions for UserScript environment.
- Improved TypeScript configuration with stricter checks and path aliases.
- Updated Vite configuration to handle development and production builds more effectively.
- Enhanced user script header generation to support environment-specific configurations.
This commit is contained in:
JonasPfalzgraf 2025-07-11 17:47:22 +02:00
parent 8089771d41
commit 88aeab8f29
17 changed files with 4064 additions and 595 deletions

78
src/utils/events.ts Normal file
View file

@ -0,0 +1,78 @@
/**
* Type-safe event emitter for UserScript modules
*/
export interface EventMap {
[event: string]: any;
}
export class EventEmitter<T extends EventMap = EventMap> {
private listeners: { [K in keyof T]?: Array<(data: T[K]) => void> } = {};
/**
* Add event listener
*/
on<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event]!.push(listener);
}
/**
* Add one-time event listener
*/
once<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
const onceListener = (data: T[K]) => {
listener(data);
this.off(event, onceListener);
};
this.on(event, onceListener);
}
/**
* Remove event listener
*/
off<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
const eventListeners = this.listeners[event];
if (eventListeners) {
const index = eventListeners.indexOf(listener);
if (index > -1) {
eventListeners.splice(index, 1);
}
}
}
/**
* Emit event
*/
emit<K extends keyof T>(event: K, data: T[K]): void {
const eventListeners = this.listeners[event];
if (eventListeners) {
eventListeners.forEach(listener => {
try {
listener(data);
} catch (error) {
console.error(`Error in event listener for "${String(event)}":`, error);
}
});
}
}
/**
* Remove all listeners for an event
*/
removeAllListeners<K extends keyof T>(event?: K): void {
if (event) {
delete this.listeners[event];
} else {
this.listeners = {};
}
}
/**
* Get listener count for an event
*/
listenerCount<K extends keyof T>(event: K): number {
return this.listeners[event]?.length || 0;
}
}