From 28c72a515d86e9f24deb5e130daa8d03d7b468ee Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sat, 14 Sep 2024 17:33:53 +0330 Subject: [PATCH 01/12] refactor: Update repository name and description Update the repository name and description to reflect the changes made in the code. The repository is now called "alwatr-flux" and the description highlights the state management and event handling capabilities provided by Alwatr Flux. This update ensures that the repository accurately represents the functionality and purpose of the code. --- README.md | 29 +++++++++++++---------------- package.json | 6 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 9b748eae..6d9044aa 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,26 @@ -# Alwatr Signal +# Alwatr Flux - Elegant State Management and Event System ## Introduction -Elegant powerful event system for handle global signals and states base on observable design pattern, written in tiny TypeScript module. +Alwatr Flux empowers your applications with elegant and powerful state management and event handling capabilities. Built on the observable design pattern, Flux provides a lightweight yet robust foundation for managing global signals and states. -Every signal has own value and can be used as a advance **state management** like redux and recoil without the complexities and unnecessary facilities of those libraries. +**Key Features:** -Contains the following packages: +- **Intuitive State Management:** Embrace Flux as an advanced alternative to Redux or Recoil, minus the complexities and unnecessary overhead. Each signal maintains its own value, offering seamless state control. +- **Finite-State Machines (FSM):** Leverage observables to gracefully manage invocations and state transitions within your finite-state machines. +- **Server Context Management:** Effortlessly handle server-side context with Flux's elegant context manager, ensuring optimal organization and control. +- ... -1. [Finite-state machines (FSM)](./packages/logger): Managing invocations finite-state machines base on observable signal pattern. -2. [Server Context](./packages/server-context): Elegant powerful server-context manager base on alwatr signal. -3. [Signal](./packages/signal): Elegant powerful event system for handle global signals and states. - - +## Usage -## Installation +Refer to the individual package READMEs for comprehensive usage instructions and examples. -```bash -npm install @alwatr/module-name -``` +## Contributing -## Usage - -Follow each package's README for usage instructions. +Contributions are welcome! Please consult the CONTRIBUTING guidelines for detailed information on how to get involved. ## License [MIT](./LICENSE) + +``` diff --git a/package.json b/package.json index 0f701704..ec36a7fb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "alwatr-signal", - "description": "Elegant powerful event system for handle global signals and states base on observable design pattern, written in tiny TypeScript module.", - "repository": "https://github.com/Alwatr/signal", + "name": "alwatr-flux", + "description": "Alwatr Flux empowers your applications with elegant and powerful state management and event handling capabilities. Built on the observable design pattern, Flux provides a lightweight yet robust foundation for managing global signals and states.", + "repository": "https://github.com/Alwatr/flux", "author": "S. Ali Mihandoost (https://ali.mihandoost.com)", "license": "MIT", "type": "module", From 44dd077584669f668ab633c0e10a1d6dd6986e21 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sat, 14 Sep 2024 17:34:13 +0330 Subject: [PATCH 02/12] refactor: Update AlwatrContextSignal to AlwatrContext This commit updates the class name from AlwatrContextSignal to AlwatrContext in the `context.ts` file. The class represents the Alwatr Context and is responsible for managing and notifying subscribers of context changes. The update aligns the class name with its purpose and improves code clarity. The commit also updates the import statement for the `Dictionary` type from `@alwatr/type-helper` in the `context.ts` file. Refactor the class name and import statement for better code clarity and consistency. --- packages/signal/src/context.ts | 16 ++--- packages/signal/src/{index.ts => main.ts} | 2 +- packages/signal/src/multithread-context.ts | 12 ++-- packages/signal/src/observable.ts | 69 +++++++++++----------- packages/signal/src/signal.ts | 4 +- packages/signal/src/simple-signal.ts | 4 +- packages/signal/src/type.ts | 2 +- 7 files changed, 56 insertions(+), 53 deletions(-) rename packages/signal/src/{index.ts => main.ts} (78%) diff --git a/packages/signal/src/context.ts b/packages/signal/src/context.ts index 5092cbdc..e9abeded 100644 --- a/packages/signal/src/context.ts +++ b/packages/signal/src/context.ts @@ -1,9 +1,11 @@ import {AlwatrObservable} from './observable.js'; +import type { Dictionary } from '@alwatr/type-helper'; + /** - * Alwatr context signal. + * Alwatr Context. */ -export class AlwatrContextSignal extends AlwatrObservable { +export class AlwatrContext extends AlwatrObservable { constructor(config: {name: string; loggerPrefix?: string}) { config.loggerPrefix ??= 'context-signal'; super(config); @@ -15,15 +17,15 @@ export class AlwatrContextSignal extends AlwatrObservable { * Return undefined if context not set before or expired. */ getValue(): T | undefined { - return super._getData(); + return super.getData_(); } /** * Set context value and notify all subscribers. */ setValue(value: T): void { - this._logger.logMethodArgs?.('setValue', {value}); - super._notify(value); + this.logger_.logMethodArgs?.('setValue', {value}); + super.notify_(value); } /** @@ -32,13 +34,13 @@ export class AlwatrContextSignal extends AlwatrObservable { * `receivePrevious` in new subscribers not work until new context changes. */ expire(): void { - super._clear(); + super.clearData_(); } /** * Get the value of the next context changes. */ untilChange(): Promise { - return super._untilNewNotify(); + return super.untilNewNotify_(); } } diff --git a/packages/signal/src/index.ts b/packages/signal/src/main.ts similarity index 78% rename from packages/signal/src/index.ts rename to packages/signal/src/main.ts index f4a673fe..7192d120 100644 --- a/packages/signal/src/index.ts +++ b/packages/signal/src/main.ts @@ -2,5 +2,5 @@ export * from './observable.js'; export * from './simple-signal.js'; export * from './signal.js'; export * from './context.js'; -export * from './multithread-context.js'; +// export * from './multithread-context.js'; export type * from './type.js'; diff --git a/packages/signal/src/multithread-context.ts b/packages/signal/src/multithread-context.ts index 83ffd675..d59ccf6b 100644 --- a/packages/signal/src/multithread-context.ts +++ b/packages/signal/src/multithread-context.ts @@ -1,6 +1,6 @@ import {createLogger} from '@alwatr/logger'; -import {AlwatrContextSignal} from './context.js'; +import {AlwatrContext} from './context.js'; interface AlwatrContextChangedMessage { type: 'alwatr_context_changed'; @@ -11,7 +11,7 @@ interface AlwatrContextChangedMessage { /** * Alwatr multithread context signal. */ -export class AlwatrMultithreadContextSignal extends AlwatrContextSignal { +export class AlwatrMultithreadContextSignal extends AlwatrContext { protected static _logger = createLogger(`alwatr/mt-context`); protected static _worker?: Worker; protected static _registry: Record | undefined> = {}; @@ -29,7 +29,7 @@ export class AlwatrMultithreadContextSignal extends AlwatrContextSignal< if (context === undefined) { throw new Error('context_not_define', {cause: 'context not define in this thread yet!'}); } - context._notify(message.payload); + context.notify_(message.payload); } static _postMessage(name: string, payload: unknown): void { @@ -47,11 +47,11 @@ export class AlwatrMultithreadContextSignal extends AlwatrContextSignal< constructor(config: {name: string; loggerPrefix?: string}) { super(config); - if (AlwatrMultithreadContextSignal._registry[this._name] !== undefined) { + if (AlwatrMultithreadContextSignal._registry[this.name_] !== undefined) { throw new Error('context_name_exist'); } - AlwatrMultithreadContextSignal._registry[this._name] = this as AlwatrMultithreadContextSignal; + AlwatrMultithreadContextSignal._registry[this.name_] = this as AlwatrMultithreadContextSignal; } /** @@ -59,6 +59,6 @@ export class AlwatrMultithreadContextSignal extends AlwatrContextSignal< */ override setValue(value: TValue): void { super.setValue(value); - AlwatrMultithreadContextSignal._postMessage(this._name, value); + AlwatrMultithreadContextSignal._postMessage(this.name_, value); } } diff --git a/packages/signal/src/observable.ts b/packages/signal/src/observable.ts index 053a9205..bd070c37 100644 --- a/packages/signal/src/observable.ts +++ b/packages/signal/src/observable.ts @@ -1,23 +1,24 @@ import {createLogger, definePackage} from '@alwatr/logger'; import type {SubscribeOptions, ListenerCallback, Observer, SubscribeResult, AlwatrObservableInterface} from './type.js'; +import type {} from '@alwatr/nano-build'; -definePackage('signal', '2.x'); +definePackage('@alwatr/signal', __package_version__); /** * Alwatr base signal. */ export abstract class AlwatrObservable implements AlwatrObservableInterface { - protected _name; - protected _logger; - protected _$data?: T; - protected _$observers: Observer[] = []; + protected name_; + protected logger_; + protected data__?: T; + protected observers__: Observer[] = []; constructor(config: {name: string; loggerPrefix?: string}) { config.loggerPrefix ??= 'signal'; - this._name = config.name; - this._logger = createLogger(`{${config.loggerPrefix}: ${this._name}}`); - this._logger.logMethod?.('constructor'); + this.name_ = config.name; + this.logger_ = createLogger(`{${config.loggerPrefix}: ${this.name_}}`); + this.logger_.logMethod?.('constructor'); } /** @@ -25,38 +26,38 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface this._$dispatch(data), 0); + protected notify_(data: T): void { + this.logger_.logMethodArgs?.('notify_', data); + this.data__ = data; + setTimeout(() => this.dispatch__(data), 0); } /** * Execute all observers callback. */ - protected _$dispatch(data: T): void { + protected dispatch__(data: T): void { const removeList: Observer[] = []; - for (const listener of this._$observers) { + for (const listener of this.observers__) { if (listener.options.disabled) continue; if (listener.options.once) removeList.push(listener); try { const ret = listener.callback.call(this, data); if (ret instanceof Promise) { - ret.catch((err) => this._logger.error('_$dispatch', 'call_listener_failed', err)); + ret.catch((err) => this.logger_.error('dispatch__', 'call_listener_failed', err)); } } catch (err) { - this._logger.error('_$dispatch', 'call_listener_failed', err); + this.logger_.error('dispatch__', 'call_listener_failed', err); } } @@ -69,15 +70,15 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface, options: SubscribeOptions = {}): SubscribeResult { - this._logger.logMethodArgs?.('subscribe', {options}); + this.logger_.logMethodArgs?.('subscribe', {options}); - const _listenerObject: Observer = { + const listenerObject_: Observer = { callback: listenerCallback, options, }; let callbackExecuted = false; - const data = this._$data; + const data = this.data__; if (data !== undefined && options.receivePrevious === true && options.disabled !== true) { // Run callback for old dispatch signal callbackExecuted = true; @@ -85,11 +86,11 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface this._logger.error('subscribe.receivePrevious', 'call_signal_callback_failed', err)); + ret.catch((err) => this.logger_.error('subscribe.receivePrevious', 'call_signal_callback_failed', err)); } } catch (err) { - this._logger.error('subscribe.receivePrevious', 'call_signal_callback_failed', err); + this.logger_.error('subscribe.receivePrevious', 'call_signal_callback_failed', err); } }, 0); } @@ -97,10 +98,10 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface implements AlwatrObservableInterface): void { - this._logger.logMethod?.('unsubscribe'); - const listenerIndex = this._$observers.findIndex((listener) => listener.callback === listenerCallback); + this.logger_.logMethod?.('unsubscribe'); + const listenerIndex = this.observers__.findIndex((listener) => listener.callback === listenerCallback); if (listenerIndex !== -1) { - void this._$observers.splice(listenerIndex, 1); + void this.observers__.splice(listenerIndex, 1); } } @@ -125,16 +126,16 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface { - this._logger.logMethod?.('_untilNewNotify'); + protected untilNewNotify_(): Promise { + this.logger_.logMethod?.('untilNewNotify_'); return new Promise((resolve) => { this.subscribe(resolve, { once: true, diff --git a/packages/signal/src/signal.ts b/packages/signal/src/signal.ts index 3ee5eb14..d5fd2beb 100644 --- a/packages/signal/src/signal.ts +++ b/packages/signal/src/signal.ts @@ -13,13 +13,13 @@ export class AlwatrSignal extends AlwatrObservable { * Dispatch an event to all listeners. */ notify(detail: T): void { - this._notify(detail); + this.notify_(detail); } /** * Wait until next event. */ untilNewNotify(): Promise { - return super._untilNewNotify(); + return super.untilNewNotify_(); } } diff --git a/packages/signal/src/simple-signal.ts b/packages/signal/src/simple-signal.ts index e2f01f03..572f2430 100644 --- a/packages/signal/src/simple-signal.ts +++ b/packages/signal/src/simple-signal.ts @@ -13,13 +13,13 @@ export class AlwatrSimpleSignal extends AlwatrObservable { * Dispatch an event to all listeners. */ notify(): void { - this._notify(undefined); + this.notify_(undefined); } /** * Wait until next event signal. */ untilNewNotify(): Promise { - return super._untilNewNotify(); + return super.untilNewNotify_(); } } diff --git a/packages/signal/src/type.ts b/packages/signal/src/type.ts index 5127d82e..e8ed8057 100644 --- a/packages/signal/src/type.ts +++ b/packages/signal/src/type.ts @@ -1,4 +1,4 @@ -import type {MaybePromise} from '@alwatr/type'; +import type {MaybePromise} from '@alwatr/type-helper'; /** * Subscribe options type. From 01283652b0798243aaac9643c5024e7856af169c Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:09:02 +0330 Subject: [PATCH 03/12] deps: update --- package.json | 2 +- packages/fsm/package.json | 2 ++ yarn.lock | 13 +++++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ec36a7fb..7049e6e2 100644 --- a/package.json +++ b/package.json @@ -60,5 +60,5 @@ "prettier": "^3.3.3", "typescript": "^5.6.2" }, - "packageManager": "yarn@4.4.1" + "packageManager": "yarn@4.5.0" } diff --git a/packages/fsm/package.json b/packages/fsm/package.json index 228eaaf3..b88379e9 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -61,12 +61,14 @@ }, "dependencies": { "@alwatr/logger": "^3.2.12", + "@alwatr/polyfill-has-own": "1.0.8", "@alwatr/signal": "workspace:^" }, "devDependencies": { "@alwatr/nano-build": "^1.3.8", "@alwatr/prettier-config": "^1.0.4", "@alwatr/tsconfig-base": "^1.2.0", + "@alwatr/type-helper": "^1.2.5", "@types/node": "^22.5.5", "jest": "^29.7.0", "typescript": "^5.6.2" diff --git a/yarn.lock b/yarn.lock index 06096e76..2ef5521d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -45,9 +45,11 @@ __metadata: dependencies: "@alwatr/logger": "npm:^3.2.12" "@alwatr/nano-build": "npm:^1.3.8" + "@alwatr/polyfill-has-own": "npm:1.0.8" "@alwatr/prettier-config": "npm:^1.0.4" "@alwatr/signal": "workspace:^" "@alwatr/tsconfig-base": "npm:^1.2.0" + "@alwatr/type-helper": "npm:^1.2.5" "@types/node": "npm:^22.5.5" jest: "npm:^29.7.0" typescript: "npm:^5.6.2" @@ -89,6 +91,13 @@ __metadata: languageName: node linkType: hard +"@alwatr/polyfill-has-own@npm:1.0.8": + version: 1.0.8 + resolution: "@alwatr/polyfill-has-own@npm:1.0.8" + checksum: 10c0/7599bb5a098ff084f47ae384465303b8be9be19e74db624c34a5cda9484c46de91928b4fdae3b208a12f68c299c8e1a050e8e2ba08f1fa2e68866673342dfc3a + languageName: node + linkType: hard + "@alwatr/prettier-config@npm:^1.0.4": version: 1.0.4 resolution: "@alwatr/prettier-config@npm:1.0.4" @@ -2312,9 +2321,9 @@ __metadata: languageName: node linkType: hard -"alwatr-signal@workspace:.": +"alwatr-flux@workspace:.": version: 0.0.0-use.local - resolution: "alwatr-signal@workspace:." + resolution: "alwatr-flux@workspace:." dependencies: "@alwatr/eslint-config": "npm:^1.2.5" "@alwatr/prettier-config": "npm:^1.0.4" From bbe18bbb3ca105ee34d802345105a71c874b60e5 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:11:09 +0330 Subject: [PATCH 04/12] refactor(signal): AlwatrContext to use class property instead of calling super.getData_() --- packages/signal/src/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/signal/src/context.ts b/packages/signal/src/context.ts index e9abeded..5885faf0 100644 --- a/packages/signal/src/context.ts +++ b/packages/signal/src/context.ts @@ -17,7 +17,7 @@ export class AlwatrContext extends AlwatrObservable { * Return undefined if context not set before or expired. */ getValue(): T | undefined { - return super.getData_(); + return this.data_; } /** From 437dbf48af845c7e8c7441566d78ff6884d1c4cc Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:11:25 +0330 Subject: [PATCH 05/12] refactor(signal): Update AlwatrContext to use class property instead of calling super.getData_() --- packages/signal/src/observable.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/signal/src/observable.ts b/packages/signal/src/observable.ts index bd070c37..8524558c 100644 --- a/packages/signal/src/observable.ts +++ b/packages/signal/src/observable.ts @@ -11,24 +11,14 @@ definePackage('@alwatr/signal', __package_version__); export abstract class AlwatrObservable implements AlwatrObservableInterface { protected name_; protected logger_; - protected data__?: T; + protected data_?: T; protected observers__: Observer[] = []; constructor(config: {name: string; loggerPrefix?: string}) { config.loggerPrefix ??= 'signal'; this.name_ = config.name; this.logger_ = createLogger(`{${config.loggerPrefix}: ${this.name_}}`); - this.logger_.logMethod?.('constructor'); - } - - /** - * Get data. - * - * Return undefined if signal not notify before or expired. - */ - protected getData_(): T | undefined { - this.logger_.logMethodFull?.('getData_', {}, this.data__); - return this.data__; + this.logger_.logMethodArgs?.('new', config); } /** @@ -36,7 +26,7 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface this.dispatch__(data), 0); } @@ -78,7 +68,7 @@ export abstract class AlwatrObservable implements AlwatrObservableInterface implements AlwatrObservableInterface Date: Sun, 15 Sep 2024 10:12:11 +0330 Subject: [PATCH 06/12] refactor(server-context): rename main --- packages/server-context/src/{index.ts => main.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/server-context/src/{index.ts => main.ts} (100%) diff --git a/packages/server-context/src/index.ts b/packages/server-context/src/main.ts similarity index 100% rename from packages/server-context/src/index.ts rename to packages/server-context/src/main.ts From 27a29ca45fb2c7998760ce2177a386c7085011f9 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:12:28 +0330 Subject: [PATCH 07/12] refactor(fsm): Update FiniteStateMachineBase class - Remove unused import - Update dependencies - Update type imports - Update package version - Rename internal variables - Update method names - Update method signatures - Update logger calls - Update action execution - Update reset method --- packages/fsm/src/base.ts | 89 +++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/packages/fsm/src/base.ts b/packages/fsm/src/base.ts index d03c8f6f..b1257b5e 100644 --- a/packages/fsm/src/base.ts +++ b/packages/fsm/src/base.ts @@ -1,61 +1,64 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ import {definePackage} from '@alwatr/logger'; +import '@alwatr/polyfill-has-own'; import {AlwatrObservable} from '@alwatr/signal'; import type {ActionName, ActionRecord, StateEventDetail, StateRecord} from './type.js'; -import type {MaybePromise} from '@alwatr/type'; +import type {} from '@alwatr/nano-build'; +import type {MaybePromise} from '@alwatr/type-helper'; -definePackage('fsm', '2.x'); +definePackage('@alwatr/signal', __package_version__); /** * Finite State Machine Base Class */ export abstract class FiniteStateMachineBase extends AlwatrObservable { - /** - * Current state - */ - protected get _state(): S { - return this._getData()!; - } - /** * States and transitions config. */ - protected _stateRecord: StateRecord = {}; + protected stateRecord_: StateRecord = {}; /** * Bind actions name to class methods */ - protected _actionRecord: ActionRecord = {}; + protected actionRecord_: ActionRecord = {}; - protected _initialState: S; + protected initialState_: S; + + protected override data_: S; constructor(config: {name: string; loggerPrefix?: string; initialState: S}) { config.loggerPrefix ??= 'fsm'; super(config); - this._initialState = config.initialState; - this._reset(); + this.data_ = this.initialState_ = config.initialState; + } + + /** + * Reset machine to initial state. + */ + protected resetToInitialState_(): void { + this.logger_.logMethod?.('resetToInitialState_'); + this.data_ = this.initialState_; } /** * Transition condition. */ - protected _shouldTransition(_eventDetail: StateEventDetail): MaybePromise { - this._logger.logMethodFull?.('_shouldTransition', _eventDetail, true); + protected shouldTransition_(_eventDetail: StateEventDetail): MaybePromise { + this.logger_.logMethodFull?.('shouldTransition_', _eventDetail, true); return true; } /** * Transition finite state machine instance to new state. */ - protected async _transition(event: E): Promise { - const fromState = this._state; - const toState = this._stateRecord[fromState]?.[event] ?? this._stateRecord._all?.[event]; + protected async transition_(event: E): Promise { + const fromState = this.data_; + const toState = this.stateRecord_[fromState]?.[event] ?? this.stateRecord_._all?.[event]; - this._logger.logMethodArgs?.('_transition', {fromState, event, toState}); + this.logger_.logMethodArgs?.('transition_', {fromState, event, toState}); if (toState == null) { - this._logger.incident?.('transition', 'invalid_target_state', { + this.logger_.incident?.('transition', 'invalid_target_state', { fromState, event, }); @@ -64,51 +67,45 @@ export abstract class FiniteStateMachineBase const eventDetail: StateEventDetail = {from: fromState, event, to: toState}; - if ((await this._shouldTransition(eventDetail)) !== true) return; + if ((await this.shouldTransition_(eventDetail)) !== true) return; - this._notify(toState); + this.notify_(toState); - this._transitioned(eventDetail); + this.postTransition__(eventDetail); } /** * Execute all actions for current state. */ - protected async _transitioned(eventDetail: StateEventDetail): Promise { - this._logger.logMethodArgs?.('_transitioned', eventDetail); + protected async postTransition__(eventDetail: StateEventDetail): Promise { + this.logger_.logMethodArgs?.('_transitioned', eventDetail); - await this._$execAction(`_on_${eventDetail.event}`, eventDetail); + await this.execAction__(`_on_${eventDetail.event}`, eventDetail); if (eventDetail.from !== eventDetail.to) { - await this._$execAction(`_on_state_exit`, eventDetail); - await this._$execAction(`_on_${eventDetail.from}_exit`, eventDetail); - await this._$execAction(`_on_state_enter`, eventDetail); - await this._$execAction(`_on_${eventDetail.to}_enter`, eventDetail); + await this.execAction__(`_on_state_exit`, eventDetail); + await this.execAction__(`_on_${eventDetail.from}_exit`, eventDetail); + await this.execAction__(`_on_state_enter`, eventDetail); + await this.execAction__(`_on_${eventDetail.to}_enter`, eventDetail); } - if (`_on_${eventDetail.from}_${eventDetail.event}` in this) { - this._$execAction(`_on_${eventDetail.from}_${eventDetail.event}`, eventDetail); + if (Object.hasOwn(this, `_on_${eventDetail.from}_${eventDetail.event}`)) { + this.execAction__(`_on_${eventDetail.from}_${eventDetail.event}`, eventDetail); } else { - this._$execAction(`_on_all_${eventDetail.event}`, eventDetail); + // The action `all_eventName` is executed only if the action `fromState_eventName` is not defined. + this.execAction__(`_on_all_${eventDetail.event}`, eventDetail); } } /** * Execute action name if defined in _actionRecord. */ - protected _$execAction(name: ActionName, eventDetail: StateEventDetail): MaybePromise { - const actionFn = this._actionRecord[name]; + protected execAction__(name: ActionName, eventDetail: StateEventDetail): MaybePromise { + const actionFn = this.actionRecord_[name]; if (typeof actionFn === 'function') { - this._logger.logMethodArgs?.('_$execAction', name); - return this._actionRecord[name]?.call(this, eventDetail); + this.logger_.logMethodArgs?.('_$execAction', name); + return actionFn.call(this, eventDetail); } } - - /** - * Reset machine to initial state. - */ - protected _reset(): void { - this._$data = this._initialState; - } } From 647a921dab405b5545aecdb66f5d1d44490795d4 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:12:45 +0330 Subject: [PATCH 08/12] refactor(fsm): Update FiniteStateMachineBase class to use class property for state and transition methods --- packages/fsm/src/fsm.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fsm/src/fsm.ts b/packages/fsm/src/fsm.ts index 924301ee..4493374a 100644 --- a/packages/fsm/src/fsm.ts +++ b/packages/fsm/src/fsm.ts @@ -7,14 +7,14 @@ export abstract class FiniteStateMachine ext /** * Current state. */ - get state(): S { - return super._state; + getState(): S { + return this.data_; } /** * Transition finite state machine instance to new state. */ transition(event: E): void { - super._transition(event); + this.transition_(event); } } From 60a52bdc1e5ae3126226a9518d81f3c8dbf238dc Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:12:56 +0330 Subject: [PATCH 09/12] refactor(fsm): rename main --- packages/fsm/src/{index.ts => main.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/fsm/src/{index.ts => main.ts} (100%) diff --git a/packages/fsm/src/index.ts b/packages/fsm/src/main.ts similarity index 100% rename from packages/fsm/src/index.ts rename to packages/fsm/src/main.ts From 6091385ae7a4c4d92aa74effe6446c8e3a7606e9 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:13:04 +0330 Subject: [PATCH 10/12] refactor(fsm): Update import statement for type.ts --- packages/fsm/src/type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fsm/src/type.ts b/packages/fsm/src/type.ts index 577f47d6..ace36eb9 100644 --- a/packages/fsm/src/type.ts +++ b/packages/fsm/src/type.ts @@ -1,4 +1,4 @@ -import type {MaybePromise} from '@alwatr/type'; +import type {MaybePromise} from '@alwatr/type-helper'; export interface StateEventDetail { from: S; From 17b566993a59be82aef59e6db336c6358856d5ea Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:13:13 +0330 Subject: [PATCH 11/12] refactor(server-context): Update import statements and package version in server-request.ts --- packages/server-context/src/server-request.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/server-context/src/server-request.ts b/packages/server-context/src/server-request.ts index 630dfb9c..04c6a6ad 100644 --- a/packages/server-context/src/server-request.ts +++ b/packages/server-context/src/server-request.ts @@ -2,9 +2,10 @@ import {fetch} from '@alwatr/fetch'; import {ActionRecord, FiniteStateMachineBase, StateRecord} from '@alwatr/fsm'; import {definePackage} from '@alwatr/logger'; -import type {FetchOptions} from '@alwatr/fetch/type.js'; +import type {FetchOptions} from '@alwatr/fetch'; +import type {} from '@alwatr/nano-build'; -definePackage('server-context', '2.x'); +definePackage('@alwatr/signal', __package_version__); export interface ServerRequestConfig extends Partial { name: string; From 3c6b2e6c8e874240ba785cfafe14922637070120 Mon Sep 17 00:00:00 2001 From: Ali Mihandoost Date: Sun, 15 Sep 2024 10:13:20 +0330 Subject: [PATCH 12/12] refactor(signal): Remove reference to api-server in tsconfig.json --- packages/signal/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/signal/tsconfig.json b/packages/signal/tsconfig.json index 8a8312fa..9bea7a7a 100644 --- a/packages/signal/tsconfig.json +++ b/packages/signal/tsconfig.json @@ -7,5 +7,5 @@ "composite": true, }, "include": ["src/**/*.ts"], - "references": [{"path": "../api-server"}], + "references": [], }