### Install Dependencies and Build Project (Bash) Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/dx.md Installs project dependencies using PNPM, builds the project for all packages, and includes commands for local development. ```bash pnpm i -g turbo pnpm install pnpm turbo build --filter=./packages/* cd perplexity/extension pnpm dev ``` -------------------------------- ### Directory Structure Example Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/architecture.md Illustrates the organized directory structure for the browser extension project, categorizing assets, components, data, entry points, hooks, plugins, services, types, and utilities. ```directory src/ ├── assets/ # Static assets ├── components/ # Shared UI components ├── data/ # Shared data sources and constants ├── entrypoints/ # Entry points for different contexts ├── hooks/ # Shared React hooks ├── plugins/ # Modular feature implementations │ ├── _core/ # Core plugin functionality │ └── */ # Individual feature plugins ├── services/ # Shared services ├── types/ # TypeScript type definitions └── utils/ # Shared utility functions ``` -------------------------------- ### Plugin Directory Structure Example Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/build-your-own-plugin.md Illustrates the standard directory structure for a plugin within the Complexity Perplexity Extension. Key files like `index.manifest.ts`, `store.ts`, and `settings-ui.tsx` are highlighted, along with conventions for UI components, hooks, utilities, types, loaders, and public exports. ```tree src/plugins/your-plugin-name/ ├── components/ # UI components ├── hooks/ # React hooks ├── index.manifest.ts[*] # Entry point and registration ├── store.ts # State management (Zustand) ├── utils.ts # Utility functions ├── types.ts # Type definitions ├── settings-ui.tsx[*] # Optional settings interface ├── **/(*.)loader.ts[*] # Run arbitrary code (still needs guard if the plugin is disabled) └── **/*.public.ts[*] # Public exports ``` -------------------------------- ### Lazy Loading and Advanced Formatting with @complexity/i18n Source: https://context7.com/elian-argentics/complexity/llms.txt Shows how to initialize the i18n module with lazy-loaded translations to optimize bundle size. Includes examples of advanced formatting for dates, numbers (currency), and lists. ```typescript import { initI18n, dt } from "@complexity/i18n"; // Lazy-load translations const { t } = await initI18n({ locale: navigator.language, fallbackLocale: ["en-US", "en"], translations: { en: () => import("./locales/en.json"), es: () => import("./locales/es.json"), fr: () => import("./locales/fr.json"), "zh-cn": () => import("./locales/zh-CN.json") } }); // Date formatting const dateTranslation = dt("Last login: {date:date}", { date: { date: { year: "numeric", month: "long", day: "numeric" } } }); console.log(t("lastLogin", { date: new Date("2025-01-15") })); // Output: "Last login: January 15, 2025" // Number formatting with currency const priceTranslation = dt("Price: {amount:number}", { number: { amount: { style: "currency", currency: "USD" } } }); console.log(t("price", { amount: 1299.99 })); // Output: "Price: $1,299.99" // List formatting const listTranslation = dt("Selected: {items:list}", { list: { items: { type: "conjunction", style: "long" } } }); console.log(t("selected", { items: ["Apple", "Banana", "Orange"] })); // Output: "Selected: Apple, Banana, and Orange" ``` -------------------------------- ### Monolithic Zustand Store Example Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/refactoring-zustand-stores.md Illustrates a single, large Zustand store before refactoring. It combines user, settings, and modal states and actions within one interface and implementation. This serves as the starting point for the refactoring process. ```typescript // src/features/some-feature/store.ts import { create } from "zustand"; import { immer } from "zustand/middleware/immer"; interface StoreState { // User state user: User | null; setUser: (user: User) => void; // Settings state theme: "dark" | "light"; toggleTheme: () => void; // Modal state isModalOpen: boolean; openModal: () => void; closeModal: () => void; } export const useFeatureStore = create()( immer((set) => ({ // User implementation user: null, setUser: (user) => set({ user }), // Settings implementation theme: "light", toggleTheme: () => set((state) => { state.theme = state.theme === "light" ? "dark" : "light"; }), // Modal implementation isModalOpen: false, openModal: () => set({ isModalOpen: true }), closeModal: () => set({ isModalOpen: false }), })), ); ``` -------------------------------- ### AudioPlayback Interface Definition Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md Defines the general interface for any audio playback subsystem. It includes methods for playing audio, piping audio from a MessagePort, getting the number of channels, accessing underlying audio nodes (shared or unshared), and closing the playback. ```typescript /** * General interface for any audio playback subsystem, user implementable. */ abstract class AudioPlayback extends events.EventEmitter { /** * Play this audio. */ play(data: Float32Array[]): void; /** * Pipe audio from this message port. Same format as pipe() in * AudioCapture. */ pipeFrom(port: MessagePort): void; /** * Get the underlying number of channels. */ channels(): number; /** * Get the underlying AudioNode, *if* there is a unique audio node for this * playback. */ unsharedNode(): AudioNode | null; /** * Get the underlying AudioNode, if it's shared. */ sharedNode(): AudioNode | null; /** * Stop this audio playback and remove any underlying data. */ close(): void; } ``` -------------------------------- ### Handle Settings Subscriptions Typescript Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/refactoring-zustand-stores.md Implements side effects for the Settings slice using Zustand's subscribe method. This example demonstrates persisting the theme preference to localStorage whenever the theme changes. It requires the FeatureStoreType to be defined. ```typescript import type { FeatureStoreType } from "../../types"; export const settingsSubscriptions = (store: FeatureStoreType) => { store.subscribe( (state) => state.theme, (theme) => { // Side effect: sync theme to localStorage console.log("Theme changed to:", theme); localStorage.setItem("theme", theme); }, ); }; ``` -------------------------------- ### Background Script CSS Import for HMR Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/hmr.md Demonstrates the correct way to import CSS files in background scripts to maintain HMR functionality. The example shows that standard imports should be used, avoiding the '?inline' suffix which breaks HMR. It also questions the necessity of importing CSS in background scripts, suggesting a design rethink. ```typescript // background.ts import styles from "./some-css-file.css"; // Standard import ``` -------------------------------- ### AudioCapture Interface Definition (JavaScript) Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md Defines the abstract interface for audio capture subsystems in Weasound. It includes methods for getting sample rate and VAD state, setting VAD state, closing the capture, and piping data to a MessagePort. It also emits 'data' and 'vad' events for audio data and voice activity detection changes, respectively. ```javascript /** * General interface for any audio capture subsystem, user-implementable. * * Events: * * data(Float32Array[]): Audio data event. Each element of the array is a * single channel of audio data. * * vad(null): Audio VAD change event. Fired every time the VAD status changes. */ abstract class AudioCapture extends events.EventEmitter { /** * Get the sample rate of this capture. Must never change. Usually *but not * always* follows an AudioContext. */ getSampleRate(): number; /** * Get the current VAD state. */ getVADState(): VADState; /** * Set the current VAD state. Subclasses may want to block this and do the * VAD themselves. */ setVADState(to: VADState); /** * Stop this audio capture and remove any underlying data. */ close(): void; /** * Pipe data to this message port, using shared memory if requested (and * possible). Message will be either a Float32Array[] (array of channels), * or, if using shared memory, a single message of the form * { * c: "buffers", * buffers: Float32Array[], * head: Int32Array * } * In the "buffers" case, the buffers are a shared memory buffer, and head * is a write head into each buffer. The writer will update the head with * each write, using the buffers as ring buffers. The receiver must be fast * enough to read the buffers before the ring wraps around. */ pipe(to: MessagePort, shared = false); } ``` -------------------------------- ### Build Project for Browsers (Bash) Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/dx.md Commands to build the project for different browsers (Chrome, Firefox) and to create distribution packages. ```bash # Build for Chrome pnpm turbo build # Build for Firefox pnpm turbo build:firefox # Build for both browsers and create .zip distribution packages pnpm turbo zip:all ``` -------------------------------- ### Run Project Tests with Vitest Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Instructions for running tests in the project using the pnpm package manager with Vitest. This includes commands for running all tests and running tests with the Vitest UI enabled for a more interactive testing experience. ```bash # Run tests pnpm test # Run tests with UI pnpm test:ui ``` -------------------------------- ### Application Entry Point with AsyncDependencyRegistry in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Shows how to initialize and use the AsyncDependencyRegistry in an application's main entry point. It demonstrates importing all feature dependency files and then loading and executing a service. ```typescript // app.ts import { createAsyncDependencyRegistry } from "./registry"; // Import all dependency registrations (which registers them with the manager) import "./feature-a-dependencies"; import "./feature-b-dependencies"; async function startApp() { const asyncDependencyRegistry = createAsyncDependencyRegistry(); // Load and use Feature B service which will automatically load all prerequisites const featureBService = await asyncDependencyRegistry.load("featureBService"); const result = await featureBService.processData("test"); console.log(result); // Or load all dependencies at once const allDeps = await asyncDependencyRegistry.loadAll(); // Use any dependency from the loaded bundle const formatted = allDeps.featureBUtils.formatData({ hello: "world" }); } startApp().catch(console.error); ``` -------------------------------- ### JavaScript Audio Capture and Playback with LibAV Resampling Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/demo/loopback/loopback.html This JavaScript code snippet initializes audio capture using Weasound and `navigator.mediaDevices.getUserMedia`. It then sets up an audio playback node and a LibAV filter graph for resampling audio. The `capture.on('data', ...)` callback processes incoming audio data, resamples it using LibAV, and plays it back, logging estimated latency. ```javascript LibAV = { base: "../../node_modules/libav.js/dist" }; async function go() { const ms = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: false, }, }); const ac = new AudioContext(); const capMethodBox = document.getElementById("cap-method"); const capMethod = capMethodBox.value; const playMethodBox = document.getElementById("play-method"); const playMethod = playMethodBox.value; // Create a capture const capture = await Weasound.createAudioCapture(ac, ms, { demandedType: capMethod, }); // Create a playback const playback = await Weasound.createAudioPlayback(ac, { demandedType: playMethod, }); (playback.unsharedNode() || playback.sharedNode()).connect( ac.destination, ); // Create the resampler const libav = await LibAV.LibAV({ noworker: true }); const frame = await libav.av_frame_alloc(); const [filter_graph, buffersrc_ctx, buffersink_ctx] = await libav.ff_init_filter_graph( "aresample", { sample_rate: capture.getSampleRate(), sample_fmt: libav.AV_SAMPLE_FMT_FLT, channel_layout: 4, }, { sample_rate: ac.sampleRate, sample_fmt: libav.AV_SAMPLE_FMT_FLT, channel_layout: 4, }, ); // And pipe the data thru capture.on("data", async (data) => { const filterFrames = await libav.ff_filter_multi( buffersrc_ctx, buffersink_ctx, frame, [ { data: data[0], channel_layout: 4, format: libav.AV_SAMPLE_FMT_FLT, sample_rate: capture.getSampleRate(), }, ], ); for (const frame of filterFrames) { const latencyIn = capture.getLatency(); const latencyOut = playback.play([frame.data]); console.log( `Estimated latency: ${latencyIn} in + ${latencyOut} out`, ); } }); } ``` -------------------------------- ### Weasound: Create and Manage Browser Audio Playback (TypeScript) Source: https://context7.com/elian-argentics/complexity/llms.txt This snippet demonstrates how to play raw PCM audio using the Weasound library. It covers creating an AudioContext, initializing the playback instance with optional preferred types, connecting the audio node to the system's output, generating and playing a test tone, queuing multiple audio chunks, and piping audio data from a Web Worker. Dependencies include the '@complexity/weasound' library and the `AudioContext` API. ```typescript import { createAudioPlayback } from "@complexity/weasound"; const audioContext = new AudioContext({ sampleRate: 48000 }); // Create playback instance const playback = await createAudioPlayback(audioContext, { // preferredType: "awp" // Optional: force specific type }); console.log(`Channels: ${playback.channels()}`); // Connect audio node to output const node = playback.unsharedNode() || playback.sharedNode(); if (node) { node.connect(audioContext.destination); } // Generate and play test tone (440 Hz sine wave) const sampleRate = audioContext.sampleRate; const duration = 1.0; // seconds const frequency = 440; // Hz const samples = Math.floor(sampleRate * duration); const audioData = [new Float32Array(samples)]; // Mono audio for (let i = 0; i < samples; i++) { audioData[0][i] = Math.sin(2 * Math.PI * frequency * i / sampleRate) * 0.3; } // Play audio (sample-perfect queueing) playback.play(audioData); // Queue multiple audio chunks seamlessly setTimeout(() => { // Play another chunk (will start immediately after first finishes) playback.play(audioData); }, 100); // Pipe from Web Worker const worker = new Worker("audio-generator.js"); const channel = new MessageChannel(); playback.pipeFrom(channel.port1); worker.postMessage({ port: channel.port2 }, [channel.port2]); // Worker sends: port.postMessage([leftChannel, rightChannel]) // Clean up setTimeout(() => { playback.close(); audioContext.close(); }, 5000); ``` -------------------------------- ### Configure CDN URL (Environment Variable) Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/dx.md Sets the CDN URL for official remote configs by adding a VITE_CPLX_CDN_URL entry to the .env file. ```env VITE_CPLX_CDN_URL=https://cdn.cplx.app ``` -------------------------------- ### JavaScript Audio Playback with LibAV.js and Weasound Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/demo/playback/playback.html This JavaScript code demonstrates how to decode an audio file using LibAV.js and play it back using the Weasound library. It initializes LibAV, opens the selected audio file, decodes its audio stream, applies filtering for format and sample rate conversion, and then plays the audio frames using Weasound's AudioPlayback. It handles potential errors like missing audio tracks and manages playback latency. ```javascript const Playback demo LibAV = { base: "../../node_modules/libav.js/dist" }; async function go() { const fileBox = document.getElementById("file"); if (!fileBox.files.length) return; const file = fileBox.files[0]; const methodBox = document.getElementById("method"); const method = methodBox.value; // Create a playback const ac = new AudioContext(); const playback = await Weasound.createAudioPlayback(ac, { demandedType: method, }); (playback.unsharedNode() || playback.sharedNode()).connect( ac.destination, ); const libav = await LibAV.LibAV(); let filter_graph = -1, buffersrc_ctx, buffersink_ctx; // Open the file await libav.mkreadaheadfile("in", file); const [fmt_ctx, streams] = await libav.ff_init_demuxer_file("in"); let streamIdx = -1; for (let i = 0; i < streams.length; i++) { if (streams[i].codec_type === libav.AVMEDIA_TYPE_AUDIO) { streamIdx = i; break; } } if (streamIdx < 0) { alert("Could not find audio track"); return; } const stream = streams[streamIdx]; // Open the decoder const [, c, pkt, frame] = await libav.ff_init_decoder( streams[streamIdx].codec_id, streams[streamIdx].codecpar, ); // Decode and play while (true) { const [res, packets] = await libav.ff_read_multi(fmt_ctx, pkt, null, { limit: 1 }); if (!packets || !packets[streamIdx]) continue; // Decode them const frames = await libav.ff_decode_multi( c, pkt, frame, packets[streamIdx], ); if (!frames.length) continue; // Filter them to get the correct format and framerate if (filter_graph < 0) { [filter_graph, buffersrc_ctx, buffersink_ctx] = await libav.ff_init_filter_graph( "aresample", { sample_rate: frames[0].sample_rate, sample_fmt: frames[0].format, channel_layout: frames[0].channel_layout, }, { sample_rate: ac.sampleRate, sample_fmt: libav.AV_SAMPLE_FMT_FLT, channel_layout: 4, }, ); } const filterFrames = await libav.ff_filter_multi( buffersrc_ctx, buffersink_ctx, frame, frames, ); for (const frame of filterFrames) { const latency = playback.play([frame.data]); console.log(`Estimated latency: ${latency}`); // Don't get too far ahead! if (latency > 200) await new Promise((res) => setTimeout(res, 100)); } if (res === 0 || res === libav.AVERROR_EOF) break; } } ``` -------------------------------- ### Load All Dependencies with AsyncDependencyRegistry in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Shows how to load all registered dependencies simultaneously using the `loadAll` method of AsyncDependencyRegistry. The result is a typed object containing all available dependencies. ```typescript const allDeps = await asyncDependencyRegistry.loadAll(); // allDeps contains all loaded dependencies with proper types const { myConfig, myService, myConstant, myUtil } = allDeps; ``` -------------------------------- ### Create Audio Capture (JavaScript) Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md Asynchronously creates an audio capture object using the provided AudioContext and MediaStream or AudioNode. This function selects the most appropriate capture mechanism for the browser. It requires an initialized AudioContext and returns a Promise that resolves to an AudioCapture instance. ```javascript /** * Create an appropriate audio capture from an AudioContext and a MediaStream. * @param ac The AudioContext for the nodes. * @param ms The MediaStream or AudioNode from which to create a capture. */ export async function createAudioCapture( ac: AudioContext, ms: MediaStream | AudioNode, opts: AudioCaptureOptions = {} ): Promise; ``` -------------------------------- ### AsyncDependencyRegistry: Create and Configure Registry (TypeScript) Source: https://context7.com/elian-argentics/complexity/llms.txt Demonstrates the creation and configuration of a type-safe distributed dependency registry using AsyncDependencyRegistry. It covers registering dependencies, handling prerequisites, loading dependencies individually or all at once, and accessing them synchronously. This pattern is useful for managing complex application states and asynchronous operations. ```typescript // registry.ts import { AsyncDependencyRegistry } from "@complexity/async-dep-registry"; import { DependencyRegistry } from "@complexity/async-dep-registry.types"; // Define your registry interface export interface AppRegistry extends DependencyRegistry { config: { apiKey: string; endpoint: string }; database: { query: (sql: string) => Promise }; auth: { login: (user: string) => Promise }; } // Create a singleton registry instance export function createRegistry() { return AsyncDependencyRegistry.create({ verbose: true, // Enable detailed logging auto: false // Manual dependency loading }); } const registry = createRegistry(); // Register dependencies with automatic type inference registry.register({ id: "config", dependencies: [], loader: () => ({ apiKey: process.env.API_KEY || "default", endpoint: "https://api.example.com" }) }); registry.register({ id: "database", dependencies: ["config"], loader: async (deps) => ({ query: async (sql: string) => { console.log(`Querying ${deps.config.endpoint}: ${sql}`); return { rows: [] }; } }) }); registry.register({ id: "auth", dependencies: ["config", "database"], loader: async (deps) => ({ login: async (user: string) => { await deps.database.query(`SELECT * FROM users WHERE name='${user}'`); return true; } }) }); // Load single dependency with prerequisites const auth = await registry.load("auth"); await auth.login("john"); // Load all dependencies in optimal parallel order const allDeps = await registry.loadAll(); console.log(allDeps.config, allDeps.database, allDeps.auth); // Synchronous access after loading const config = registry.getSync("config"); console.log(config.apiKey); // Performance analysis registry.summary(); ``` -------------------------------- ### Weasound: Create and Manage Browser Audio Capture (TypeScript) Source: https://context7.com/elian-argentics/complexity/llms.txt This snippet demonstrates how to create and manage audio capture from the browser's microphone using the Weasound library. It includes requesting microphone access, setting up an AudioContext, initializing the capture with automatic technology selection, listening for audio data events, handling Voice Activity Detection (VAD), and piping data to a Web Worker for efficient processing. Dependencies include the '@complexity/weasound' library and browser APIs like `navigator.mediaDevices.getUserMedia` and `AudioContext`. ```typescript import { createAudioCapture } from "@complexity/weasound"; // Request microphone access const stream = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true } }); // Create audio context const audioContext = new AudioContext({ sampleRate: 48000 }); // Create capture (automatically selects best available method) const capture = await createAudioCapture(audioContext, stream, { // Optional: force specific capture type // preferredType: "awp" // awp, mstp, mr, mropus, sp }); console.log(`Sample rate: ${capture.getSampleRate()} Hz`); console.log(`Latency: ${capture.getLatency()} ms`); // Listen for audio data (Float32Array per channel) capture.on("data", (audioData) => { // audioData is Float32Array[] - one array per channel console.log(`Received ${audioData.length} channels`); console.log(`Samples per channel: ${audioData[0].length}`); // Process audio data for (let channel = 0; channel < audioData.length; channel++) { const samples = audioData[channel]; // Calculate RMS level for visualization const rms = Math.sqrt( samples.reduce((sum, val) => sum + val * val, 0) / samples.length ); console.log(`Channel ${channel} RMS: ${rms}`); } }); // Voice Activity Detection (manual) capture.on("vad", () => { console.log(`VAD state changed: ${capture.getVADState()}`); }); // Set VAD state based on custom logic capture.setVADState("yes"); // "yes", "maybe", "no" // Pipe to Web Worker with shared memory for performance const worker = new Worker("audio-processor.js"); const channel = new MessageChannel(); capture.pipe(channel.port1, true); // true = use shared memory worker.postMessage({ port: channel.port2 }, [channel.port2]); // Clean up setTimeout(() => { capture.close(); audioContext.close(); stream.getTracks().forEach(track => track.stop()); }, 10000); ``` -------------------------------- ### Create Async Dependency Registry (TypeScript) Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md This snippet demonstrates how to create an asynchronous dependency registry instance using TypeScript. It involves defining a registry interface that extends `DependencyRegistry` and then creating the registry with optional configuration for verbosity. ```typescript import { AsyncDependencyRegistry } from "@/async-dep-manager"; import { DependencyRegistry } from "@/async-dep-manager.types"; // Define your registry interface export interface YourAppRegistry extends DependencyRegistry { // Your custom dependencies will be defined here } // Create a dependency manager instance with your registry type export function createAsyncDependencyRegistry() { return AsyncDependencyRegistry.create({ verbose: false, // Set to true for more detailed logging }); } ``` -------------------------------- ### Create Audio Capture Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md Creates an audio capture object from an AudioContext and a MediaStream or AudioNode. The best capture technology is chosen automatically. ```APIDOC ## POST /createAudioCapture ### Description Creates an appropriate audio capture from an AudioContext and a MediaStream or AudioNode. ### Method POST ### Endpoint /createAudioCapture ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **ac** (AudioContext) - Required - The AudioContext for the nodes. - **ms** (MediaStream | AudioNode) - Required - The MediaStream or AudioNode from which to create a capture. - **opts** (AudioCaptureOptions) - Optional - Options for overriding the type of capture. ### Request Example ```json { "ac": "AudioContext object", "ms": "MediaStream or AudioNode object" } ``` ### Response #### Success Response (200) - **AudioCapture** (object) - An object implementing the AudioCapture interface. #### Response Example ```json { "audioCapture": "AudioCapture object" } ``` ``` -------------------------------- ### Create Settings Slice Typescript Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/refactoring-zustand-stores.md Creates the Settings slice using Zustand's StateCreator. It initializes the theme to 'light' and provides a toggleTheme function to switch between 'dark' and 'light' modes. This slice also re-exports settings subscriptions. ```typescript import type { StateCreator } from "zustand"; import type { FeatureStoreType } from "../../types"; import type { SettingsSlice } from "./types"; export const createSettingsSlice: StateCreator< FeatureStoreType, [], [], SettingsSlice > = (set) => ({ theme: "light", toggleTheme: () => set((state) => { state.theme = state.theme === "light" ? "dark" : "light"; }), }); // Re-export subscriptions for easy import in the main index export { settingsSubscriptions } from "./subs"; ``` -------------------------------- ### Create Audio Playback with AudioContext Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md Creates an audio playback object using an AudioContext. The playback object manages audio nodes that need to be connected to the AudioContext to produce sound. Options can override the default playback technology. ```typescript /** * Create an appropriate audio playback from an AudioContext. */ export async function createAudioPlayback( ac: AudioContext, opts: AudioPlaybackOptions = {} ): Promise { ``` -------------------------------- ### BrowserRuntimeAdapter: Cross-Context Communication in Browser Extensions Source: https://context7.com/elian-argentics/complexity/llms.txt Enables communication between different parts of a browser extension (background scripts, content scripts, popup pages) using a pub/sub pattern. It handles message passing and asynchronous responses. Dependencies include `@comctx-adapters/core` and `comctx`. ```typescript import { BrowserRuntimeAdapter } from "@comctx-adapters/core"; import { Context } from "comctx"; // Background script (service worker) const bgContext = new Context("background", new BrowserRuntimeAdapter()); bgContext.on("getData", async (message, meta) => { console.log(`Request from tab ${meta.sender.tabId}, frame ${meta.sender.frameId}`); // Perform background work const data = await fetch("https://api.example.com/data"); return data.json(); }); bgContext.on("updateBadge", (count) => { chrome.action.setBadgeText({ text: String(count) }); }); // Content script const contentContext = new Context("content", new BrowserRuntimeAdapter()); async function fetchData() { try { const result = await contentContext.send("getData", { query: "test" }); console.log("Received from background:", result); return result; } catch (error) { console.error("Failed to communicate:", error); } } // Send message without waiting for response contentContext.send("updateBadge", 5); // Listen for messages from background contentContext.on("notification", (message) => { console.log("Background sent notification:", message); // Display in-page notification const div = document.createElement("div"); div.textContent = message.text; document.body.appendChild(div); }); // Popup script const popupContext = new Context("popup", new BrowserRuntimeAdapter()); document.getElementById("btn").addEventListener("click", async () => { const data = await popupContext.send("getData", {}); displayData(data); }); ``` -------------------------------- ### AudioCapture Interface Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/README.md The general interface for any audio capture subsystem, including methods for sample rate, VAD state, closing the capture, and piping data. ```APIDOC ## AudioCapture Interface ### Description The AudioCapture interface represents a general audio capture subsystem. It provides methods for accessing capture properties, managing voice activity detection (VAD), and handling audio data output. ### Methods - **getSampleRate()**: Returns the sample rate of the capture. - **getVADState()**: Returns the current Voice Activity Detection state. - **setVADState(to: VADState)**: Sets the current Voice Activity Detection state. Subclasses may override this. - **close()**: Stops the audio capture and releases resources. - **pipe(to: MessagePort, shared = false)**: Pipes audio data to a MessagePort. Supports shared memory for performance. ### Events - **data(Float32Array[])**: Fired when new audio data is available. Each element in the array represents a single channel. - **vad(null)**: Fired when the VAD status changes. ### Usage Example (Data Event) ```javascript audioCapture.on('data', (channelData) => { console.log('Received audio data:', channelData); }); ``` ### Usage Example (Piping with Shared Memory) ```javascript const messageChannel = new MessageChannel(); audioCapture.pipe(messageChannel.port1, true); messageChannel.port2.onmessage = (event) => { if (event.data.c === 'buffers') { console.log('Received shared audio buffers:', event.data.buffers); console.log('Current head position:', event.data.head); } }; ``` ``` -------------------------------- ### JavaScript Audio Playback with Weasound Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/weasound/demo/tone/tone.html This JavaScript code creates and controls audio playback using the Weasound library. It initializes an AudioContext, allows selection of playback types (e.g., Shared ScriptProcessor, AudioWorkletProcessor), and plays audio frames with dynamic sample generation. It also estimates and logs playback latency, providing a mechanism to avoid falling too far behind. ```javascript let ac, playback, playbackType, workers; async function go() { const btn = document.getElementById("go"); btn.onclick = void 0; const methodBox = document.getElementById("method"); const method = methodBox.value; // Create a playback if (!ac) ac = new AudioContext(); if (!playback || playbackType !== method) { playbackType = method; playback = await Weasound.createAudioPlayback(ac, { demandedType: method, }); (playback.unsharedNode() || playback.sharedNode()).connect(ac.destination); } let stop = false; btn.innerText = "Stop"; btn.onclick = () => { stop = true; btn.innerText = "Play"; btn.onclick = go; }; // Play let si = 0; while (!stop) { // Create a frame const samples = new Float32Array( Math.floor(Math.random() * 1000) + 100 ); for (let i = 0; i < samples.length; i++) { samples[i] = Math.sin((si / ac.sampleRate) * 600 * Math.PI); si++; } const latency = playback.play([samples]); console.log(`Estimated latency: ${latency}`); // Don't get too far ahead! if (latency > 200) await new Promise((res) => setTimeout(res, 100)); } } // Playback type: Default Shared AudioWorkletProcessor Shared ScriptProcessor AudioBuffers Private AudioWorkletProcessor Private ScriptProcessor document.getElementById("go").onclick = go; ``` -------------------------------- ### Create Windows Symbolic Link Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/cli/README.md This script demonstrates how to create a symbolic link (folder symlink) on Windows using PowerShell. It is useful for linking directories, such as a changelog directory, to a different location. ```powershell New-Item -ItemType SymbolicLink -Path "$(pwd)\release\changelog" -Target "$(pwd)\cdn-template\changelog" ``` -------------------------------- ### Slice-based Zustand Store: Assembling Slices Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/refactoring-zustand-stores.md Demonstrates how to create a slice-based Zustand store by assembling individual slice functions. It utilizes middleware like `immer` and `subscribeWithSelector` for optimized state management and subscriptions. The `createWithEqualityFn` is used for efficient store updates. ```typescript // src/plugins/some-feature/store/index.ts import { subscribeWithSelector } from "zustand/middleware"; import { immer } from "zustand/middleware/immer"; import { createWithEqualityFn } from "zustand/traditional"; import { createModalSlice } from "./slices/modal"; import { createSettingsSlice, settingsSubscriptions } from "./slices/settings"; import { createUserSlice } from "./slices/user"; import type { FeatureStoreType } from "./types"; export const featureStore = createWithEqualityFn()( subscribeWithSelector( immer((set, get, ...props) => ({ ...createUserSlice(set, get, ...props), ...createSettingsSlice(set, get, ...props), ...createModalSlice(set, get, ...props), })), ), ); // Initialize any centralized subscriptions (() => { settingsSubscriptions(featureStore); })(); export const useFeatureStore = featureStore; ``` -------------------------------- ### Load Multiple Dependencies with AsyncDependencyRegistry in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Explains how to use `loadMultiple` to ensure several specified dependencies, along with their prerequisites, are loaded into the AsyncDependencyRegistry. This is useful for pre-loading necessary components. ```typescript await asyncDependencyRegistry.loadMultiple(["myConfig", "myService"]); // This ensures that 'myConfig' and 'myService' (and their prerequisites) are loaded. // You can then access them individually using `load` if needed, or rely on them being available for other dependencies. ``` -------------------------------- ### AsyncDependencyRegistry: Modular Registration Pattern (TypeScript) Source: https://context7.com/elian-argentics/complexity/llms.txt Illustrates a modular registration pattern for AsyncDependencyRegistry, allowing dependency definitions to be spread across different files and feature modules. It uses TypeScript's module augmentation to extend the main registry interface, enabling a scalable and organized approach to managing dependencies in larger applications. ```typescript // features/analytics.ts import { createRegistry } from "./registry"; // Extend registry interface in feature file declare module "./registry" { interface AppRegistry { analytics: { track: (event: string) => void }; } } const registry = createRegistry(); registry.register({ id: "analytics", dependencies: ["config"], loader: (deps) => ({ track: (event: string) => { console.log(`[${deps.config.endpoint}] Event: ${event}`); } }) }); // features/notifications.ts import { createRegistry } from "./registry"; declare module "./registry" { interface AppRegistry { notifications: { send: (msg: string) => Promise }; } } const registry = createRegistry(); registry.register({ id: "notifications", dependencies: ["config", "analytics"], loader: async (deps) => ({ send: async (msg: string) => { deps.analytics.track("notification_sent"); console.log(`Sending: ${msg}`); } }) }); // app.ts - Import all features import "./features/analytics"; import "./features/notifications"; import { createRegistry } from "./registry"; async function main() { const registry = createRegistry(); // Load specific dependency (auto-loads prerequisites) const notif = await registry.load("notifications"); await notif.send("Hello World"); // Or load everything await registry.loadMultiple(["analytics", "notifications"]); } ``` -------------------------------- ### Load Single Dependency with AsyncDependencyRegistry in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Demonstrates the process of loading a single dependency using the `load` method of AsyncDependencyRegistry. The loaded dependency is fully typed based on the application's registry definition. ```typescript const myService = await asyncDependencyRegistry.load("myService"); // myService is fully typed based on YourAppRegistry definition const data = await myService.getData(); ``` -------------------------------- ### New Query Key Definition Pattern (TypeScript) Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/drop-@lukemorales-query-key-factory/index.md This snippet illustrates the new pattern for defining query keys, emphasizing the use of `as const` for literal type inference and `queryOptions` for query configuration. This pattern aims to improve type safety and reduce the need for manual type assertions. ```typescript export const queries = { all: () => ["scope"] as const, endpoint: { all: () => [...queries.all(), "endpoint"] as const, detail: (params) => queryOptions({ queryKey: [...queries.endpoint.all(), params], queryFn: () => fetchData(params), }), }, }; ``` -------------------------------- ### Create Multiple AsyncDependencyRegistry Instances in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Illustrates how to create distinct instances of AsyncDependencyRegistry for different application subsystems. Each instance manages its dependencies independently, allowing for isolated scopes and configurable options like verbosity. ```typescript // Create separate dependency managers for different subsystems const authAsyncDependencyRegistry = AsyncDependencyRegistry.create({ verbose: true, }); const dataAsyncDependencyRegistry = AsyncDependencyRegistry.create({ verbose: false, }); // Each instance manages its own dependencies independently ``` -------------------------------- ### Initialize and Use Translations with @complexity/i18n Source: https://context7.com/elian-argentics/complexity/llms.txt Demonstrates how to initialize the i18n module with static translations and use the 't' function for type-safe access to translated strings. Supports parameter substitution, pluralization, enum substitution, and nested key paths. ```typescript import { initI18n, dt } from "@complexity/i18n"; // Define base translations const enTranslations = { greeting: "Hello, {name}!", items: dt("You have {count:plural} items.", { plural: { count: { type: "cardinal", zero: "no {?}", one: "{?} item", other: "{?} items" } } }), status: dt("Status: {state:enum}", { enum: { state: { active: "Active", inactive: "Inactive", pending: "Pending" } } }), nested: { profile: { title: "User Profile" } } }; const esTranslations = { greeting: "Hola, {name}!", items: dt("Tienes {count:plural} artículos.", { plural: { count: { type: "cardinal", zero: "ningún {?}", one: "{?} artículo", other: "{?} artículos" } } }), status: dt("Estado: {state:enum}", { enum: { state: { active: "Activo", inactive: "Inactivo", pending: "Pendiente" } } }), nested: { profile: { title: "Perfil de Usuario" } } }; // Initialize i18n const { t } = await initI18n({ locale: "en-US", fallbackLocale: "en", translations: { en: enTranslations, es: esTranslations } }); // Type-safe translation with parameters console.log(t("greeting", { name: "Alice" })); // Output: "Hello, Alice!" // Pluralization with automatic number formatting console.log(t("items", { count: 0 })); // "You have no items." console.log(t("items", { count: 1 })); // "You have 1 item." console.log(t("items", { count: 5 })); // "You have 5 items." // Enum substitution console.log(t("status", { state: "active" })); // Output: "Status: Active" // Nested key access with dot notation console.log(t("nested.profile.title")); // Output: "User Profile" ``` -------------------------------- ### Define Settings Slice Typescript Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/articles/refactor/refactoring-zustand-stores.md Defines the TypeScript interface for the Settings slice, including the current theme ('dark' or 'light') and a function to toggle the theme. This provides a clear contract for theme management. ```typescript export interface SettingsSlice { theme: "dark" | "light"; toggleTheme: () => void; } ``` -------------------------------- ### Register Feature Dependencies in TypeScript Source: https://github.com/elian-argentics/complexity/blob/nxt/packages/async-dep-manager/README.md Demonstrates how to extend the AsyncDependencyRegistry with feature-specific dependencies in separate TypeScript files. It shows defining types and registering loader functions for configuration and services, including cross-feature dependencies. ```typescript // feature-a-dependencies.ts import { createAsyncDependencyRegistry } from "./registry"; // Extend the registry with this feature's dependencies declare module "./registry" { interface YourAppRegistry { featureAConfig: { apiKey: string }; featureAService: { getData: () => Promise }; } } // Get the dependency manager instance const asyncDependencyRegistry = createAsyncDependencyRegistry(); // Register this feature's dependencies asyncDependencyRegistry.register({ id: "featureAConfig", dependencies: [], loader: () => ({ apiKey: "feature-a-api-key" }), }); asyncDependencyRegistry.register({ id: "featureAService", dependencies: ["featureAConfig"], loader: (deps) => ({ getData: async () => { console.log(`Using API key: ${deps.featureAConfig.apiKey}`); return { result: "Feature A data" }; }, }), }); // feature-b-dependencies.ts import { createAsyncDependencyRegistry } from "./registry"; // Extend the registry with this feature's dependencies declare module "./registry" { interface YourAppRegistry { featureBUtils: { formatData: (data: unknown) => string }; featureBService: { processData: (input: string) => Promise }; } } // Get the dependency manager instance const asyncDependencyRegistry = createAsyncDependencyRegistry(); // Register this feature's dependencies asyncDependencyRegistry.register({ id: "featureBUtils", dependencies: [], loader: () => ({ formatData: (data) => JSON.stringify(data, null, 2), }), }); asyncDependencyRegistry.register({ id: "featureBService", dependencies: ["featureBUtils", "featureAService"], // Dependencies can cross features loader: async (deps) => ({ processData: async (input) => { const data = await deps.featureAService.getData(); return deps.featureBUtils.formatData({ input, data }); }, }), }); ``` -------------------------------- ### Update Comet Assistant Windows Launcher Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/changelogs/2.3.0.md This PowerShell script downloads and executes a patch to update the Comet Assistant launcher on Windows. Ensure you have the necessary permissions to run scripts. ```powershell irm "https://cdn.cplx.app/assets/comet-patch.ps1" | iex ``` -------------------------------- ### Patch Comet Extensions on Windows (PowerShell) Source: https://github.com/elian-argentics/complexity/blob/nxt/perplexity/extension/docs/comet-enable-extensions.md This script, when run with administrator privileges in PowerShell, downloads and executes a patch to enable Comet browser extensions on perplexity.ai domains. A browser restart is required after execution. ```powershell irm "https://cdn.cplx.app/assets/comet-policy-patch-win.ps1" | iex ``` ```powershell irm "https://cdn.cplx.app/assets/comet-patch.ps1" | iex ```