Commit compiled dist for git installs
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,2 @@
|
||||
node_modules/
|
||||
dist/
|
||||
*.tsbuildinfo
|
||||
|
||||
31
dist/PluginContext.d.ts
vendored
Normal file
31
dist/PluginContext.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { PluginContext, NotificationOptions } from './PluginInterfaces.js';
|
||||
import type { IPluginEventClient } from './interfaces.js';
|
||||
import type { PluginRegistry } from './PluginRegistry.js';
|
||||
/**
|
||||
* Options for constructing a PluginContext via `createPluginContext`.
|
||||
*/
|
||||
export interface PluginContextOptions {
|
||||
/** The plugin's unique identifier. */
|
||||
pluginId: string;
|
||||
/**
|
||||
* Optional event client for the `context.events` API.
|
||||
* Any object implementing `on(event, handler)` / `off(event, handler)` works —
|
||||
* e.g. a MatrixClient, Node.js EventEmitter, or socket.io socket.
|
||||
*/
|
||||
eventClient?: IPluginEventClient;
|
||||
/**
|
||||
* Called when a plugin invokes `context.notify(...)`.
|
||||
* The host is responsible for displaying the notification however it wants.
|
||||
*/
|
||||
onNotify?: (options: NotificationOptions) => void | Promise<void>;
|
||||
}
|
||||
/**
|
||||
* Creates a PluginContext wired to the given registry.
|
||||
* Call this before registering and loading a plugin.
|
||||
*
|
||||
* @param options - Host-specific dependencies for the plugin.
|
||||
* @param registry - The shared PluginRegistry instance.
|
||||
* @returns A fully-wired PluginContext ready to be passed to `plugin.onLoad`.
|
||||
*/
|
||||
export declare function createPluginContext(options: PluginContextOptions, registry: PluginRegistry): PluginContext;
|
||||
//# sourceMappingURL=PluginContext.d.ts.map
|
||||
1
dist/PluginContext.d.ts.map
vendored
Normal file
1
dist/PluginContext.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PluginContext.d.ts","sourceRoot":"","sources":["../src/PluginContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,cAAc,GACvB,aAAa,CAqJf"}
|
||||
151
dist/PluginContext.js
vendored
Normal file
151
dist/PluginContext.js
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Creates a PluginContext wired to the given registry.
|
||||
* Call this before registering and loading a plugin.
|
||||
*
|
||||
* @param options - Host-specific dependencies for the plugin.
|
||||
* @param registry - The shared PluginRegistry instance.
|
||||
* @returns A fully-wired PluginContext ready to be passed to `plugin.onLoad`.
|
||||
*/
|
||||
export function createPluginContext(options, registry) {
|
||||
const { pluginId, eventClient, onNotify } = options;
|
||||
return {
|
||||
pluginId,
|
||||
commands: {
|
||||
register: (command) => {
|
||||
registry.registerCommand(pluginId, command);
|
||||
registry.addLog(pluginId, 'log', [`Registered command: /${command.name}`]);
|
||||
},
|
||||
unregister: (name) => {
|
||||
registry.unregisterCommand(name);
|
||||
},
|
||||
execute: async (name, args) => {
|
||||
return registry.executeCommand(name, JSON.stringify(args));
|
||||
},
|
||||
},
|
||||
messages: {
|
||||
onBeforeSend: (interceptor) => {
|
||||
registry.addBeforeSendInterceptor(pluginId, interceptor);
|
||||
registry.addLog(pluginId, 'log', ['Registered beforeSend interceptor']);
|
||||
},
|
||||
onReceive: (interceptor) => {
|
||||
registry.addReceiveInterceptor(pluginId, interceptor);
|
||||
registry.addLog(pluginId, 'log', ['Registered receive interceptor']);
|
||||
},
|
||||
},
|
||||
ui: {
|
||||
registerRenderer: (type, renderer) => {
|
||||
registry.registerRenderer(pluginId, type, renderer);
|
||||
registry.addLog(pluginId, 'log', [`Registered renderer: ${type}`]);
|
||||
},
|
||||
unregisterRenderer: (type) => {
|
||||
registry.unregisterRenderer(type);
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
define: (schema) => {
|
||||
registry.defineSettings(pluginId, schema);
|
||||
registry.addLog(pluginId, 'log', ['Defined settings schema']);
|
||||
},
|
||||
get: (key) => {
|
||||
return registry.getPluginSetting(pluginId, key);
|
||||
},
|
||||
set: (key, value) => {
|
||||
registry.setPluginSetting(pluginId, key, value);
|
||||
},
|
||||
},
|
||||
themes: {
|
||||
register: (theme) => {
|
||||
registry.registerTheme(pluginId, theme);
|
||||
registry.addLog(pluginId, 'log', [`Registered theme: ${theme.name}`]);
|
||||
},
|
||||
unregister: (themeId) => {
|
||||
registry.unregisterTheme(pluginId, themeId);
|
||||
},
|
||||
},
|
||||
events: {
|
||||
on: (eventType, handler) => {
|
||||
if (!eventClient) {
|
||||
console.warn(`[Plugin ${pluginId}] No event client provided — events.on() is a no-op`);
|
||||
return;
|
||||
}
|
||||
registry.addEventHandler(pluginId, eventType, handler);
|
||||
eventClient.on(eventType, handler);
|
||||
registry.addLog(pluginId, 'log', [`Listening to event: ${eventType}`]);
|
||||
},
|
||||
off: (eventType, handler) => {
|
||||
if (!eventClient)
|
||||
return;
|
||||
registry.removeEventHandler(pluginId, eventType, handler);
|
||||
eventClient.off(eventType, handler);
|
||||
},
|
||||
},
|
||||
timers: {
|
||||
setInterval: (callback, ms) => {
|
||||
const id = setInterval(() => {
|
||||
try {
|
||||
callback();
|
||||
}
|
||||
catch (err) {
|
||||
registry.addLog(pluginId, 'error', ['Interval error:', err]);
|
||||
}
|
||||
}, ms);
|
||||
registry.addTimer(pluginId, id);
|
||||
return id;
|
||||
},
|
||||
setTimeout: (callback, ms) => {
|
||||
const id = setTimeout(() => {
|
||||
try {
|
||||
callback();
|
||||
}
|
||||
catch (err) {
|
||||
registry.addLog(pluginId, 'error', ['Timeout error:', err]);
|
||||
}
|
||||
registry.removeTimer(pluginId, id);
|
||||
}, ms);
|
||||
registry.addTimer(pluginId, id);
|
||||
return id;
|
||||
},
|
||||
clearInterval: (id) => {
|
||||
clearInterval(id);
|
||||
registry.removeTimer(pluginId, id);
|
||||
},
|
||||
clearTimeout: (id) => {
|
||||
clearTimeout(id);
|
||||
registry.removeTimer(pluginId, id);
|
||||
},
|
||||
},
|
||||
notify: async (options) => {
|
||||
const opts = typeof options === 'string' ? { title: 'Plugin', body: options } : options;
|
||||
registry.addLog(pluginId, 'log', ['Notification:', opts]);
|
||||
if (onNotify) {
|
||||
try {
|
||||
await onNotify(opts);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`[Plugin ${pluginId}] Notification handler error:`, err);
|
||||
}
|
||||
}
|
||||
},
|
||||
log: (...args) => {
|
||||
console.log(`[Plugin ${pluginId}]`, ...args);
|
||||
registry.addLog(pluginId, 'log', args);
|
||||
},
|
||||
warn: (...args) => {
|
||||
console.warn(`[Plugin ${pluginId}]`, ...args);
|
||||
registry.addLog(pluginId, 'warn', args);
|
||||
},
|
||||
error: (...args) => {
|
||||
console.error(`[Plugin ${pluginId}]`, ...args);
|
||||
registry.addLog(pluginId, 'error', args);
|
||||
},
|
||||
require: (requiredPluginId) => {
|
||||
const exports = registry.getPluginExports(requiredPluginId);
|
||||
if (exports === undefined) {
|
||||
throw new Error(`Plugin ${requiredPluginId} not found or has no exports`);
|
||||
}
|
||||
registry.addLog(pluginId, 'log', [`Required plugin: ${requiredPluginId}`]);
|
||||
return exports;
|
||||
},
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=PluginContext.js.map
|
||||
1
dist/PluginContext.js.map
vendored
Normal file
1
dist/PluginContext.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
215
dist/PluginInterfaces.d.ts
vendored
Normal file
215
dist/PluginInterfaces.d.ts
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Color group with five container variants and an OnContainer text color.
|
||||
*/
|
||||
export interface ThemeColorGroup {
|
||||
container: string;
|
||||
containerHover: string;
|
||||
containerActive: string;
|
||||
containerLine: string;
|
||||
onContainer: string;
|
||||
}
|
||||
/**
|
||||
* Color group for interactive palette entries (Main + Container sub-groups).
|
||||
*/
|
||||
export interface ThemePaletteGroup {
|
||||
main: string;
|
||||
mainHover: string;
|
||||
mainActive: string;
|
||||
mainLine: string;
|
||||
onMain: string;
|
||||
container: string;
|
||||
containerHover: string;
|
||||
containerActive: string;
|
||||
containerLine: string;
|
||||
onContainer: string;
|
||||
}
|
||||
/**
|
||||
* Full color token set for a plugin theme.
|
||||
* Property names map directly to the folds design-token contract.
|
||||
*/
|
||||
export interface PluginThemeColors {
|
||||
background: ThemeColorGroup;
|
||||
surface: ThemeColorGroup;
|
||||
surfaceVariant: ThemeColorGroup;
|
||||
primary: ThemePaletteGroup;
|
||||
secondary: ThemePaletteGroup;
|
||||
success: ThemePaletteGroup;
|
||||
warning: ThemePaletteGroup;
|
||||
critical: ThemePaletteGroup;
|
||||
other: {
|
||||
focusRing: string;
|
||||
shadow: string;
|
||||
overlay: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Theme definition supplied by a plugin.
|
||||
*/
|
||||
export interface PluginTheme {
|
||||
id: string;
|
||||
name: string;
|
||||
kind: 'light' | 'dark';
|
||||
colors: PluginThemeColors;
|
||||
/** Optional extra CSS injected alongside the theme variables. */
|
||||
extraCss?: string;
|
||||
}
|
||||
/**
|
||||
* A command argument definition.
|
||||
*/
|
||||
export interface CommandArg {
|
||||
name: string;
|
||||
type?: 'string' | 'number' | 'boolean';
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
}
|
||||
/**
|
||||
* A command registered by a plugin.
|
||||
*/
|
||||
export interface PluginCommand {
|
||||
name: string;
|
||||
description?: string;
|
||||
args?: string[] | CommandArg[];
|
||||
run: (args: Record<string, unknown>, ctx: PluginContext) => string | void | Promise<string | void>;
|
||||
}
|
||||
/** Callback invoked for outgoing or incoming messages. */
|
||||
export type MessageInterceptor = (msg: MessageContext) => void | Promise<void>;
|
||||
/**
|
||||
* Message context passed to interceptors.
|
||||
*/
|
||||
export interface MessageContext {
|
||||
content: string;
|
||||
roomId: string;
|
||||
eventType: string;
|
||||
formatted?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
/**
|
||||
* Custom renderer function.
|
||||
* The return type is `unknown` so the package stays framework-agnostic.
|
||||
* Hosts using React should cast to `ReactNode` at the call-site.
|
||||
*/
|
||||
export type CustomRenderer = (data: unknown, defaultRenderer?: () => unknown) => unknown;
|
||||
/**
|
||||
* A single setting definition within a plugin's settings schema.
|
||||
*/
|
||||
export interface SettingDefinition {
|
||||
type: 'string' | 'number' | 'boolean' | 'select' | 'color';
|
||||
label?: string;
|
||||
description?: string;
|
||||
default?: unknown;
|
||||
options?: Array<{
|
||||
value: unknown;
|
||||
label: string;
|
||||
}>;
|
||||
}
|
||||
/** The full settings schema for a plugin. */
|
||||
export type SettingsSchema = Record<string, SettingDefinition>;
|
||||
/**
|
||||
* Options for a notification emitted by a plugin.
|
||||
*/
|
||||
export interface NotificationOptions {
|
||||
title: string;
|
||||
body: string;
|
||||
type?: 'info' | 'success' | 'error' | 'warning';
|
||||
duration?: number;
|
||||
actions?: Array<{
|
||||
label: string;
|
||||
action: () => void;
|
||||
}>;
|
||||
}
|
||||
/**
|
||||
* The context provided to plugins when they are initialized.
|
||||
* All APIs are available through this object.
|
||||
*/
|
||||
export interface PluginContext {
|
||||
/** Plugin ID */
|
||||
pluginId: string;
|
||||
/** Commands API */
|
||||
commands: {
|
||||
register: (command: PluginCommand) => void;
|
||||
unregister: (name: string) => void;
|
||||
execute: (name: string, args: Record<string, unknown>) => Promise<string | void>;
|
||||
};
|
||||
/** Messages API */
|
||||
messages: {
|
||||
onBeforeSend: (interceptor: MessageInterceptor) => void;
|
||||
onReceive: (interceptor: MessageInterceptor) => void;
|
||||
};
|
||||
/** UI API — framework-agnostic renderer registry */
|
||||
ui: {
|
||||
registerRenderer: (type: string, renderer: CustomRenderer) => void;
|
||||
unregisterRenderer: (type: string) => void;
|
||||
};
|
||||
/** Settings API */
|
||||
settings: {
|
||||
define: (schema: SettingsSchema) => void;
|
||||
get: <T = unknown>(key: string) => T | undefined;
|
||||
set: (key: string, value: unknown) => void;
|
||||
};
|
||||
/** Themes API */
|
||||
themes: {
|
||||
register: (theme: PluginTheme) => void;
|
||||
unregister: (themeId: string) => void;
|
||||
};
|
||||
/**
|
||||
* Generic event emitter API.
|
||||
* Wire up any event client (Matrix, socket.io, Node EventEmitter, etc.)
|
||||
* via the `eventClient` option passed to `createPluginContext`.
|
||||
*/
|
||||
events: {
|
||||
on: (eventType: string, handler: (...args: any[]) => void) => void;
|
||||
off: (eventType: string, handler: (...args: any[]) => void) => void;
|
||||
};
|
||||
/** Background tasks API */
|
||||
timers: {
|
||||
setInterval: (callback: () => void, ms: number) => number;
|
||||
setTimeout: (callback: () => void, ms: number) => number;
|
||||
clearInterval: (id: number) => void;
|
||||
clearTimeout: (id: number) => void;
|
||||
};
|
||||
/** Send a notification through the host application. */
|
||||
notify: (options: NotificationOptions | string) => void | Promise<void>;
|
||||
/** Logging API */
|
||||
log: (...args: any[]) => void;
|
||||
warn: (...args: any[]) => void;
|
||||
error: (...args: any[]) => void;
|
||||
/** Require another loaded plugin's exports. */
|
||||
require: (pluginId: string) => unknown;
|
||||
}
|
||||
/**
|
||||
* Custom settings section that a plugin can inject into the settings UI.
|
||||
* The `component` value is `unknown` to remain framework-agnostic.
|
||||
* Hosts using React should treat it as `ReactNode`.
|
||||
*/
|
||||
export interface PluginSettingsSection {
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
component: unknown;
|
||||
}
|
||||
/** UI locations where plugins can inject content. */
|
||||
export type UILocation = 'room-header' | 'message-actions' | 'user-menu' | 'room-menu' | 'composer-actions';
|
||||
/**
|
||||
* The main plugin interface that all plugins must implement.
|
||||
*/
|
||||
export interface Plugin {
|
||||
name?: string;
|
||||
version?: string;
|
||||
dependencies?: Record<string, string>;
|
||||
/** Called when the plugin is loaded. */
|
||||
onLoad: (context: PluginContext) => void | Promise<void>;
|
||||
/** Called when the plugin is unloaded or disabled. */
|
||||
onUnload?: () => void | Promise<void>;
|
||||
/** Exposed API surface for other plugins to consume via `context.require()`. */
|
||||
exports?: unknown;
|
||||
}
|
||||
/**
|
||||
* A single log entry produced by a plugin.
|
||||
*/
|
||||
export interface PluginLogEntry {
|
||||
pluginId: string;
|
||||
level: 'log' | 'warn' | 'error';
|
||||
timestamp: number;
|
||||
args: unknown[];
|
||||
}
|
||||
//# sourceMappingURL=PluginInterfaces.d.ts.map
|
||||
1
dist/PluginInterfaces.d.ts.map
vendored
Normal file
1
dist/PluginInterfaces.d.ts.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/PluginInterfaces.js
vendored
Normal file
2
dist/PluginInterfaces.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=PluginInterfaces.js.map
|
||||
1
dist/PluginInterfaces.js.map
vendored
Normal file
1
dist/PluginInterfaces.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PluginInterfaces.js","sourceRoot":"","sources":["../src/PluginInterfaces.ts"],"names":[],"mappings":""}
|
||||
122
dist/PluginRegistry.d.ts
vendored
Normal file
122
dist/PluginRegistry.d.ts
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
import type { Plugin, PluginContext, PluginCommand, MessageInterceptor, MessageContext, CustomRenderer, SettingsSchema, PluginTheme, PluginLogEntry } from './PluginInterfaces.js';
|
||||
import type { IPluginStorage } from './interfaces.js';
|
||||
/**
|
||||
* Configuration options for the PluginRegistry.
|
||||
*/
|
||||
export interface PluginRegistryOptions {
|
||||
/**
|
||||
* Storage adapter for persisting plugin settings.
|
||||
* Defaults to in-memory storage if not provided.
|
||||
* Pass `localStorage` (or a wrapper) for browser environments.
|
||||
*/
|
||||
storage?: IPluginStorage;
|
||||
/**
|
||||
* Called when a plugin registers a theme.
|
||||
* The host is responsible for injecting the CSS into the document.
|
||||
* Receives the full theme ID (used as the CSS class name) and the generated CSS string.
|
||||
*/
|
||||
onThemeRegistered?: (themeId: string, className: string, css: string) => void;
|
||||
/**
|
||||
* Called when a plugin unregisters a theme.
|
||||
* The host is responsible for removing the injected CSS.
|
||||
*/
|
||||
onThemeUnregistered?: (themeId: string) => void;
|
||||
}
|
||||
/**
|
||||
* Central registry that manages all loaded plugins and their side-effects.
|
||||
* Create a single instance and share it across your application.
|
||||
*/
|
||||
export declare class PluginRegistry {
|
||||
private readonly plugins;
|
||||
private readonly commands;
|
||||
private beforeSendInterceptors;
|
||||
private receiveInterceptors;
|
||||
private readonly renderers;
|
||||
private readonly settingsSchemas;
|
||||
private readonly pluginSettings;
|
||||
private readonly matrixHandlers;
|
||||
private readonly timers;
|
||||
private readonly themes;
|
||||
private logs;
|
||||
private readonly maxLogs;
|
||||
private readonly storage;
|
||||
private readonly onThemeRegistered?;
|
||||
private readonly onThemeUnregistered?;
|
||||
constructor(options?: PluginRegistryOptions);
|
||||
/** Register a plugin and its context. Called after the host has loaded the module. */
|
||||
registerPlugin(id: string, plugin: Plugin, context: PluginContext): void;
|
||||
/** Unregister a plugin, calling its onUnload hook and cleaning up all side-effects. */
|
||||
unregisterPlugin(id: string): Promise<void>;
|
||||
/** Register a command contributed by a plugin. */
|
||||
registerCommand(pluginId: string, command: PluginCommand): void;
|
||||
/** Remove a registered command by name. */
|
||||
unregisterCommand(name: string): void;
|
||||
/** Execute a command by name, passing raw argument string. */
|
||||
executeCommand(name: string, rawArgs: string): Promise<string | void>;
|
||||
private parseCommandArgs;
|
||||
/** Return all registered commands. */
|
||||
getCommands(): Array<{
|
||||
name: string;
|
||||
pluginId: string;
|
||||
command: PluginCommand;
|
||||
}>;
|
||||
/** Add a before-send interceptor for a plugin. */
|
||||
addBeforeSendInterceptor(pluginId: string, interceptor: MessageInterceptor): void;
|
||||
/** Add a receive interceptor for a plugin. */
|
||||
addReceiveInterceptor(pluginId: string, interceptor: MessageInterceptor): void;
|
||||
/** Run a message through all before-send interceptors in registration order. */
|
||||
processBeforeSend(msg: MessageContext): Promise<MessageContext>;
|
||||
/** Run a message through all receive interceptors in registration order. */
|
||||
processReceive(msg: MessageContext): Promise<MessageContext>;
|
||||
/** Register a custom renderer contributed by a plugin. */
|
||||
registerRenderer(pluginId: string, type: string, renderer: CustomRenderer): void;
|
||||
/** Remove a renderer by type. */
|
||||
unregisterRenderer(type: string): void;
|
||||
/** Get the renderer for a given type, if any. */
|
||||
getRenderer(type: string): CustomRenderer | undefined;
|
||||
/** Define the settings schema for a plugin and load persisted values. */
|
||||
defineSettings(pluginId: string, schema: SettingsSchema): void;
|
||||
/** Get a plugin setting value. */
|
||||
getPluginSetting<T = unknown>(pluginId: string, key: string): T | undefined;
|
||||
/** Set a plugin setting value and persist it. */
|
||||
setPluginSetting(pluginId: string, key: string, value: unknown): void;
|
||||
/** Get the settings schema for a plugin. */
|
||||
getPluginSettingsSchema(pluginId: string): SettingsSchema | undefined;
|
||||
/** Register a theme contributed by a plugin. */
|
||||
registerTheme(pluginId: string, theme: PluginTheme): void;
|
||||
/** Unregister a theme contributed by a plugin. */
|
||||
unregisterTheme(pluginId: string, themeId: string): void;
|
||||
/** Return all registered plugin themes. */
|
||||
getPluginThemes(): Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
kind: 'light' | 'dark';
|
||||
className: string;
|
||||
}>;
|
||||
/** Track an event handler registered by a plugin. */
|
||||
addEventHandler(pluginId: string, eventType: string, handler: (...args: any[]) => void): void;
|
||||
/** Remove a previously tracked event handler. */
|
||||
removeEventHandler(pluginId: string, eventType: string, handler: (...args: any[]) => void): void;
|
||||
/** Get all tracked handlers for an event type. */
|
||||
getEventHandlers(eventType: string): Array<{
|
||||
pluginId: string;
|
||||
handler: (...args: any[]) => void;
|
||||
}>;
|
||||
/** Track a timer ID for a plugin so it can be cleared on unload. */
|
||||
addTimer(pluginId: string, timerId: number): void;
|
||||
/** Remove a timer ID from tracking (e.g. after manual clearInterval). */
|
||||
removeTimer(pluginId: string, timerId: number): void;
|
||||
/** Append a log entry from a plugin. */
|
||||
addLog(pluginId: string, level: 'log' | 'warn' | 'error', args: unknown[]): void;
|
||||
/** Return log entries, optionally filtered to a specific plugin. */
|
||||
getLogs(pluginId?: string): PluginLogEntry[];
|
||||
/** Clear log entries, optionally scoped to a specific plugin. */
|
||||
clearLogs(pluginId?: string): void;
|
||||
/** Get the public exports of a loaded plugin. */
|
||||
getPluginExports(pluginId: string): unknown;
|
||||
/** Unload the current plugin instance and load a new one in-place. */
|
||||
reloadPlugin(pluginId: string, newPlugin: Plugin, newContext: PluginContext): Promise<void>;
|
||||
/** Unload all plugins and clear all registry state. */
|
||||
clear(): void;
|
||||
}
|
||||
//# sourceMappingURL=PluginRegistry.d.ts.map
|
||||
1
dist/PluginRegistry.d.ts.map
vendored
Normal file
1
dist/PluginRegistry.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../src/PluginRegistry.ts"],"names":[],"mappings":"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"}
|
||||
335
dist/PluginRegistry.js
vendored
Normal file
335
dist/PluginRegistry.js
vendored
Normal file
@@ -0,0 +1,335 @@
|
||||
import { MemoryStorage } from './interfaces.js';
|
||||
import { generateThemeCSS } from './theme-css.js';
|
||||
/**
|
||||
* Central registry that manages all loaded plugins and their side-effects.
|
||||
* Create a single instance and share it across your application.
|
||||
*/
|
||||
export class PluginRegistry {
|
||||
constructor(options = {}) {
|
||||
this.plugins = new Map();
|
||||
this.commands = new Map();
|
||||
this.beforeSendInterceptors = [];
|
||||
this.receiveInterceptors = [];
|
||||
this.renderers = new Map();
|
||||
this.settingsSchemas = new Map();
|
||||
this.pluginSettings = new Map();
|
||||
this.matrixHandlers = new Map();
|
||||
this.timers = new Map();
|
||||
this.themes = new Map();
|
||||
this.logs = [];
|
||||
this.maxLogs = 1000;
|
||||
this.storage = options.storage ?? new MemoryStorage();
|
||||
this.onThemeRegistered = options.onThemeRegistered;
|
||||
this.onThemeUnregistered = options.onThemeUnregistered;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Plugin lifecycle
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Register a plugin and its context. Called after the host has loaded the module. */
|
||||
registerPlugin(id, plugin, context) {
|
||||
if (this.plugins.has(id)) {
|
||||
console.warn(`[PluginRegistry] Plugin ${id} is already registered`);
|
||||
return;
|
||||
}
|
||||
this.plugins.set(id, { plugin, context });
|
||||
this.timers.set(id, []);
|
||||
}
|
||||
/** Unregister a plugin, calling its onUnload hook and cleaning up all side-effects. */
|
||||
async unregisterPlugin(id) {
|
||||
const entry = this.plugins.get(id);
|
||||
if (!entry)
|
||||
return;
|
||||
if (entry.plugin.onUnload) {
|
||||
try {
|
||||
await entry.plugin.onUnload();
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`[PluginRegistry] Error unloading plugin ${id}:`, err);
|
||||
}
|
||||
}
|
||||
for (const [cmdName, cmd] of this.commands.entries()) {
|
||||
if (cmd.pluginId === id)
|
||||
this.commands.delete(cmdName);
|
||||
}
|
||||
this.beforeSendInterceptors = this.beforeSendInterceptors.filter(i => i.pluginId !== id);
|
||||
this.receiveInterceptors = this.receiveInterceptors.filter(i => i.pluginId !== id);
|
||||
for (const [type, renderer] of this.renderers.entries()) {
|
||||
if (renderer.pluginId === id)
|
||||
this.renderers.delete(type);
|
||||
}
|
||||
for (const [themeId, theme] of this.themes.entries()) {
|
||||
if (theme.pluginId === id) {
|
||||
this.onThemeUnregistered?.(themeId);
|
||||
this.themes.delete(themeId);
|
||||
}
|
||||
}
|
||||
const timerIds = this.timers.get(id) ?? [];
|
||||
timerIds.forEach(timerId => clearInterval(timerId));
|
||||
this.timers.delete(id);
|
||||
for (const [eventType, handlers] of this.matrixHandlers.entries()) {
|
||||
const filtered = handlers.filter(h => h.pluginId !== id);
|
||||
if (filtered.length === 0) {
|
||||
this.matrixHandlers.delete(eventType);
|
||||
}
|
||||
else {
|
||||
this.matrixHandlers.set(eventType, filtered);
|
||||
}
|
||||
}
|
||||
this.plugins.delete(id);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Commands
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Register a command contributed by a plugin. */
|
||||
registerCommand(pluginId, command) {
|
||||
if (this.commands.has(command.name)) {
|
||||
console.warn(`[PluginRegistry] Command /${command.name} already exists`);
|
||||
return;
|
||||
}
|
||||
this.commands.set(command.name, { pluginId, command });
|
||||
}
|
||||
/** Remove a registered command by name. */
|
||||
unregisterCommand(name) {
|
||||
this.commands.delete(name);
|
||||
}
|
||||
/** Execute a command by name, passing raw argument string. */
|
||||
async executeCommand(name, rawArgs) {
|
||||
const cmd = this.commands.get(name);
|
||||
if (!cmd)
|
||||
throw new Error(`Command /${name} not found`);
|
||||
const args = this.parseCommandArgs(cmd.command, rawArgs);
|
||||
const entry = this.plugins.get(cmd.pluginId);
|
||||
if (!entry)
|
||||
throw new Error(`Plugin ${cmd.pluginId} not loaded`);
|
||||
return await cmd.command.run(args, entry.context);
|
||||
}
|
||||
parseCommandArgs(command, rawArgs) {
|
||||
if (!command.args || command.args.length === 0)
|
||||
return {};
|
||||
const parts = rawArgs.trim().split(/\s+/);
|
||||
const result = {};
|
||||
command.args.forEach((arg, index) => {
|
||||
const argName = typeof arg === 'string' ? arg : arg.name;
|
||||
result[argName] = parts[index];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/** Return all registered commands. */
|
||||
getCommands() {
|
||||
return Array.from(this.commands.entries()).map(([name, data]) => ({ name, ...data }));
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Message interceptors
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Add a before-send interceptor for a plugin. */
|
||||
addBeforeSendInterceptor(pluginId, interceptor) {
|
||||
this.beforeSendInterceptors.push({ pluginId, interceptor });
|
||||
}
|
||||
/** Add a receive interceptor for a plugin. */
|
||||
addReceiveInterceptor(pluginId, interceptor) {
|
||||
this.receiveInterceptors.push({ pluginId, interceptor });
|
||||
}
|
||||
/** Run a message through all before-send interceptors in registration order. */
|
||||
async processBeforeSend(msg) {
|
||||
let processed = { ...msg };
|
||||
for (const { interceptor } of this.beforeSendInterceptors) {
|
||||
try {
|
||||
await interceptor(processed);
|
||||
}
|
||||
catch (err) {
|
||||
console.error('[PluginRegistry] Error in beforeSend interceptor:', err);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
/** Run a message through all receive interceptors in registration order. */
|
||||
async processReceive(msg) {
|
||||
let processed = { ...msg };
|
||||
for (const { interceptor } of this.receiveInterceptors) {
|
||||
try {
|
||||
await interceptor(processed);
|
||||
}
|
||||
catch (err) {
|
||||
console.error('[PluginRegistry] Error in receive interceptor:', err);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Renderers
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Register a custom renderer contributed by a plugin. */
|
||||
registerRenderer(pluginId, type, renderer) {
|
||||
this.renderers.set(type, { pluginId, renderer });
|
||||
}
|
||||
/** Remove a renderer by type. */
|
||||
unregisterRenderer(type) {
|
||||
this.renderers.delete(type);
|
||||
}
|
||||
/** Get the renderer for a given type, if any. */
|
||||
getRenderer(type) {
|
||||
return this.renderers.get(type)?.renderer;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Settings
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Define the settings schema for a plugin and load persisted values. */
|
||||
defineSettings(pluginId, schema) {
|
||||
this.settingsSchemas.set(pluginId, schema);
|
||||
const stored = this.storage.getItem(`plugin:${pluginId}:settings`);
|
||||
if (stored) {
|
||||
try {
|
||||
this.pluginSettings.set(pluginId, JSON.parse(stored));
|
||||
}
|
||||
catch (err) {
|
||||
console.error(`[PluginRegistry] Failed to load settings for ${pluginId}:`, err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const defaults = {};
|
||||
for (const [key, def] of Object.entries(schema)) {
|
||||
if (def.default !== undefined)
|
||||
defaults[key] = def.default;
|
||||
}
|
||||
this.pluginSettings.set(pluginId, defaults);
|
||||
}
|
||||
}
|
||||
/** Get a plugin setting value. */
|
||||
getPluginSetting(pluginId, key) {
|
||||
return this.pluginSettings.get(pluginId)?.[key];
|
||||
}
|
||||
/** Set a plugin setting value and persist it. */
|
||||
setPluginSetting(pluginId, key, value) {
|
||||
const settings = this.pluginSettings.get(pluginId) ?? {};
|
||||
settings[key] = value;
|
||||
this.pluginSettings.set(pluginId, settings);
|
||||
this.storage.setItem(`plugin:${pluginId}:settings`, JSON.stringify(settings));
|
||||
}
|
||||
/** Get the settings schema for a plugin. */
|
||||
getPluginSettingsSchema(pluginId) {
|
||||
return this.settingsSchemas.get(pluginId);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Themes
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Register a theme contributed by a plugin. */
|
||||
registerTheme(pluginId, theme) {
|
||||
const fullId = `plugin-${pluginId}-${theme.id}`;
|
||||
if (this.themes.has(fullId)) {
|
||||
console.warn(`[PluginRegistry] Theme ${fullId} already registered`);
|
||||
return;
|
||||
}
|
||||
const css = generateThemeCSS(fullId, theme);
|
||||
this.themes.set(fullId, { pluginId, theme: { ...theme, id: fullId } });
|
||||
this.onThemeRegistered?.(fullId, fullId, css);
|
||||
console.log(`[PluginRegistry] Theme registered: ${fullId}`);
|
||||
}
|
||||
/** Unregister a theme contributed by a plugin. */
|
||||
unregisterTheme(pluginId, themeId) {
|
||||
const fullId = `plugin-${pluginId}-${themeId}`;
|
||||
if (this.themes.has(fullId)) {
|
||||
this.onThemeUnregistered?.(fullId);
|
||||
this.themes.delete(fullId);
|
||||
}
|
||||
}
|
||||
/** Return all registered plugin themes. */
|
||||
getPluginThemes() {
|
||||
return Array.from(this.themes.values()).map(({ theme }) => ({
|
||||
id: theme.id,
|
||||
name: theme.name,
|
||||
kind: theme.kind,
|
||||
className: theme.id,
|
||||
}));
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Event handlers (generic — wire to Matrix, socket.io, etc.)
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Track an event handler registered by a plugin. */
|
||||
addEventHandler(pluginId, eventType, handler) {
|
||||
if (!this.matrixHandlers.has(eventType)) {
|
||||
this.matrixHandlers.set(eventType, []);
|
||||
}
|
||||
this.matrixHandlers.get(eventType).push({ pluginId, handler });
|
||||
}
|
||||
/** Remove a previously tracked event handler. */
|
||||
removeEventHandler(pluginId, eventType, handler) {
|
||||
const handlers = this.matrixHandlers.get(eventType);
|
||||
if (handlers) {
|
||||
const filtered = handlers.filter(h => h.pluginId !== pluginId || h.handler !== handler);
|
||||
this.matrixHandlers.set(eventType, filtered);
|
||||
}
|
||||
}
|
||||
/** Get all tracked handlers for an event type. */
|
||||
getEventHandlers(eventType) {
|
||||
return this.matrixHandlers.get(eventType) ?? [];
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timers
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Track a timer ID for a plugin so it can be cleared on unload. */
|
||||
addTimer(pluginId, timerId) {
|
||||
const timers = this.timers.get(pluginId) ?? [];
|
||||
timers.push(timerId);
|
||||
this.timers.set(pluginId, timers);
|
||||
}
|
||||
/** Remove a timer ID from tracking (e.g. after manual clearInterval). */
|
||||
removeTimer(pluginId, timerId) {
|
||||
const timers = this.timers.get(pluginId) ?? [];
|
||||
this.timers.set(pluginId, timers.filter(id => id !== timerId));
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Logging
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Append a log entry from a plugin. */
|
||||
addLog(pluginId, level, args) {
|
||||
this.logs.push({ pluginId, level, timestamp: Date.now(), args });
|
||||
if (this.logs.length > this.maxLogs) {
|
||||
this.logs = this.logs.slice(-this.maxLogs);
|
||||
}
|
||||
}
|
||||
/** Return log entries, optionally filtered to a specific plugin. */
|
||||
getLogs(pluginId) {
|
||||
return pluginId ? this.logs.filter(l => l.pluginId === pluginId) : [...this.logs];
|
||||
}
|
||||
/** Clear log entries, optionally scoped to a specific plugin. */
|
||||
clearLogs(pluginId) {
|
||||
this.logs = pluginId ? this.logs.filter(l => l.pluginId !== pluginId) : [];
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Plugin exports (require())
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Get the public exports of a loaded plugin. */
|
||||
getPluginExports(pluginId) {
|
||||
return this.plugins.get(pluginId)?.plugin.exports;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Hot reload
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Unload the current plugin instance and load a new one in-place. */
|
||||
async reloadPlugin(pluginId, newPlugin, newContext) {
|
||||
await this.unregisterPlugin(pluginId);
|
||||
this.registerPlugin(pluginId, newPlugin, newContext);
|
||||
await newPlugin.onLoad(newContext);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Teardown
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Unload all plugins and clear all registry state. */
|
||||
clear() {
|
||||
for (const pluginId of this.plugins.keys()) {
|
||||
this.unregisterPlugin(pluginId).catch(err => {
|
||||
console.error(`[PluginRegistry] Error clearing plugin ${pluginId}:`, err);
|
||||
});
|
||||
}
|
||||
this.plugins.clear();
|
||||
this.commands.clear();
|
||||
this.beforeSendInterceptors = [];
|
||||
this.receiveInterceptors = [];
|
||||
this.renderers.clear();
|
||||
this.settingsSchemas.clear();
|
||||
this.matrixHandlers.clear();
|
||||
this.timers.clear();
|
||||
this.logs = [];
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=PluginRegistry.js.map
|
||||
1
dist/PluginRegistry.js.map
vendored
Normal file
1
dist/PluginRegistry.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11
dist/index.d.ts
vendored
Normal file
11
dist/index.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export type { IPluginStorage, IPluginEventClient, } from './interfaces.js';
|
||||
export { MemoryStorage } from './interfaces.js';
|
||||
export type { PluginMetadata, PluginIndex, InstalledPlugin, } from './types.js';
|
||||
export { PluginTab } from './types.js';
|
||||
export type { ThemeColorGroup, ThemePaletteGroup, PluginThemeColors, PluginTheme, CommandArg, PluginCommand, MessageInterceptor, MessageContext, CustomRenderer, SettingDefinition, SettingsSchema, NotificationOptions, PluginContext, PluginSettingsSection, UILocation, Plugin, PluginLogEntry, } from './PluginInterfaces.js';
|
||||
export { generateThemeCSS } from './theme-css.js';
|
||||
export { PluginRegistry } from './PluginRegistry.js';
|
||||
export type { PluginRegistryOptions } from './PluginRegistry.js';
|
||||
export { createPluginContext } from './PluginContext.js';
|
||||
export type { PluginContextOptions } from './PluginContext.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
dist/index.d.ts.map
vendored
Normal file
1
dist/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,YAAY,EACV,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,MAAM,EACN,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
||||
6
dist/index.js
vendored
Normal file
6
dist/index.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export { MemoryStorage } from './interfaces.js';
|
||||
export { PluginTab } from './types.js';
|
||||
export { generateThemeCSS } from './theme-css.js';
|
||||
export { PluginRegistry } from './PluginRegistry.js';
|
||||
export { createPluginContext } from './PluginContext.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/index.js.map
vendored
Normal file
1
dist/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOhD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAsBvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
||||
27
dist/interfaces.d.ts
vendored
Normal file
27
dist/interfaces.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Minimal key-value storage adapter.
|
||||
* Pass `localStorage` in browser environments, or any Map-backed adapter for Node.js / tests.
|
||||
*/
|
||||
export interface IPluginStorage {
|
||||
getItem(key: string): string | null;
|
||||
setItem(key: string, value: string): void;
|
||||
}
|
||||
/**
|
||||
* Minimal event emitter interface for the plugin events API.
|
||||
* Compatible with Node.js EventEmitter, matrix-js-sdk MatrixClient, and similar clients.
|
||||
*/
|
||||
export interface IPluginEventClient {
|
||||
on(event: string, handler: (...args: any[]) => void): void;
|
||||
off(event: string, handler: (...args: any[]) => void): void;
|
||||
}
|
||||
/**
|
||||
* In-memory storage implementation — used as the default when no storage adapter is provided.
|
||||
*/
|
||||
export declare class MemoryStorage implements IPluginStorage {
|
||||
private readonly store;
|
||||
/** @inheritdoc */
|
||||
getItem(key: string): string | null;
|
||||
/** @inheritdoc */
|
||||
setItem(key: string, value: string): void;
|
||||
}
|
||||
//# sourceMappingURL=interfaces.d.ts.map
|
||||
1
dist/interfaces.d.ts.map
vendored
Normal file
1
dist/interfaces.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7D;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,kBAAkB;IAClB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,kBAAkB;IAClB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAG1C"}
|
||||
17
dist/interfaces.js
vendored
Normal file
17
dist/interfaces.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* In-memory storage implementation — used as the default when no storage adapter is provided.
|
||||
*/
|
||||
export class MemoryStorage {
|
||||
constructor() {
|
||||
this.store = new Map();
|
||||
}
|
||||
/** @inheritdoc */
|
||||
getItem(key) {
|
||||
return this.store.get(key) ?? null;
|
||||
}
|
||||
/** @inheritdoc */
|
||||
setItem(key, value) {
|
||||
this.store.set(key, value);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=interfaces.js.map
|
||||
1
dist/interfaces.js.map
vendored
Normal file
1
dist/interfaces.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAkBA;;GAEG;AACH,MAAM,OAAO,aAAa;IAA1B;QACmB,UAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAWrD,CAAC;IATC,kBAAkB;IAClB,OAAO,CAAC,GAAW;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACrC,CAAC;IAED,kBAAkB;IAClB,OAAO,CAAC,GAAW,EAAE,KAAa;QAChC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF"}
|
||||
11
dist/theme-css.d.ts
vendored
Normal file
11
dist/theme-css.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { PluginTheme } from './PluginInterfaces.js';
|
||||
/**
|
||||
* Generates a CSS block that overrides the folds vanilla-extract design tokens
|
||||
* for a given theme class name.
|
||||
*
|
||||
* NOTE: The `--oq6d07*` variable names are stable compiled identifiers for the
|
||||
* version of the `folds` design system used in Paarrot. They will need updating
|
||||
* if folds is upgraded to a version that recompiles its theme contract.
|
||||
*/
|
||||
export declare function generateThemeCSS(className: string, theme: PluginTheme): string;
|
||||
//# sourceMappingURL=theme-css.d.ts.map
|
||||
1
dist/theme-css.d.ts.map
vendored
Normal file
1
dist/theme-css.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"theme-css.d.ts","sourceRoot":"","sources":["../src/theme-css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAsF9E"}
|
||||
84
dist/theme-css.js
vendored
Normal file
84
dist/theme-css.js
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Generates a CSS block that overrides the folds vanilla-extract design tokens
|
||||
* for a given theme class name.
|
||||
*
|
||||
* NOTE: The `--oq6d07*` variable names are stable compiled identifiers for the
|
||||
* version of the `folds` design system used in Paarrot. They will need updating
|
||||
* if folds is upgraded to a version that recompiles its theme contract.
|
||||
*/
|
||||
export function generateThemeCSS(className, theme) {
|
||||
const { background: bg, surface: sf, surfaceVariant: sv, primary: pr, secondary: sc, success: su, warning: wa, critical: cr, other: ot, } = theme.colors;
|
||||
const vars = `
|
||||
.${className} {
|
||||
--oq6d070: ${bg.container};
|
||||
--oq6d071: ${bg.containerHover};
|
||||
--oq6d072: ${bg.containerActive};
|
||||
--oq6d073: ${bg.containerLine};
|
||||
--oq6d074: ${bg.onContainer};
|
||||
--oq6d075: ${sf.container};
|
||||
--oq6d076: ${sf.containerHover};
|
||||
--oq6d077: ${sf.containerActive};
|
||||
--oq6d078: ${sf.containerLine};
|
||||
--oq6d079: ${sf.onContainer};
|
||||
--oq6d07a: ${sv.container};
|
||||
--oq6d07b: ${sv.containerHover};
|
||||
--oq6d07c: ${sv.containerActive};
|
||||
--oq6d07d: ${sv.containerLine};
|
||||
--oq6d07e: ${sv.onContainer};
|
||||
--oq6d07f: ${pr.main};
|
||||
--oq6d07g: ${pr.mainHover};
|
||||
--oq6d07h: ${pr.mainActive};
|
||||
--oq6d07i: ${pr.mainLine};
|
||||
--oq6d07j: ${pr.onMain};
|
||||
--oq6d07k: ${pr.container};
|
||||
--oq6d07l: ${pr.containerHover};
|
||||
--oq6d07m: ${pr.containerActive};
|
||||
--oq6d07n: ${pr.containerLine};
|
||||
--oq6d07o: ${pr.onContainer};
|
||||
--oq6d07p: ${sc.main};
|
||||
--oq6d07q: ${sc.mainHover};
|
||||
--oq6d07r: ${sc.mainActive};
|
||||
--oq6d07s: ${sc.mainLine};
|
||||
--oq6d07t: ${sc.onMain};
|
||||
--oq6d07u: ${sc.container};
|
||||
--oq6d07v: ${sc.containerHover};
|
||||
--oq6d07w: ${sc.containerActive};
|
||||
--oq6d07x: ${sc.containerLine};
|
||||
--oq6d07y: ${sc.onContainer};
|
||||
--oq6d07z: ${su.main};
|
||||
--oq6d0710: ${su.mainHover};
|
||||
--oq6d0711: ${su.mainActive};
|
||||
--oq6d0712: ${su.mainLine};
|
||||
--oq6d0713: ${su.onMain};
|
||||
--oq6d0714: ${su.container};
|
||||
--oq6d0715: ${su.containerHover};
|
||||
--oq6d0716: ${su.containerActive};
|
||||
--oq6d0717: ${su.containerLine};
|
||||
--oq6d0718: ${su.onContainer};
|
||||
--oq6d0719: ${wa.main};
|
||||
--oq6d071a: ${wa.mainHover};
|
||||
--oq6d071b: ${wa.mainActive};
|
||||
--oq6d071c: ${wa.mainLine};
|
||||
--oq6d071d: ${wa.onMain};
|
||||
--oq6d071e: ${wa.container};
|
||||
--oq6d071f: ${wa.containerHover};
|
||||
--oq6d071g: ${wa.containerActive};
|
||||
--oq6d071h: ${wa.containerLine};
|
||||
--oq6d071i: ${wa.onContainer};
|
||||
--oq6d071j: ${cr.main};
|
||||
--oq6d071k: ${cr.mainHover};
|
||||
--oq6d071l: ${cr.mainActive};
|
||||
--oq6d071m: ${cr.mainLine};
|
||||
--oq6d071n: ${cr.onMain};
|
||||
--oq6d071o: ${cr.container};
|
||||
--oq6d071p: ${cr.containerHover};
|
||||
--oq6d071q: ${cr.containerActive};
|
||||
--oq6d071r: ${cr.containerLine};
|
||||
--oq6d071s: ${cr.onContainer};
|
||||
--oq6d071t: ${ot.focusRing};
|
||||
--oq6d071u: ${ot.shadow};
|
||||
--oq6d071v: ${ot.overlay};
|
||||
}`;
|
||||
return theme.extraCss ? `${vars}\n${theme.extraCss}` : vars;
|
||||
}
|
||||
//# sourceMappingURL=theme-css.js.map
|
||||
1
dist/theme-css.js.map
vendored
Normal file
1
dist/theme-css.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"theme-css.js","sourceRoot":"","sources":["../src/theme-css.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,KAAkB;IACpE,MAAM,EACJ,UAAU,EAAE,EAAE,EACd,OAAO,EAAE,EAAE,EACX,cAAc,EAAE,EAAE,EAClB,OAAO,EAAE,EAAE,EACX,SAAS,EAAE,EAAE,EACb,OAAO,EAAE,EAAE,EACX,OAAO,EAAE,EAAE,EACX,QAAQ,EAAE,EAAE,EACZ,KAAK,EAAE,EAAE,GACV,GAAG,KAAK,CAAC,MAAM,CAAC;IAEjB,MAAM,IAAI,GAAG;KACV,SAAS;iBACG,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,cAAc;iBACjB,EAAE,CAAC,eAAe;iBAClB,EAAE,CAAC,aAAa;iBAChB,EAAE,CAAC,WAAW;iBACd,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,cAAc;iBACjB,EAAE,CAAC,eAAe;iBAClB,EAAE,CAAC,aAAa;iBAChB,EAAE,CAAC,WAAW;iBACd,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,cAAc;iBACjB,EAAE,CAAC,eAAe;iBAClB,EAAE,CAAC,aAAa;iBAChB,EAAE,CAAC,WAAW;iBACd,EAAE,CAAC,IAAI;iBACP,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,UAAU;iBACb,EAAE,CAAC,QAAQ;iBACX,EAAE,CAAC,MAAM;iBACT,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,cAAc;iBACjB,EAAE,CAAC,eAAe;iBAClB,EAAE,CAAC,aAAa;iBAChB,EAAE,CAAC,WAAW;iBACd,EAAE,CAAC,IAAI;iBACP,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,UAAU;iBACb,EAAE,CAAC,QAAQ;iBACX,EAAE,CAAC,MAAM;iBACT,EAAE,CAAC,SAAS;iBACZ,EAAE,CAAC,cAAc;iBACjB,EAAE,CAAC,eAAe;iBAClB,EAAE,CAAC,aAAa;iBAChB,EAAE,CAAC,WAAW;iBACd,EAAE,CAAC,IAAI;kBACN,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,UAAU;kBACb,EAAE,CAAC,QAAQ;kBACX,EAAE,CAAC,MAAM;kBACT,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,cAAc;kBACjB,EAAE,CAAC,eAAe;kBAClB,EAAE,CAAC,aAAa;kBAChB,EAAE,CAAC,WAAW;kBACd,EAAE,CAAC,IAAI;kBACP,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,UAAU;kBACb,EAAE,CAAC,QAAQ;kBACX,EAAE,CAAC,MAAM;kBACT,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,cAAc;kBACjB,EAAE,CAAC,eAAe;kBAClB,EAAE,CAAC,aAAa;kBAChB,EAAE,CAAC,WAAW;kBACd,EAAE,CAAC,IAAI;kBACP,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,UAAU;kBACb,EAAE,CAAC,QAAQ;kBACX,EAAE,CAAC,MAAM;kBACT,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,cAAc;kBACjB,EAAE,CAAC,eAAe;kBAClB,EAAE,CAAC,aAAa;kBAChB,EAAE,CAAC,WAAW;kBACd,EAAE,CAAC,SAAS;kBACZ,EAAE,CAAC,MAAM;kBACT,EAAE,CAAC,OAAO;IACxB,CAAC;IAEH,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}
|
||||
37
dist/types.d.ts
vendored
Normal file
37
dist/types.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Plugin metadata as returned by the marketplace / plugin directory.
|
||||
*/
|
||||
export interface PluginMetadata {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
description: string;
|
||||
author: string;
|
||||
repository: string;
|
||||
thumbnail: string;
|
||||
downloadUrl: string;
|
||||
homepage: string;
|
||||
tags: string[];
|
||||
addedDate: string;
|
||||
}
|
||||
/**
|
||||
* Plugin directory index response from the marketplace.
|
||||
*/
|
||||
export interface PluginIndex {
|
||||
version: string;
|
||||
updatedAt: string;
|
||||
plugins: string[];
|
||||
}
|
||||
/**
|
||||
* An installed plugin — extends metadata with runtime state.
|
||||
*/
|
||||
export interface InstalledPlugin extends PluginMetadata {
|
||||
installedDate: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
/** Tab identifiers for the plugin manager UI. */
|
||||
export declare enum PluginTab {
|
||||
Marketplace = "marketplace",
|
||||
Installed = "installed"
|
||||
}
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
dist/types.d.ts.map
vendored
Normal file
1
dist/types.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,iDAAiD;AACjD,oBAAY,SAAS;IACnB,WAAW,gBAAgB;IAC3B,SAAS,cAAc;CACxB"}
|
||||
7
dist/types.js
vendored
Normal file
7
dist/types.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/** Tab identifiers for the plugin manager UI. */
|
||||
export var PluginTab;
|
||||
(function (PluginTab) {
|
||||
PluginTab["Marketplace"] = "marketplace";
|
||||
PluginTab["Installed"] = "installed";
|
||||
})(PluginTab || (PluginTab = {}));
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
dist/types.js.map
vendored
Normal file
1
dist/types.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkCA,iDAAiD;AACjD,MAAM,CAAN,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,wCAA2B,CAAA;IAC3B,oCAAuB,CAAA;AACzB,CAAC,EAHW,SAAS,KAAT,SAAS,QAGpB"}
|
||||
Reference in New Issue
Block a user