Factory
Definition
Section titled “Definition”The Factory pattern encapsulates complex object creation logic behind simple functions. Callers provide minimal configuration and receive ready-to-use instances without knowing initialization details.
This is the dominant pattern in granit-front — every package exposes at least one factory.
Diagram
Section titled “Diagram”graph LR
Config["Config object"] --> Factory["createXxx()"]
Factory --> Instance["Ready-to-use instance"]
Implementation in Granit
Section titled “Implementation in Granit”| Factory | Package | Creates |
|---|---|---|
createLogger(prefix, options?) | @granit/logger | Logger with configured transports |
createApiClient(config) | @granit/api-client | Axios instance with Bearer interceptor |
createAuthContext<T>() | @granit/react-authentication | Generic, type-safe auth context + hook |
createLocalization(config?) | @granit/localization | Isolated i18next instance |
createReactLocalization(config?) | @granit/react-localization | i18next with initReactI18next plugin |
createSignalRTransport(config) | @granit/notifications-signalr | SignalR notification transport |
createSseTransport(config) | @granit/notifications-sse | SSE notification transport |
createKlaroCookieConsentProvider(options) | @granit/cookies-klaro | Klaro CMP adapter |
createStorage<T>(key, options?) | @granit/storage | Typed localStorage/sessionStorage accessor |
createMockProvider<T>() | @granit/react-authentication | Test provider using same context |
Rationale
Section titled “Rationale”Factory functions keep the public API surface minimal while hiding initialization complexity (transport wiring, plugin injection, default configuration). They also enable tree-shaking — unused factories are eliminated at build time.
Usage example
Section titled “Usage example”import { createLogger } from '@granit/logger';import { createApiClient } from '@granit/api-client';import { createAuthContext } from '@granit/react-authentication';import type { BaseAuthContextType } from '@granit/authentication';
// Logger with console transportconst logger = createLogger('app');
// HTTP client with automatic Bearer injectionconst api = createApiClient({ baseURL: import.meta.env.VITE_API_URL });
// Typed auth context for the applicationinterface AuthContextType extends BaseAuthContextType { register: () => void;}export const { AuthContext, useAuth } = createAuthContext<AuthContextType>();