### Install Project Dependencies with Yarn Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/README.md Installs all necessary project dependencies using the Yarn package manager. This is typically the first step before running any other commands. ```shell $ yarn ``` -------------------------------- ### Start Local Development Server with Yarn Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/README.md Starts a local development server for the website. This command opens a browser window and reflects most changes live without requiring a server restart. ```shell $ yarn start ``` -------------------------------- ### Reactive State and Effects with Nrgy Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/src/pages/_usage-example.mdx Demonstrates the core reactive state and effect primitives in Nrgy. It shows how to create atoms, compute derived values, and trigger side effects based on state changes. Dependencies include the 'nrgy' library. ```typescript import { atom, compute, effect, signal } from 'nrgy'; const name = atom('World'); const greetings = compute(() => `Hello ${name()}!`); console.log(greetings()); // console: Hello World! name.update((value) => value.toUpperCase()); effect(greetings, (value) => console.log(value)); // console: Hello WORLD! const changeName = signal(); effect(changeName, (nextValue) => name.set(nextValue)); changeName('UserName'); // console: Hello UserName! ``` -------------------------------- ### Declare State Updates (With Example) Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Declares a record of factories for creating state mutations, providing an example of the state structure. This overload allows for type inference of the 'Updates' based on the provided 'stateExample' and the 'updates' object. It helps in defining and type-checking state mutation functions. ```typescript declareStateUpdates(stateExample, updates: Updates): Updates; ``` -------------------------------- ### Create Store with Factory Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Initializes a state store using the factory. This function allows for creating reactive stores with initial states, optional comparators for state updates, and names for identification. It returns a store object with methods for getting, setting, updating, and querying state. ```typescript import { Observable, Subscription, Observer, Partial } from 'rxjs'; // Assuming types like TeardownLogic, Action, EffectHandler, etc. are defined as in the previous snippets type TeardownLogic = () => void; type Action = { get: () => Event; value$: Observable }; type EffectHandler = (event: Event) => Result | Promise; type EffectPipeline = (source: Observable) => Observable; type EffectError = { event: Event; error: ErrorType }; type EffectNotification = { event: Event; result?: Result; error?: ErrorType; }; interface Effect extends Readonly>; error$: Observable>; final$: Observable>; pending: Readonly<{ get: () => boolean; value$: Observable }>; pendingCount: Readonly<{ get: () => number; value$: Observable }>; result$: Observable; }>> & { handle: (source: Observable | Action | Readonly<{ get: () => Event; value$: Observable }>) => Subscription; } & { destroy: () => void; }> { handle: (source: Observable | Action | Readonly<{ get: () => Event; value$: Observable }>) => Subscription; destroy: () => void; } interface EffectController { // ... properties and methods for effect controller } interface Service { destroy?: () => void; } interface ControllerProps { // ... properties for controller props } interface Controller extends Service { destroy?: () => void; } interface StoreQueryFn { (state: State): any; } interface Store extends Readonly State; value$: Observable; }>> & { query: StoreQueryFn; }> & { id: number; name?: string; notify: () => void; set: (state: State) => void; update: StoreUpdateFunction; } & { destroy: () => void; } > {} type StoreUpdateFunction = (state: State) => State; interface Factory { add: (teardown: TeardownLogic) => void; createController: (factory: () => Readonly void }>) => Readonly void }>; createEffect: ( handler: EffectHandler, options?: Readonly<{ pipeline?: EffectPipeline }> ) => Effect; handle: ( source: Observable | Action | Readonly<{ get: () => Event; value$: Observable }>, handler: EffectHandler, options?: Readonly<{ pipeline?: EffectPipeline }> ) => Effect; onDestroy: (teardown: () => void) => void; subscribe: ( source: Observable ) => Subscription(source: Observable, next: (value: T) => void) => Subscription(source: Observable, observer: Partial>) => Subscription; createStore: ( initialState: State, options?: Readonly<{ comparator?: (prevState: State, nextState: State) => boolean; name?: string; onDestroy?: () => void; }> ) => Store; } // Example usage of createStore: // const userStore = factory.createStore({ name: 'Guest', age: 0 }, { // name: 'userStore', // comparator: (prevState, nextState) => prevState.age === nextState.age // }); // To update the store: // userStore.set({ name: 'Alice', age: 30 }); // userStore.update(state => ({ ...state, age: state.age + 1 })); // To get the current state: // const currentState = userStore.get(); // To subscribe to state changes: // userStore.value$.subscribe(state => console.log('User state changed:', state)); ``` -------------------------------- ### MVVM Pattern: Counter View Model Implementation Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/src/pages/_usage-example.mdx Implements the Counter ViewModel using Nrgy's `declareViewModel` function. It sets up the internal state, effects, and methods for the counter. Dependencies include 'nrgy/mvc' and the defined types. ```typescript import { declareViewModel } from 'nrgy/mvc'; import { CounterViewModelType } from './types.ts'; export const CounterViewModel = declareViewModel( ({ scope, view }) => { const { initialValue } = view.props; const counter = scope.atom(initialValue()); scope.effect(counter, (value) => { // Performing a side effect console.log('counter', value); }); return { state: { counter: counter.asReadonly() }, increase: () => counter.update((prev) => prev + 1), }; }, ); ``` -------------------------------- ### MVVM Pattern: Counter View Model Definition Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/src/pages/_usage-example.mdx Defines the TypeScript types for a Counter ViewModel using Nrgy's MVVM utilities. It specifies the props, state, and methods available in the ViewModel. Dependencies include 'nrgy'. ```typescript import { Atom } from 'nrgy'; import { ViewModel } from 'nrgy/mvc'; export type CounterViewModelType = ViewModel<{ props: { initialValue: Atom }; state: { counter: Atom }; increase(): void; }>; ``` -------------------------------- ### Create Store with Initial State in TypeScript Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md The `createStore` function initializes a reactive store with a given initial state. It provides methods to get the current state, subscribe to state changes via an observable, update the state directly, or update it using a function. Optional configuration includes a comparator for state changes and a name for debugging. ```typescript createStore(initialState: State, options?: Readonly<{ comparator?: (prevState: State, nextState: State) => boolean; name?: string; onDestroy?: () => void }>) => Readonly State; value$: Observable }> & { query: StoreQueryFn }> & { id: number; name?: string; notify: () => void; set: (state: State) => void; update: StoreUpdateFunction } & { destroy: () => void }>; ``` -------------------------------- ### Declare View Models for MVVM in TypeScript Source: https://context7.com/mnasyrov/nrgy/llms.txt Illustrates the use of `declareViewModel` for creating view models in the presentation layer, supporting props binding and state management within the MVVM pattern. It defines props, state, and actions for a counter example. Dependencies include 'nrgy/mvc'. ```typescript import { declareViewModel, Atom, compute } from 'nrgy/mvc'; // Define view model with props and state type CounterViewModel = { props: { initialCount: Atom; step: Atom; }; state: { count: Atom; doubled: Atom; }; increment: () => void; decrement: () => void; reset: () => void; }; const CounterViewModel = declareViewModel(({ scope, view }) => { // Get initial values from props const count = scope.atom(view.props.initialCount()); const doubled = compute(() => count() * 2); // Actions const increment = () => count.update((c) => c + view.props.step()); const decrement = () => count.update((c) => c - view.props.step()); const reset = () => count.set(view.props.initialCount()); // React to prop changes scope.effect(view.props.initialCount, (newInitial) => { console.log('Initial count changed to:', newInitial); }); return { state: { count, doubled }, increment, decrement, reset, }; }); ``` -------------------------------- ### Create Derived Reactive Values with compute() in TypeScript Source: https://context7.com/mnasyrov/nrgy/llms.txt Illustrates the creation of computed atoms using the `compute()` function, which derive their values from other atoms. It shows how computed values are lazily evaluated, cached, and automatically updated when their dependencies change. Examples include combining strings, depending on other computed values, handling multiple dependencies, and using custom equality functions for computed results. ```typescript import { atom, compute, effect } from 'nrgy'; // Create source atoms const firstName = atom('John'); const lastName = atom('Doe'); // Create computed atom const fullName = compute(() => `${firstName()} ${lastName()}`); console.log(fullName()); // Output: John Doe // Updates automatically when dependencies change firstName.set('Jane'); console.log(fullName()); // Output: Jane Doe // Computed values can depend on other computed values const greeting = compute(() => `Hello, ${fullName()}!`); console.log(greeting()); // Output: Hello, Jane Doe! // Multiple dependencies const items = atom([1, 2, 3, 4, 5]); const filter = atom((x: number) => x > 2); const filteredItems = compute(() => items().filter(filter())); console.log(filteredItems()); // Output: [3, 4, 5] // Computed atoms with custom equality const position = atom({ x: 0, y: 0 }); const distance = compute( () => Math.sqrt(position().x ** 2 + position().y ** 2), { equal: (a, b) => Math.abs(a - b) < 0.001 } ); // Effects on computed values effect(distance, (d) => console.log('Distance:', d)); position.set({ x: 3, y: 4 }); // Output: Distance: 5 ``` -------------------------------- ### createStore Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Creates a store for managing application state. ```APIDOC ## POST /api/stores ### Description Creates a `Store` for managing application state. Stores provide a mechanism for holding and updating state in a predictable and reactive manner, often used in conjunction with RxJS observables. ### Method POST ### Endpoint /api/stores ### Parameters #### Request Body - **initialState** (State) - Required - The initial state of the store. - **options** (Readonly<{ comparator?: (prevState: State, nextState: State) => boolean; name?: string; onDestroy?: () => void }>)- Optional - Configuration options for the store, including a custom comparator, name, and an optional destroy callback. ### Request Example ```json { "initialState": { "count": 0 }, "options": { "name": "counterStore", "comparator": "(prevState, nextState) => prevState.count === nextState.count" } } ``` ### Response #### Success Response (200) - **store** (Readonly State; value$: Observable }> & { query: StoreQueryFn }> & { id: number; name?: string; notify: () => void; set: (state: State) => void; update: StoreUpdateFunction }> & { destroy: () => void }>)- The created store object. #### Response Example ```json { "store": { "id": 1, "name": "counterStore", "get": "() => State", "value$": "Observable", "query": "StoreQueryFn", "notify": "() => void", "set": "(state: State) => void", "update": "StoreUpdateFunction", "destroy": "() => void" } } ``` ``` -------------------------------- ### Query Type Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Represents a queryable state provider, offering a way to get the current value and subscribe to its changes. ```APIDOC ## Type: Query ### Description A reactive query that provides access to a state value and allows subscription to its updates. ### Type Parameters - **T**: The type of the value managed by the query. ### Fields - **get** (`() => T`) - A function to synchronously retrieve the current value. - **value$** (`Observable`) - An observable that emits the value whenever it changes. ### Defined in `packages/rx-effects/src/query.ts:6` ``` -------------------------------- ### Store Creation and Updates Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md This section details the creation of a store with initial state and provides mechanisms for updating that state using defined update functions. ```APIDOC ## POST /store ### Description Creates a new store with an initial state and a set of update functions. The store provides methods to get the current state, subscribe to state changes, and update the state. ### Method POST ### Endpoint /store ### Parameters #### Query Parameters - **initialState** (State) - Required - The initial state of the store. #### Request Body - **updates** (Updates) - Required - An object containing functions that define how the state can be mutated. Each function should return a `StateMutation`. ### Request Example ```json { "updates": { "increment": "(state) => state + 1", "decrement": "(state) => state - 1" } } ``` ### Response #### Success Response (200) - **store** (StoreWithUpdates) - An object representing the created store, including methods for state management. #### Response Example ```json { "store": { "id": 1, "name": "MyStore", "get": "() => State", "value$": "Observable", "query": "StoreQueryFn", "notify": "() => void", "set": "(state: State) => void", "update": "(updater: StoreUpdateFunction) => void", "destroy": "() => void" } } ``` #### Defined in [packages/rx-effects/src/store.ts:347](https://github.com/mnasyrov/rx-effects/blob/1454a59/packages/rx-effects/src/store.ts#L347) ``` -------------------------------- ### Declare State Updates API Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Declares factories for creating state mutations. This API provides two overloaded methods for declaring state updates, one requiring an example state and the other inferring it. ```APIDOC ## POST /declareStateUpdates ### Description Declares a record of factories for creating state mutations. This function helps in organizing and type-safely defining how the application state can be updated. ### Method POST ### Endpoint /declareStateUpdates ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body **Overload 1:** `declareStateUpdates()` - **updates** (Updates) - Required - A record of factories for state mutations. **Overload 2:** `declareStateUpdates(stateExample, updates)` - **stateExample** (State) - Required - An example of the state structure. - **updates** (Updates) - Required - A record of factories for state mutations. ### Request Example **Overload 1:** ```json { "updates": { "increment": (count) => count + 1, "decrement": (count) => count - 1 } } ``` **Overload 2:** ```json { "stateExample": { "count": 0 }, "updates": { "increment": (count) => count + 1, "decrement": (count) => count - 1 } } ``` ### Response #### Success Response (200) - **Updates** (Updates) - The record of state update factories. #### Response Example ```json { "message": "State updates declared successfully" } ``` ``` -------------------------------- ### pipeStore Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Creates a deferred or transformed view of a store. ```APIDOC ## pipeStore ### Description Creates a deferred or transformed view of the store. ### Method N/A (Function Signature) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ### Type Parameters - `T`: The type of the store's state. ### Parameters - `store` (`Readonly<...>`): The store to pipe. - `operator` (`MonoTypeOperatorFunction`): The operator to apply to the store's observable. ``` -------------------------------- ### Controller Type Definition Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md The Controller type in rx-effects represents a controller for managing effects and business logic. It extends the ControllerProps and must include a 'destroy' method for cleaning up subscriptions and resources. An example demonstrates how to define a LoggerController. ```typescript Ƭ **Controller**<`ControllerProps`>: `Readonly`<`ControllerProps` & { `destroy`: () => `void` }> Effects and business logic controller. Implementation of the controller must provide `destroy()` method. It should be used for closing subscriptions and disposing resources. **`Example`** ```ts type LoggerController = Controller<{ log: (message: string) => void; }>; ``` ``` -------------------------------- ### Deploy Website using Yarn (SSH) Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/README.md Deploys the website using SSH. This command builds the static content and pushes it to the 'gh-pages' branch, suitable for GitHub Pages hosting. ```shell $ USE_SSH=true yarn deploy ``` -------------------------------- ### Create and Declare Stores for State Management in TypeScript Source: https://context7.com/mnasyrov/nrgy/llms.txt Demonstrates how to create and declare stores using `createStore` and `declareStore` for structured state management in TypeScript. It covers defining state types, update functions, and subscribing to state changes. Dependencies include 'nrgy'. ```typescript import { createStore, declareStore, effect } from 'nrgy'; // Define state type type TodoState = { items: Array<{ id: number; text: string; done: boolean }>; filter: 'all' | 'active' | 'completed'; }; // Using declareStore for reusable store factory const TodoStore = declareStore({ initialState: { items: [], filter: 'all', } as TodoState, updates: { addTodo: (text: string) => (state) => ({ ...state, items: [...state.items, { id: Date.now(), text, done: false }], }), toggleTodo: (id: number) => (state) => ({ ...state, items: state.items.map((item) => item.id === id ? { ...item, done: !item.done } : item ), }), removeTodo: (id: number) => (state) => ({ ...state, items: state.items.filter((item) => item.id !== id), }), setFilter: (filter: TodoState['filter']) => (state) => ({ ...state, filter, }), }, }); // Create store instance const store = TodoStore(); // Subscribe to state changes effect(store, (state) => { console.log('Todos:', state.items.length, 'Filter:', state.filter); }); // Output: Todos: 0 Filter: all // Use typed update functions store.updates.addTodo('Learn Nrgy'); // Output: Todos: 1 Filter: all store.updates.addTodo('Build app'); // Output: Todos: 2 Filter: all store.updates.setFilter('active'); // Output: Todos: 2 Filter: active // Direct state access console.log(store().items[0].text); // Output: Learn Nrgy // Create store with custom initial state const customStore = TodoStore({ items: [{ id: 1, text: 'Preset task', done: false }], filter: 'all' }); // Cleanup store.destroy(); ``` -------------------------------- ### Deploy Website using Yarn (No SSH) Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/README.md Deploys the website without using SSH. Requires specifying the GitHub username for deployment, typically used for GitHub Pages hosting. ```shell $ GIT_USER= yarn deploy ``` -------------------------------- ### createController API Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Documentation for the `createController` function, used to create a controller for managing services. ```APIDOC ## createController API ### Description The `createController` function is a generic function used to create a `Controller` instance. It takes a `factory` function as an argument, which is responsible for creating the service instance that the controller will manage. ### Method (Implicitly a function call, not a standard HTTP method) ### Endpoint (Not applicable, this is a library function) ### Parameters #### Path Parameters (Not applicable) #### Query Parameters (Not applicable) #### Request Body (Not applicable) ### Request Example ```typescript import { createController } from '@rx-effects/controller'; interface MyService { // ... service methods } const controller = createController(() => { // factory function to create MyService instance return { /* ... */ }; }); ``` ### Response #### Success Response (200) - **Controller** (`Controller`): Returns a controller instance that manages the provided service. #### Response Example (Not applicable, this is a type definition) ### Type Parameters - **Service**: A type that extends `AnyObject`, representing the type of the service managed by the controller. ``` -------------------------------- ### Map Query Values in TypeScript Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md The `mapQuery` function transforms the value of an existing query by applying a mapping function. It takes a source query (an object with `get` and `value$` properties) and a mapper function, returning a new query with the transformed values. ```typescript mapQuery(query: Readonly<{ get: () => T; value$: Observable }>, mapper: (value: T) => R): Query; ``` -------------------------------- ### Manage Subscriptions and Resources with Scopes Source: https://github.com/mnasyrov/nrgy/wiki/Getting-Started Shows how to use `scope` to manage subscriptions and resources, allowing for their cleanup when no longer needed. Includes adding destroyable resources and callbacks for scope destruction. ```typescript import { scope } from 'nrgy'; import { Subject } from 'rxjs'; // Create the scope const scope = createScope(); // Use built-in helpers for core components const counter = scope.atom(1); const onValue = scope.signal(); scope.effect(counter, onValue); scope.effect(onValue, (value) => console.log(value)); // Register some destroyable resource const someRxObservable = new Subject(); scope.add( someRxObservable.subscribe(() => { console.log(); }), ); // Register a callback to be called on scope destruction scope.onDestroy(() => console.log('The scope is destroyed')); // Destroy the scope scope.destroy(); ``` -------------------------------- ### MVVM Pattern: Counter Higher-Order Component Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/src/pages/_usage-example.mdx A React Higher-Order Component (HOC) that combines the Counter ViewModel and Counter View. It uses Nrgy's `withViewModel` HOC to provide the ViewModel instance to the View component. Dependencies include 'nrgy/mvc-react'. ```typescript import { withViewModel } from 'nrgy/mvc-react'; import { CounterView } from './counter.view.tsx'; import { CounterViewModel } from './counter.viewModel.tsx'; // HOC component combines the view and the view model export const Counter = withViewModel(CounterViewModel)(CounterView); ``` -------------------------------- ### withStoreUpdates Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Creates a proxy for the store with "updates" to change a state by provided mutations. ```APIDOC ## withStoreUpdates ### Description Creates a proxy for the store with "updates" to change a state by provided mutations. ### Method N/A (Function Signature) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ### Type Parameters - `State`: The type of the store's state. - `Updates`: The type of the updates object. ### Parameters - `store` (The store object) - `updates` (The updates object. ``` -------------------------------- ### Declare State Updates (No Example) Source: https://github.com/mnasyrov/nrgy/blob/0.x/docs/README.md Declares a record of factories for creating state mutations. This function is generic over the 'State' type and returns a function that accepts 'updates' of type 'StateUpdates' and returns the same 'Updates'. It's used to define how the application state can be modified. ```typescript declareStateUpdates(): (updates: Updates) => Updates; ``` -------------------------------- ### MVVM Pattern: Counter View Component Source: https://github.com/mnasyrov/nrgy/blob/0.x/website/src/pages/_usage-example.mdx A React functional component for the Counter View. It uses Nrgy's `useAtoms` hook to subscribe to ViewModel state and renders the current count and a button to increase it. Dependencies include 'nrgy/react' and the ViewModel types. ```typescript import { useAtoms } from 'nrgy/react'; import { FC } from 'react'; import { CounterViewModelType } from './types.ts'; export const CounterView: FC<{ viewModel: CounterViewModelType; label: string; }> = ({ viewModel, label }) => { const { value } = useAtoms(viewModel.state); return ( <> {label}: {value}