UNPKG

@ssv/ngx.command

Version:

Command pattern implementation for angular. Command used to encapsulate information which is needed to perform an action.

1 lines 29 kB
{"version":3,"file":"ssv-ngx.command.mjs","sources":["../../../../libs/ngx.command/src/command.options.ts","../../../../libs/ngx.command/src/command.ts","../../../../libs/ngx.command/src/command.util.ts","../../../../libs/ngx.command/src/command.directive.ts","../../../../libs/ngx.command/src/command-ref.directive.ts","../../../../libs/ngx.command/src/command.module.ts","../../../../libs/ngx.command/src/version.ts","../../../../libs/ngx.command/src/ssv-ngx.command.ts"],"sourcesContent":["import { InjectionToken, type Provider } from \"@angular/core\";\n\nexport interface CommandOptions {\n\t/**\n\t * Css Class which gets added/removed on the Command element's host while Command `isExecuting$`.\n\t */\n\texecutingCssClass: string;\n\n\t/** Determines whether the disabled will be handled by the directive or not.\n\t * Disable handled by directive's doesn't always play nice when used with other component/pipe/directive and they also handle disabled.\n\t * This disables the handling manually and need to pass explicitly `[disabled]=\"!saveCmd.canExecute\"`.\n\t */\n\thandleDisabled: boolean;\n}\n\nconst DEFAULT_OPTIONS = Object.freeze<CommandOptions>({\n\texecutingCssClass: \"executing\",\n\thandleDisabled: true,\n});\n\nexport const COMMAND_OPTIONS = new InjectionToken<CommandOptions>(\"SSV_COMMAND_OPTIONS\", {\n\tfactory: () => DEFAULT_OPTIONS,\n});\n\nexport function provideSsvCommandOptions(\n\toptions: Partial<CommandOptions> | ((defaults: Readonly<CommandOptions>) => Partial<CommandOptions>)\n): Provider[] {\n\treturn [\n\t\t{\n\t\t\tprovide: COMMAND_OPTIONS,\n\t\t\tuseFactory: () => {\n\t\t\t\tlet opts = typeof options === \"function\" ? options(DEFAULT_OPTIONS) : options;\n\t\t\t\topts = opts\n\t\t\t\t\t? {\n\t\t\t\t\t\t...DEFAULT_OPTIONS,\n\t\t\t\t\t\t...opts,\n\t\t\t\t\t}\n\t\t\t\t\t: DEFAULT_OPTIONS;\n\t\t\t\treturn opts;\n\t\t\t},\n\t\t},\n\t];\n}\n","\nimport { isObservable, lastValueFrom } from \"rxjs\";\nimport { toSignal } from \"@angular/core/rxjs-interop\";\nimport type { CanExecute, ExecuteFn, ExecuteReturnType, ICommand } from \"./command.model\";\nimport { assertInInjectionContext, computed, inject, Injector, isSignal, signal, type Signal } from \"@angular/core\";\n\nexport interface CommandCreateOptions {\n\tinjector?: Injector;\n}\n\n// todo: remove\n/** Creates an async {@link Command}. Must be used within an injection context.\n * @deprecated Use {@link command} instead, as it handles both sync and async execute functions.\n */\nexport const commandAsync = command;\n\n/** Creates a {@link Command}. Must be used within an injection context (or the injector must be provided in the options). */\nexport function command<TExecute extends ExecuteFn>(\n\texecute: TExecute,\n\tcanExecute?: CanExecute,\n\topts?: CommandCreateOptions,\n): Command<TExecute> {\n\tif (!opts?.injector) {\n\t\tassertInInjectionContext(command);\n\t}\n\tconst injector = opts?.injector ?? inject(Injector);\n\tconst cmd = new Command(execute, canExecute, injector);\n\treturn cmd;\n}\n\n/**\n * Command object used to encapsulate information which is needed to perform an action.\n */\nexport class Command<TExecute extends ExecuteFn = ExecuteFn> implements ICommand<TExecute> {\n\n\tget isExecuting(): boolean { return this.$isExecuting(); }\n\n\tget canExecute(): boolean { return this.$canExecute(); }\n\n\treadonly $isExecuting = signal(false);\n\treadonly $canExecute = computed(() => !this.$isExecuting() && this.#canExecute());\n\n\treadonly #canExecute: Signal<boolean>;\n\n\t/**\n\t * Creates an instance of Command.\n\t *\n\t * @param execute Execute function to invoke.\n\t * @param canExecute Observable which determines whether it can execute or not.\n\t * @deprecated Use {@link command} or {@link commandAsync} instead for creating instances.\n\t */\n\tconstructor(\n\t\tprivate readonly _execute: TExecute,\n\t\tcanExecute?: CanExecute,\n\t\tinjector?: Injector,\n\t) {\n\t\tthis.#canExecute = this.#buildCanExecuteSignal(canExecute, injector);\n\t}\n\n\t/** Execute function to invoke. Returns Promise if the execute function returns Observable, otherwise returns the original type. */\n\texecute(...args: Parameters<TExecute>): ExecuteReturnType<TExecute> {\n\t\tif (!this.$canExecute()) {\n\t\t\tthrow new Error(\"Command cannot execute in its current state.\");\n\t\t\t// return Promise.reject() as ReturnType<TExecute>;\n\t\t}\n\t\tthis.$isExecuting.set(true);\n\n\t\t// console.warn(\"[command::execute]\", args);\n\n\t\ttry {\n\t\t\tconst result = args.length > 0 ? this._execute(...args) : this._execute();\n\n\t\t\tif (isObservable(result)) {\n\t\t\t\t// Convert observable to promise using lastValueFrom\n\t\t\t\t// This ensures fire-and-forget execution without requiring manual subscription\n\t\t\t\t// Use defaultValue to handle empty observables (those that complete without emitting)\n\t\t\t\tconst promise = lastValueFrom(result, { defaultValue: undefined })\n\t\t\t\t\t.finally(() => this.$isExecuting.set(false));\n\t\t\t\treturn promise as ExecuteReturnType<TExecute>;\n\t\t\t} else if (result instanceof Promise) {\n\t\t\t\t// Return promise with proper cleanup\n\t\t\t\treturn result\n\t\t\t\t\t.finally(() => this.$isExecuting.set(false)) as ExecuteReturnType<TExecute>;\n\t\t\t}\n\t\t\t// Sync execution\n\t\t\tthis.$isExecuting.set(false);\n\t\t\treturn result as ExecuteReturnType<TExecute>;\n\t\t} catch (err) {\n\t\t\tthis.$isExecuting.set(false);\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t#buildCanExecuteSignal(canExecute?: CanExecute, injector?: Injector): Signal<boolean> {\n\t\tif (canExecute === undefined) {\n\t\t\treturn computed(() => true);\n\t\t}\n\t\tif (isSignal(canExecute)) {\n\t\t\treturn canExecute;\n\t\t}\n\t\tif (typeof canExecute === \"function\") {\n\t\t\treturn computed(canExecute);\n\t\t}\n\t\tif (typeof canExecute === \"boolean\") {\n\t\t\treturn computed(() => canExecute);\n\t\t}\n\t\treturn toSignal(canExecute, { initialValue: false, injector });\n\t}\n\n}\n","import { type AbstractControl, PristineChangeEvent, StatusChangeEvent } from \"@angular/forms\";\nimport { Observable, map, distinctUntilChanged, filter, combineLatest, of, defer, concat } from \"rxjs\";\n\nimport type { CommandCreator, ICommand } from \"./command.model\";\nimport { Command } from \"./command\";\nimport { type Signal, computed } from \"@angular/core\";\n\n/** Determines whether the arg object is of type `Command`. */\nexport function isCommand<T extends ICommand>(arg: unknown | T): arg is T {\n\treturn arg instanceof Command;\n}\n\n/** Determines whether the arg object is of type `CommandCreator`. */\nexport function isCommandCreator<T extends CommandCreator>(arg: unknown | T): arg is T {\n\tif (arg instanceof Command) {\n\t\treturn false;\n\t} else if (isAssumedType<T>(arg) && arg.execute && arg.host) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport interface CanExecuteFormOptions {\n\t/** Determines whether to check for validity. (defaults: true) */\n\tvalidity?: boolean;\n\n\t/** Determines whether to check whether UI has been touched. (defaults: true) */\n\tdirty?: boolean;\n}\n\nconst CAN_EXECUTE_FORM_OPTIONS_DEFAULTS = Object.freeze<CanExecuteFormOptions>({\n\tvalidity: true,\n\tdirty: true,\n})\n\n/** Get can execute from form validity/pristine as an observable. */\nexport function canExecuteFromNgForm(\n\tform: AbstractControl,\n\toptions?: CanExecuteFormOptions\n): Observable<boolean> {\n\tconst opts: CanExecuteFormOptions = options ?\n\t\t{ ...CAN_EXECUTE_FORM_OPTIONS_DEFAULTS, ...options }\n\t\t: CAN_EXECUTE_FORM_OPTIONS_DEFAULTS;\n\n\tconst pristine$ = opts.dirty\n\t\t? concat(\n\t\t\tdefer(() => of(form.pristine)),\n\t\t\tform.events.pipe(\n\t\t\t\tfilter(x => x instanceof PristineChangeEvent),\n\t\t\t\tmap(x => x.pristine),\n\t\t\t)\n\t\t).pipe(distinctUntilChanged(),)\n\t\t: of(true);\n\n\tconst valid$ = opts.validity\n\t\t? concat(\n\t\t\tdefer(() => of(form.valid)),\n\t\t\tform.events.pipe(\n\t\t\t\tfilter(x => x instanceof StatusChangeEvent),\n\t\t\t\tmap(x => x.status === \"VALID\"),\n\t\t\t)\n\t\t).pipe(distinctUntilChanged(),)\n\t\t: of(true);\n\n\treturn combineLatest([pristine$, valid$]).pipe(\n\t\tmap(([pristine, valid]) => !!(!opts.validity || valid) && !!(!opts.dirty || !pristine)),\n\t\tdistinctUntilChanged(),\n\t);\n}\n\n/** Can executed based on valid/dirty signal inputs. */\nexport function canExecuteFromSignals(\n\tsignals: { valid: Signal<boolean>, dirty: Signal<boolean> },\n\toptions?: CanExecuteFormOptions\n): Signal<boolean> {\n\tconst opts: CanExecuteFormOptions = options ?\n\t\t{ ...CAN_EXECUTE_FORM_OPTIONS_DEFAULTS, ...options }\n\t\t: CAN_EXECUTE_FORM_OPTIONS_DEFAULTS;\n\treturn computed(() => !!(!opts.validity || signals.valid()) && !!(!opts.dirty || signals.dirty()));\n}\n\n\nfunction isAssumedType<T = Record<string, unknown>>(x: unknown): x is Partial<T> {\n\treturn x !== null && typeof x === \"object\";\n}\n","import {\n\tDirective,\n\tOnInit,\n\tElementRef,\n\tRenderer2,\n\tChangeDetectorRef,\n\tinject,\n\teffect,\n\tinput,\n\tInjector,\n\tcomputed,\n\tsignal,\n} from \"@angular/core\";\n\nimport { type CommandOptions, COMMAND_OPTIONS } from \"./command.options\";\nimport { command, type Command } from \"./command\";\nimport { isCommand, isCommandCreator } from \"./command.util\";\nimport { CommandCreator, type ICommand, type CanExecute, type ExecuteFn, type CommandParams, type Simplify } from \"./command.model\";\n\n/** Helper type to extract ExecuteFn from ICommand/Command or use ExecuteFn directly */\ntype ExtractExecuteFn<T> = T extends Command<infer TExec>\n\t? TExec\n\t: T extends ICommand<infer TExec>\n\t? TExec\n\t: T extends ExecuteFn\n\t? T\n\t: never;\n\nconst NAME_CAMEL = \"ssvCommand\";\n\n// let nextUniqueId = 0;\n\n/**\n * Controls the state of a component in sync with `Command`.\n *\n * @example\n * ### Most common usage\n * ```html\n * <button [ssvCommand]=\"saveCmd\">Save</button>\n * ```\n *\n *\n * ### Usage with options\n * ```html\n * <button [ssvCommand]=\"saveCmd\" [ssvCommandOptions]=\"{executingCssClass: 'in-progress'}\">Save</button>\n * ```\n *\n *\n * ### Usage with params\n * This is useful for collections (loops) or using multiple actions with different args.\n * *NOTE: This will share the `isExecuting` when used with multiple controls.*\n *\n * #### With single param (direct)\n *\n * ```html\n * <button [ssvCommand]=\"saveCmd\" [ssvCommandParams]=\"hero\">Save</button>\n * ```\n *\n * #### With single param (array)\n *\n * ```html\n * <button [ssvCommand]=\"saveCmd\" [ssvCommandParams]=\"[hero]\">Save</button>\n * ```\n *\n * *NOTE: if you have only 1 argument as an array, it should be enclosed within an array e.g. `[['apple', 'banana']]`,\n * else it will spread and you will get `arg1: \"apple\", arg2: \"banana\"`*\n *\n * #### With multi params\n * ```html\n * <button [ssvCommand]=\"saveCmd\" [ssvCommandParams]=\"[{id: 1}, 'hello', hero]\">Save</button>\n * ```\n *\n * ### Usage with Command Creator\n * This is useful for collections (loops) or using multiple actions with different args, whilst not sharing `isExecuting`.\n *\n *\n * ```html\n * <button [ssvCommand]=\"{host: this, execute: removeHero$, canExecute: isValid$, params: [hero, 1337, 'xx']}\">Save</button>\n * ```\n *\n */\n@Directive({\n\tselector: `[${NAME_CAMEL}]`,\n\thost: {\n\t\t\"[class]\": \"_hostClasses()\",\n\t\t\"(click)\": \"_handleClick()\",\n\t},\n\t// todo: handle keydown/enter?\n\texportAs: NAME_CAMEL,\n\tstandalone: true,\n})\nexport class SsvCommand<T extends ICommand | ExecuteFn = ExecuteFn> implements OnInit {\n\n\t// readonly id = `${NAME_CAMEL}-${nextUniqueId++}`;\n\treadonly #options = inject(COMMAND_OPTIONS);\n\treadonly #renderer = inject(Renderer2);\n\treadonly #element = inject(ElementRef);\n\treadonly #cdr = inject(ChangeDetectorRef);\n\treadonly #injector = inject(Injector);\n\n\treadonly commandOrCreator = input.required<T extends ICommand ? T : (ICommand<ExtractExecuteFn<T>> | CommandCreator<ExtractExecuteFn<T>>)>({\n\t\talias: `ssvCommand`\n\t});\n\treadonly ssvCommandOptions = input<Partial<CommandOptions>>(this.#options);\n\treadonly commandOptions = computed<CommandOptions>(() => {\n\t\tconst value = this.ssvCommandOptions();\n\t\tif (value === this.#options) {\n\t\t\treturn this.#options;\n\t\t}\n\t\treturn {\n\t\t\t...this.#options,\n\t\t\t...value,\n\t\t};\n\t});\n\treadonly ssvCommandParams = input<Simplify<CommandParams<ExtractExecuteFn<T>>>>();\n\treadonly commandParams = computed(() => {\n\t\tconst params = this.ssvCommandParams();\n\t\tif (params === undefined) {\n\t\t\treturn this.#creatorParams();\n\t\t}\n\t\t// Normalize single param to array format for consistent handling\n\t\treturn this.#normalizeParams(params as CommandParams<ExtractExecuteFn<T>>);\n\t});\n\treadonly _hostClasses = computed(() => [\"ssv-command\", this.#executingClass()]);\n\treadonly #executingClass = computed(() => this.#command().$isExecuting() ? this.commandOptions().executingCssClass : \"\");\n\n\treadonly #creatorParams = signal<Parameters<ExtractExecuteFn<T>> | undefined>(undefined);\n\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\treadonly #command = signal<ICommand<ExtractExecuteFn<T>>>(undefined!);\n\treadonly command = this.#command.asReadonly();\n\n\tconstructor() {\n\t\teffect(() => {\n\t\t\tconst canExecute = this.#command().$canExecute();\n\t\t\tthis.trySetDisabled(!canExecute);\n\t\t\t// console.log(\"[ssvCommand::canExecute$]\", { canExecute: x });\n\t\t\tthis.#cdr.markForCheck();\n\t\t});\n\t}\n\n\t// todo: afterNextRender\n\tngOnInit(): void {\n\t\tconst commandOrCreator = this.commandOrCreator();\n\t\t// console.log(\"[ssvCommand::init]\", this.#options);\n\t\tif (isCommand(commandOrCreator)) {\n\t\t\tthis.#command.set(commandOrCreator);\n\t\t} else if (isCommandCreator(commandOrCreator)) {\n\t\t\tthis.#creatorParams.set(this.#normalizeParams(commandOrCreator.params as CommandParams<ExtractExecuteFn<T>>));\n\n\t\t\t// todo: find something like this for ivy (or angular10+)\n\t\t\t// const hostComponent = (this.viewContainer as any)._view.component;\n\n\t\t\tconst execFn = commandOrCreator.execute.bind(commandOrCreator.host) as ExtractExecuteFn<T>;\n\t\t\tconst params = this.commandParams();\n\n\t\t\tlet canExec: CanExecute | undefined;\n\t\t\tif (commandOrCreator.canExecute instanceof Function) {\n\t\t\t\tconst boundFn = commandOrCreator.canExecute.bind(commandOrCreator.host);\n\t\t\t\tconst result = Array.isArray(params) ? boundFn(...params) : boundFn();\n\t\t\t\tcanExec = result as CanExecute;\n\t\t\t} else {\n\t\t\t\tcanExec = commandOrCreator.canExecute;\n\t\t\t}\n\n\t\t\t// console.log(\"[ssvCommand::init] command creator\", {\n\t\t\t// \tfirstParam: params ? params[0] : null,\n\t\t\t// \tparams\n\t\t\t// });\n\t\t\tconst cmd = command(execFn, canExec, { injector: this.#injector });\n\t\t\tthis.#command.set(cmd);\n\t\t} else {\n\t\t\tthrow new Error(`${NAME_CAMEL}: [${NAME_CAMEL}] is not defined properly!`);\n\t\t}\n\t}\n\n\t_handleClick(): void {\n\t\tconst commandParams = this.commandParams();\n\t\t// console.log(\"[ssvCommand::onClick]\", commandParams);\n\t\tif (Array.isArray(commandParams)) {\n\t\t\tthis.#command().execute(...commandParams);\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t(this.#command().execute as any)();\n\t\t}\n\t}\n\n\tprivate trySetDisabled(disabled: boolean) {\n\t\tif (this.commandOptions().handleDisabled) {\n\t\t\t// console.warn(\">>>> disabled\", { id: this.id, disabled });\n\t\t\tthis.#renderer.setProperty(this.#element.nativeElement, \"disabled\", disabled);\n\t\t}\n\t}\n\n\t/** Normalizes params to array format for consistent execution */\n\t#normalizeParams(params: CommandParams<ExtractExecuteFn<T>>): Parameters<ExtractExecuteFn<T>> | undefined {\n\t\t// If params is already an array, return as-is\n\t\tif (Array.isArray(params)) {\n\t\t\treturn params as Parameters<ExtractExecuteFn<T>>;\n\t\t}\n\t\t// Single non-array param - wrap it\n\t\treturn [params] as Parameters<ExtractExecuteFn<T>>;\n\t}\n\n}\n","import { Directive, OnInit, inject, Injector, input, signal } from \"@angular/core\";\n\nimport type { ICommand, CommandCreator, CanExecute, ExecuteFn } from \"./command.model\";\nimport { isCommandCreator } from \"./command.util\";\nimport { command } from \"./command\";\n\nconst NAME_CAMEL = \"ssvCommandRef\";\n\n/**\n * Command creator ref, directive which allows creating Command in the template\n * and associate it to a command (in order to share executions).\n * @example\n * ### Most common usage\n * ```html\n * <div #actionCmd=\"ssvCommandRef\" [ssvCommandRef]=\"{host: this, execute: removeHero$, canExecute: isValid$}\">\n * <button [ssvCommand]=\"actionCmd.command()\" [ssvCommandParams]=\"[hero]\">\n * Remove\n * </button>\n * <button [ssvCommand]=\"actionCmd.command()\" [ssvCommandParams]=\"[hero]\">\n * Remove\n * </button>\n * </div>\n * ```\n *\n */\n@Directive({\n\tselector: `[${NAME_CAMEL}]`,\n\texportAs: NAME_CAMEL,\n\tstandalone: true,\n})\nexport class SsvCommandRef<TExecute extends ExecuteFn = ExecuteFn> implements OnInit {\n\n\treadonly #injector = inject(Injector);\n\n\treadonly commandCreator = input.required<CommandCreator<TExecute>>({\n\t\talias: `ssvCommandRef`\n\t});\n\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\treadonly #command = signal<ICommand<TExecute>>(undefined!);\n\treadonly command = this.#command.asReadonly();\n\n\t// todo: use afterNextRender\n\tngOnInit(): void {\n\t\tconst commandOrCreator = this.commandCreator();\n\t\tif (isCommandCreator(commandOrCreator)) {\n\t\t\tconst commandCreator = commandOrCreator;\n\n\t\t\tconst execFn = commandCreator.execute.bind(commandCreator.host) as TExecute;\n\n\t\t\tconst cmd = command(execFn, commandCreator.canExecute as CanExecute, { injector: this.#injector });\n\t\t\tthis.#command.set(cmd);\n\t\t} else {\n\t\t\tthrow new Error(`${NAME_CAMEL}: [${NAME_CAMEL}] is not defined properly!`);\n\t\t}\n\t}\n\n}\n","import { NgModule } from \"@angular/core\";\n\nimport { SsvCommand } from \"./command.directive\";\nimport { SsvCommandRef } from \"./command-ref.directive\";\n\nconst EXPORTED_IMPORTS = [\n\tSsvCommand,\n\tSsvCommandRef\n];\n\n/** @deprecated Use standalone instead. */\n@NgModule({\n\timports: [EXPORTED_IMPORTS],\n\texports: [EXPORTED_IMPORTS]\n})\nexport class SsvCommandModule {\n\n}\n","export const VERSION = \"5.1.0\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NAME_CAMEL"],"mappings":"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"}