Composition API pattern implementation for vanilla JavaScript libraries with context injection, async support, and namespace management.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Composition API pattern implementation for vanilla JavaScript libraries with context injection, async support, and namespace management
npm install unctx or yarn add unctx// ESM imports - Main context API
import {
createContext,
createNamespace,
getContext,
useContext,
withAsyncContext,
executeAsync,
defaultNamespace
} from "unctx";
// ESM imports - Build-time transformation (separate entry points)
import { unctxPlugin } from "unctx/plugin";
import { createTransformer } from "unctx/transform";
// CommonJS imports
const { createContext, createNamespace, getContext, useContext } = require("unctx");import { createContext } from "unctx";
// Create a typed context
const userContext = createContext<User>();
// Use context synchronously
userContext.call({ id: 1, name: "Alice" }, () => {
const user = userContext.use(); // { id: 1, name: "Alice" }
console.log(`Hello ${user.name}`);
});
// Use with namespace for version safety
import { useContext } from "unctx";
const useMyLibContext = useContext<MyData>("my-lib");
interface User {
id: number;
name: string;
}unctx provides three main architectural components:
Create and manage context instances with typed injection patterns.
/**
* Creates a new context instance
*/
function createContext<T = any>(opts: ContextOptions): UseContext<T>;
interface UseContext<T> {
use(): T;
tryUse(): T | null;
set(instance?: T, replace?: boolean): void;
unset(): void;
call<R>(instance: T, callback: () => R): R;
callAsync<R>(instance: T, callback: () => R | Promise<R>): Promise<R>;
}
interface ContextOptions {
asyncContext?: boolean;
AsyncLocalStorage?: typeof AsyncLocalStorage;
}Global context registry system to avoid conflicts between library versions.
/**
* Create a namespace for managing multiple contexts
*/
function createNamespace<T = any>(defaultOpts: ContextOptions): ContextNamespace;
/**
* Get context from default global namespace
*/
function getContext<T>(key: string, opts?: ContextOptions): UseContext<T>;
/**
* Get use function for named context
*/
function useContext<T>(key: string, opts?: ContextOptions): () => T;
interface ContextNamespace {
get<T>(key: string, opts?: ContextOptions): UseContext<T>;
}Maintain context across async boundaries using AsyncLocalStorage or build-time transformation.
/**
* Wrapper for async functions requiring context preservation
*/
function withAsyncContext<T>(fn: () => Promise<T>, transformed?: boolean): () => Promise<T>;
/**
* Execute async function with context restoration helpers
*/
function executeAsync<T>(fn: () => Promise<T>): [Promise<T>, () => void];Universal bundler plugins for automatic async context transformation.
/**
* Universal bundler plugin for async context transformation
*/
const unctxPlugin: {
rollup(): Plugin;
vite(): Plugin;
webpack(): Plugin;
};
/**
* Create AST transformer for async context preservation
*/
function createTransformer(options?: TransformerOptions): {
transform(code: string): { code: string; magicString: MagicString } | undefined;
shouldTransform(code: string): boolean;
};
interface TransformerOptions {
asyncFunctions?: string[];
helperModule?: string;
helperName?: string;
objectDefinitions?: Record<string, string[]>;
}interface UseContext<T> {
/**
* Get the current context. Throws if no context is set.
*/
use(): T;
/**
* Get the current context. Returns null when no context is set.
*/
tryUse(): T | null;
/**
* Set the context as Singleton Pattern.
*/
set(instance?: T, replace?: boolean): void;
/**
* Clear current context.
*/
unset(): void;
/**
* Execute a synchronous function with the provided context.
*/
call<R>(instance: T, callback: () => R): R;
/**
* Execute an asynchronous function with the provided context.
* Requires installing the transform plugin to work properly.
*/
callAsync<R>(instance: T, callback: () => R | Promise<R>): Promise<R>;
}
interface ContextOptions {
/**
* Enable async context support using AsyncLocalStorage
*/
asyncContext?: boolean;
/**
* AsyncLocalStorage implementation for async context
*/
AsyncLocalStorage?: typeof AsyncLocalStorage;
}
interface ContextNamespace {
/**
* Get or create a context by key
*/
get<T>(key: string, opts?: ContextOptions): UseContext<T>;
}
/**
* Default global namespace instance
* Used by getContext and useContext functions
*/
const defaultNamespace: ContextNamespace;