### Complex Server Setup with Real-time Updates using Pumped.fn Source: https://pumped-fn.github.io/pumped-fn/index Presents a sophisticated example involving real-time translation updates. It demonstrates deriving components for loading translations, updating them periodically, and integrating them into server routes and the main server logic. ```typescript import { provide, derive, createScope } from "@pumped-fn/core-next"; /** * Pretty advanced example to expose API surfaces * * We have more value containers, more complicated dependencies * ... we have scope * ... and nothing changes, we can resolve things so easily still */ const config = provide(() => ({ server: { port: 3000, host: "localhost", }, db: { uri: "mongodb://localhost:27017/mydb", }, logger: { defaultLevel: "info", transport: "console", }, translation: { poll: 5000, source: "https://example.com/translations", }, })); const logger = derive(config, (config) => { /** logger implementation */ }); const connection = derive([logger, config], ([logger, config]) => { /** connection implementation */ }); const translationsLoader = derive( [logger, config], ([logger, config]) => async () => { /** translation loader implementation */ } ); const translations = derive( [translationsLoader], async ([translationsLoader]) => { return await translationsLoader(); } ); const translationUpdator = derive( [logger, config, translationsLoader, translations.static], ([logger, config, loader, translations], ctl) => { /** translation updator implementation */ const interval = setInterval(async () => { // sample code only, don't use for production please const newTranslations = await loader(); translations.update(newTranslations); }, config.translation.poll); ctl.cleanup(() => { interval && clearInterval(interval); }); } ); const healthcheckRoute = derive( [logger, connection], ([logger, connection]) => { /** healthcheck route implementation */ } ); const translationRoute = derive([translations.static], ([translations]) => { translations.get(); // retrieve the latest }); const server = derive( [logger, config, healthcheckRoute, translationRoute], ([logger, config, healthcheckRoute, translationRoute]) => ({ /** server implementation */ start: () => { // register routes ... console.log( `Server running at http://${config.server.host}:${config.server.port}` ); // Start server logic... }, }) ); const scope = createScope(); await scope.resolve(translationUpdator); // Start the translation updater const resolvedServer = await scope.resolve(server); resolvedServer.start(); // Start the server await scope.dispose(); // Cleanup resources, release memory ``` -------------------------------- ### Install Pumped Functions Core Source: https://pumped-fn.github.io/pumped-fn/index Instructions for installing the core package of Pumped Functions using various package managers like npm, pnpm, yarn, and bun. ```bash $ npm add @pumped-fn/core-next ``` ```bash $ pnpm add @pumped-fn/core-next ``` ```bash $ yarn add @pumped-fn/core-next ``` ```bash $ bun add @pumped-fn/core-next ``` -------------------------------- ### Traditional Mocking vs. Graph Testing Setup Source: https://pumped-fn.github.io/pumped-fn/testings Illustrates the difference between mocking individual components in a traditional approach and setting up an entire system for testing using Pumped Functions' graph approach. ```typescript // Mock everything individually mockFetch.mockResolvedValue(...) mockCache.mockImplementation(...) mockConfig.mockReturnValue(...) mockDatabase.mockResolvedValue(...) // Hope they work together correctly ``` ```typescript // Change the environment, everything adapts const scope = createScope( preset(env, 'test') ) // Entire system configured for testing ``` -------------------------------- ### Practical Middleware Examples: Analytics and Sanitizer Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates practical middleware implementations for analytics tracking and value sanitization. These middlewares can be registered with a scope to enhance its functionality. ```typescript import { createScope, middleware, provide, derive, preset } from "@pumped-fn/core-next"; // Analytics middleware const analytics = middleware({ init: (scope) => { scope.onChange((event, executor, value) => { if (event === "resolve") { // Track resolution metrics } }); } }); // Value sanitizer const sanitizer = middleware({ init: (scope) => { scope.onChange((event, executor, value, scope) => { if (typeof value === "string" && value.includes("unsafe")) { return preset(executor, value.replace("unsafe", "safe")); } }); } }); const scope = createScope(); scope.use(analytics); scope.use(sanitizer); ``` -------------------------------- ### Practical Meta Patterns: Versioning and Deprecation Source: https://pumped-fn.github.io/pumped-fn/api Presents practical patterns for using metadata, including version tracking and deprecation warnings. This example defines meta keys for version, deprecation status, and service tier, and implements a middleware for deprecation notices. ```typescript import { provide, derive, meta, custom, createScope, middleware } from "@pumped-fn/core-next"; // Version tracking const version = meta("version", custom()); // Deprecation warnings const deprecated = meta("deprecated", custom<{ since: string; alternative?: string }>()); // Service classification const tier = meta("tier", custom<"critical" | "standard" | "low">()); // Deprecation middleware const deprecationWarning = middleware({ init: (scope) => { scope.onChange((event, executor) => { const deprecation = deprecated.find(executor); if (deprecation && event === "resolve") { console.warn( `Deprecated since ${deprecation.since}`, deprecation.alternative ? `Use ${deprecation.alternative} instead` : "" ); } }); } }); // Usage const oldApi = provide( () => ({ v1: true }), version("1.0.0"), deprecated({ since: "2.0.0", alternative: "newApi" }), tier("low") ); const newApi = provide( () => ({ v2: true }), version("2.0.0"), tier("critical") ); ``` -------------------------------- ### Function-Based Service Architecture (Preferred) Source: https://pumped-fn.github.io/pumped-fn/llm Presents the preferred function-based approach for building services, highlighting its elegance in handling asynchronous dependencies and reactive updates. It provides an example of creating an API service using async initialization and reactive configuration. ```typescript // Handles async dependencies elegantly const createAPI = async (config: Config, http: Http) => { await http.connect(config.baseUrl); // Async init return { async get(path: string) { return http.get(config.baseUrl + path); }, async post(path: string, data: any) { return http.post(config.baseUrl + path, data); }, }; }; const api = derive([config.reactive, httpClient], createAPI); ``` -------------------------------- ### Debug Metadata Source: https://pumped-fn.github.io/pumped-fn/llm Shows how to attach and retrieve debug metadata for executors using `meta`. This example defines a schema for debug information and provides it during executor creation. ```typescript // Debug metadata const debug = meta( "debug", object({ created: string(), purpose: string(), }) ); const svc = provide( factory, debug({ created: new Date().toISOString(), purpose: "User authentication", }) ); ``` -------------------------------- ### Static Accessor Control for Configuration Management Source: https://pumped-fn.github.io/pumped-fn/llm Illustrates how to build control systems using `.static` for configuration management. It covers creating accessors for updating, resetting, getting, and checking configuration values, and demonstrates mixing reactive state changes with static configuration control. ```typescript // Build control systems with .static const ctrl = derive(config.static, (cfgAccessor) => ({ update: (v) => cfgAccessor.update(v), reset: () => cfgAccessor.update(defaultConfig), get: () => cfgAccessor.get(), check: () => cfgAccessor.lookup(), // Check without resolving })); // Mixed reactive + control const svc = derive([state.reactive, config.static], ([state, cfgCtl], ctl) => { // React to state changes, control config if (state.error) cfgCtl.update((c) => ({ ...c, retry: true })); ctl.cleanup(() => console.log("cleaning")); return { state, control: cfgCtl }; }); ``` -------------------------------- ### Pumped-FN Dependency Graph Testing Examples Source: https://pumped-fn.github.io/pumped-fn/testings This snippet demonstrates various testing scenarios for a dependency graph using Pumped-FN. It covers setting up different environments (development, production), simulating slow networks, and handling API failures by providing isolated scopes and presets. ```typescript import { test, expect } from 'vitest' import { provide, derive, createScope, preset } from '@pumped-fn/core-next' // Your application dependency graph const env = provide(() => process.env.NODE_ENV || 'production') const config = derive(env, (environment) => ({ apiUrl: environment === 'production' ? 'https://api.prod.com' : 'https://api.test.com', cache: environment === 'production' ? 'redis' : 'memory', timeout: environment === 'production' ? 5000 : 100 })) const httpClient = derive(config, (cfg) => ({ get: async (path: string) => { const url = `${cfg.apiUrl}${path}` // In tests, this would use cfg.timeout of 100ms // In production, this would use 5000ms return fetch(url, { signal: AbortSignal.timeout(cfg.timeout) }) } })) const cache = derive(config, (cfg) => ({ type: cfg.cache, get: (key: string) => cfg.cache === 'redis' ? `redis:${key}` : `memory:${key}` })) const userRepository = derive([httpClient, cache], (client, cache) => ({ async getUser(id: number) { const cacheKey = cache.get(`user:${id}`) // Would check cache first... return { source: cache.type, endpoint: `${client.get}/users/${id}`, cached: cacheKey } } })) // Test 1: Change the root, entire graph adapts test('development environment setup', async () => { const scope = createScope( preset(env, 'development') ) const repo = await scope.resolve(userRepository) const user = await repo.getUser(123) // Everything automatically configured for development expect(user.source).toBe('memory') expect(user.cached).toBe('memory:user:123') // API calls would go to test server with 100ms timeout }) // Test 2: Production environment (isolated scope) test.concurrent('production environment', async () => { const scope = createScope( preset(env, 'production') ) const repo = await scope.resolve(userRepository) const user = await repo.getUser(456) // Completely different configuration, same code expect(user.source).toBe('redis') expect(user.cached).toBe('redis:user:456') // API calls would go to production with 5s timeout }) // Test 3: Custom scenario - slow network simulation test.concurrent('slow network scenario', async () => { const scope = createScope( // Override just the config, everything downstream updates preset(config, { apiUrl: 'https://api.slow.com', cache: 'memory', timeout: 30000 // 30 second timeout }) ) const client = await scope.resolve(httpClient) // Client automatically uses 30s timeout const repo = await scope.resolve(userRepository) // Repository uses slow client and memory cache }) // Test 4: Failure scenario test('api failure handling', async () => { const scope = createScope( // Mock just the HTTP client preset(httpClient, { get: async () => { throw new Error('Network error') } }) ) const repo = await scope.resolve(userRepository) // Test error handling with mocked failure await expect(repo.getUser(1)).rejects.toThrow('Network error') }) // The key insight: One preset can change the entire behavior // No need to mock fetch, cache, config separately // The graph propagates changes automatically // Each test has an isolated scope - run them all concurrently! ``` -------------------------------- ### State Inspection Source: https://pumped-fn.github.io/pumped-fn/llm Provides an example of inspecting the current state of an executor, checking if it's resolved, rejected, or still pending, and logging the relevant information. ```typescript // State inspection const state = accessor.lookup(); switch (state?.kind) { case "resolved": console.log("Value:", state.value); break; case "rejected": console.error("Error:", state.error); break; case "pending": console.log("Still resolving..."); break; } ``` -------------------------------- ### Meta with Middleware for Conditional Logic Source: https://pumped-fn.github.io/pumped-fn/api Illustrates how to use metadata within middleware for conditional execution. This example shows a middleware that logs executor events only if the executor has metrics enabled. ```typescript import { createScope, middleware, provide, meta, custom } from "@pumped-fn/core-next"; const name = meta("name", custom()); const metrics = meta("metrics", custom()); // Middleware that uses meta for conditional logic const metricsMiddleware = middleware({ init: (scope) => { scope.onChange((event, executor, value) => { // Check if executor has metrics enabled if (metrics.find(executor)) { const serviceName = name.get(executor) ?? "unknown"; console.log(`[${serviceName}] ${event}:`, value); } }); } }); const api = provide( () => ({ endpoint: "/api" }), name("api-service"), metrics(true) // Enable metrics for this executor ); const internal = provide( () => ({ data: "internal" }), name("internal-service") // No metrics meta - won't be tracked ); ``` -------------------------------- ### Access Executor Representative in Scope Source: https://pumped-fn.github.io/pumped-fn/api Retrieves the singleton of an executor representative within a scope. It allows for getting, looking up, or resolving the value associated with an accessor. ```typescript import { createScope } from "@pumped-fn/core-next"; const valueAccessor = scope.accessor(value); const getValue = valueAccessor.get(); // retrieve value. Will throw error if executor is yet resolved const maybeValue = valueAccessor.lookup(); const resolvedValue = await valueAccessor.resolve(); ``` -------------------------------- ### Accessing Meta Values from Executors Source: https://pumped-fn.github.io/pumped-fn/api Shows how to retrieve metadata values associated with executors. It covers getting a specific meta value, finding the first matching meta, and retrieving all matching meta values. ```typescript import { provide, meta, custom } from "@pumped-fn/core-next"; const name = meta("name", custom()); const service = provide(() => {}, name("auth")); // Get meta value from executor const serviceName = name.get(service); // "auth" // Find first matching meta const maybeName = name.find(service); // "auth" | undefined // Get all matching metas (executors can have multiple of same type) const allNames = name.some(service); // string[] ``` -------------------------------- ### Lazy Resolution Flow Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Depicts the lazy resolution flow, where an 'Accessor' is returned for a lazy Executor. The actual resolution and computation happen only when the value is explicitly requested via the 'get()' method, demonstrating a deferred execution strategy. ```javascript Later, when value neededStandard resolution flowalt[Cache Hit][Cache Miss]resolve(executor.lazy)1create(executor, scope)2return Accessor3get()4lookup(executor)5cachedValue6return cachedValue7resolve(executor)8computedValue9return computedValue10 o4dkn ``` -------------------------------- ### Global State with Reactive Updates Source: https://pumped-fn.github.io/pumped-fn/llm Demonstrates setting up global application state with reactive updates using `provide` and deriving reactive states. It also shows how to update the state immutably. ```typescript // Global state with reactive updates const appState = provide(() => ({ user: null, theme: "light", notifications: [], })); // Derived states const isAuthenticated = derive( appState.reactive, (state) => state.user !== null ); const unreadCount = derive( appState.reactive, (state) => state.notifications.filter((n) => !n.read).length ); // State updates await scope.update(appState, (state) => ({ ...state, user: { id: "123", name: "Alice" }, })); ``` -------------------------------- ### Advanced Server Configuration and Dependencies with Pumped.fn Source: https://pumped-fn.github.io/pumped-fn/index Illustrates a more advanced use case with Pumped.fn, setting up server configuration, logger, database connection, and a health check route. It shows how to derive complex objects and manage their lifecycle. ```typescript import { provide, derive, createScope } from "@pumped-fn/core-next"; /** * A little bit more advanced to expose API surfaces * * We have more value containers, more complicated dependencies * ... we have scope * ... and nothing changes, we can resolve things so easily still */ const config = provide(() => ({ server: { port: 3000, host: "localhost", }, db: { uri: "mongodb://localhost:27017/mydb", }, logger: { defaultLevel: "info", transport: "console", }, })); const logger = derive(config, (config) => { /** logger implementation */ }); const connection = derive({ logger, config }, ({ logger, config }) => { /** connection implementation */ }); const healthcheckRoute = derive( [logger, connection], ([logger, connection]) => { /** healthcheck route implementation */ } ); const server = derive( [logger, config, healthcheckRoute], ([logger, config, healthcheckRoute]) => ({ /** server implementation */ start: () => { console.log( `Server running at http://${config.server.host}:${config.server.port}` ); // Start server logic... }, }) ); const scope = createScope(); const resolvedServer = await scope.resolve(server); resolvedServer.start(); // Start the server await scope.dispose(); // Cleanup resources, release memory ``` -------------------------------- ### Pumped Functions Testing Overview Source: https://pumped-fn.github.io/pumped-fn/testings Explains the core concept of testing entire dependency graphs with Pumped Functions, highlighting the adaptive nature of the system when changes occur. ```markdown With Pumped-fn, you test entire dependency graphs, not individual units. Change one node, the entire graph adapts. ``` -------------------------------- ### Pumped Functions API Reference Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Provides an overview of the Pumped Functions API, referencing key areas like creation, scope management, middleware integration, and meta-information. It also points to LLM-specific functionalities. ```APIDOC API creation scope middleware meta LLM ``` -------------------------------- ### Core API Reference: Variants Source: https://pumped-fn.github.io/pumped-fn/llm Explains the different variants of executors available in @pumped-fn/core-next, such as reactive, lazy, and static, along with the Accessor interface for managing their state. ```typescript executor.reactive // Triggers updatesexecutor.lazy // Returns Accessorexecutor.static // Returns Accessor (eager) // Accessor interface: accessor.get(): T // Current value accessor.update(v | fn): void // Update value accessor.resolve(force?): T // Re-resolve accessor.release(): void // Release accessor.lookup(): State // Check state without resolving ``` -------------------------------- ### Core API Reference: Executor Creation Source: https://pumped-fn.github.io/pumped-fn/llm Provides functions for creating executors within the @pumped-fn/core-next library. This includes methods for defining dependencies, overriding values, and batch resolution. ```typescript provide(factory, ...metas); // No dependencies derive(deps, factory, ...metas); // With dependencies derive([dep1, dep2, dep3], factory, ...metas); // With dependencies array. Factory will receive [resolved1, resolved2, resolved3] derive({ dep1, dep2, dep3 }, factory, ...metas); // With dependencies object. Factory will receive { dep1: resolved1, dep2: resolved2, dep3: resolved 3} preset(executor, value); // Override value placeholder(); // Throws if resolved resolves(...executors); // Batch resolution helper ``` -------------------------------- ### Simple Value Derivation with Pumped.fn Source: https://pumped-fn.github.io/pumped-fn/index Demonstrates a basic usage of Pumped.fn, showing how to provide a value and derive a new value based on it. It includes creating a scope, resolving a derived value, and cleaning up resources. ```typescript import { provide, derive, createScope } from "@pumped-fn/core-next"; /** * A very simple example. * * We have value containers * ... we have scope * ... and magic happens just a little bit way too quick */ const value = provide(() => 1); const derived = derive(value, (value) => value + 1); const scope = createScope(); const resolvedDerived = await scope.resolve(derived); console.log(resolvedDerived); // 2 await scope.dispose(); // Cleanup resources, release memory ``` -------------------------------- ### Pumped Functions Core Imports Source: https://pumped-fn.github.io/pumped-fn/api Imports core functions like provide, derive, createScope, and preset from the @pumped-fn/core-next package. ```typescript import { provide , derive } from "@pumped-fn/core-next"; ``` ```typescript import { provide , derive , createScope , preset } from "@pumped-fn/core-next"; ``` ```typescript import { createScope } from "@pumped-fn/core-next"; ``` -------------------------------- ### Problems with Class-Based Service Architecture Source: https://pumped-fn.github.io/pumped-fn/llm Explains the drawbacks of using classes for service architecture in a reactive framework. It points out issues with asynchronous initialization, inability to react to configuration changes, encouragement of mutable state, and breaking reactive updates. ```typescript // PROBLEMS with classes: class APIService { constructor(private config: Config, private http: Http) { // ❌ Can't handle async init in constructor // ❌ Can't react to config changes // ❌ Encourages mutable state } } // ❌ Classes break reactive updates const api = derive( [config.reactive, http], (cfg, http) => new APIService(cfg, http) ); // Service never updates when config changes ``` -------------------------------- ### Pumped Functions: Testing Different Environments and Scenarios Source: https://pumped-fn.github.io/pumped-fn/testings Demonstrates how to use Pumped Functions to create different testing scopes for production, testing, failure conditions, and specific data sets, emphasizing the power of single-line system behavior changes. ```typescript // Test different environments const prodScope = createScope(preset(env, 'production')) const testScope = createScope(preset(env, 'test')) // Test failure scenarios const failScope = createScope( preset(httpClient, { get: async () => { throw error } }) ) // Test with specific data const dataScope = createScope( preset(database, { users: testData }) ) ``` -------------------------------- ### Controller Capabilities for Executor Management Source: https://pumped-fn.github.io/pumped-fn/llm Explains how controllers enhance factories with capabilities like registering cleanup functions, releasing executors, accessing parent scopes, and managing metadata. It also shows scope access patterns for creating sub-scopes and resolving other executors. ```typescript // provide((ctl) => ...) or derive(deps, (deps, ctl) => ...) ctl.cleanup(() => dispose()); // Register cleanup ctl.release(); // Release self ctl.scope; // Access parent scope ctl.meta; // Access executor metadata // Scope access patterns const manager = provide((ctl) => { // Create sub-scope const pod = ctl.scope.pod(preset(config, override)); ctl.cleanup(() => pod.dispose()); // Access other executors const other = await ctl.scope.resolve(otherExec); // Self-management if (shouldStop) ctl.release(); }); ``` -------------------------------- ### Comprehensive Tracing Source: https://pumped-fn.github.io/pumped-fn/llm Demonstrates how to implement comprehensive tracing within the framework using `scope.onChange`. This allows logging of state changes, including the event type, executor, and new value, with optional metadata lookup. ```typescript // Comprehensive tracing scope.onChange((event, exec, val) => { const name = meta("name").find(exec); console.log(`[${event}] ${name || "anonymous"}: ${val}`); }); ``` -------------------------------- ### Batch Updates for Performance Source: https://pumped-fn.github.io/pumped-fn/llm Shows how to perform multiple state updates simultaneously in a single operation, resulting in a single reactive propagation and improving performance by reducing update overhead. ```typescript // Batch updates for performance await scope.update(state, (s) => ({ ...s, multiple: "changes", at: "once", })); // Single reactive propagation ``` -------------------------------- ### Middleware System Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Details the 'Middleware' system, which enables an event-driven approach to intercepting and modifying the executor resolution pipeline. It outlines the middleware interface with 'init' and 'dispose' hooks, event callbacks like 'onChange' and 'onRelease', and the ability to transform values using 'preset()'. ```javascript Middleware provides a powerful event-driven system for intercepting and modifying the executor resolution pipeline. It operates through event hooks that are triggered during resolution, update, and release operations. The middleware system consists of: * **Middleware Interface** : `init` and `dispose` lifecycle hooks * **Event Callbacks** : `onChange` for resolve/update events, `onRelease` for cleanup * **Value Transformation** : Return `preset()` to override resolved/updated values ``` -------------------------------- ### Provide Function Usage Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates the usage of the `provide` function to create a value. The function can optionally accept a controller argument. ```typescript const value = provide (() => "string"); ``` ```typescript const value = provide (( ctl ) => "string"); ``` ```typescript const otherValue = provide (( ctl ) => 20); ``` ```typescript const value = provide (() => 0); ``` -------------------------------- ### Attaching Meta to Executors Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates how to attach metadata to executors using the `meta` and `provide` functions. This includes defining meta keys with custom types and applying them during executor creation. ```typescript import { provide, derive, meta, custom } from "@pumped-fn/core-next"; const name = meta("name", custom()); const priority = meta("priority", custom()); // Attach meta during creation const database = provide( () => ({ connection: "postgres://..." }), name("database"), priority(1) ); // Multiple metas const cache = provide( () => new Map(), name("cache"), priority(2) ); ``` -------------------------------- ### Enhanced Middleware System with Events and Transformations Source: https://pumped-fn.github.io/pumped-fn/llm Details the enhanced middleware system, focusing on event handling and value transformations. It shows how to track events based on executor metadata, react to specific executor updates, and transform resolved values, including asynchronous cleanup operations. ```typescript // Enhanced middleware with events const analytics = middleware({ init: (scope) => { scope.onChange((event, executor, value) => { // 'resolving' | 'resolved' | 'updated' | 'released' track(event, meta("name").find(executor)); }); scope.onUpdate(userState, (accessor) => { // React to specific executor updates logUserChange(accessor.get()); }); }, // Transform values resolve: (value, executor) => { if (shouldSanitize(executor)) { return preset(executor, sanitize(value)); } return value; }, dispose: async () => { await analytics.flush(); }, }); ``` -------------------------------- ### Executor Lifecycle Management Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Describes the lifecycle of an executor within Pumped.fn, covering its creation, resolution, active phase, and disposal, including steps for providing, resolving, storing, updating, and disposing of executors. ```javascript ListenersGarbage CollectorCacheExecutorScopeClient ListenersGarbage CollectorCacheExecutorScopeClient Creation Phase Resolution Phase Active Phase loop[During application lifecycle] Disposal Phase opt[Has cleanup function] provide(factory, ...metas) 1 executor instance 2 resolve(executor) 3 store(executor, value) 4 register(executor) 5 value 6 update(executor, newValue) 7 notify(executor, newValue) 8 dispose(executor) 9 unregister(executor) 10 evict(executor) 11 markForCollection(executor) 12 runCleanup() 13 disposed 14 ``` -------------------------------- ### Batch Update Optimization Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Explains the batch update optimization strategy, which groups multiple updates together, deduplicates them, and processes them in a topologically sorted order to improve efficiency. ```javascript FactoryCacheUpdateQueueBatchManagerScopeClient FactoryCacheUpdateQueueBatchManagerScopeClient loop[For each update in sorted order] loop[Process reactive updates once] startBatch() 1 initBatch() 2 update(executorA, value1) 3 queueUpdate(executorA, value1) 4 update(executorB, value2) 5 queueUpdate(executorB, value2) 6 update(executorC, value3) 7 queueUpdate(executorC, value3) 8 endBatch() 9 processBatch() 10 deduplicateUpdates() 11 topologicalSort() 12 store(executor, value) 13 enqueueReactiveDependents(executor) 14 processAll() 15 recompute(dependent) 16 newValue 17 store(dependent, newValue) 18 batchComplete 19 ``` -------------------------------- ### Type-Safe Metadata with StandardSchema Source: https://pumped-fn.github.io/pumped-fn/llm Demonstrates how to define and use type-safe metadata with StandardSchema. It covers defining meta properties, applying them to executors, retrieving metadata, and using it within middleware for event handling. ```typescript const serviceName = meta("service", string()); const version = meta("version", object({ major: number() })); // Apply to executors const api = provide(factory, serviceName("user-api"), version({ major: 2 })); // Retrieve meta serviceName.find(api); // 'user-api' version.get(api); // [{ major: 2 }] serviceName.some(api); // true // Use in middleware const telemetry = middleware({ init: (scope) => scope.onChange((event, exec) => { const name = serviceName.find(exec); if (name) metrics.record(event, name); }), }); ``` -------------------------------- ### Preset Function Usage Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates the `preset` function for setting an initial or assumed value for an executor, useful for testing and middleware. ```typescript import { provide , derive , createScope , preset } from "@pumped-fn/core-next"; const value = provide (() => 0); const assumedValue = preset ( value , 1); const scope = createScope ( assumedValue ); const resolvedValue = await scope . resolve ( value ); // will be 1 ``` -------------------------------- ### Creating Meta Functions with Schemas Source: https://pumped-fn.github.io/pumped-fn/api Defines how to create meta functions using the `meta` and `custom` utilities. These functions attach type-safe decorative information to executors, which can be validated against schemas. ```typescript import { meta, custom } from "@pumped-fn/core-next"; // Create a meta function with a schema const name = meta("service-name", custom()); const port = meta("port", custom()); const config = meta("config", custom<{ url: string; timeout: number }>()); ``` -------------------------------- ### Conditional Resolution with Lazy Loading Source: https://pumped-fn.github.io/pumped-fn/llm Illustrates conditional dependency resolution using lazy loading. The database service is only resolved if the configuration indicates it's needed, optimizing performance by deferring expensive operations. ```typescript // Conditional resolution with lazy const service = derive( { cfg: config.reactive, db: database.lazy }, async ({ cfg, db }) => { // Only resolve DB if needed if (cfg.useDb) { const database = await db.resolve(); return createDbService(database); } return createMemoryService(); } ); ``` -------------------------------- ### Corrected Anti-Patterns Source: https://pumped-fn.github.io/pumped-fn/llm Presents corrected versions of common anti-patterns. This includes storing the reactive variant directly, using the reactive variant with `scope.onUpdate`, using classes for services, updating before resolving, having side effects in factories, and passing too many dependencies. ```typescript // ✅ CORRECT const c = provide(() => 0); // Store main derive(c.reactive, v => v * 2); // Inline variant const svc = (db) => ({ query: db.q }); // Function factory await scope.resolve(exec); scope.update(exec, val); // Resolve first derive(deps, async () => new Database()) // Async for side effects derive(serviceGroup, ([a, b, c]) => ...) // Group related deps ``` -------------------------------- ### Static Resolution with Dependency Pre-resolution Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Illustrates the process of static dependency resolution where all dependencies are pre-resolved before execution. This involves a depth-first traversal of the dependency graph. ```javascript FactoryCacheDependency ResolverScopeClient FactoryCacheDependency ResolverScopeClient loop[Depth-first traversal] All deps pre-resolved resolve(executor.static) 1 resolveAllDependencies(executor) 2 findDependencies(current) 3 resolve(dependency) 4 dependencyValue 5 warmCache(dependency, value) 6 dependencyMap 7 execute(dependencyMap) 8 computedValue 9 store(executor, computedValue) 10 return computedValue 11 ``` -------------------------------- ### Release Reference and Dependencies Source: https://pumped-fn.github.io/pumped-fn/api Releases a reference and its value, along with all dependencies that rely on it. This ensures proper cleanup of resources. ```typescript import { derive, createScope } from "@pumped-fn/core-next"; const derivedValue = derive(value, (value) => value + "1"); let resolvedValue = await scope.resolve(derivedValue); await scope.release(value); // will also release derivedValue ``` -------------------------------- ### Core API Reference: Scope Operations Source: https://pumped-fn.github.io/pumped-fn/llm Details operations for managing scopes in @pumped-fn/core-next, including resolving, updating, subscribing to changes, and disposing of resources. ```typescript scope.resolve(executor); // Get value scope.update(executor, value); // Update & trigger reactive scope.onUpdate(executor, cb); // Subscribe to changes scope.onChange(cb); // Global change events scope.onRelease(executor, cb); // Cleanup events scope.use(middleware); // Add middleware scope.pod(...presets); // Create sub-scope scope.dispose(); // Cleanup all ``` -------------------------------- ### Graph-Based Testing with Isolated Scopes Source: https://pumped-fn.github.io/pumped-fn/llm Demonstrates how to perform graph-based testing by configuring entire dependency graphs for testing. It covers setting up test scopes with mock dependencies, testing complete flows, verifying side effects, and performing concurrent testing with isolated scopes. ```typescript // Configure entire system for testing const testScope = createScope( preset(environment, "test"), preset(database, mockDb), preset(logger, silentLogger) ); // Test complete flows test("user registration flow", async () => { const scope = createScope( preset(emailService, mockEmail), preset(database, inMemoryDb) ); try { // Test entire registration graph const registration = await scope.resolve(registrationFlow); const result = await registration.execute({ email: "test@example.com", password: "secure123", }); // Verify side effects expect(mockEmail.sent).toHaveLength(1); expect(await inMemoryDb.users.count()).toBe(1); } finally { await scope.dispose(); } }); // Concurrent testing with isolated scopes await Promise.all([test1WithScope(), test2WithScope(), test3WithScope()]); // No interference between tests ``` -------------------------------- ### Scope Creation Source: https://pumped-fn.github.io/pumped-fn/api Shows the basic creation of a scope, which is responsible for resolving dependency graphs. ```typescript import { createScope } from "@pumped-fn/core-next"; const scope = createScope (); ``` -------------------------------- ### Accessing Controller in Provide/Derive Source: https://pumped-fn.github.io/pumped-fn/api Shows how to access the controller within the factory functions of `provide` and `derive` for advanced state management. ```typescript const value = provide (( ctl ) => "string"); ``` ```typescript const otherValue = provide (( ctl ) => 20); ``` ```typescript const derived = derive ( value , ( value , ctl ) => { /* */ }); ``` ```typescript const derivedUsingArray = derive ( [ value , otherValue ], ([ value , otherValue ], ctl ) => { /* */ } ); ``` ```typescript const derivedUsingObject = derive ( { value , otherValue }, ({ value , otherValue }, ctl )=> { ctl . /* */ } ); ``` -------------------------------- ### Error Handling and Recovery Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Details the error handling and recovery mechanisms, including the use of fallback strategies and error boundaries to manage errors thrown by factories during execution. ```javascript FallbackCacheFactoryErrorBoundaryScopeClient FallbackCacheFactoryErrorBoundaryScopeClient alt[Has fallback] [No fallback] alt[Factory throws error] [Factory succeeds] resolve(executor) 1 execute(deps) 2 throw Error 3 handleError(executor, error) 4 getFallback(executor) 5 fallbackValue 6 store(executor, fallbackValue) 7 logError(error) 8 return fallbackValue 9 markAsErrored(executor) 10 propagateError(error) 11 throw Error 12 value 13 store(executor, value) 14 return value 15 ``` -------------------------------- ### Standard Resolution Flow Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Illustrates the standard resolution process for Executors within Pumped Functions. It shows a recursive resolution loop that checks a cache before resolving dependencies, executing the factory function, and storing the computed value. ```javascript Recursive resolutionloop[For each dependency]alt[Cache Hit][Cache Miss]resolve(executorA)1lookup(executorA)2cachedValue3return cachedValue4getDependencies(executorA)5[executorB, executorC]6resolve(dependency)7dependencyValue8getFactory()9factory function10execute(depValues)11computedValue12store(executorA, computedValue)13registerResolution(executorA)14return computedValue15 8xutbse ``` -------------------------------- ### Executor Primitives Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Explains the core 'Executor' concept in Pumped Functions, which is an object containing a factory function, dependencies, and metadata. It details the 'lazy', 'reactive', and 'static' references used to control dependency resolution behavior within a Scope. ```javascript Executor is the atom of `pumped-fn`. At its heart, it's measely an object to be used as a reference. It contains the factory function, dependencies and metas Executor has a few references used as signal the scope to treat the graph of dependencies slightly differently * `lazy` is a representation of an Executor at the Scope. It gives you the access to the Accessor. It fuels conditional dependency, lazy evalution * `reactive` is a Reactive indicator of an Executor at the Scope. When a value depending on a reactive variation, whenever the main Executor got updated, the factory will be triggered * `static` is a static representation of an Executor at the Scope. Similar to .lazy, the major different is `static` will also resolve the dependency graph prior to triggering the factory ``` -------------------------------- ### Meta Accessor Integration Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates how to integrate meta accessors with scopes. An accessor created from a scope can be used to retrieve metadata associated with executors within that scope. ```typescript import { createScope, provide, meta, custom } from "@pumped-fn/core-next"; const description = meta("description", custom()); const service = provide(() => "service", description("Main service")); const scope = createScope(); const accessor = scope.accessor(service); // Accessor includes metas const desc = description.find(accessor); // "Main service" ``` -------------------------------- ### Reactive Update Propagation Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Details the reactive update propagation mechanism, which handles updates by processing an update queue. It includes steps for invalidating, storing, and re-computing values for dependent executors. ```javascript FactoryListenersCacheDependency GraphUpdateQueueScopeClient FactoryListenersCacheDependency GraphUpdateQueueScopeClient par[Parallel dependency resolution] Skip non-reactive alt[Is Reactive Dependent] [Not Reactive] loop[Process update queue] update(executorA, newValue) 1 invalidate(executorA) 2 store(executorA, newValue) 3 getReactiveDependents(executorA) 4 [executorB.reactive, executorC.reactive] 5 enqueue([executorB, executorC]) 6 nextExecutor 7 getDependencies(nextExecutor) 8 dependencies 9 getValue(dep1) 10 getValue(dep2) 11 execute(dependencies) 12 newComputedValue 13 store(nextExecutor, newComputedValue) 14 notify(nextExecutor, newComputedValue) 15 getReactiveDependents(nextExecutor) 16 moreDependents 17 enqueue(moreDependents) 18 notifyComplete() 19 updateComplete 20 ``` -------------------------------- ### Scope Resolve Method Source: https://pumped-fn.github.io/pumped-fn/api Demonstrates how to use the `scope.resolve` method to asynchronously retrieve a value from the scope. ```typescript const resolvedValue = await scope . resolve ( value ); ``` -------------------------------- ### Middleware During Update Propagation Source: https://pumped-fn.github.io/pumped-fn/how-does-it-work Describes how middleware can intercept update propagation, allowing for value transformation before an update is applied to an executor or its dependents. ```javascript ReactiveQueueCacheMiddlewareScopeClient ReactiveQueueCacheMiddlewareScopeClient Pre-update middleware alt[Middleware transforms value] [No transformation] Middleware also intercepts these loop[For each reactive dependent] update(executor, newValue) 1 onChange("update", executor, newValue, scope) 2 preset(executor, transformedValue) 3 use transformedValue 4 void 5 use newValue 6 store(executor, finalValue) 7 findReactiveDependents(executor) 8 [dependent1, dependent2] 9 resolve(dependent, force=true) 10 updateComplete 11 ```