@embedpdf/plugin-commands 2.0.0-next.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/LICENSE +21 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +316 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions.d.ts +25 -0
- package/dist/lib/commands-plugin.d.ts +31 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/manifest.d.ts +4 -0
- package/dist/lib/reducer.d.ts +5 -0
- package/dist/lib/types.d.ts +98 -0
- package/dist/preact/adapter.d.ts +5 -0
- package/dist/preact/core.d.ts +1 -0
- package/dist/preact/index.cjs +2 -0
- package/dist/preact/index.cjs.map +1 -0
- package/dist/preact/index.d.ts +1 -0
- package/dist/preact/index.js +89 -0
- package/dist/preact/index.js.map +1 -0
- package/dist/react/adapter.d.ts +2 -0
- package/dist/react/core.d.ts +1 -0
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +88 -0
- package/dist/react/index.js.map +1 -0
- package/dist/shared/components/index.d.ts +1 -0
- package/dist/shared/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared/hooks/index.d.ts +1 -0
- package/dist/shared/hooks/use-commands.d.ts +23 -0
- package/dist/shared/index.d.ts +4 -0
- package/dist/shared/utils/index.d.ts +1 -0
- package/dist/shared/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-preact/components/index.d.ts +1 -0
- package/dist/shared-preact/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared-preact/hooks/index.d.ts +1 -0
- package/dist/shared-preact/hooks/use-commands.d.ts +23 -0
- package/dist/shared-preact/index.d.ts +4 -0
- package/dist/shared-preact/utils/index.d.ts +1 -0
- package/dist/shared-preact/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-react/components/index.d.ts +1 -0
- package/dist/shared-react/components/keyboard-shortcuts.d.ts +6 -0
- package/dist/shared-react/hooks/index.d.ts +1 -0
- package/dist/shared-react/hooks/use-commands.d.ts +23 -0
- package/dist/shared-react/index.d.ts +4 -0
- package/dist/shared-react/utils/index.d.ts +1 -0
- package/dist/shared-react/utils/keyboard-handler.d.ts +10 -0
- package/dist/shared-vue/utils/index.d.ts +1 -0
- package/dist/shared-vue/utils/keyboard-handler.d.ts +10 -0
- package/dist/svelte/components/KeyboardShortcuts.svelte.d.ts +18 -0
- package/dist/svelte/components/index.d.ts +1 -0
- package/dist/svelte/hooks/index.d.ts +1 -0
- package/dist/svelte/hooks/use-commands.svelte.d.ts +21 -0
- package/dist/svelte/index.cjs +2 -0
- package/dist/svelte/index.cjs.map +1 -0
- package/dist/svelte/index.d.ts +4 -0
- package/dist/svelte/index.js +90 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/vue/components/index.d.ts +1 -0
- package/dist/vue/components/keyboard-shortcuts.vue.d.ts +3 -0
- package/dist/vue/hooks/index.d.ts +1 -0
- package/dist/vue/hooks/use-commands.d.ts +46 -0
- package/dist/vue/index.cjs +2 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.ts +4 -0
- package/dist/vue/index.js +90 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +82 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 CloudPDF
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t="commands",s={id:t,name:"Commands Plugin",version:"1.0.0",provides:["commands"],requires:[],optional:["i18n"],defaultConfig:{enabled:!0,commands:{}}},o=class extends e.BasePlugin{constructor(t,s,o){super(t,s),this.commands=new Map,this.i18n=null,this.shortcutMap=new Map,this.commandExecuted$=e.createEmitter(),this.commandStateChanged$=e.createEmitter(),this.shortcutExecuted$=e.createEmitter(),this.previousStates=new Map;const i=s.getPlugin("i18n");this.i18n=(null==i?void 0:i.provides())??null,Object.values(o.commands).forEach(e=>{this.registerCommand(e)}),this.registry.getStore().subscribe((e,t)=>{this.onGlobalStoreChange(t)})}onDocumentClosed(e){this.previousStates.delete(e),this.logger.debug("CommandsPlugin","DocumentClosed",`Cleaned up command state cache for document: ${e}`)}async initialize(){this.logger.info("CommandsPlugin","Initialize","Commands plugin initialized")}async destroy(){this.commandExecuted$.clear(),this.commandStateChanged$.clear(),this.shortcutExecuted$.clear(),this.commands.clear(),this.shortcutMap.clear(),this.previousStates.clear(),super.destroy()}buildCapability(){return{resolve:(e,t)=>this.resolve(e,t),execute:(e,t,s="ui")=>this.execute(e,t,s),getAllCommands:e=>this.getAllCommands(e),getCommandsByCategory:(e,t)=>this.getCommandsByCategory(e,t),getCommandByShortcut:e=>this.getCommandByShortcut(e),getAllShortcuts:()=>new Map(this.shortcutMap),forDocument:e=>this.createCommandScope(e),registerCommand:e=>this.registerCommand(e),unregisterCommand:e=>this.unregisterCommand(e),onCommandExecuted:this.commandExecuted$.on,onCommandStateChanged:this.commandStateChanged$.on,onShortcutExecuted:this.shortcutExecuted$.on}}createCommandScope(e){return{resolve:t=>this.resolve(t,e),execute:(t,s="ui")=>this.execute(t,e,s),getAllCommands:()=>this.getAllCommands(e),getCommandsByCategory:t=>this.getCommandsByCategory(t,e),onCommandStateChanged:t=>this.commandStateChanged$.on(s=>{if(s.documentId===e){const{documentId:e,...o}=s;t(o)}})}}resolve(e,t){const s=t??this.getActiveDocumentId(),o=this.commands.get(e);if(!o)throw new Error(`Command not found: ${e}`);const i=this.registry.getStore().getState(),n=this.resolveLabel(o,i,s),a=o.shortcuts?Array.isArray(o.shortcuts)?o.shortcuts:[o.shortcuts]:void 0;return{id:o.id,label:n,icon:this.resolveDynamic(o.icon,i,s),iconProps:this.resolveDynamic(o.iconProps,i,s),active:this.resolveDynamic(o.active,i,s)??!1,disabled:this.resolveDynamic(o.disabled,i,s)??!1,visible:this.resolveDynamic(o.visible,i,s)??!0,shortcuts:a,shortcutLabel:o.shortcutLabel,category:o.category,description:o.description,execute:()=>o.action({registry:this.registry,state:i,documentId:s})}}resolveLabel(e,t,s){if(e.labelKey&&this.i18n){const o=this.resolveDynamic(e.labelParams,t,s);return this.i18n.t(e.labelKey,{params:o,documentId:s})}return e.label?e.label:e.id}resolveDynamic(e,t,s){if(void 0!==e)return"function"==typeof e?e({state:t,documentId:s}):e}execute(e,t,s="ui"){const o=t??this.getActiveDocumentId(),i=this.resolve(e,o);i.disabled?this.logger.warn("CommandsPlugin","ExecutionBlocked",`Command '${e}' is disabled for document '${o}'`):i.visible?(i.execute(),this.commandExecuted$.emit({commandId:e,documentId:o,source:s}),this.logger.debug("CommandsPlugin","CommandExecuted",`Command '${e}' executed for document '${o}' (source: ${s})`)):this.logger.warn("CommandsPlugin","ExecutionBlocked",`Command '${e}' is not visible for document '${o}'`)}registerCommand(e){if(this.commands.has(e.id)&&this.logger.warn("CommandsPlugin","CommandOverwrite",`Command '${e.id}' already exists and will be overwritten`),this.commands.set(e.id,e),e.shortcuts){(Array.isArray(e.shortcuts)?e.shortcuts:[e.shortcuts]).forEach(t=>{const s=this.normalizeShortcut(t);this.shortcutMap.set(s,e.id)})}this.logger.debug("CommandsPlugin","CommandRegistered",`Command '${e.id}' registered`)}unregisterCommand(e){const t=this.commands.get(e);if(t){if(t.shortcuts){(Array.isArray(t.shortcuts)?t.shortcuts:[t.shortcuts]).forEach(e=>{const t=this.normalizeShortcut(e);this.shortcutMap.delete(t)})}this.commands.delete(e),this.logger.debug("CommandsPlugin","CommandUnregistered",`Command '${e}' unregistered`)}}getCommandByShortcut(e){const t=this.normalizeShortcut(e),s=this.shortcutMap.get(t);return s?this.commands.get(s)??null:null}normalizeShortcut(e){return e.toLowerCase().split("+").sort().join("+")}getAllCommands(e){const t=e??this.getActiveDocumentId();return Array.from(this.commands.keys()).map(e=>this.resolve(e,t))}getCommandsByCategory(e,t){const s=t??this.getActiveDocumentId();return Array.from(this.commands.values()).filter(t=>t.category===e).map(e=>this.resolve(e.id,s))}onGlobalStoreChange(e){Object.keys(e.core.documents).forEach(t=>{this.detectCommandChanges(t,e)})}detectCommandChanges(t,s){const o=this.previousStates.get(t)??new Map;this.commands.forEach((s,i)=>{const n=this.resolve(i,t),a=o.get(i);if(!a)return void o.set(i,n);const r={};a.active!==n.active&&(r.active=n.active),a.disabled!==n.disabled&&(r.disabled=n.disabled),a.visible!==n.visible&&(r.visible=n.visible),a.label!==n.label&&(r.label=n.label),e.arePropsEqual(a.iconProps,n.iconProps)||(r.iconProps=n.iconProps),Object.keys(r).length>0&&(o.set(i,n),this.commandStateChanged$.emit({commandId:i,documentId:t,changes:r}))}),this.previousStates.set(t,o)}};o.id="commands";let i=o;const n={changedCommands:new Set},a={manifest:s,create:(e,s)=>new i(t,e,s),reducer:(e=n,t)=>{switch(t.type){case"COMMANDS/MARK_CHANGED":{const s=new Set(e.changedCommands);return t.payload.forEach(e=>s.add(e)),{...e,changedCommands:s}}case"COMMANDS/CLEAR_CHANGED":return{...e,changedCommands:new Set};default:return e}},initialState:n};exports.COMMANDS_PLUGIN_ID=t,exports.CommandsPlugin=i,exports.CommandsPluginPackage=a,exports.manifest=s;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/commands-plugin.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { CommandsPluginConfig } from './types';\n\nexport const COMMANDS_PLUGIN_ID = 'commands';\n\nexport const manifest: PluginManifest<CommandsPluginConfig> = {\n id: COMMANDS_PLUGIN_ID,\n name: 'Commands Plugin',\n version: '1.0.0',\n provides: ['commands'],\n requires: [],\n optional: ['i18n'],\n defaultConfig: {\n enabled: true,\n commands: {},\n },\n};\n","import {\n BasePlugin,\n PluginRegistry,\n StoreState,\n createEmitter,\n Listener,\n arePropsEqual,\n} from '@embedpdf/core';\nimport { I18nCapability, I18nPlugin } from '@embedpdf/plugin-i18n';\nimport {\n CommandsCapability,\n CommandsPluginConfig,\n CommandsState,\n Command,\n ResolvedCommand,\n CommandExecutedEvent,\n CommandStateChangedEvent,\n ShortcutExecutedEvent,\n CommandScope,\n Dynamic,\n} from './types';\nimport { CommandsAction } from './actions';\n\nexport class CommandsPlugin extends BasePlugin<\n CommandsPluginConfig,\n CommandsCapability,\n CommandsState,\n CommandsAction\n> {\n static readonly id = 'commands' as const;\n\n private commands = new Map<string, Command>();\n private i18n: I18nCapability | null = null;\n private shortcutMap = new Map<string, string>(); // shortcut -> commandId\n\n private readonly commandExecuted$ = createEmitter<CommandExecutedEvent>();\n private readonly commandStateChanged$ = createEmitter<CommandStateChangedEvent>();\n private readonly shortcutExecuted$ = createEmitter<ShortcutExecutedEvent>();\n\n // Cache previous resolved states per document to detect changes\n private previousStates = new Map<string, Map<string, ResolvedCommand>>();\n\n constructor(id: string, registry: PluginRegistry, config: CommandsPluginConfig) {\n super(id, registry);\n\n // Check if i18n plugin is available (optional dependency)\n const i18nPlugin = registry.getPlugin<I18nPlugin>('i18n');\n this.i18n = i18nPlugin?.provides() ?? null;\n\n // Register all commands from config\n Object.values(config.commands).forEach((command) => {\n this.registerCommand(command);\n });\n\n // Subscribe to global store changes\n this.registry.getStore().subscribe((_action, newState) => {\n this.onGlobalStoreChange(newState);\n });\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Cleanup previous states cache\n this.previousStates.delete(documentId);\n\n this.logger.debug(\n 'CommandsPlugin',\n 'DocumentClosed',\n `Cleaned up command state cache for document: ${documentId}`,\n );\n }\n\n async initialize(): Promise<void> {\n this.logger.info('CommandsPlugin', 'Initialize', 'Commands plugin initialized');\n }\n\n async destroy(): Promise<void> {\n this.commandExecuted$.clear();\n this.commandStateChanged$.clear();\n this.shortcutExecuted$.clear();\n this.commands.clear();\n this.shortcutMap.clear();\n this.previousStates.clear();\n super.destroy();\n }\n\n // ─────────────────────────────────────────────────────────\n // Capability\n // ─────────────────────────────────────────────────────────\n\n protected buildCapability(): CommandsCapability {\n return {\n resolve: (commandId, documentId) => this.resolve(commandId, documentId),\n execute: (commandId, documentId, source = 'ui') =>\n this.execute(commandId, documentId, source),\n getAllCommands: (documentId) => this.getAllCommands(documentId),\n getCommandsByCategory: (category, documentId) =>\n this.getCommandsByCategory(category, documentId),\n getCommandByShortcut: (shortcut) => this.getCommandByShortcut(shortcut),\n getAllShortcuts: () => new Map(this.shortcutMap),\n forDocument: (documentId) => this.createCommandScope(documentId),\n registerCommand: (command) => this.registerCommand(command),\n unregisterCommand: (commandId) => this.unregisterCommand(commandId),\n onCommandExecuted: this.commandExecuted$.on,\n onCommandStateChanged: this.commandStateChanged$.on,\n onShortcutExecuted: this.shortcutExecuted$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Scoping\n // ─────────────────────────────────────────────────────────\n\n private createCommandScope(documentId: string): CommandScope {\n return {\n resolve: (commandId) => this.resolve(commandId, documentId),\n execute: (commandId, source = 'ui') => this.execute(commandId, documentId, source),\n getAllCommands: () => this.getAllCommands(documentId),\n getCommandsByCategory: (category) => this.getCommandsByCategory(category, documentId),\n onCommandStateChanged: (listener: Listener<Omit<CommandStateChangedEvent, 'documentId'>>) =>\n this.commandStateChanged$.on((event) => {\n if (event.documentId === documentId) {\n const { documentId: _, ...rest } = event;\n listener(rest);\n }\n }),\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Resolution\n // ─────────────────────────────────────────────────────────\n\n private resolve(commandId: string, documentId?: string): ResolvedCommand {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n\n const command = this.commands.get(commandId);\n if (!command) {\n throw new Error(`Command not found: ${commandId}`);\n }\n\n const state = this.registry.getStore().getState();\n\n // Resolve label with i18n if available\n const label = this.resolveLabel(command, state, resolvedDocId);\n\n // Resolve shortcuts\n const shortcuts = command.shortcuts\n ? Array.isArray(command.shortcuts)\n ? command.shortcuts\n : [command.shortcuts]\n : undefined;\n\n return {\n id: command.id,\n label,\n icon: this.resolveDynamic(command.icon, state, resolvedDocId),\n iconProps: this.resolveDynamic(command.iconProps, state, resolvedDocId),\n active: this.resolveDynamic(command.active, state, resolvedDocId) ?? false,\n disabled: this.resolveDynamic(command.disabled, state, resolvedDocId) ?? false,\n visible: this.resolveDynamic(command.visible, state, resolvedDocId) ?? true,\n shortcuts,\n shortcutLabel: command.shortcutLabel,\n category: command.category,\n description: command.description,\n execute: () => command.action({ registry: this.registry, state, documentId: resolvedDocId }),\n };\n }\n\n private resolveLabel(command: Command, state: StoreState<any>, documentId: string): string {\n // Priority: labelKey (with i18n) > label (plain string) > id (fallback)\n if (command.labelKey && this.i18n) {\n const params = this.resolveDynamic(command.labelParams, state, documentId);\n return this.i18n.t(command.labelKey, { params, documentId });\n }\n\n if (command.label) {\n return command.label;\n }\n\n return command.id; // Fallback to ID\n }\n\n private resolveDynamic<T>(\n value: Dynamic<any, T> | undefined,\n state: StoreState<any>,\n documentId: string,\n ): T | undefined {\n if (value === undefined) return undefined;\n\n // Check if it's a function (the dynamic evaluator)\n if (typeof value === 'function') {\n return (value as (context: { state: StoreState<any>; documentId: string }) => T)({\n state,\n documentId,\n });\n }\n\n // Otherwise it's the static value\n return value as T;\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Execution\n // ─────────────────────────────────────────────────────────\n\n private execute(\n commandId: string,\n documentId?: string,\n source: 'keyboard' | 'ui' | 'api' = 'ui',\n ): void {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n const resolved = this.resolve(commandId, resolvedDocId);\n\n if (resolved.disabled) {\n this.logger.warn(\n 'CommandsPlugin',\n 'ExecutionBlocked',\n `Command '${commandId}' is disabled for document '${resolvedDocId}'`,\n );\n return;\n }\n\n if (!resolved.visible) {\n this.logger.warn(\n 'CommandsPlugin',\n 'ExecutionBlocked',\n `Command '${commandId}' is not visible for document '${resolvedDocId}'`,\n );\n return;\n }\n\n resolved.execute();\n\n this.commandExecuted$.emit({\n commandId,\n documentId: resolvedDocId,\n source,\n });\n\n this.logger.debug(\n 'CommandsPlugin',\n 'CommandExecuted',\n `Command '${commandId}' executed for document '${resolvedDocId}' (source: ${source})`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Registration\n // ─────────────────────────────────────────────────────────\n\n private registerCommand(command: Command): void {\n if (this.commands.has(command.id)) {\n this.logger.warn(\n 'CommandsPlugin',\n 'CommandOverwrite',\n `Command '${command.id}' already exists and will be overwritten`,\n );\n }\n\n this.commands.set(command.id, command);\n\n // Register shortcuts\n if (command.shortcuts) {\n const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];\n\n shortcuts.forEach((shortcut) => {\n const normalized = this.normalizeShortcut(shortcut);\n this.shortcutMap.set(normalized, command.id);\n });\n }\n\n this.logger.debug('CommandsPlugin', 'CommandRegistered', `Command '${command.id}' registered`);\n }\n\n private unregisterCommand(commandId: string): void {\n const command = this.commands.get(commandId);\n if (!command) return;\n\n // Remove shortcuts\n if (command.shortcuts) {\n const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];\n\n shortcuts.forEach((shortcut) => {\n const normalized = this.normalizeShortcut(shortcut);\n this.shortcutMap.delete(normalized);\n });\n }\n\n this.commands.delete(commandId);\n this.logger.debug(\n 'CommandsPlugin',\n 'CommandUnregistered',\n `Command '${commandId}' unregistered`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Shortcuts\n // ─────────────────────────────────────────────────────────\n\n private getCommandByShortcut(shortcut: string): Command | null {\n const normalized = this.normalizeShortcut(shortcut);\n const commandId = this.shortcutMap.get(normalized);\n return commandId ? (this.commands.get(commandId) ?? null) : null;\n }\n\n private normalizeShortcut(shortcut: string): string {\n // Normalize: \"Ctrl+Shift+A\" -> \"ctrl+shift+a\"\n return shortcut.toLowerCase().split('+').sort().join('+');\n }\n\n // ─────────────────────────────────────────────────────────\n // Query Methods\n // ─────────────────────────────────────────────────────────\n\n private getAllCommands(documentId?: string): ResolvedCommand[] {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n return Array.from(this.commands.keys()).map((id) => this.resolve(id, resolvedDocId));\n }\n\n private getCommandsByCategory(category: string, documentId?: string): ResolvedCommand[] {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n return Array.from(this.commands.values())\n .filter((cmd) => cmd.category === category)\n .map((cmd) => this.resolve(cmd.id, resolvedDocId));\n }\n\n // ─────────────────────────────────────────────────────────\n // State Change Detection\n // ─────────────────────────────────────────────────────────\n\n private onGlobalStoreChange(newState: StoreState<any>): void {\n // Get all documents from core state\n const documentIds = Object.keys(newState.core.documents);\n\n // Check each document for command state changes\n documentIds.forEach((documentId) => {\n this.detectCommandChanges(documentId, newState);\n });\n }\n\n private detectCommandChanges(documentId: string, newState: StoreState<any>): void {\n const previousCache = this.previousStates.get(documentId) ?? new Map();\n const changedCommandIds: string[] = [];\n\n this.commands.forEach((command, commandId) => {\n const newResolved = this.resolve(commandId, documentId);\n const prevResolved = previousCache.get(commandId);\n\n if (!prevResolved) {\n // First time resolving for this document\n previousCache.set(commandId, newResolved);\n return;\n }\n\n // Check for changes\n const changes: CommandStateChangedEvent['changes'] = {};\n\n if (prevResolved.active !== newResolved.active) {\n changes.active = newResolved.active;\n }\n if (prevResolved.disabled !== newResolved.disabled) {\n changes.disabled = newResolved.disabled;\n }\n if (prevResolved.visible !== newResolved.visible) {\n changes.visible = newResolved.visible;\n }\n if (prevResolved.label !== newResolved.label) {\n changes.label = newResolved.label;\n }\n if (!arePropsEqual(prevResolved.iconProps, newResolved.iconProps)) {\n changes.iconProps = newResolved.iconProps;\n }\n\n if (Object.keys(changes).length > 0) {\n changedCommandIds.push(commandId);\n previousCache.set(commandId, newResolved);\n\n this.commandStateChanged$.emit({\n commandId,\n documentId,\n changes,\n });\n }\n });\n\n this.previousStates.set(documentId, previousCache);\n }\n}\n","import { Action } from '@embedpdf/core';\n\nexport const REGISTER_COMMAND = 'COMMANDS/REGISTER';\nexport const UNREGISTER_COMMAND = 'COMMANDS/UNREGISTER';\nexport const MARK_COMMANDS_CHANGED = 'COMMANDS/MARK_CHANGED';\nexport const CLEAR_CHANGED_COMMANDS = 'COMMANDS/CLEAR_CHANGED';\n\nexport interface RegisterCommandAction extends Action {\n type: typeof REGISTER_COMMAND;\n payload: string; // commandId\n}\n\nexport interface UnregisterCommandAction extends Action {\n type: typeof UNREGISTER_COMMAND;\n payload: string; // commandId\n}\n\nexport interface MarkCommandsChangedAction extends Action {\n type: typeof MARK_COMMANDS_CHANGED;\n payload: string[]; // commandIds\n}\n\nexport interface ClearChangedCommandsAction extends Action {\n type: typeof CLEAR_CHANGED_COMMANDS;\n}\n\nexport type CommandsAction =\n | RegisterCommandAction\n | UnregisterCommandAction\n | MarkCommandsChangedAction\n | ClearChangedCommandsAction;\n\nexport const registerCommand = (commandId: string): RegisterCommandAction => ({\n type: REGISTER_COMMAND,\n payload: commandId,\n});\n\nexport const unregisterCommand = (commandId: string): UnregisterCommandAction => ({\n type: UNREGISTER_COMMAND,\n payload: commandId,\n});\n\nexport const markCommandsChanged = (commandIds: string[]): MarkCommandsChangedAction => ({\n type: MARK_COMMANDS_CHANGED,\n payload: commandIds,\n});\n\nexport const clearChangedCommands = (): ClearChangedCommandsAction => ({\n type: CLEAR_CHANGED_COMMANDS,\n});\n","import { Reducer } from '@embedpdf/core';\nimport { CommandsState } from './types';\nimport { CommandsAction, MARK_COMMANDS_CHANGED, CLEAR_CHANGED_COMMANDS } from './actions';\n\nexport const initialState: CommandsState = {\n changedCommands: new Set(),\n};\n\nexport const commandsReducer: Reducer<CommandsState, CommandsAction> = (\n state = initialState,\n action,\n) => {\n switch (action.type) {\n case MARK_COMMANDS_CHANGED: {\n const newSet = new Set(state.changedCommands);\n action.payload.forEach((id) => newSet.add(id));\n return {\n ...state,\n changedCommands: newSet,\n };\n }\n\n case CLEAR_CHANGED_COMMANDS: {\n return {\n ...state,\n changedCommands: new Set(),\n };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, COMMANDS_PLUGIN_ID } from './manifest';\nimport { CommandsPluginConfig, CommandsState } from './types';\nimport { CommandsPlugin } from './commands-plugin';\nimport { CommandsAction } from './actions';\nimport { commandsReducer, initialState } from './reducer';\n\nexport const CommandsPluginPackage: PluginPackage<\n CommandsPlugin,\n CommandsPluginConfig,\n CommandsState,\n CommandsAction\n> = {\n manifest,\n create: (registry, config) => new CommandsPlugin(COMMANDS_PLUGIN_ID, registry, config),\n reducer: commandsReducer,\n initialState,\n};\n\nexport * from './commands-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["COMMANDS_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","commands","_CommandsPlugin","BasePlugin","constructor","registry","config","super","this","Map","i18n","shortcutMap","commandExecuted$","createEmitter","commandStateChanged$","shortcutExecuted$","previousStates","i18nPlugin","getPlugin","Object","values","forEach","command","registerCommand","getStore","subscribe","_action","newState","onGlobalStoreChange","onDocumentClosed","documentId","delete","logger","debug","initialize","info","destroy","clear","buildCapability","resolve","commandId","execute","source","getAllCommands","getCommandsByCategory","category","getCommandByShortcut","shortcut","getAllShortcuts","forDocument","createCommandScope","unregisterCommand","onCommandExecuted","on","onCommandStateChanged","onShortcutExecuted","listener","event","_","rest","resolvedDocId","getActiveDocumentId","get","Error","state","getState","label","resolveLabel","shortcuts","Array","isArray","icon","resolveDynamic","iconProps","active","disabled","visible","shortcutLabel","description","action","labelKey","params","labelParams","t","value","resolved","warn","emit","has","set","normalized","normalizeShortcut","toLowerCase","split","sort","join","from","keys","map","filter","cmd","core","documents","detectCommandChanges","previousCache","newResolved","prevResolved","changes","arePropsEqual","length","CommandsPlugin","initialState","changedCommands","Set","CommandsPluginPackage","create","reducer","type","newSet","payload","add"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { BasePlugin, createEmitter, arePropsEqual } from "@embedpdf/core";
|
|
2
|
+
const COMMANDS_PLUGIN_ID = "commands";
|
|
3
|
+
const manifest = {
|
|
4
|
+
id: COMMANDS_PLUGIN_ID,
|
|
5
|
+
name: "Commands Plugin",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
provides: ["commands"],
|
|
8
|
+
requires: [],
|
|
9
|
+
optional: ["i18n"],
|
|
10
|
+
defaultConfig: {
|
|
11
|
+
enabled: true,
|
|
12
|
+
commands: {}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const _CommandsPlugin = class _CommandsPlugin extends BasePlugin {
|
|
16
|
+
constructor(id, registry, config) {
|
|
17
|
+
super(id, registry);
|
|
18
|
+
this.commands = /* @__PURE__ */ new Map();
|
|
19
|
+
this.i18n = null;
|
|
20
|
+
this.shortcutMap = /* @__PURE__ */ new Map();
|
|
21
|
+
this.commandExecuted$ = createEmitter();
|
|
22
|
+
this.commandStateChanged$ = createEmitter();
|
|
23
|
+
this.shortcutExecuted$ = createEmitter();
|
|
24
|
+
this.previousStates = /* @__PURE__ */ new Map();
|
|
25
|
+
const i18nPlugin = registry.getPlugin("i18n");
|
|
26
|
+
this.i18n = (i18nPlugin == null ? void 0 : i18nPlugin.provides()) ?? null;
|
|
27
|
+
Object.values(config.commands).forEach((command) => {
|
|
28
|
+
this.registerCommand(command);
|
|
29
|
+
});
|
|
30
|
+
this.registry.getStore().subscribe((_action, newState) => {
|
|
31
|
+
this.onGlobalStoreChange(newState);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
onDocumentClosed(documentId) {
|
|
35
|
+
this.previousStates.delete(documentId);
|
|
36
|
+
this.logger.debug(
|
|
37
|
+
"CommandsPlugin",
|
|
38
|
+
"DocumentClosed",
|
|
39
|
+
`Cleaned up command state cache for document: ${documentId}`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
async initialize() {
|
|
43
|
+
this.logger.info("CommandsPlugin", "Initialize", "Commands plugin initialized");
|
|
44
|
+
}
|
|
45
|
+
async destroy() {
|
|
46
|
+
this.commandExecuted$.clear();
|
|
47
|
+
this.commandStateChanged$.clear();
|
|
48
|
+
this.shortcutExecuted$.clear();
|
|
49
|
+
this.commands.clear();
|
|
50
|
+
this.shortcutMap.clear();
|
|
51
|
+
this.previousStates.clear();
|
|
52
|
+
super.destroy();
|
|
53
|
+
}
|
|
54
|
+
// ─────────────────────────────────────────────────────────
|
|
55
|
+
// Capability
|
|
56
|
+
// ─────────────────────────────────────────────────────────
|
|
57
|
+
buildCapability() {
|
|
58
|
+
return {
|
|
59
|
+
resolve: (commandId, documentId) => this.resolve(commandId, documentId),
|
|
60
|
+
execute: (commandId, documentId, source = "ui") => this.execute(commandId, documentId, source),
|
|
61
|
+
getAllCommands: (documentId) => this.getAllCommands(documentId),
|
|
62
|
+
getCommandsByCategory: (category, documentId) => this.getCommandsByCategory(category, documentId),
|
|
63
|
+
getCommandByShortcut: (shortcut) => this.getCommandByShortcut(shortcut),
|
|
64
|
+
getAllShortcuts: () => new Map(this.shortcutMap),
|
|
65
|
+
forDocument: (documentId) => this.createCommandScope(documentId),
|
|
66
|
+
registerCommand: (command) => this.registerCommand(command),
|
|
67
|
+
unregisterCommand: (commandId) => this.unregisterCommand(commandId),
|
|
68
|
+
onCommandExecuted: this.commandExecuted$.on,
|
|
69
|
+
onCommandStateChanged: this.commandStateChanged$.on,
|
|
70
|
+
onShortcutExecuted: this.shortcutExecuted$.on
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// ─────────────────────────────────────────────────────────
|
|
74
|
+
// Document Scoping
|
|
75
|
+
// ─────────────────────────────────────────────────────────
|
|
76
|
+
createCommandScope(documentId) {
|
|
77
|
+
return {
|
|
78
|
+
resolve: (commandId) => this.resolve(commandId, documentId),
|
|
79
|
+
execute: (commandId, source = "ui") => this.execute(commandId, documentId, source),
|
|
80
|
+
getAllCommands: () => this.getAllCommands(documentId),
|
|
81
|
+
getCommandsByCategory: (category) => this.getCommandsByCategory(category, documentId),
|
|
82
|
+
onCommandStateChanged: (listener) => this.commandStateChanged$.on((event) => {
|
|
83
|
+
if (event.documentId === documentId) {
|
|
84
|
+
const { documentId: _, ...rest } = event;
|
|
85
|
+
listener(rest);
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// ─────────────────────────────────────────────────────────
|
|
91
|
+
// Command Resolution
|
|
92
|
+
// ─────────────────────────────────────────────────────────
|
|
93
|
+
resolve(commandId, documentId) {
|
|
94
|
+
const resolvedDocId = documentId ?? this.getActiveDocumentId();
|
|
95
|
+
const command = this.commands.get(commandId);
|
|
96
|
+
if (!command) {
|
|
97
|
+
throw new Error(`Command not found: ${commandId}`);
|
|
98
|
+
}
|
|
99
|
+
const state = this.registry.getStore().getState();
|
|
100
|
+
const label = this.resolveLabel(command, state, resolvedDocId);
|
|
101
|
+
const shortcuts = command.shortcuts ? Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts] : void 0;
|
|
102
|
+
return {
|
|
103
|
+
id: command.id,
|
|
104
|
+
label,
|
|
105
|
+
icon: this.resolveDynamic(command.icon, state, resolvedDocId),
|
|
106
|
+
iconProps: this.resolveDynamic(command.iconProps, state, resolvedDocId),
|
|
107
|
+
active: this.resolveDynamic(command.active, state, resolvedDocId) ?? false,
|
|
108
|
+
disabled: this.resolveDynamic(command.disabled, state, resolvedDocId) ?? false,
|
|
109
|
+
visible: this.resolveDynamic(command.visible, state, resolvedDocId) ?? true,
|
|
110
|
+
shortcuts,
|
|
111
|
+
shortcutLabel: command.shortcutLabel,
|
|
112
|
+
category: command.category,
|
|
113
|
+
description: command.description,
|
|
114
|
+
execute: () => command.action({ registry: this.registry, state, documentId: resolvedDocId })
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
resolveLabel(command, state, documentId) {
|
|
118
|
+
if (command.labelKey && this.i18n) {
|
|
119
|
+
const params = this.resolveDynamic(command.labelParams, state, documentId);
|
|
120
|
+
return this.i18n.t(command.labelKey, { params, documentId });
|
|
121
|
+
}
|
|
122
|
+
if (command.label) {
|
|
123
|
+
return command.label;
|
|
124
|
+
}
|
|
125
|
+
return command.id;
|
|
126
|
+
}
|
|
127
|
+
resolveDynamic(value, state, documentId) {
|
|
128
|
+
if (value === void 0) return void 0;
|
|
129
|
+
if (typeof value === "function") {
|
|
130
|
+
return value({
|
|
131
|
+
state,
|
|
132
|
+
documentId
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
// ─────────────────────────────────────────────────────────
|
|
138
|
+
// Command Execution
|
|
139
|
+
// ─────────────────────────────────────────────────────────
|
|
140
|
+
execute(commandId, documentId, source = "ui") {
|
|
141
|
+
const resolvedDocId = documentId ?? this.getActiveDocumentId();
|
|
142
|
+
const resolved = this.resolve(commandId, resolvedDocId);
|
|
143
|
+
if (resolved.disabled) {
|
|
144
|
+
this.logger.warn(
|
|
145
|
+
"CommandsPlugin",
|
|
146
|
+
"ExecutionBlocked",
|
|
147
|
+
`Command '${commandId}' is disabled for document '${resolvedDocId}'`
|
|
148
|
+
);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!resolved.visible) {
|
|
152
|
+
this.logger.warn(
|
|
153
|
+
"CommandsPlugin",
|
|
154
|
+
"ExecutionBlocked",
|
|
155
|
+
`Command '${commandId}' is not visible for document '${resolvedDocId}'`
|
|
156
|
+
);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
resolved.execute();
|
|
160
|
+
this.commandExecuted$.emit({
|
|
161
|
+
commandId,
|
|
162
|
+
documentId: resolvedDocId,
|
|
163
|
+
source
|
|
164
|
+
});
|
|
165
|
+
this.logger.debug(
|
|
166
|
+
"CommandsPlugin",
|
|
167
|
+
"CommandExecuted",
|
|
168
|
+
`Command '${commandId}' executed for document '${resolvedDocId}' (source: ${source})`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
// ─────────────────────────────────────────────────────────
|
|
172
|
+
// Command Registration
|
|
173
|
+
// ─────────────────────────────────────────────────────────
|
|
174
|
+
registerCommand(command) {
|
|
175
|
+
if (this.commands.has(command.id)) {
|
|
176
|
+
this.logger.warn(
|
|
177
|
+
"CommandsPlugin",
|
|
178
|
+
"CommandOverwrite",
|
|
179
|
+
`Command '${command.id}' already exists and will be overwritten`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
this.commands.set(command.id, command);
|
|
183
|
+
if (command.shortcuts) {
|
|
184
|
+
const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];
|
|
185
|
+
shortcuts.forEach((shortcut) => {
|
|
186
|
+
const normalized = this.normalizeShortcut(shortcut);
|
|
187
|
+
this.shortcutMap.set(normalized, command.id);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
this.logger.debug("CommandsPlugin", "CommandRegistered", `Command '${command.id}' registered`);
|
|
191
|
+
}
|
|
192
|
+
unregisterCommand(commandId) {
|
|
193
|
+
const command = this.commands.get(commandId);
|
|
194
|
+
if (!command) return;
|
|
195
|
+
if (command.shortcuts) {
|
|
196
|
+
const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];
|
|
197
|
+
shortcuts.forEach((shortcut) => {
|
|
198
|
+
const normalized = this.normalizeShortcut(shortcut);
|
|
199
|
+
this.shortcutMap.delete(normalized);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
this.commands.delete(commandId);
|
|
203
|
+
this.logger.debug(
|
|
204
|
+
"CommandsPlugin",
|
|
205
|
+
"CommandUnregistered",
|
|
206
|
+
`Command '${commandId}' unregistered`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
// ─────────────────────────────────────────────────────────
|
|
210
|
+
// Shortcuts
|
|
211
|
+
// ─────────────────────────────────────────────────────────
|
|
212
|
+
getCommandByShortcut(shortcut) {
|
|
213
|
+
const normalized = this.normalizeShortcut(shortcut);
|
|
214
|
+
const commandId = this.shortcutMap.get(normalized);
|
|
215
|
+
return commandId ? this.commands.get(commandId) ?? null : null;
|
|
216
|
+
}
|
|
217
|
+
normalizeShortcut(shortcut) {
|
|
218
|
+
return shortcut.toLowerCase().split("+").sort().join("+");
|
|
219
|
+
}
|
|
220
|
+
// ─────────────────────────────────────────────────────────
|
|
221
|
+
// Query Methods
|
|
222
|
+
// ─────────────────────────────────────────────────────────
|
|
223
|
+
getAllCommands(documentId) {
|
|
224
|
+
const resolvedDocId = documentId ?? this.getActiveDocumentId();
|
|
225
|
+
return Array.from(this.commands.keys()).map((id) => this.resolve(id, resolvedDocId));
|
|
226
|
+
}
|
|
227
|
+
getCommandsByCategory(category, documentId) {
|
|
228
|
+
const resolvedDocId = documentId ?? this.getActiveDocumentId();
|
|
229
|
+
return Array.from(this.commands.values()).filter((cmd) => cmd.category === category).map((cmd) => this.resolve(cmd.id, resolvedDocId));
|
|
230
|
+
}
|
|
231
|
+
// ─────────────────────────────────────────────────────────
|
|
232
|
+
// State Change Detection
|
|
233
|
+
// ─────────────────────────────────────────────────────────
|
|
234
|
+
onGlobalStoreChange(newState) {
|
|
235
|
+
const documentIds = Object.keys(newState.core.documents);
|
|
236
|
+
documentIds.forEach((documentId) => {
|
|
237
|
+
this.detectCommandChanges(documentId, newState);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
detectCommandChanges(documentId, newState) {
|
|
241
|
+
const previousCache = this.previousStates.get(documentId) ?? /* @__PURE__ */ new Map();
|
|
242
|
+
this.commands.forEach((command, commandId) => {
|
|
243
|
+
const newResolved = this.resolve(commandId, documentId);
|
|
244
|
+
const prevResolved = previousCache.get(commandId);
|
|
245
|
+
if (!prevResolved) {
|
|
246
|
+
previousCache.set(commandId, newResolved);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const changes = {};
|
|
250
|
+
if (prevResolved.active !== newResolved.active) {
|
|
251
|
+
changes.active = newResolved.active;
|
|
252
|
+
}
|
|
253
|
+
if (prevResolved.disabled !== newResolved.disabled) {
|
|
254
|
+
changes.disabled = newResolved.disabled;
|
|
255
|
+
}
|
|
256
|
+
if (prevResolved.visible !== newResolved.visible) {
|
|
257
|
+
changes.visible = newResolved.visible;
|
|
258
|
+
}
|
|
259
|
+
if (prevResolved.label !== newResolved.label) {
|
|
260
|
+
changes.label = newResolved.label;
|
|
261
|
+
}
|
|
262
|
+
if (!arePropsEqual(prevResolved.iconProps, newResolved.iconProps)) {
|
|
263
|
+
changes.iconProps = newResolved.iconProps;
|
|
264
|
+
}
|
|
265
|
+
if (Object.keys(changes).length > 0) {
|
|
266
|
+
previousCache.set(commandId, newResolved);
|
|
267
|
+
this.commandStateChanged$.emit({
|
|
268
|
+
commandId,
|
|
269
|
+
documentId,
|
|
270
|
+
changes
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
this.previousStates.set(documentId, previousCache);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
_CommandsPlugin.id = "commands";
|
|
278
|
+
let CommandsPlugin = _CommandsPlugin;
|
|
279
|
+
const MARK_COMMANDS_CHANGED = "COMMANDS/MARK_CHANGED";
|
|
280
|
+
const CLEAR_CHANGED_COMMANDS = "COMMANDS/CLEAR_CHANGED";
|
|
281
|
+
const initialState = {
|
|
282
|
+
changedCommands: /* @__PURE__ */ new Set()
|
|
283
|
+
};
|
|
284
|
+
const commandsReducer = (state = initialState, action) => {
|
|
285
|
+
switch (action.type) {
|
|
286
|
+
case MARK_COMMANDS_CHANGED: {
|
|
287
|
+
const newSet = new Set(state.changedCommands);
|
|
288
|
+
action.payload.forEach((id) => newSet.add(id));
|
|
289
|
+
return {
|
|
290
|
+
...state,
|
|
291
|
+
changedCommands: newSet
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
case CLEAR_CHANGED_COMMANDS: {
|
|
295
|
+
return {
|
|
296
|
+
...state,
|
|
297
|
+
changedCommands: /* @__PURE__ */ new Set()
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
default:
|
|
301
|
+
return state;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const CommandsPluginPackage = {
|
|
305
|
+
manifest,
|
|
306
|
+
create: (registry, config) => new CommandsPlugin(COMMANDS_PLUGIN_ID, registry, config),
|
|
307
|
+
reducer: commandsReducer,
|
|
308
|
+
initialState
|
|
309
|
+
};
|
|
310
|
+
export {
|
|
311
|
+
COMMANDS_PLUGIN_ID,
|
|
312
|
+
CommandsPlugin,
|
|
313
|
+
CommandsPluginPackage,
|
|
314
|
+
manifest
|
|
315
|
+
};
|
|
316
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/manifest.ts","../src/lib/commands-plugin.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { CommandsPluginConfig } from './types';\n\nexport const COMMANDS_PLUGIN_ID = 'commands';\n\nexport const manifest: PluginManifest<CommandsPluginConfig> = {\n id: COMMANDS_PLUGIN_ID,\n name: 'Commands Plugin',\n version: '1.0.0',\n provides: ['commands'],\n requires: [],\n optional: ['i18n'],\n defaultConfig: {\n enabled: true,\n commands: {},\n },\n};\n","import {\n BasePlugin,\n PluginRegistry,\n StoreState,\n createEmitter,\n Listener,\n arePropsEqual,\n} from '@embedpdf/core';\nimport { I18nCapability, I18nPlugin } from '@embedpdf/plugin-i18n';\nimport {\n CommandsCapability,\n CommandsPluginConfig,\n CommandsState,\n Command,\n ResolvedCommand,\n CommandExecutedEvent,\n CommandStateChangedEvent,\n ShortcutExecutedEvent,\n CommandScope,\n Dynamic,\n} from './types';\nimport { CommandsAction } from './actions';\n\nexport class CommandsPlugin extends BasePlugin<\n CommandsPluginConfig,\n CommandsCapability,\n CommandsState,\n CommandsAction\n> {\n static readonly id = 'commands' as const;\n\n private commands = new Map<string, Command>();\n private i18n: I18nCapability | null = null;\n private shortcutMap = new Map<string, string>(); // shortcut -> commandId\n\n private readonly commandExecuted$ = createEmitter<CommandExecutedEvent>();\n private readonly commandStateChanged$ = createEmitter<CommandStateChangedEvent>();\n private readonly shortcutExecuted$ = createEmitter<ShortcutExecutedEvent>();\n\n // Cache previous resolved states per document to detect changes\n private previousStates = new Map<string, Map<string, ResolvedCommand>>();\n\n constructor(id: string, registry: PluginRegistry, config: CommandsPluginConfig) {\n super(id, registry);\n\n // Check if i18n plugin is available (optional dependency)\n const i18nPlugin = registry.getPlugin<I18nPlugin>('i18n');\n this.i18n = i18nPlugin?.provides() ?? null;\n\n // Register all commands from config\n Object.values(config.commands).forEach((command) => {\n this.registerCommand(command);\n });\n\n // Subscribe to global store changes\n this.registry.getStore().subscribe((_action, newState) => {\n this.onGlobalStoreChange(newState);\n });\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Cleanup previous states cache\n this.previousStates.delete(documentId);\n\n this.logger.debug(\n 'CommandsPlugin',\n 'DocumentClosed',\n `Cleaned up command state cache for document: ${documentId}`,\n );\n }\n\n async initialize(): Promise<void> {\n this.logger.info('CommandsPlugin', 'Initialize', 'Commands plugin initialized');\n }\n\n async destroy(): Promise<void> {\n this.commandExecuted$.clear();\n this.commandStateChanged$.clear();\n this.shortcutExecuted$.clear();\n this.commands.clear();\n this.shortcutMap.clear();\n this.previousStates.clear();\n super.destroy();\n }\n\n // ─────────────────────────────────────────────────────────\n // Capability\n // ─────────────────────────────────────────────────────────\n\n protected buildCapability(): CommandsCapability {\n return {\n resolve: (commandId, documentId) => this.resolve(commandId, documentId),\n execute: (commandId, documentId, source = 'ui') =>\n this.execute(commandId, documentId, source),\n getAllCommands: (documentId) => this.getAllCommands(documentId),\n getCommandsByCategory: (category, documentId) =>\n this.getCommandsByCategory(category, documentId),\n getCommandByShortcut: (shortcut) => this.getCommandByShortcut(shortcut),\n getAllShortcuts: () => new Map(this.shortcutMap),\n forDocument: (documentId) => this.createCommandScope(documentId),\n registerCommand: (command) => this.registerCommand(command),\n unregisterCommand: (commandId) => this.unregisterCommand(commandId),\n onCommandExecuted: this.commandExecuted$.on,\n onCommandStateChanged: this.commandStateChanged$.on,\n onShortcutExecuted: this.shortcutExecuted$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Scoping\n // ─────────────────────────────────────────────────────────\n\n private createCommandScope(documentId: string): CommandScope {\n return {\n resolve: (commandId) => this.resolve(commandId, documentId),\n execute: (commandId, source = 'ui') => this.execute(commandId, documentId, source),\n getAllCommands: () => this.getAllCommands(documentId),\n getCommandsByCategory: (category) => this.getCommandsByCategory(category, documentId),\n onCommandStateChanged: (listener: Listener<Omit<CommandStateChangedEvent, 'documentId'>>) =>\n this.commandStateChanged$.on((event) => {\n if (event.documentId === documentId) {\n const { documentId: _, ...rest } = event;\n listener(rest);\n }\n }),\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Resolution\n // ─────────────────────────────────────────────────────────\n\n private resolve(commandId: string, documentId?: string): ResolvedCommand {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n\n const command = this.commands.get(commandId);\n if (!command) {\n throw new Error(`Command not found: ${commandId}`);\n }\n\n const state = this.registry.getStore().getState();\n\n // Resolve label with i18n if available\n const label = this.resolveLabel(command, state, resolvedDocId);\n\n // Resolve shortcuts\n const shortcuts = command.shortcuts\n ? Array.isArray(command.shortcuts)\n ? command.shortcuts\n : [command.shortcuts]\n : undefined;\n\n return {\n id: command.id,\n label,\n icon: this.resolveDynamic(command.icon, state, resolvedDocId),\n iconProps: this.resolveDynamic(command.iconProps, state, resolvedDocId),\n active: this.resolveDynamic(command.active, state, resolvedDocId) ?? false,\n disabled: this.resolveDynamic(command.disabled, state, resolvedDocId) ?? false,\n visible: this.resolveDynamic(command.visible, state, resolvedDocId) ?? true,\n shortcuts,\n shortcutLabel: command.shortcutLabel,\n category: command.category,\n description: command.description,\n execute: () => command.action({ registry: this.registry, state, documentId: resolvedDocId }),\n };\n }\n\n private resolveLabel(command: Command, state: StoreState<any>, documentId: string): string {\n // Priority: labelKey (with i18n) > label (plain string) > id (fallback)\n if (command.labelKey && this.i18n) {\n const params = this.resolveDynamic(command.labelParams, state, documentId);\n return this.i18n.t(command.labelKey, { params, documentId });\n }\n\n if (command.label) {\n return command.label;\n }\n\n return command.id; // Fallback to ID\n }\n\n private resolveDynamic<T>(\n value: Dynamic<any, T> | undefined,\n state: StoreState<any>,\n documentId: string,\n ): T | undefined {\n if (value === undefined) return undefined;\n\n // Check if it's a function (the dynamic evaluator)\n if (typeof value === 'function') {\n return (value as (context: { state: StoreState<any>; documentId: string }) => T)({\n state,\n documentId,\n });\n }\n\n // Otherwise it's the static value\n return value as T;\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Execution\n // ─────────────────────────────────────────────────────────\n\n private execute(\n commandId: string,\n documentId?: string,\n source: 'keyboard' | 'ui' | 'api' = 'ui',\n ): void {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n const resolved = this.resolve(commandId, resolvedDocId);\n\n if (resolved.disabled) {\n this.logger.warn(\n 'CommandsPlugin',\n 'ExecutionBlocked',\n `Command '${commandId}' is disabled for document '${resolvedDocId}'`,\n );\n return;\n }\n\n if (!resolved.visible) {\n this.logger.warn(\n 'CommandsPlugin',\n 'ExecutionBlocked',\n `Command '${commandId}' is not visible for document '${resolvedDocId}'`,\n );\n return;\n }\n\n resolved.execute();\n\n this.commandExecuted$.emit({\n commandId,\n documentId: resolvedDocId,\n source,\n });\n\n this.logger.debug(\n 'CommandsPlugin',\n 'CommandExecuted',\n `Command '${commandId}' executed for document '${resolvedDocId}' (source: ${source})`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Command Registration\n // ─────────────────────────────────────────────────────────\n\n private registerCommand(command: Command): void {\n if (this.commands.has(command.id)) {\n this.logger.warn(\n 'CommandsPlugin',\n 'CommandOverwrite',\n `Command '${command.id}' already exists and will be overwritten`,\n );\n }\n\n this.commands.set(command.id, command);\n\n // Register shortcuts\n if (command.shortcuts) {\n const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];\n\n shortcuts.forEach((shortcut) => {\n const normalized = this.normalizeShortcut(shortcut);\n this.shortcutMap.set(normalized, command.id);\n });\n }\n\n this.logger.debug('CommandsPlugin', 'CommandRegistered', `Command '${command.id}' registered`);\n }\n\n private unregisterCommand(commandId: string): void {\n const command = this.commands.get(commandId);\n if (!command) return;\n\n // Remove shortcuts\n if (command.shortcuts) {\n const shortcuts = Array.isArray(command.shortcuts) ? command.shortcuts : [command.shortcuts];\n\n shortcuts.forEach((shortcut) => {\n const normalized = this.normalizeShortcut(shortcut);\n this.shortcutMap.delete(normalized);\n });\n }\n\n this.commands.delete(commandId);\n this.logger.debug(\n 'CommandsPlugin',\n 'CommandUnregistered',\n `Command '${commandId}' unregistered`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Shortcuts\n // ─────────────────────────────────────────────────────────\n\n private getCommandByShortcut(shortcut: string): Command | null {\n const normalized = this.normalizeShortcut(shortcut);\n const commandId = this.shortcutMap.get(normalized);\n return commandId ? (this.commands.get(commandId) ?? null) : null;\n }\n\n private normalizeShortcut(shortcut: string): string {\n // Normalize: \"Ctrl+Shift+A\" -> \"ctrl+shift+a\"\n return shortcut.toLowerCase().split('+').sort().join('+');\n }\n\n // ─────────────────────────────────────────────────────────\n // Query Methods\n // ─────────────────────────────────────────────────────────\n\n private getAllCommands(documentId?: string): ResolvedCommand[] {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n return Array.from(this.commands.keys()).map((id) => this.resolve(id, resolvedDocId));\n }\n\n private getCommandsByCategory(category: string, documentId?: string): ResolvedCommand[] {\n const resolvedDocId = documentId ?? this.getActiveDocumentId();\n return Array.from(this.commands.values())\n .filter((cmd) => cmd.category === category)\n .map((cmd) => this.resolve(cmd.id, resolvedDocId));\n }\n\n // ─────────────────────────────────────────────────────────\n // State Change Detection\n // ─────────────────────────────────────────────────────────\n\n private onGlobalStoreChange(newState: StoreState<any>): void {\n // Get all documents from core state\n const documentIds = Object.keys(newState.core.documents);\n\n // Check each document for command state changes\n documentIds.forEach((documentId) => {\n this.detectCommandChanges(documentId, newState);\n });\n }\n\n private detectCommandChanges(documentId: string, newState: StoreState<any>): void {\n const previousCache = this.previousStates.get(documentId) ?? new Map();\n const changedCommandIds: string[] = [];\n\n this.commands.forEach((command, commandId) => {\n const newResolved = this.resolve(commandId, documentId);\n const prevResolved = previousCache.get(commandId);\n\n if (!prevResolved) {\n // First time resolving for this document\n previousCache.set(commandId, newResolved);\n return;\n }\n\n // Check for changes\n const changes: CommandStateChangedEvent['changes'] = {};\n\n if (prevResolved.active !== newResolved.active) {\n changes.active = newResolved.active;\n }\n if (prevResolved.disabled !== newResolved.disabled) {\n changes.disabled = newResolved.disabled;\n }\n if (prevResolved.visible !== newResolved.visible) {\n changes.visible = newResolved.visible;\n }\n if (prevResolved.label !== newResolved.label) {\n changes.label = newResolved.label;\n }\n if (!arePropsEqual(prevResolved.iconProps, newResolved.iconProps)) {\n changes.iconProps = newResolved.iconProps;\n }\n\n if (Object.keys(changes).length > 0) {\n changedCommandIds.push(commandId);\n previousCache.set(commandId, newResolved);\n\n this.commandStateChanged$.emit({\n commandId,\n documentId,\n changes,\n });\n }\n });\n\n this.previousStates.set(documentId, previousCache);\n }\n}\n","import { Action } from '@embedpdf/core';\n\nexport const REGISTER_COMMAND = 'COMMANDS/REGISTER';\nexport const UNREGISTER_COMMAND = 'COMMANDS/UNREGISTER';\nexport const MARK_COMMANDS_CHANGED = 'COMMANDS/MARK_CHANGED';\nexport const CLEAR_CHANGED_COMMANDS = 'COMMANDS/CLEAR_CHANGED';\n\nexport interface RegisterCommandAction extends Action {\n type: typeof REGISTER_COMMAND;\n payload: string; // commandId\n}\n\nexport interface UnregisterCommandAction extends Action {\n type: typeof UNREGISTER_COMMAND;\n payload: string; // commandId\n}\n\nexport interface MarkCommandsChangedAction extends Action {\n type: typeof MARK_COMMANDS_CHANGED;\n payload: string[]; // commandIds\n}\n\nexport interface ClearChangedCommandsAction extends Action {\n type: typeof CLEAR_CHANGED_COMMANDS;\n}\n\nexport type CommandsAction =\n | RegisterCommandAction\n | UnregisterCommandAction\n | MarkCommandsChangedAction\n | ClearChangedCommandsAction;\n\nexport const registerCommand = (commandId: string): RegisterCommandAction => ({\n type: REGISTER_COMMAND,\n payload: commandId,\n});\n\nexport const unregisterCommand = (commandId: string): UnregisterCommandAction => ({\n type: UNREGISTER_COMMAND,\n payload: commandId,\n});\n\nexport const markCommandsChanged = (commandIds: string[]): MarkCommandsChangedAction => ({\n type: MARK_COMMANDS_CHANGED,\n payload: commandIds,\n});\n\nexport const clearChangedCommands = (): ClearChangedCommandsAction => ({\n type: CLEAR_CHANGED_COMMANDS,\n});\n","import { Reducer } from '@embedpdf/core';\nimport { CommandsState } from './types';\nimport { CommandsAction, MARK_COMMANDS_CHANGED, CLEAR_CHANGED_COMMANDS } from './actions';\n\nexport const initialState: CommandsState = {\n changedCommands: new Set(),\n};\n\nexport const commandsReducer: Reducer<CommandsState, CommandsAction> = (\n state = initialState,\n action,\n) => {\n switch (action.type) {\n case MARK_COMMANDS_CHANGED: {\n const newSet = new Set(state.changedCommands);\n action.payload.forEach((id) => newSet.add(id));\n return {\n ...state,\n changedCommands: newSet,\n };\n }\n\n case CLEAR_CHANGED_COMMANDS: {\n return {\n ...state,\n changedCommands: new Set(),\n };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, COMMANDS_PLUGIN_ID } from './manifest';\nimport { CommandsPluginConfig, CommandsState } from './types';\nimport { CommandsPlugin } from './commands-plugin';\nimport { CommandsAction } from './actions';\nimport { commandsReducer, initialState } from './reducer';\n\nexport const CommandsPluginPackage: PluginPackage<\n CommandsPlugin,\n CommandsPluginConfig,\n CommandsState,\n CommandsAction\n> = {\n manifest,\n create: (registry, config) => new CommandsPlugin(COMMANDS_PLUGIN_ID, registry, config),\n reducer: commandsReducer,\n initialState,\n};\n\nexport * from './commands-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Action } from '@embedpdf/core';
|
|
2
|
+
export declare const REGISTER_COMMAND = "COMMANDS/REGISTER";
|
|
3
|
+
export declare const UNREGISTER_COMMAND = "COMMANDS/UNREGISTER";
|
|
4
|
+
export declare const MARK_COMMANDS_CHANGED = "COMMANDS/MARK_CHANGED";
|
|
5
|
+
export declare const CLEAR_CHANGED_COMMANDS = "COMMANDS/CLEAR_CHANGED";
|
|
6
|
+
export interface RegisterCommandAction extends Action {
|
|
7
|
+
type: typeof REGISTER_COMMAND;
|
|
8
|
+
payload: string;
|
|
9
|
+
}
|
|
10
|
+
export interface UnregisterCommandAction extends Action {
|
|
11
|
+
type: typeof UNREGISTER_COMMAND;
|
|
12
|
+
payload: string;
|
|
13
|
+
}
|
|
14
|
+
export interface MarkCommandsChangedAction extends Action {
|
|
15
|
+
type: typeof MARK_COMMANDS_CHANGED;
|
|
16
|
+
payload: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ClearChangedCommandsAction extends Action {
|
|
19
|
+
type: typeof CLEAR_CHANGED_COMMANDS;
|
|
20
|
+
}
|
|
21
|
+
export type CommandsAction = RegisterCommandAction | UnregisterCommandAction | MarkCommandsChangedAction | ClearChangedCommandsAction;
|
|
22
|
+
export declare const registerCommand: (commandId: string) => RegisterCommandAction;
|
|
23
|
+
export declare const unregisterCommand: (commandId: string) => UnregisterCommandAction;
|
|
24
|
+
export declare const markCommandsChanged: (commandIds: string[]) => MarkCommandsChangedAction;
|
|
25
|
+
export declare const clearChangedCommands: () => ClearChangedCommandsAction;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BasePlugin, PluginRegistry } from '@embedpdf/core';
|
|
2
|
+
import { CommandsCapability, CommandsPluginConfig, CommandsState } from './types';
|
|
3
|
+
import { CommandsAction } from './actions';
|
|
4
|
+
export declare class CommandsPlugin extends BasePlugin<CommandsPluginConfig, CommandsCapability, CommandsState, CommandsAction> {
|
|
5
|
+
static readonly id: "commands";
|
|
6
|
+
private commands;
|
|
7
|
+
private i18n;
|
|
8
|
+
private shortcutMap;
|
|
9
|
+
private readonly commandExecuted$;
|
|
10
|
+
private readonly commandStateChanged$;
|
|
11
|
+
private readonly shortcutExecuted$;
|
|
12
|
+
private previousStates;
|
|
13
|
+
constructor(id: string, registry: PluginRegistry, config: CommandsPluginConfig);
|
|
14
|
+
protected onDocumentClosed(documentId: string): void;
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
destroy(): Promise<void>;
|
|
17
|
+
protected buildCapability(): CommandsCapability;
|
|
18
|
+
private createCommandScope;
|
|
19
|
+
private resolve;
|
|
20
|
+
private resolveLabel;
|
|
21
|
+
private resolveDynamic;
|
|
22
|
+
private execute;
|
|
23
|
+
private registerCommand;
|
|
24
|
+
private unregisterCommand;
|
|
25
|
+
private getCommandByShortcut;
|
|
26
|
+
private normalizeShortcut;
|
|
27
|
+
private getAllCommands;
|
|
28
|
+
private getCommandsByCategory;
|
|
29
|
+
private onGlobalStoreChange;
|
|
30
|
+
private detectCommandChanges;
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PluginPackage } from '@embedpdf/core';
|
|
2
|
+
import { CommandsPluginConfig, CommandsState } from './types';
|
|
3
|
+
import { CommandsPlugin } from './commands-plugin';
|
|
4
|
+
import { CommandsAction } from './actions';
|
|
5
|
+
export declare const CommandsPluginPackage: PluginPackage<CommandsPlugin, CommandsPluginConfig, CommandsState, CommandsAction>;
|
|
6
|
+
export * from './commands-plugin';
|
|
7
|
+
export * from './types';
|
|
8
|
+
export * from './manifest';
|