### Project Setup and Build Commands Source: https://github.com/wraithyy/attunement/blob/main/CONTRIBUTING.md Commands to install dependencies, run tests, check types, and build the project. Ensure all commands pass before pushing changes. ```sh pnpm install pnpm test # Vitest pnpm typecheck # tsc --noEmit pnpm build # tsup → dist ``` -------------------------------- ### CLI Documentation Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example of generating documentation and piping it to a file. ```bash attunement docs --schema src/config.ts > CONFIG_SCHEMA.md ``` -------------------------------- ### CLI Validation Examples Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Basic and advanced usage examples for validating configuration files. ```bash # Basic validation attunement check --schema src/config.ts config/prod.json # With all options attunement check \ --schema src/config.ts \ --diff \ --strict \ --print-fingerprint \ config/prod.json \ config/staging.json ``` -------------------------------- ### HTML injection examples Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Demonstrates how configuration is injected into index.html for development and production builds. ```html ``` ```html ``` -------------------------------- ### Install Attunement Source: https://github.com/wraithyy/attunement/blob/main/README.md Add the package to your project using your preferred package manager. ```sh pnpm add attunement # or npm / yarn ``` -------------------------------- ### Basic Vite Plugin Setup Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Initializes the plugin with default settings in the Vite configuration file. ```typescript // vite.config.ts import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { attunement } from "attunement/vite"; export default defineConfig({ plugins: [ react(), attunement(), // uses defaults ], }); ``` -------------------------------- ### Initialize Configuration Loader Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Example usage of the attune function with a Zod schema and JSON source. ```typescript import { z } from "zod"; import { attune, fromJson } from "attunement"; const appConfig = attune({ schema: z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("warn"), }), sources: [fromJson("/app-config.json")], onLoad: (config) => { initializeApiClient(config.API_URL); }, }); // Call before bootstrap await appConfig.load(); ``` -------------------------------- ### Common Test Setup Pattern Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Use beforeEach to initialize the TestProvider with specific configuration overrides. ```typescript // Setup const testConfig = { API_URL: "http://localhost:3000", FEATURE_FLAGS: { darkMode: true }, // defaults for other keys come from schema }; beforeEach(() => { const TestProvider = createTestProvider(appConfig, testConfig); render(); }); ``` -------------------------------- ### Initialize MSW in main entry Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Import the setup module in the main entry point to ensure onReady callbacks execute at boot. ```typescript // main.tsx import "./mocks/setup"; // runs onReady callbacks import { createRoot } from "react-dom/client"; ``` -------------------------------- ### Migrating from a hand-rolled loader Source: https://github.com/wraithyy/attunement/blob/main/README.md Examples showing the transition from manual promise-based configuration loading to the declarative Attunement pattern. ```tsx // before fetchConfig().then((config) => { setApiBaseUrl(config.API_URL); root.render(); }); ``` ```tsx // after: wiring → onLoad, gating → Provider, render is unconditional export const appConfig = attuneReact({ schema, sources: [fromJson("/app-config.json")], onLoad: (config) => setApiBaseUrl(config.API_URL), }); root.render( }> ); ``` -------------------------------- ### Replace build placeholder via command line Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Example command to replace the build placeholder with actual configuration data. ```bash # Helm/envsubst/sed sed "s/__ATTUNEMENT_CONFIG__/$(cat config.json | jq -c '.')/g" dist/index.html ``` -------------------------------- ### Test Provider Setup Errors Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/errors.md Examples of errors triggered by invalid overrides or unsupported async schemas in createTestProvider. ```typescript createTestProvider(appConfig, { LOG_LEVEL: "invalid", // not one of enum values }) // → throws ConfigError with validation issues ``` ```typescript // Schema with async validation const schema = z.object({...}).parseAsync(...); createTestProvider(appConfig, {}) // → Error: attunement: async schema validation is not supported in createTestProvider ``` -------------------------------- ### AttunedReact Usage Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Demonstrates wrapping an application with the Provider and consuming configuration via the use hook. ```typescript // Provider wraps the app tree } errorFallback={} > // Hook inside tree function MyComponent() { const { API_URL } = appConfig.use(); return
API: {API_URL}
; } ``` -------------------------------- ### Accessing Configuration Fingerprint Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Example of retrieving and using the configuration fingerprint for tracking. ```typescript const fp = await appConfig.fingerprint(); console.log(fp.hash); // "a1b2c3d4" Sentry.setTag("config_version", fp.version ?? fp.hash); ``` -------------------------------- ### Imperative Configuration Setup Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Initializes global services like loggers or API clients after configuration validation but before the application renders. ```ts onLoad: (config) => { setApiBaseUrl(config.API_URL); initLogger(config.LOG_LEVEL); }, ``` -------------------------------- ### Initialize attune configuration Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example usage of the attune function with a Zod schema and a JSON source. ```typescript const appConfig = attune({ schema: z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("warn"), }), sources: [fromJson("/app-config.json")], onLoad: (config, fingerprint) => { initializeApi(config.API_URL); Sentry.setTag("config", fingerprint.hash); }, }); ``` -------------------------------- ### Configuration Overrides Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example of integrating local storage overrides into the application configuration. ```typescript export const appConfig = attuneReact({ schema, sources: [ merge( fromJson("/app-config.json"), ...import.meta.env.DEV ? [fromOverrides()] : [], ), ], }); ``` -------------------------------- ### Configure fromJson source Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example of configuring the fromJson source with custom timeout, retry, and header settings. ```typescript fromJson("/app-config.json", { timeoutMs: 5000, // faster timeout retries: 1, // fewer retries backoffMs: 500, // slower backoff headers: { "Authorization": "Bearer token", "X-Version": "1.0", }, }) ``` -------------------------------- ### Register MSW via onReady Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Register MSW setup logic using the onReady callback for non-render-critical initialization. ```typescript // mocks/setup.ts import { appConfig } from "../config"; appConfig.onReady((config) => { if (config.USE_MOCKS) { // Start MSW worker } }); ``` -------------------------------- ### Vite Plugin Configuration Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example of integrating the attunement plugin into the Vite configuration file. ```typescript // vite.config.ts import { attunement } from "attunement/vite"; export default defineConfig({ plugins: [ attunement({ configFile: "config/app-config.json", url: "/runtime-config.json", injectKey: "__APP_CONFIG__", buildPlaceholder: `${JSON.stringify({...})}`, }), ], }); ``` -------------------------------- ### Initialize React Configuration Source: https://github.com/wraithyy/attunement/blob/main/README.md Define the configuration schema and sources in a module scope to ensure the fetch starts with the application. ```tsx // config.ts — module scope, so the fetch starts with the app, not with a render import { z } from "zod"; import { attuneReact, fromJson } from "attunement/react"; import { setApiBaseUrl } from "./api"; export const appConfig = attuneReact({ schema: z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("warn"), }), sources: [fromJson("/app-config.json")], onLoad: (config) => { setApiBaseUrl(config.API_URL); // runs before first render }, }); ``` -------------------------------- ### fromJson Retry Logic Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/errors.md Demonstration of the exponential backoff retry behavior for network-related errors. ```text Attempt 1: fail (timeout 8s) → wait 300ms Attempt 2: fail (timeout 8s) → wait 600ms Attempt 3: fail (timeout 8s) → throw error ``` -------------------------------- ### Callback Failure Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/errors.md Example of a callback throwing an error that gets wrapped into a ConfigError. ```typescript onLoad: (config) => { throw new Error("initialization failed"); } // → ConfigError: config callback failed: initialization failed ``` -------------------------------- ### Handling ConfigError Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Example of catching and processing configuration validation errors. ```typescript const config = await appConfig.load().catch((error) => { if (error instanceof ConfigError) { console.error("Config validation failed:", error.message); error.issues.forEach((issue) => { console.error(` ${issue.path?.join(".")}: ${issue.message}`); }); } }); ``` -------------------------------- ### Provider Component Implementation Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Example of rendering the Provider with custom fallback, error handling, and error reporting. ```typescript createRoot(el).render( Loading config...} errorFallback={(error, retry) => (

