### Install Nano Stores Logger Source: https://github.com/nanostores/logger/blob/main/README.md Install the Nano Stores Logger package using npm. ```sh npm install @nanostores/logger ``` -------------------------------- ### Async Actions with Callbacks Source: https://context7.com/nanostores/logger/llms.txt Use async functions with actions to automatically track start, completion, and errors. Ensure necessary imports are included. ```javascript import { action } from '@nanostores/logger' import { logger } from '@nanostores/logger' import { map } from 'nanostores' let $user = map({ username: 'guest', fullname: 'Guest User', loading: false }) // Async action - logger tracks start, end, and errors automatically let fetchUser = action($user, 'Fetch User', async (store, userId) => { store.setKey('loading', true) try { let response = await fetch(`/api/users/${userId}`) let data = await response.json() store.setKey('username', data.username) store.setKey('fullname', data.fullname) } finally { store.setKey('loading', false) } }) // Async action with error handling let dangerousAction = action($user, 'Dangerous Action', async (store) => { await someAsyncOperation() throw new Error('Something went wrong') // Error will be logged automatically by logger }) logger({ User: $user }) $user.listen(() => {}) await fetchUser('123') // Logs: action start → changes → action end try { await dangerousAction() } catch (e) { // Error is logged in console with action name } ``` -------------------------------- ### Basic Logger Setup for Nano Stores Source: https://context7.com/nanostores/logger/llms.txt Use the logger function to track mount, unmount, change, and action events for specified Nano Stores instances. Call the returned destroy function to stop logging. ```javascript import { logger } from '@nanostores/logger' import { atom, map } from 'nanostores' // Create stores let $counter = atom(0) let $user = map({ id: 'A10', username: 'suetin', fullname: 'Nikolay Suetin', artworks: 213 }) // Start logging with descriptive names let destroy = logger({ 'Counter': $counter, 'User': $user }) // All store operations are now logged: let unbind = $counter.listen(() => {}) // Logs: "Counter store was mounted" $counter.set(1) // Logs: "Counter store was changed" with 0 → 1 $user.setKey('artworks', 300) // Logs: "User store was changed in the artworks key" unbind() // Logs: "Counter store was unmounted" // Stop logging when done destroy() ``` -------------------------------- ### Action with Async Callbacks Source: https://context7.com/nanostores/logger/llms.txt Demonstrates how to use the `action` function to wrap asynchronous operations. The logger automatically tracks the start, completion, and errors of these actions. ```APIDOC ## Action with Async Callbacks Actions support async functions and automatically track start, completion, and errors. ### Method `action` (from `@nanostores/logger`) ### Description Wraps an asynchronous function to automatically log its lifecycle (start, changes, end, errors) when used with the `logger`. ### Parameters #### Store - **store** (Object) - The Nanostores store to be updated. - **actionName** (string) - A descriptive name for the action. - **asyncFunction** (Function) - The asynchronous function to execute. It receives the store and any arguments passed to the action. ### Request Example (Conceptual) ```javascript import { action } from '@nanostores/logger' import { map } from 'nanostores' let $user = map({ username: 'guest', loading: false }) let fetchUser = action($user, 'Fetch User', async (store, userId) => { store.setKey('loading', true) try { let response = await fetch(`/api/users/${userId}`) let data = await response.json() store.setKey('username', data.username) } finally { store.setKey('loading', false) } }) // Usage: await fetchUser('123') // Logs action start, changes, and action end automatically. ``` ### Response Example (Conceptual - Logs) When `fetchUser('123')` is called, the logger will output messages similar to: `[ACTION START] Fetch User on $user with args: ["123"]` `[CHANGE] $user was changed in the loading key from false to true by action Fetch User` `[CHANGE] $user was changed in the username key from guest to John Doe by action Fetch User` `[CHANGE] $user was changed in the loading key from true to false by action Fetch User` `[ACTION END] Fetch User on $user completed` ### Error Handling If the async function throws an error, it will be automatically logged. ```javascript import { action } from '@nanostores/logger' let dangerousAction = action($user, 'Dangerous Action', async (store) => { await someAsyncOperation() throw new Error('Something went wrong') }) try { await dangerousAction() } catch (e) { // Error is logged in console with action name } ``` **Error Log Example:** `[ACTION ERROR] Dangerous Action on $user failed: Something went wrong` ``` -------------------------------- ### Basic Usage of Nano Stores Logger Source: https://github.com/nanostores/logger/blob/main/README.md Import and initialize the logger with stores to begin logging lifecycle events and changes. ```js import { logger } from '@nanostores/logger' import { $profile, $users } from './stores/index.js' let destroy = logger({ 'Profile': $profile, 'Users': $users }) ``` -------------------------------- ### Styled Console Logging with Nano Stores Utilities Source: https://context7.com/nanostores/logger/llms.txt Utilize log, group, and groupEnd for creating styled console messages with Nano Stores branding. These functions allow for custom log output with color badges and collapsible groups, enhancing debugging clarity. ```javascript import { log, group, groupEnd } from '@nanostores/logger' // Simple log with predefined type badge log({ logo: true, type: 'mount', message: [ ['bold', 'UserStore'], ['regular', 'was initialized'] ] }) // Log with custom badge color log({ logo: true, type: { name: 'Fetch', color: '#510080' }, message: [ ['bold', 'Profile'], ['regular', 'store is fetching new data'] ] }) // Log with a value object log({ logo: false, type: 'new', value: { username: 'john', email: 'john@example.com' } }) // Create collapsible group group({ logo: true, type: 'action', message: [ ['bold', 'UserStore'], ['regular', 'was changed by action'], ['bold', 'Update Profile'] ] }) // Nested logs inside the group log({ type: 'old', value: { name: 'John' } }) log({ type: 'new', value: { name: 'Jane' } }) // Close the group groupEnd() // Available predefined types: // 'action', 'arguments', 'build', 'change', 'error', // 'mount', 'new', 'old', 'unmount', 'value' ``` -------------------------------- ### Define Actions with Logger Source: https://github.com/nanostores/logger/blob/main/README.md Wrap store changes in `action()` to log action names and track their execution, including async operations. ```js import { action } from '@nanostores/logger' import { atom, map } from 'nanostores' let $counter = atom(0) let increase = action($counter, 'Increase', ($store, value = 1) => { $store.set($store.get() + value) return $store.get() }) increase() //=> 1 increase(5) //=> 6 ``` ```js let fetchUser = action($user, 'Fetch User', async ($store, id) => { $store.set(await api.getUser(id)) }) ``` -------------------------------- ### Build Custom Logger Source: https://context7.com/nanostores/logger/llms.txt Provides a low-level API to create custom logging implementations with specific event handlers for store lifecycle events. ```APIDOC ## buildLogger Low-level API for creating custom logging implementations. Use this to build your own devtools with custom event handlers for mount, unmount, change, and action events. ### Method `buildLogger(store, storeName, eventHandlers, options)` ### Parameters #### `store` - **store** (Object) - The Nanostores store to attach the logger to. #### `storeName` - **storeName** (string) - A name for the store, used in log messages. #### `eventHandlers` - **mount** (Function) - Callback for when the store is mounted. - **unmount** (Function) - Callback for when the store is unmounted. - **change** (Function) - Callback for when the store's value changes. - **action** (Object) - An object containing callbacks for action lifecycle events: - **start** (Function) - Callback for when an action starts. - **error** (Function) - Callback for when an action encounters an error. - **end** (Function) - Callback for when an action completes. #### `options` (Optional) - **messages** (Object) - Controls which default messages are enabled (e.g., `{ mount: true, change: true }`). - **ignoreActions** (Array) - An array of action names to ignore. ### Request Example ```javascript import { buildLogger } from '@nanostores/logger' import { map } from 'nanostores' let $profile = map({ name: 'John' }) let destroy = buildLogger($profile, 'Profile', { mount: ({ storeName }) => { console.log(`[MOUNT] ${storeName} was mounted`) }, change: ({ storeName, changed, newValue, oldValue }) => { console.log(`[CHANGE] ${storeName} changed ${changed} from ${JSON.stringify(oldValue)} to ${JSON.stringify(newValue)}`) }, action: { start: ({ actionName, args }) => { console.log(`[ACTION START] ${actionName} with args:`, args) }, error: ({ actionName, error }) => { console.error(`[ACTION ERROR] ${actionName} failed:`, error.message) }, end: ({ actionName }) => { console.log(`[ACTION END] ${actionName} completed`) } } }, { messages: { mount: true, change: true, action: true }, ignoreActions: [] }) // Use the store $profile.setKey('name', 'Jane') // To stop logging: destroy() ``` ### Response Example (Console Output) ``` [MOUNT] Profile was mounted [CHANGE] Profile changed name from "John" to "Jane" ``` ``` -------------------------------- ### Build Custom Devtools with buildLogger Source: https://github.com/nanostores/logger/blob/main/README.md Utilize `buildLogger` to create custom devtools or extensions by defining handlers for different logging events like mount, unmount, change, and action. ```js import { buildLogger } from '@nanostores/logger' import { $profile } from './stores/index.js' let destroy = buildLogger($profile, 'Profile', { mount: ({ storeName }) => { console.log(`${storeName} was mounted`) }, unmount: ({ storeName }) => { console.log(`${storeName} was unmounted`) }, change: ({ storeName, actionName, changed, newValue, oldValue, valueMessage }) => { let message = `${storeName} was changed` if (changed) message += `in the ${changed} key` if (oldValue) message += `from ${oldValue}` message += `to ${newValue}` if (actionName) message += `by action ${actionName}` console.log(message, valueMessage) }, action: { start: ({ actionName, args }) => { let message = `${actionName} was started` if (args.length) message += 'with arguments' console.log(message, args) }, error: ({ actionName, error }) => { console.log(`${actionName} was failed`, error) }, end: ({ actionName }) => { console.log(`${actionName} was ended`) } } }) ``` -------------------------------- ### Build Custom Logger Implementation Source: https://context7.com/nanostores/logger/llms.txt Use buildLogger for low-level API to create custom logging. This allows for custom event handlers for mount, unmount, change, and action events. ```javascript import { buildLogger } from '@nanostores/logger' import { map } from 'nanostores' let $profile = map({ name: 'John', email: 'john@example.com' }) let destroy = buildLogger($profile, 'Profile', { mount: ({ storeName }) => { console.log(`[MOUNT] ${storeName} was mounted`) }, unmount: ({ storeName }) => { console.log(`[UNMOUNT] ${storeName} was unmounted`) }, change: ({ storeName, actionName, changed, newValue, oldValue, valueMessage }) => { let message = `[CHANGE] ${storeName} was changed` if (changed) message += ` in the ${changed} key` if (oldValue) message += ` from ${JSON.stringify(oldValue)}` message += ` to ${JSON.stringify(newValue)}` if (actionName) message += ` by action ${actionName}` console.log(message) if (valueMessage) console.log(` Value: ${valueMessage}`) }, action: { start: ({ actionName, args, storeName }) => { let message = `[ACTION START] ${actionName} on ${storeName}` if (args.length) console.log(message, 'with args:', args) else console.log(message) }, error: ({ actionName, error, storeName }) => { console.error(`[ACTION ERROR] ${actionName} on ${storeName} failed:`, error.message) }, end: ({ actionName, storeName }) => { console.log(`[ACTION END] ${actionName} on ${storeName} completed`) } } }, { messages: { mount: true, unmount: true, change: true, action: true }, ignoreActions: [] }) // Use the store $profile.listen(() => {}) $profile.setKey('name', 'Jane') destroy() ``` -------------------------------- ### Build Custom Creator Logger with Nano Stores Source: https://context7.com/nanostores/logger/llms.txt Use buildCreatorLogger to create custom logging implementations for map creator factories. This is useful for devtools that track the instantiation of new store instances. It allows attaching custom monitoring, such as store value change listeners. ```javascript import { buildCreatorLogger } from '@nanostores/logger' import { map } from 'nanostores' // Map creator factory let UserCreator = { build: (id) => map({ id, name: '', status: 'offline' }), value: { id: '' } } let destroy = buildCreatorLogger(UserCreator, 'User', { build: ({ creatorName, store, storeName }) => { console.log(`[BUILD] ${storeName} was built by ${creatorName} creator`) console.log(' Initial value:', store.value) // You can attach additional monitoring here store.listen((value) => { console.log(`[${storeName}] Value updated:`, value) }) } }, { nameGetter: (creatorName, store) => `${creatorName}:${store.value.id}`, messages: { build: true } }) // When a store is built, custom logging fires let userStore = UserCreator.build('user-456') // Logs: "[BUILD] User:user-456 was built by User creator" destroy() ``` -------------------------------- ### Create Custom Log Messages Source: https://github.com/nanostores/logger/blob/main/README.md Use `log`, `group`, and `groupEnd` to create custom log messages with specific types, colors, and nested structures. ```js import { group, groupEnd, log } from '@nanostores/logger' log({ logo: true, type: { color: '#510080', name: 'Fetch' }, message: [ ['bold', 'Profile'], ['regular', 'store is trying to get new values'] ] }) ``` -------------------------------- ### Creator Logger for Map Creators Source: https://context7.com/nanostores/logger/llms.txt Use creatorLogger to log when new store instances are built by map creators. It automatically attaches logging to each created store. ```javascript import { creatorLogger } from '@nanostores/logger' // Example map creator (similar to Logux's SyncMapTemplate) function createUserStore(id) { let store = map({ id, name: '', loaded: false }) store.build = (userId) => { return map({ id: userId, name: '', loaded: false }) } return store } let UserStore = { build: (id) => map({ id, name: '', loaded: false }), value: { id: '' } } // Log all stores built by the creator let destroy = creatorLogger({ User: UserStore }, { // Custom name for each built store instance nameGetter: (creatorName, store) => { return `${creatorName}:${store.value.id}` } }) // When UserStore.build('123') is called, it logs: // "User:123 store was built by User creator" // And all subsequent changes to that store are logged destroy() ``` -------------------------------- ### Log Map Creators with Creator Logger Source: https://github.com/nanostores/logger/blob/main/README.md Use `creatorLogger` to log map creators, providing a custom `nameGetter` for store identification. ```js import { creatorLogger } from '@nanostores/logger' let destroy = creatorLogger({ $users }, { nameGetter: (creatorName, store) => { return `${creatorName}:${store.value.id}` } }) ``` -------------------------------- ### Configure Logger with Options Source: https://context7.com/nanostores/logger/llms.txt Customize the logger's behavior by disabling specific message types like mount or unmount events using the options parameter. ```javascript import { logger } from '@nanostores/logger' import { atom, map } from 'nanostores' let $counter = atom(0) let $user = map({ name: 'John' }) // Disable mount and unmount messages let destroy = logger({ Counter: $counter, User: $user }, { messages: { mount: false, unmount: false, // change: false, // Disable change logs // action: false // Disable action logs } }) // Only change and action events will be logged $counter.listen(() => {}) $counter.set(42) // This will be logged ``` -------------------------------- ### Wrap Store Modifications with Named Actions Source: https://context7.com/nanostores/logger/llms.txt Use the action wrapper to associate named actions with store modifications. This allows the logger to display action names, improving clarity for synchronous and asynchronous operations. ```javascript import { action } from '@nanostores/logger' import { atom, map } from 'nanostores' // Synchronous action with atom let $counter = atom(0) let increase = action($counter, 'Increase', (store, value = 1) => { store.set(store.get() + value) return store.get() }) increase() // Returns 1, logs: "Counter store was changed by action Increase" increase(5) // Returns 6, logs with arguments shown // Synchronous action with map using setKey let $user = map({ name: 'John', artworks: 100 }) let updateArtworks = action($user, 'Update Artworks', (store, count) => { store.setKey('artworks', count) }) updateArtworks(250) // Logs change in the artworks key by action Update Artworks ``` -------------------------------- ### Creator Logger for Map Creators Source: https://context7.com/nanostores/logger/llms.txt A specialized logger for map creators (factory functions) that automatically logs when new store instances are built and attaches logging to them. ```APIDOC ## creatorLogger Specialized logger for map creators (factory functions) like Logux's SyncMapTemplate. Automatically logs when new store instances are built and attaches logging to each created store. ### Method `creatorLogger(creators, options)` ### Parameters #### `creators` - **creators** (Object) - An object where keys are creator names and values are the creator objects (which must have a `build` method). #### `options` (Optional) - **nameGetter** (Function) - A function to customize the name of each logged store instance. It receives the creator name and the store instance. ### Request Example ```javascript import { creatorLogger } from '@nanostores/logger' import { map } from 'nanostores' // Example map creator let UserStore = { build: (id) => map({ id, name: '', loaded: false }), value: { id: '' } // Placeholder for type inference } let destroy = creatorLogger({ User: UserStore }, { nameGetter: (creatorName, store) => { return `${creatorName}:${store.value.id}` } }) // When UserStore.build('123') is called, it logs: // "User:123 store was built by User creator" // And all subsequent changes to that store are logged. // Example usage: let user1 = UserStore.build('123') user1.setKey('name', 'Alice') // This change will also be logged. // To stop logging: destroy() ``` ### Response Example (Console Output) When `UserStore.build('123')` is called: `User:123 store was built by User creator` ``` -------------------------------- ### Ignore Specific Actions from Logging Source: https://github.com/nanostores/logger/blob/main/README.md Use the 'ignoreActions' option to prevent logging of actions with specified names. ```js import { logger } from '@nanostores/logger' import { $users } from './stores/index.js' let destroy = logger({ $users }, { ignoreActions: [ 'Change Username', 'Fetch User Profile' ] }) ``` -------------------------------- ### Filter Actions with ignoreActions Option Source: https://context7.com/nanostores/logger/llms.txt Prevent specific actions from being logged by providing an array of action names to the 'ignoreActions' option. This helps reduce console noise from frequent or irrelevant actions. ```javascript import { logger } from '@nanostores/logger' import { action } from '@nanostores/logger' import { map } from 'nanostores' let $user = map({ name: 'John', count: 0 }) let updateName = action($user, 'Update Name', (store, name) => { store.setKey('name', name) }) let incrementCount = action($user, 'Increment Count', (store) => { store.setKey('count', store.get().count + 1) }) // Ignore frequent counter updates in logs let destroy = logger({ User: $user }, { ignoreActions: ['Increment Count'] }) $user.listen(() => {}) updateName('Jane') // This action will be logged incrementCount() // This action will NOT be logged incrementCount() // This action will NOT be logged ``` -------------------------------- ### Disable Specific Log Message Types Source: https://github.com/nanostores/logger/blob/main/README.md Use the 'messages' option to disable specific log types like 'mount' or 'unmount'. ```js import { logger } from '@nanostores/logger' import { $users } from './stores/index.js' let destroy = logger({ $users }, { messages: { mount: false, unmount: false } }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.