Config failed: {error.message}

)} onError={(error) => Sentry.captureException(error)} >
); ``` -------------------------------- ### Implement Provider Component Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Example usage of the Provider component with fallback and error handling configurations. ```typescript Loading...} errorFallback={(error, retry) => (

Config Failed

{error.message}

)} onError={(error) => logErrorToService(error)} >
``` -------------------------------- ### Dev server middleware behavior Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Example of the HTTP responses provided by the dev server middleware. ```http GET http://localhost:5173/app-config.json → 200 + file contents (application/json) GET http://localhost:5173/app-config.json (file deleted) → 404 + "attunement: config/app-config.json not found" ``` -------------------------------- ### Config File Missing Error Response Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Example of the 404 error returned by the dev server when a configuration file is missing. ```text GET /app-config.json ← 404 Not Found ← "attunement: config/app-config.json not found" ``` -------------------------------- ### attune(options) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Factory function that creates a config loader. Loading starts immediately at module scope; the returned handle caches results across all calls. ```APIDOC ## attune(options) ### Description Factory function that creates a config loader. Loading starts immediately at module scope; the returned handle caches results across all calls. ### Signature `function attune(options: AttuneOptions): Attuned, S>` ### Parameters - **options** (AttuneOptions) - Required - Configuration object containing schema, sources, and optional callbacks - **options.schema** (StandardSchemaV1) - Required - A Standard Schema (Zod, Valibot, ArkType) defining the config shape and validation - **options.sources** (Source[]) - Required - Array of source functions tried in order; first non-nullish result wins - **options.onLoad** ((config: T, fingerprint: Fingerprint) => void | Promise) - Optional - Callback run after validation completes, before load() resolves ### Returns - **load** (() => Promise) - Method to load the configuration - **fingerprint** (() => Promise) - Method to retrieve the configuration fingerprint - **onReady** ((cb: ReadyCallback) => void) - Method to register a callback for when the configuration is ready ### Throws - **ConfigError** - Thrown if all sources fail or validation fails ### Example ```typescript import { z } from "zod"; import { attune, fromJson } from "attunement"; const appConfig = attune({ schema: z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("warn"), }), sources: [fromJson("/app-config.json")], onLoad: (config) => { initializeApiClient(config.API_URL); }, }); await appConfig.load(); ``` ``` -------------------------------- ### Devtools Component Usage Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Examples of implementing AttunementDevtools with standard and non-zod schemas. ```typescript ``` ```typescript const fields = [ { key: "API_URL", type: "string", description: "API endpoint" }, { key: "LOG_LEVEL", type: "enum", values: ["debug", "info", "warn", "error"], description: "" }, ]; ``` -------------------------------- ### GET [url] Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md The dev server middleware endpoint that serves the configured JSON file. ```APIDOC ## GET [url] ### Description Serves the configuration file at the specified URL during development. ### Method GET ### Endpoint Configured via `options.url` (Default: `/app-config.json`) ### Response #### Success Response (200) - **Content** (application/json) - The contents of the configuration file. #### Error Response (404) - **Message** - "attunement: [path] not found" ``` -------------------------------- ### Configure Attunement Devtools Plugin Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Example of using the attunementDevtoolsPlugin with custom options like a specific storage key. ```typescript import { TanStackDevtools } from "@tanstack/react-devtools"; import { attunementDevtoolsPlugin } from "attunement/devtools"; export function App() { return ( <> {import.meta.env.DEV && ( )} ); } ``` -------------------------------- ### Configure attunement plugin in vite.config.ts Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Basic setup for the attunement plugin within a Vite configuration file. ```typescript // vite.config.ts import { defineConfig } from "vite"; import { attunement } from "attunement/vite"; export default defineConfig({ plugins: [ attunement({ configFile: "config/app-config.json", injectKey: "__APP_CONFIG__", }), ], }); ``` -------------------------------- ### Initialize attuneReact Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Example usage of attuneReact at module scope for eager loading. Requires React 19+. ```typescript import { z } from "zod"; import { attuneReact, fromJson } from "attunement/react"; export const appConfig = attuneReact({ schema: z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("warn"), }), sources: [fromJson("/app-config.json")], onLoad: (config) => initializeApiClient(config.API_URL), }); ``` -------------------------------- ### Configuration Validation Error Message Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Example of the error output generated when runtime configuration overrides fail validation. ```text ConfigError: Invalid runtime config — you didn't say the magic word: LOG_LEVEL: Invalid enum value. Expected 'debug' | 'info' | 'warn' | 'error' (did you mean "LOG_LEVEL"?) ``` -------------------------------- ### Integrate Standalone Widget and TanStack Plugin Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Example of lazy-loading the Attunement devtools widget and configuring the TanStack plugin within a React application. ```typescript // App.tsx import { lazy, Suspense } from "react"; import { TanStackDevtools } from "@tanstack/react-devtools"; import { attunementDevtoolsPlugin } from "attunement/devtools"; import { appConfig } from "./config"; // Lazy load both devtools const AttunementDevtools = lazy(() => import("attunement/devtools").then((m) => ({ default: m.AttunementDevtools })) ); export function App() { return ( } errorFallback={} > {import.meta.env.DEV && ( <> {/* Standalone widget */} {/* TanStack plugin */} )} ); } ``` -------------------------------- ### Test component configuration with createTestProvider Source: https://github.com/wraithyy/attunement/blob/main/README.md Use createTestProvider to inject configuration overrides synchronously during component testing. Overrides are validated against the schema at setup. ```tsx import { createTestProvider } from "attunement/testing"; import { appConfig } from "./config"; const TestProvider = createTestProvider(appConfig, { API_URL: "http://localhost:9999", // merged over schema defaults }); render(); ``` -------------------------------- ### Validation Failure Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/errors.md Example of data failing schema validation during configuration loading. ```typescript // sources return: { API_URL: 123 } // schema expects: { API_URL: string } ``` -------------------------------- ### Invalid Schema Module Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md An example of a schema module that fails because it imports application-specific code. ```typescript // src/config-schema.ts — NOT OK for CLI import { z } from "zod"; import { myHelpers } from "./helpers"; // relative import is OK import { setupLogger } from "./app"; // ERROR: pulls in app code export const schema = z.object({...}); ``` -------------------------------- ### Initialize app config module Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Fetch configuration from a remote JSON file using the attuneReact helper. ```typescript export const appConfig = attuneReact({ schema, sources: [fromJson("/app-config.json")], // fetches from S3 }); ``` -------------------------------- ### Bootstrap configuration via URL parameters Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Pass configuration values directly through the URL query string to override existing settings at runtime. ```text ?config.API_URL=http://localhost:3000&config.LOG_LEVEL=debug ``` -------------------------------- ### Project File Structure Source: https://github.com/wraithyy/attunement/blob/main/CLAUDE.md Overview of the core source files and configuration files in the repository. ```text src/index.ts core: attune(), Source, fromJson, fromWindow, ConfigError src/react.tsx attuneReact(): Provider (Suspense + ConfigBoundary), use() src/index.test.ts core tests (Vitest) tsup.config.ts one entry per file = one entry in package.json exports docs/design.md design pillars, case studies, out of scope ``` -------------------------------- ### Development Commands Source: https://github.com/wraithyy/attunement/blob/main/CLAUDE.md Standard commands for testing, type checking, and building the project. ```bash pnpm test # Vitest pnpm typecheck # tsc --noEmit pnpm build # tsup → dist (ESM + d.ts) ``` -------------------------------- ### Provide Configuration to React App Source: https://github.com/wraithyy/attunement/blob/main/README.md Wrap the application with the configuration provider in the main entry point. ```tsx // main.tsx createRoot(el).render( } errorFallback={(error, retry) => }> ); ``` -------------------------------- ### Inject config via entrypoint script Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Use a shell script to replace placeholders in index.html with JSON configuration. ```bash # entrypoint.sh CONFIG_JSON=$(node -e "console.log(JSON.stringify({...}))") sed "s/__ATTUNEMENT_CONFIG__/$CONFIG_JSON/g" index.html > index.html.tmp mv index.html.tmp index.html ``` -------------------------------- ### Generate schema documentation Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/README.md Generate markdown documentation from a configuration schema using the CLI. ```bash attunement docs --schema src/config.ts > CONFIG.md ``` -------------------------------- ### Valid Schema Module Example Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md A compliant schema module using Zod for validation and only external imports. ```typescript // src/config-schema.ts — OK for CLI import { z } from "zod"; // external only export const schema = z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]), }); ``` -------------------------------- ### Using the Attuned Interface Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Demonstrates loading configuration, accessing fingerprints for telemetry, and registering lifecycle callbacks. ```typescript const config = await appConfig.load(); console.log(config.API_URL); // fully typed, never undefined const fp = await appConfig.fingerprint(); Sentry.setTag("config", fp.version ?? fp.hash); appConfig.onReady((config, fingerprint) => { // runs before first render (React) or before bootstrap (vanilla) router.setBasePath(config.BASE_PATH); }); ``` -------------------------------- ### CLI Documentation Command Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Syntax for generating documentation from a schema. ```bash attunement docs --schema ``` -------------------------------- ### Integrate with Vue provide/inject Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Await the configuration load before mounting the application and share the instance using Vue's provide/inject pattern. ```ts // main.ts const config = await appConfig.load(); const app = createApp(App); app.provide(configKey, config); app.mount("#app"); ``` -------------------------------- ### Wrap core config with bindReact Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Example usage of bindReact for scenarios where the schema is defined in a non-React module. ```typescript // When schema lives in a React-free module (CLI/app split) import { attune } from "attunement"; import { bindReact } from "attunement/react"; import { schema } from "./config-schema"; // schema only, no React const coreConfig = attune({ schema, sources: [fromJson("/app-config.json")] }); export const appConfig = bindReact(coreConfig); ``` -------------------------------- ### fromOverrides Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Utility to load configuration overrides from localStorage. ```APIDOC ## fromOverrides ### Description Retrieves configuration overrides stored in localStorage. ### Parameters - **storageKey** (string) - Optional - localStorage key for overrides (default: "attunement:overrides") ### Example ```typescript fromOverrides("my_key") ``` ``` -------------------------------- ### fromJson(url, options?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Configures a JSON source for fetching configuration data from a URL. ```APIDOC ## fromJson(url, options?) ### Description Fetches configuration data from a specified URL with configurable retry and timeout settings. ### Parameters - **url** (string) - Required - Absolute or relative URL to fetch. - **timeoutMs** (number) - Optional - Per-attempt timeout in milliseconds (default: 8000). - **retries** (number) - Optional - Extra attempts after first (default: 2). - **backoffMs** (number) - Optional - Base backoff in milliseconds (default: 300). - **cache** (string) - Optional - Fetch cache policy (default: "no-store"). - **headers** (object) - Optional - Request headers. - **credentials** (string) - Optional - Credentials mode (default: "same-origin"). - **signal** (AbortSignal) - Optional - Abort controller signal. ``` -------------------------------- ### Generate schema documentation with attunement docs Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md Generates a markdown table representing schema fields, types, and defaults. ```bash attunement docs --schema ``` ```bash attunement docs --schema src/config.ts > CONFIG.md ``` -------------------------------- ### Configuring Multiple Overrides Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Shows how to provide multiple configuration overrides simultaneously when creating a test provider. ```typescript const TestProvider = createTestProvider(appConfig, { API_URL: "http://localhost:9999", LOG_LEVEL: "debug", FEATURE_FLAGS: { betaUI: true }, THEME: "dark", }); ``` -------------------------------- ### fromOverrides(storageKey?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Creates a source that loads configuration overrides from localStorage and URL parameters. This function is intended for development use to dynamically adjust application settings. ```APIDOC ## fromOverrides(storageKey?) ### Description Loads configuration overrides from localStorage and URL parameters. Overrides are merged with existing configuration and validated against the schema. ### Signature `function fromOverrides(storageKey?: string): Source` ### Parameters - **storageKey** (string) - Optional - The localStorage key used for persisting overrides. Defaults to "attunement:overrides". ### Returns - **Source** - A source function to be used in the attunement configuration pipeline. ### Usage Example ```typescript import { fromOverrides } from "attunement/devtools"; import { merge, fromJson, attuneReact } from "attunement/react"; const devOverrides = import.meta.env.DEV ? [fromOverrides()] : []; export const appConfig = attuneReact({ schema, sources: [merge(fromJson("/app-config.json"), ...devOverrides)], onLoad: (config) => initializeApi(config.API_URL), }); ``` ### URL Bootstrap Overrides can be passed via URL query parameters using the `config.` prefix: `?config.API_URL=http://localhost:3000&config.LOG_LEVEL=debug` ``` -------------------------------- ### fromWindow(key) Source: https://github.com/wraithyy/attunement/blob/main/README.md Retrieves configuration from a global window object, requiring zero network requests. ```APIDOC ## fromWindow(key) ### Description Retrieves configuration from a global window object, requiring zero network requests. ``` -------------------------------- ### Configure onReady wiring Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Use onReady in external modules to register callbacks during initial load. Ensure these modules are statically imported in the main entry file. ```ts // router.ts — imported by main.tsx, not by config.ts import { appConfig } from "./config"; appConfig.onReady((config) => { router.update({ context: { apiUrl: config.API_URL } }); }); ``` -------------------------------- ### attunement(options: AttunementViteOptions) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Initializes the Attunement Vite plugin with configuration options. ```APIDOC ## attunement(options: AttunementViteOptions) ### Description Initializes the plugin within the Vite configuration to serve application configuration files. ### Parameters - **configFile** (string) - Optional - Path to the configuration file. - **url** (string) - Optional - The URL endpoint where the config is served. - **injectKey** (string | false) - Optional - The key used for window injection, or false to disable. - **buildPlaceholder** (string) - Optional - Placeholder string used during build time. ``` -------------------------------- ### Invalid JSON Error Response Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Example of the 500 error returned by the dev server when the configuration file contains invalid JSON. ```text GET /app-config.json ← 500 ``` -------------------------------- ### Initialize Non-React Configuration Source: https://github.com/wraithyy/attunement/blob/main/README.md Use the core library to load configuration in non-React environments by awaiting the load method. ```ts import { attune, fromJson } from "attunement"; export const appConfig = attune({ schema, sources: [fromJson("/app-config.json")] }); await appConfig.load(); // typed, validated, cached ``` -------------------------------- ### Initialize Attunement with Standard Schema Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/README.md Demonstrates how to use Zod, Valibot, or ArkType schemas with the attune function. ```typescript import { z } from "zod"; import { v } from "valibot"; import { type } from "arktype"; // All work the same const schema1 = z.object({...}); const schema2 = v.object({...}); const schema3 = type({...}); const appConfig = attune({ schema: schema1, sources: [...] }); ``` -------------------------------- ### Runtime Configuration Fetching Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Fetches the configuration from a JSON file at runtime. ```typescript // src/config.ts export const appConfig = attuneReact({ schema, sources: [fromJson("/app-config.json")], }); ``` -------------------------------- ### Create an independent kill switch configuration Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Define a secondary configuration instance for emergency shutdowns by reading a separate JSON file at boot. ```ts export const shutdownConfig = attune({ schema: z.object({ SHUTDOWN: z.boolean().default(false) }), sources: [fromJson("/shutdown.json", { retries: 0 })], }); ``` -------------------------------- ### Organize schema and configuration files Source: https://github.com/wraithyy/attunement/blob/main/README.md Split configuration into a schema-only file, a core handle, and optional React bindings to maintain clean dependencies. ```ts // src/config-schema.ts — schema only, zero imports except zod import { z } from "zod"; export const schema = z.object({ API_URL: z.string(), LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]), }); // src/config.ts — core handle, same module scope as main.tsx/cli.ts import { attune } from "attunement"; import { schema } from "./config-schema"; export const appConfig = attune({ schema, sources: [fromJson("/app-config.json")] }); // src/config.react.tsx — React bindings (you don't need this yet) import { bindReact } from "attunement/react"; import { appConfig } from "./config"; export const AppConfig = bindReact(appConfig); // independent context if multiple bindings needed ``` -------------------------------- ### Handle optional configuration overrides Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Wrap a source in a helper function to treat 404 errors as empty configurations instead of merge failures. ```typescript const optional = (source: Source): Source => () => Promise.resolve(source()).catch(() => undefined); merge(fromJson("/config/base.json"), optional(fromJson("/config/env.json"))) ``` -------------------------------- ### writeOverrides(overrides, storageKey?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Writes configuration overrides to localStorage. ```APIDOC ## writeOverrides(overrides, storageKey?) ### Description Writes the provided overrides object to localStorage. This function silently fails if in private mode or if the storage quota is exceeded. ### Signature `function writeOverrides(overrides: Record, storageKey?: string): void` ### Parameters - **overrides** (Record) - Required - The configuration overrides to save. - **storageKey** (string) - Optional - The key used to access localStorage. ``` -------------------------------- ### Configuring Error Boundaries Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Demonstrates how to use errorFallback within the Provider to catch configuration-specific errors while allowing app-level errors to bubble up. ```jsx }> {/* Render errors here bubble to a higher boundary */} }> {/* Catches app render errors */} ``` -------------------------------- ### makeFingerprint(config, raw) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Computes a fingerprint from the loaded configuration and raw input. ```APIDOC ## makeFingerprint(config, raw) ### Description Computes a fingerprint from loaded config and raw input. Exported for CLI fingerprinting. ### Signature `function makeFingerprint(config: unknown, raw: unknown): Fingerprint` ``` -------------------------------- ### Validate configuration files with attunement check Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md Use the check command to validate JSON files against a schema, detect environment drift, or enforce strict secret hygiene. ```bash attunement check --schema [--diff] [--strict] [--print-fingerprint] ``` ```bash # Basic validation attunement check --schema src/config.ts config/prod.json config/staging.json # With drift detection and fingerprints attunement check --schema src/config.ts --diff --print-fingerprint config/*.json # Strict secret hygiene (fail on credential-like keys) attunement check --schema src/config.ts --strict config/*.json ``` -------------------------------- ### optional(source) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Wraps a configuration source to ensure that any failures result in skipping the source rather than failing the entire chain. ```APIDOC ## optional(source) ### Description Wraps a source so that failures (synchronous throws or promise rejections) are treated as 'skip this source' instead of causing the chain to fail. This is useful for optional configuration files or environment-specific overrides. ### Signature `function optional(source: Source): Source` ### Parameters - **source** (`Source`) - Required - The source to make optional. ### Returns - A `Source` function that returns `undefined` on any error. ``` -------------------------------- ### Use Window Injection Source Source: https://github.com/wraithyy/attunement/blob/main/README.md Add the window source to the configuration sources to enable zero-request injection. ```tsx // config.ts import { fromWindow, fromJson } from "attunement/react"; export const appConfig = attuneReact({ schema, sources: [ fromWindow("__APP_CONFIG__"), // dev/staging: window global, zero request fromJson("/app-config.json"), // fallback: fetch from static file ], onLoad: (config) => { /* ... */ }, }); ``` -------------------------------- ### Run Single Test File Source: https://github.com/wraithyy/attunement/blob/main/CONTRIBUTING.md Execute a specific test file using Vitest. ```sh pnpm vitest run src/index.test.ts ``` -------------------------------- ### Defining a Custom Source Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Shows the Source type signature and an implementation for retrieving configuration from localStorage. ```typescript type Source = () => unknown; ``` ```typescript // Custom source: localStorage const fromLocalStorage: Source = () => localStorage.getItem("config") ? JSON.parse(localStorage.getItem("config")!) : undefined; const appConfig = attune({ schema, sources: [fromLocalStorage, fromJson("/fallback.json")], }); ``` -------------------------------- ### attunement(options?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Configures the Attunement Vite plugin with options for file paths, injection keys, and build placeholders. ```APIDOC ## attunement(options?) ### Description Initializes the Attunement plugin for Vite. It accepts an optional configuration object to define how the application configuration is loaded and injected. ### Parameters - **configFile** (string) - Optional - Path to config file relative to root. Default: "config/app-config.json" - **url** (string) - Optional - URL served in dev. Default: "/app-config.json" - **injectKey** (string | false) - Optional - Window global for injection; false disables. Default: false - **buildPlaceholder** (string) - Optional - JS placeholder for builds. Default: "__ATTUNEMENT_CONFIG__" ### Usage Example ```typescript import { attunement } from "attunement/vite"; export default defineConfig({ plugins: [ attunement({ configFile: "config/app-config.json", url: "/runtime-config.json", injectKey: "__APP_CONFIG__", buildPlaceholder: "__CONFIG__" }), ], }); ``` ``` -------------------------------- ### Integration with Vitest and React Testing Library Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Uses beforeEach to initialize a fresh TestProvider for each test case within a Vitest suite. ```typescript import { describe, it, expect, beforeEach } from "vitest"; import { render, screen } from "@testing-library/react"; import { createTestProvider } from "attunement/testing"; import { appConfig } from "./config"; describe("MyComponent", () => { let TestProvider; beforeEach(() => { TestProvider = createTestProvider(appConfig, { API_URL: "http://test:3000", }); }); it("uses test config", () => { render(); const { API_URL } = appConfig.use(); expect(API_URL).toBe("http://test:3000"); }); }); ``` -------------------------------- ### Load configuration without guarantees Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Use the load promise to execute logic after the first render if the before-first-render guarantee is not required. ```ts // auth.ts — fires after first render is OK appConfig.load().then((config) => { userManager = new UserManager({ authority: config.OAUTH_AUTHORITY }); }); ``` -------------------------------- ### Accessing config fingerprint Source: https://github.com/wraithyy/attunement/blob/main/README.md Demonstrates how to access the configuration hash and version metadata within the onLoad callback. ```ts onLoad: (config, { hash, version }) => { Sentry.setTag("config", version ?? hash); }, ``` -------------------------------- ### use() Hook Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/react-api.md Provides synchronous access to validated, fully-typed configuration. Must be used within a Provider component. ```APIDOC ## use() ### Description Synchronous access to validated, fully-typed config. Only valid inside . ### Signature function use(): T ### Returns Validated config object (same type as load() promise). ### Throws - Error if called outside context ``` -------------------------------- ### Custom Plugin Configuration Paths Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Defines custom paths, URLs, and placeholders for the configuration injection process. ```typescript // vite.config.ts export default defineConfig({ plugins: [ react(), attunement({ configFile: "src/runtime-config.json", // anywhere in root url: "/api/config", // any path injectKey: "__RUNTIME__", // any key name buildPlaceholder: '"__REPLACE_ME__"', // custom placeholder }), ], }); ``` -------------------------------- ### Configure onLoad wiring Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Use onLoad within the config module to execute logic before the first render. ```ts // config.ts export const appConfig = attuneReact({ schema, sources: [...], onLoad: (config) => { setApiBaseUrl(config.API_URL); // run before first render }, }); ``` -------------------------------- ### Configure Vite Plugin for Injection Source: https://github.com/wraithyy/attunement/blob/main/README.md Set up the Vite plugin to inject configuration into the window object during development. ```ts // vite.config.ts import { attunement } from "attunement/vite"; export default defineConfig({ plugins: [ attunement({ configFile: "config/app-config.json", injectKey: "__APP_CONFIG__", // injects into window at dev, placeholder for deploy }), ], }); ``` -------------------------------- ### attunement docs Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md Generates a markdown table of schema fields, types, defaults, and descriptions. ```APIDOC ## CLI Command: attunement docs ### Description Generates a markdown table of schema fields, types, defaults, and descriptions based on the provided schema module. ### Usage `attunement docs --schema ` ### Options - **--schema** (string) - Required - Path to module exporting the schema. ``` -------------------------------- ### Config Module with Injection Support Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/vite-plugin.md Uses the injected window key as a primary source with a fallback to the JSON file. ```typescript // src/config.ts import { fromWindow, fromJson } from "attunement/react"; export const appConfig = attuneReact({ schema, sources: [ fromWindow("__APP_CONFIG__"), // zero-request in dev fromJson("/app-config.json"), // fallback for prod or if window missed ], }); ``` -------------------------------- ### attunement docs Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Generates documentation from a schema module. ```APIDOC ## attunement docs ### Description Generates documentation based on the provided schema module. ### Parameters - **--schema** (string) - Required - Module path exporting schema ### Example ```bash attunement docs --schema src/config.ts > CONFIG_SCHEMA.md ``` ``` -------------------------------- ### Make a source optional Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/core-api.md Wraps a source to suppress errors, returning undefined instead of failing the chain. Useful for optional configuration files. ```typescript const appConfig = attune({ schema, sources: [ fromJson("/app-config.json"), optional(fromJson("/environment.json")), // 404 OK, try next ], }); ``` -------------------------------- ### Basic Component Test with Attunement Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Demonstrates wrapping a component in a TestProvider to inject configuration values during testing. ```typescript import { render, screen } from "@testing-library/react"; import { createTestProvider } from "attunement/testing"; import { appConfig } from "./app-config"; import { Dashboard } from "./Dashboard"; describe("Dashboard", () => { const TestProvider = createTestProvider(appConfig, { API_URL: "http://localhost:9999", }); it("displays the API URL", () => { render( ); expect(screen.getByText(/localhost:9999/)).toBeInTheDocument(); }); }); ``` -------------------------------- ### createTestProvider(config, overrides?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/testing-api.md Creates a synchronous Provider for tests that injects validated configuration directly into the React context. ```APIDOC ## createTestProvider(config, overrides?) ### Description Creates a synchronous Provider for tests that injects validated config directly into the context. This allows components to consume configuration without triggering network requests or Suspense fallbacks. ### Parameters - **config** (AttunedReact) - Required - App config handle (from attuneReact()). - **overrides** (Partial) - Optional - Values merged over schema defaults; validated against schema. ### Returns - **Provider** (Function) - A synchronous React component that provides the configuration to its children. ### Throws - **ConfigError** - If overrides fail validation. - **Error** - If the schema is async (async validation is not supported in tests). ### Example ```typescript import { render } from "@testing-library/react"; import { createTestProvider } from "attunement/testing"; import { appConfig } from "./config"; const TestProvider = createTestProvider(appConfig, { API_URL: "http://localhost:9999", }); render( ); ``` -------------------------------- ### Validate configuration in CI Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/README.md Use the CLI to validate configuration files against a defined schema during continuous integration. ```bash attunement check --schema src/config.ts config/*.json ``` -------------------------------- ### Configure MSW with attuneReact Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Use the onLoad hook to conditionally initialize MSW based on the USE_MOCKS configuration flag. ```typescript // config.ts export const appConfig = attuneReact({ schema: z.object({ API_URL: z.string(), USE_MOCKS: z.boolean().default(import.meta.env.DEV), }), sources: [...], onLoad: (config) => { if (config.USE_MOCKS) { // MSW setup fires at module scope after config loads void import("./mocks/handlers").then((m) => { // start MSW worker }); } }, }); ``` -------------------------------- ### Lazy Loading Pattern for AttunementDevtools Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Demonstrates the correct dynamic import pattern versus the incorrect static import pattern that would include the component in production builds. ```typescript // ✅ Correct: static import wrapped in dynamic boundary const AttunementDevtools = lazy(() => import("attunement/devtools").then((m) => ({ default: m.AttunementDevtools })) ); // ❌ Wrong: static import shipped to production import { AttunementDevtools } from "attunement/devtools"; if (import.meta.env.DEV) { // AttunementDevtools bundle already included ^^ } ``` -------------------------------- ### Validate configuration in GitHub Actions Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Integrate Attunement into a CI pipeline to ensure configuration files match the defined schema on every push. ```yaml # .github/workflows/ci.yml config-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 24 - run: npm ci - run: npx attunement check --schema src/config-schema.ts config/*.json --diff ``` -------------------------------- ### readOverrides(storageKey?) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/devtools-api.md Reads configuration overrides from localStorage. ```APIDOC ## readOverrides(storageKey?) ### Description Reads overrides from localStorage for the specified storage key. ### Signature `function readOverrides(storageKey?: string): Record` ### Parameters - **storageKey** (string) - Optional - The key used to access localStorage. ### Returns - **Record** - Parsed overrides object, or {} if invalid/missing. ``` -------------------------------- ### Generate Changeset Source: https://github.com/wraithyy/attunement/blob/main/CONTRIBUTING.md Create a new changeset file to track user-facing changes for release automation. ```sh pnpm changeset ``` -------------------------------- ### Inject Environment Variables into Config Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Methods for replacing placeholders in a template configuration file using shell utilities or infrastructure-as-code. ```bash # Using envsubst (Kubernetes, docker entrypoint, CI) export API_URL=https://api.prod.example.com export LOG_LEVEL=warn envsubst < /app/config.template.json > /app/config.json ``` ```bash # Using sed (shell only) sed -e "s|__API_URL__|https://api.prod.example.com|g" \ -e "s|__LOG_LEVEL__|warn|g" \ /app/config.template.json > /app/config.json ``` ```hcl # Using Terraform + null_resource locals { config_values = { API_URL = var.api_url LOG_LEVEL = "warn" } } resource "null_resource" "config" { provisioners "local-exec" { command = "envsubst < config.template.json > config.json" environment = { API_URL = local.config_values.API_URL LOG_LEVEL = local.config_values.LOG_LEVEL } } } ``` -------------------------------- ### diffKeys(files) Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/cli-api.md Finds keys present in some files but missing in others to detect environment drift. ```APIDOC ## diffKeys(files) ### Description Finds keys present in some files but missing in others (environment drift). Reports the union of all keys across files and identifies which files are missing specific keys. ### Signature `function diffKeys(files: { file: string; raw: Record }[]): { file: string; key: string }[]` ### Parameters - **files** (Array) - Required - Array of files with their parsed config objects - **files[].file** (string) - Required - File name/path - **files[].raw** (object) - Required - Parsed config object ### Returns - **Array** (Object) - Array of { file, key } tuples for missing keys ``` -------------------------------- ### Integrate with Angular APP_INITIALIZER Source: https://github.com/wraithyy/attunement/blob/main/docs/recipes.md Delay application bootstrap until the configuration is resolved using an injection token and the app initializer. ```ts // config.ts export const appConfig = attune({ schema, sources: [fromJson("/app-config.json")] }); // app.config.ts export const CONFIG = new InjectionToken("app-config"); providers: [ provideAppInitializer(() => appConfig.load()), { provide: CONFIG, useFactory: () => awaitedConfigValue() }, ] ``` -------------------------------- ### LocalStorage Format Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Expected JSON structure for configuration overrides in localStorage. ```json { "API_URL": "http://localhost:3000", "LOG_LEVEL": "debug" } ``` -------------------------------- ### Create Test Provider Source: https://github.com/wraithyy/attunement/blob/main/_autodocs/configuration.md Initializes a test provider with configuration overrides for testing environments. ```typescript const TestProvider = createTestProvider(appConfig, { API_URL: "http://localhost:9999", LOG_LEVEL: "debug", // other fields use schema defaults }); ```