@molecule/app-solid
Framework · framework · App (browser) · v1.0.2 · Apache-2.0
Solid.js framework bindings for molecule.dev
npm install @molecule/app-solidHow it works
@molecule/app-solid adapts the @molecule/* cores to the framework framework on the app (browser) side.
import { MoleculeProvider, createAuth, createTheme } from '@molecule/app-solid'
import { Show } from 'solid-js'
import { provider as stateProvider } from '@molecule/app-state-zustand'
import { provider as themeProvider } from '@molecule/app-theme-css-variables'
import { createJWTAuthClient } from '@molecule/app-auth'
const authClient = createJWTAuthClient({ baseURL: '/api' })
function UserProfile() {
const { user, isAuthenticated, logout } = createAuth<{ name?: string }>()
const { theme, toggleTheme } = createTheme()
return (
<Show when={isAuthenticated()} fallback={<a href="/login">Log in</a>}>
<div style={{ background: theme().colors.background }}>
<h1>Welcome, {user()?.name}</h1>
<button onClick={toggleTheme}>Toggle Theme</button>
<button onClick={() => logout()}>Logout</button>
</div>
</Show>
)
}
function App() {
return (
<MoleculeProvider config={{ state: stateProvider, auth: authClient, theme: themeProvider }}>
<UserProfile />
</MoleculeProvider>
)
}Works with: @molecule/app-auth, @molecule/app-device, @molecule/app-forms, @molecule/app-http, @molecule/app-i18n, @molecule/app-logger, @molecule/app-platform, @molecule/app-push, @molecule/app-routing, @molecule/app-state, @molecule/app-storage, @molecule/app-theme, @molecule/app-ui, @molecule/app-utilities, @molecule/app-version
Reference
Solid.js framework bindings for molecule.dev.
Provides Solid-specific implementations of molecule.dev core interfaces
using Solid's reactive primitives (signals, effects, resources): wrap the
app in MoleculeProvider with a config of providers, then consume them
through createAuth, createTheme, createRouter, createI18n, and the
other primitives.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { MoleculeProvider, createAuth, createTheme } from '@molecule/app-solid'
import { Show } from 'solid-js'
import { provider as stateProvider } from '@molecule/app-state-zustand'
import { provider as themeProvider } from '@molecule/app-theme-css-variables'
import { createJWTAuthClient } from '@molecule/app-auth'
const authClient = createJWTAuthClient({ baseURL: '/api' })
function UserProfile() {
const { user, isAuthenticated, logout } = createAuth<{ name?: string }>()
const { theme, toggleTheme } = createTheme()
return (
<Show when={isAuthenticated()} fallback={<a href="/login">Log in</a>}>
<div style={{ background: theme().colors.background }}>
<h1>Welcome, {user()?.name}</h1>
<button onClick={toggleTheme}>Toggle Theme</button>
<button onClick={() => logout()}>Logout</button>
</div>
</Show>
)
}
function App() {
return (
<MoleculeProvider config={{ state: stateProvider, auth: authClient, theme: themeProvider }}>
<UserProfile />
</MoleculeProvider>
)
}
Type
framework
Installation
npm install @molecule/app-solid @molecule/app-auth @molecule/app-device @molecule/app-forms @molecule/app-http @molecule/app-i18n @molecule/app-logger @molecule/app-platform @molecule/app-push @molecule/app-routing @molecule/app-state @molecule/app-storage @molecule/app-theme @molecule/app-ui @molecule/app-utilities @molecule/app-version solid-js
API
Interfaces
AuthState
Reactive authentication state snapshot (initialized, authenticated, user, loading, and error).
interface AuthState<T = UserProfile> {
/**
* The session's state as one value — render from this instead of combining
* `initialized`/`authenticated`/`loading`. See `AuthStatus`.
*/
status: AuthStatus
/**
* Whether auth state has been initialized.
*/
initialized: boolean
/**
* Whether the user is authenticated.
*/
authenticated: boolean
/**
* Current user (if authenticated).
*/
user: T | null
/**
* Whether an auth operation is in progress.
*/
loading: boolean
/**
* Last auth error (if any).
*/
error: string | null
}
AuthClient
Auth client interface that all auth bond packages must implement. Provides login/logout/register flows, token management, profile updates, and auth state subscription.
interface AuthClient<T = UserProfile> {
/**
* Returns the current authentication state snapshot.
*/
getState(): AuthState<T>
/**
* Returns whether the user is currently authenticated.
*/
isAuthenticated(): boolean
/**
* Gets the current user.
*/
getUser(): T | null
/**
* Updates the cached user object (state + persistent storage) without
* hitting the network. Intended for local refreshes after a per-app
* mutation (e.g., the user just PATCHed their own profile and the
* server returned the canonical row). Does NOT change tokens.
*/
setUser(user: T | null): void
/**
* Gets the current access token.
*/
getAccessToken(): string | null
/**
* Stores the access token in the configured token storage adapter (in-memory
* by default). Use this to seed the token after an out-of-band exchange (e.g.
* the OAuth code→token redirect) instead of writing to `localStorage` directly,
* which would violate the in-memory-default storage contract and make the bearer
* token JS-readable (XSS-exfiltratable). Pass `null` to clear it.
*/
setAccessToken(token: string | null): void
/**
* Gets the refresh token.
*/
getRefreshToken(): string | null
/**
* Logs in with credentials.
*/
login(credentials: LoginCredentials): Promise<AuthResult<T>>
/**
* Logs out the current user.
*/
logout(): Promise<void>
/**
* Registers a new user.
*/
register(data: RegisterData): Promise<AuthResult<T>>
/**
* Refreshes the access token.
*/
refresh(): Promise<AuthResult<T>>
/**
* Requests a password reset.
*/
requestPasswordReset(data: PasswordResetRequest): Promise<void>
/**
* Confirms a password reset.
*/
confirmPasswordReset(data: PasswordResetConfirm): Promise<void>
/**
* Updates the current user's profile.
*/
updateProfile(data: Partial<T>): Promise<T>
/**
* Changes the current user's password.
*/
changePassword(oldPassword: string, newPassword: string): Promise<void>
/**
* Initializes auth state (e.g., from stored tokens).
*/
initialize(): Promise<void>
/**
* Re-checks a restored session against the server, in the background — the
* boot-time validation an app with a stored token needs when a revoked or
* expired token must sign the user out. Call it AFTER the first render
* (`initialize()` restores synchronously from storage; this costs one request).
*
* - The server confirms the user: the session is refreshed and `AuthState.status`
* stays `'authenticated'`.
* - The server answers 4xx: the token is dead — the stored session is cleared and
* the status becomes `'unauthenticated'`.
* - The server cannot answer (network failure or 5xx): the session is KEPT and the
* status becomes `'unavailable'`, so the app can retry instead of signing the
* user out over a bad connection.
*
* Do not hand-write this beside the client: a parallel token/user store for a
* "validating"/"unavailable" flag is the race this method removes.
*
* Optional: a provider with no restorable session has nothing to validate.
*/
validateSession?(): Promise<void>
/**
* Resolves when the session restore started by `initialize()` has settled — the point
* after which the client knows whether this visitor is signed in.
*
* Resolves IMMEDIATELY when no restore is in flight: before `initialize()` is ever
* called, and after it has finished. A restore that failed resolves too (it settled the
* question), so an HTTP client can await this before every request without risking one
* held forever. That is what makes the fetch-before-restore race impossible: a page that
* fetches viewer-dependent data on mount waits here instead of going out anonymously
* (see `setAuthGate` in `@molecule/app-http`).
*
* Optional: a provider that restores no session has nothing to wait for. Without it, an
* HTTP client bonded to that provider sends first-paint requests unauthenticated.
*
* A provider whose restore sends a request THROUGH the gated HTTP client must send that
* request with `skipAuthGate: true` (`RequestConfig` in `@molecule/app-http`): the gate
* waits on this promise, so holding the restore's own request makes the gate wait on
* itself and stalls every request it holds until it times out. `createJWTAuthClient`'s
* restore does not need it — it uses `fetch`, not the bonded client.
*/
whenRestored?(): Promise<void>
/**
* Subscribes to auth state changes.
*/
subscribe(callback: (state: AuthState<T>) => void): () => void
/**
* Subscribes to auth state changes (alias for subscribe).
*/
onAuthChange(callback: (state: AuthState<T>) => void): () => void
/**
* Gets the current access token (alias for getAccessToken).
*/
getToken?(): string | null
/**
* Adds an auth event listener.
*/
addEventListener(listener: AuthEventListener): () => void
/**
* Destroys the auth client.
*/
destroy(): void
}
FormController
Form controller interface.
All form providers must implement this interface.
interface FormController<T extends Record<string, unknown> = Record<string, unknown>> {
/**
* Gets the current form state.
*/
getState(): FormState<T>
/**
* Gets the value of a specific field.
*/
getValue(name: string): unknown
getValue<K extends keyof T>(name: K): T[K]
/**
* Gets all form values.
*/
getValues(): T
/**
* Sets the value of a specific field.
*/
setValue(
name: string,
value: unknown,
options?: {
shouldValidate?: boolean
shouldDirty?: boolean
shouldTouch?: boolean
},
): void
/**
* Sets multiple values at once.
*/
setValues(
values: Partial<T>,
options?: {
shouldValidate?: boolean
},
): void
/**
* Gets the error for a specific field.
*/
getError(name: string): string | undefined
/**
* Sets the error for a specific field.
*/
setError(name: string, error: string | undefined): void
/**
* Clears the error for a specific field.
*/
clearError<K extends keyof T>(name: K): void
/**
* Clears all errors.
*/
clearErrors(): void
/**
* Gets the field state for a specific field.
*/
getFieldState<K extends keyof T>(name: K): FieldState<T[K]>
/**
* Registers a field for form management.
*/
register(nameOrOptions: string | RegisterOptions, options?: RegisterOptions): FieldRegistration
/**
* Unregisters a field.
*/
unregister(name: string): void
/**
* Validates a specific field.
*/
validateField<K extends keyof T>(name: K): Promise<boolean>
/**
* Validates all fields.
*/
validate(): Promise<boolean>
/**
* Resets the form to initial values.
*/
reset(values?: Partial<T>): void
/**
* Handles form submission.
*/
handleSubmit(
onSubmit: (values: T) => void | Promise<void>,
onError?: (errors: Partial<Record<keyof T, string>>) => void,
): (event?: { preventDefault?: () => void }) => Promise<void>
/**
* Sets focus to a field.
*/
setFocus(name: keyof T): void
/**
* Subscribes to form state changes.
*/
subscribe(callback: (state: FormState<T>) => void): () => void
/**
* Destroys the form controller.
*/
destroy(): void
}
FormOptions
Form creation options.
interface FormOptions<T extends Record<string, unknown>> {
/**
* Default values.
*/
defaultValues?: Partial<T>
/**
* Validation mode.
*/
mode?: 'onSubmit' | 'onChange' | 'onBlur' | 'all'
/**
* Revalidation mode.
*/
reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit'
/**
* Whether to focus the first error field on submit.
*/
shouldFocusError?: boolean
/**
* Form-level validation function.
*/
validate?: (
values: T,
) => Partial<Record<keyof T, string>> | Promise<Partial<Record<keyof T, string>>>
}
HttpClient
HTTP client interface.
All HTTP providers must implement this interface.
interface HttpClient {
/**
* Base URL for all requests.
*/
baseURL: string
/**
* Default headers for all requests.
*/
defaultHeaders: Record<string, string>
/**
* Makes a generic HTTP request. `data` is a field of THIS config object — the same body
* `post(url, data, config)` takes as its second argument.
*/
request<T = unknown>(config: FullRequestConfig): Promise<HttpResponse<T>>
/**
* Makes a GET request.
*/
get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
/**
* Makes a POST request. `data` is the request BODY, not a config object: the wire body is
* `data` itself, so `post(url, { data: body })` sends `{"data":body}` — pass `body` directly.
* A config (headers, params) is the THIRD argument.
*/
post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
/**
* Makes a PUT request. `data` is the request BODY (second argument) — never `{ data: body }`,
* which sends `{"data":body}`; a config is the THIRD argument.
*/
put<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
/**
* Makes a PATCH request. `data` is the request BODY (second argument) — never `{ data: body }`,
* which sends `{"data":body}`; a config is the THIRD argument.
*/
patch<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
/**
* Makes a DELETE request.
*/
delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
/**
* Adds a request interceptor.
* Returns a function to remove the interceptor.
*/
addRequestInterceptor(interceptor: RequestInterceptor): () => void
/**
* Adds a response interceptor.
* Returns a function to remove the interceptor.
*/
addResponseInterceptor(interceptor: ResponseInterceptor): () => void
/**
* Adds an error interceptor.
* Returns a function to remove the interceptor.
*/
addErrorInterceptor(interceptor: ErrorInterceptor): () => void
/**
* Sets the authorization token.
*/
setAuthToken(token: string | null): void
/**
* Returns the current authorization token, or `null` if not set.
*/
getAuthToken(): string | null
/**
* Registers a handler for authentication errors (401).
*
* @returns An unsubscribe function.
*/
onAuthError(handler: () => void): () => void
}
I18nProvider
i18n provider interface.
All i18n providers must implement this interface.
interface I18nProvider {
/**
* Gets the current locale.
*/
getLocale(): string
/**
* Sets the current locale.
*
* **Fleet contract:** every conformant provider (the core simple provider,
* `@molecule/api-i18n-simple`, `@molecule/app-i18n-i18next`, and
* `@molecule/app-i18n-react-i18next`) MUST throw `Error('Locale "<code>"
* not found')` when `locale` is not registered — via the constructor's
* `initialLocales`/`locales` config, `addLocale()`, or `addTranslations()`
* (all three register a locale). It must NOT silently degrade to
* fallback-locale text while `getLocale()` reports the unregistered code —
* that divergence makes a misconfigured locale switch indistinguishable
* from a working one until a user notices the wrong language on screen.
*/
setLocale(locale: string): Promise<void>
/**
* Gets all available locales.
*/
getLocales(): LocaleConfig[]
/**
* Adds a locale.
*/
addLocale(config: LocaleConfig): void
/**
* Removes a locale by code, notifying subscribers so language pickers
* built on `onLocaleChange` re-render their list. If the removed locale
* is currently active, the caller is responsible for switching to a
* fallback (e.g. `'en'`) BEFORE calling this — the provider will not
* auto-fall-back on its own.
*
* Returns `true` if the locale was registered and removed, `false`
* otherwise.
*/
removeLocale(code: string): boolean
/**
* Adds translations to a locale. Auto-creates the locale if it doesn't exist.
*
* **Fleet contract:** merges are DEEP, not a shallow spread — registering
* two calls (e.g. two modules) that share a top-level namespace key merges
* their subtrees instead of the second call clobbering the first's nested
* translations wholesale. `@molecule/api-i18n-simple` implements the same
* contract on the API side.
*/
addTranslations(locale: string, translations: Translations, namespace?: string): void
/**
* Translates a key with optional interpolation values and pluralization.
*
* **Fleet plural contract (matches i18next's own key resolution order):**
* when `options.count` is provided, the plural-suffixed key
* (`` `${key}_${pluralForm}` ``, e.g. `item_one`/`item_few`/…, falling back
* to `` `${key}_other` ``) is looked up FIRST and wins over the base `key`
* if BOTH are registered. Only when no plural-suffixed key exists at all
* does resolution fall back to the base key. A catalog that ships both
* `item` and `item_one`/`item_other` therefore pluralizes identically
* whichever provider is bonded.
*
* @returns The translated string, or the default value / key if not found.
*/
t(
key: string,
values?: InterpolationValues,
options?: {
defaultValue?: string
count?: number
},
): string
/**
* Checks if a translation key exists.
*
* **Fleet contract:** follows the SAME locale-resolution chain as `t()` —
* the active locale, then the English fallback — so `exists(key) === true`
* whenever `t(key)` would render real translated text (not the raw key or
* an inline `defaultValue`). Do not narrow this to "only the active
* locale's own catalog"; that made `exists()` return `false` for keys `t()`
* happily rendered via the English fallback, and the answer differed by
* provider.
*
* @returns `true` if the key has a translation.
*/
exists(key: string): boolean
/**
* Formats a number according to the current locale.
*
* @returns The locale-formatted number string.
*/
formatNumber(value: number, options?: NumberFormatOptions): string
/**
* Formats a date according to the current locale.
*
* @returns The locale-formatted date string.
*/
formatDate(value: Date | number | string, options?: DateFormatOptions): string
/**
* Formats a relative time (e.g. "2 hours ago").
*
* @returns The locale-formatted relative time string.
*/
formatRelativeTime(
value: Date | number,
options?: {
unit?: Intl.RelativeTimeFormatUnit
},
): string
/**
* Formats a list (e.g. "A, B, and C").
*
* @returns The locale-formatted list string.
*/
formatList(
values: string[],
options?: {
type?: 'conjunction' | 'disjunction' | 'unit'
},
): string
/**
* Subscribes to locale changes.
*
* @returns An unsubscribe function.
*/
onLocaleChange(listener: (locale: string) => void): () => void
/**
* Gets the text direction for the current locale.
*
* @returns `'ltr'` or `'rtl'`.
*/
getDirection(): 'ltr' | 'rtl'
/**
* Checks if a translation key exists (alias for exists).
*/
hasKey?(key: string): boolean
/**
* Checks if the provider is ready.
*/
isReady?(): boolean
/**
* Registers a callback for when the provider is ready.
*/
onReady?(callback: () => void): () => void
/**
* Registers a lazily-loaded content module for automatic reload on locale changes.
* All registered content is reloaded during `setLocale()` before listeners fire,
* ensuring content is available on the first re-render with no flash.
*
* Idempotent: registering the same module name twice is a no-op.
*/
registerContent?(module: string, loader: (locale: string) => Promise<void>): void
}
Logger
Logger instance with leveled logging methods, child logger creation, and transport management.
interface Logger {
/**
* Logs a trace message.
*/
trace(message: string, ...args: unknown[]): void
/**
* Logs a debug message.
*/
debug(message: string, ...args: unknown[]): void
/**
* Logs an info message.
*/
info(message: string, ...args: unknown[]): void
/**
* Logs a warning message.
*/
warn(message: string, ...args: unknown[]): void
/**
* Logs an error message.
*/
error(message: string | Error, ...args: unknown[]): void
/**
* Sets the log level.
*/
setLevel(level: LogLevel): void
/**
* Gets the current log level.
*/
getLevel(): LogLevel
/**
* Creates a child logger with a namespace.
*/
child(name: string, context?: Record<string, unknown>): Logger
/**
* Adds additional context to the logger.
*/
withContext(context: Record<string, unknown>): Logger
/**
* Adds a transport.
*/
addTransport(transport: LogTransport): () => void
/**
* Removes a transport.
*/
removeTransport(transport: LogTransport): void
}
LoggerProvider
Logger provider interface that all logger bond packages must implement. Creates and manages logger instances and global log configuration.
interface LoggerProvider {
/**
* Gets a logger by name, or the root logger if no name given.
*/
getLogger(name?: string): Logger
/**
* Creates a named logger.
*/
createLogger(nameOrConfig: string | LoggerConfig, config?: LoggerConfig): Logger
/**
* Sets the global log level.
*/
setLevel(level: LogLevel): void
/**
* Gets the global log level.
*/
getLevel(): LogLevel
/**
* Adds a global transport.
*/
addTransport(transport: LogTransport): () => void
/**
* Enables logging.
*/
enable(): void
/**
* Disables logging.
*/
disable(): void
/**
* Checks if logging is enabled.
*
* @returns `true` if logging is currently enabled.
*/
isEnabled(): boolean
}
RouteLocation
Current URL decomposed into pathname, search string, hash, navigation state, and unique key.
interface RouteLocation {
/**
* Current pathname.
*/
pathname: string
/**
* Query string (including leading ?).
*/
search: string
/**
* Hash (including leading #).
*/
hash: string
/**
* State data passed with navigation.
*/
state?: unknown
/**
* Unique key for this location.
*/
key?: string
}
Router
Client-side router providing navigation, guards, route matching, and history control.
All routing providers must implement this interface.
interface Router {
/**
* Returns the current route location (pathname, search, hash, state).
*/
getLocation(): RouteLocation
/**
* Gets the current route params.
*/
getParams<T extends RouteParams = RouteParams>(): T
/**
* Gets the current query params.
*/
getQuery(): QueryParams
/**
* Gets a specific query parameter.
*/
getQueryParam(key: string): string | undefined
/**
* Gets the current hash.
*/
getHash(): string
/**
* Navigates to a path.
*/
navigate(path: string, options?: NavigateOptions): void
/**
* Navigates to a named route.
*/
navigateTo(
name: string,
params?: RouteParams,
query?: QueryParams,
options?: NavigateOptions,
): void
/**
* Goes back in history.
*/
back(): void
/**
* Goes forward in history.
*/
forward(): void
/**
* Goes to a specific point in history.
*/
go(delta: number): void
/**
* Updates the current query params.
*/
setQuery(params: QueryParams, options?: NavigateOptions): void
/**
* Updates a specific query parameter.
*/
setQueryParam(key: string, value: string | undefined, options?: NavigateOptions): void
/**
* Updates the current hash.
*/
setHash(hash: string, options?: NavigateOptions): void
/**
* Checks if a path matches the current location.
*
* @returns `true` if the path matches the current route.
*/
isActive(path: string, exact?: boolean): boolean
/**
* Matches a path pattern against a pathname.
*/
matchPath<Params extends RouteParams = RouteParams>(
pattern: string,
pathname: string,
): RouteMatch<Params> | null
/**
* Generates a URL from a named route.
*/
generatePath(name: string, params?: RouteParams, query?: QueryParams): string
/**
* Subscribes to route changes.
*/
subscribe(listener: RouteChangeListener): () => void
/**
* Adds a navigation guard.
*/
addGuard(guard: NavigationGuard): () => void
/**
* Registers route definitions.
*/
registerRoutes(routes: RouteDefinition[]): void
/**
* Gets all registered routes.
*/
getRoutes(): RouteDefinition[]
/**
* Destroys the router.
*/
destroy(): void
}
StoreConfig
Configuration for creating a store (initial state, optional name, and middleware chain).
interface StoreConfig<T> {
/**
* Initial state value.
*/
initialState: T
/**
* Optional name for debugging.
*/
name?: string
/**
* Optional middleware functions.
*/
middleware?: StoreMiddleware<T>[]
}
MoleculeStore
Reactive state container with getState, setState, subscribe, and destroy.
All state management providers must implement this interface.
interface Store<T> {
/**
* Gets the current state.
*/
getState(): T
/**
* Sets the state (partial or via updater function).
*/
setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
/**
* Subscribes to state changes.
* Returns an unsubscribe function.
*/
subscribe(listener: StateListener<T>): () => void
/**
* Destroys the store and cleans up subscriptions.
*/
destroy(): void
}
StateProvider
State provider interface that all state management bond packages must implement. Provides the store creation factory.
interface StateProvider {
/**
* Creates a new store.
*/
createStore<T>(config: StoreConfig<T>): Store<T>
}
StorageProvider
Storage provider interface.
All storage providers must implement this interface.
interface StorageProvider {
/**
* Gets a value from storage.
*/
get<T = unknown>(key: string): Promise<T | null>
/**
* Sets a value in storage.
*/
set<T = unknown>(key: string, value: T): Promise<void>
/**
* Removes a value from storage.
*/
remove(key: string): Promise<void>
/**
* Clears all values from storage.
*/
clear(): Promise<void>
/**
* Gets all keys in storage.
*/
keys(): Promise<string[]>
/**
* Gets multiple values from storage.
*/
getMany?<T = unknown>(keys: string[]): Promise<Map<string, T | null>>
/**
* Sets multiple values in storage.
*/
setMany?<T = unknown>(entries: Array<[string, T]>): Promise<void>
/**
* Removes multiple values from storage.
*/
removeMany?(keys: string[]): Promise<void>
}
ThemeProvider
Manages theme state including the active theme, mode toggling, and change subscriptions.
interface ThemeProvider {
/**
* Returns the currently active theme.
*/
getTheme(): Theme
/**
* Sets the active theme by reference or by name.
*
* @param theme - A `Theme` object or a theme name string to activate.
*/
setTheme(theme: Theme | string): void
/**
* Toggles between light and dark mode for the active theme.
*/
toggleMode(): void
/**
* Subscribes to theme changes. The callback fires whenever
* `setTheme()` or `toggleMode()` is called.
*
* @param callback - Invoked with the new theme after each change.
* @returns An unsubscribe function.
*/
subscribe(callback: (theme: Theme) => void): () => void
/**
* Returns all registered themes. Optional — not all providers
* support multiple themes.
*/
getThemes?(): Theme[]
/**
* Returns the theme a render WITHOUT a browser produces — a server or
* build-time render, which has no storage and no `prefers-color-scheme`
* to read. A hydrating client renders this theme first, so its markup
* matches what the server sent, and switches to `getTheme()` right
* after. Optional — a provider whose theme cannot differ between the two
* need not implement it.
*/
getServerTheme?(): Theme
}
Theme
Complete theme definition.
interface Theme {
name: string
mode: 'light' | 'dark'
colors: ThemeColors
breakpoints: ThemeBreakpoints
spacing: ThemeSpacing
typography: ThemeTypography
borderRadius: ThemeBorderRadius
shadows: ThemeShadows
transitions: ThemeTransitions
zIndex: ThemeZIndex
}
CreateAsyncStateReturn
Return type for createAsyncState.
interface CreateAsyncStateReturn<T> {
state: () => T
setState: (value: T | ((prev: T) => T) | Promise<T | ((prev: T) => T)>) => void
extendState: (
partial:
Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
) => void
}
CapacitorAppPrimitives
Capacitor app primitives return type.
interface CapacitorAppPrimitives {
state: Accessor<CapacitorAppState>
ready: Accessor<boolean>
initialize: () => Promise<void>
}
CreateChangePasswordReturn
Return type for createChangePassword primitive.
interface CreateChangePasswordReturn {
state: Accessor<PromiseState<void>>
changePassword: (oldPassword: string, newPassword: string) => Promise<void>
reset: () => void
}
DevicePrimitives
Device primitives return type.
interface DevicePrimitives {
deviceInfo: DeviceInfo
screenInfo: ScreenInfo
hardwareInfo: HardwareInfo
featureSupport: FeatureSupport
supports: (feature: keyof FeatureSupport) => boolean
isOnline: () => boolean
isStandalone: () => boolean
language: string
languages: string[]
}
CreateFormResult
Result of createForm primitive.
interface CreateFormResult<T extends Record<string, unknown>> {
/** Reactive form state accessor. */
formState: Accessor<FormState<T>>
/** Whether the form is currently valid. */
isValid: Accessor<boolean>
/** Whether any field has been modified. */
isDirty: Accessor<boolean>
/** Whether the form is currently submitting. */
isSubmitting: Accessor<boolean>
/** Current field errors. */
errors: Accessor<Partial<Record<keyof T, string>>>
/** Register a field for form management. */
register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
/** Get the current value of a field. */
getValue: <K extends keyof T>(name: K) => T[K]
/** Set the value of a field. */
setValue: <K extends keyof T>(name: K, value: T[K]) => void
/** Get the error message for a field. */
getError: (name: keyof T) => string | undefined
/** Set an error message for a field. */
setError: (name: keyof T, error: string | undefined) => void
/** Clear all field errors. */
clearErrors: () => void
/** Create a submit handler function. */
handleSubmit: (
onSubmit: (values: T) => void | Promise<void>,
) => (event?: { preventDefault?: () => void }) => Promise<void>
/** Reset the form to initial or provided values. */
reset: (values?: Partial<T>) => void
/** Validate all fields. */
validate: () => Promise<boolean>
/** The raw FormController instance for advanced use. */
controller: FormController<T>
}
CreateLoginReturn
Return type for createLogin primitive.
interface CreateLoginReturn<T = unknown> {
state: Accessor<PromiseState<AuthResult<T>>>
login: (credentials: LoginCredentials) => Promise<AuthResult<T>>
reset: () => void
}
CreateOAuthOptions
OAuth configuration options.
interface CreateOAuthOptions {
/** Base URL for the API server (e.g. `https://api.example.com`). */
baseURL?: string
/** List of supported OAuth provider names (e.g. `['github', 'google']`). */
oauthProviders?: string[]
/** Path prefix for OAuth initiation routes. Defaults to `/oauth`. */
oauthEndpoint?: string
/** Path for the OAuth login POST endpoint. Defaults to `/users/log-in/oauth`. */
loginEndpoint?: string
/** Called after a successful OAuth login (session established). */
onSuccess?: () => void
/** Called with a failure message when the OAuth login fails. */
onError?: (error: string) => void
/**
* Auth client used to establish the session after the code exchange.
* Overrides context resolution — when omitted, the client is resolved from
* the surrounding `MoleculeProvider` (tolerated when absent; see the
* cookie-session fallback documented on
* `CreateOAuthReturn.handleCallback`).
*/
authClient?: AuthClient<unknown>
}
CreateOAuthReturn
Return type for createOAuth primitive.
interface CreateOAuthReturn {
/** Accessor for the configured OAuth provider names. */
providers: Accessor<string[]>
/** Builds the OAuth initiation URL for a provider. */
getOAuthUrl: (provider: string) => string
/** Starts the full-page redirect flow for a provider. */
redirect: (provider: string) => void
/**
* Handles the OAuth callback: exchanges the `code` URL parameter for a
* session. Invoked automatically at creation (see `createOAuth`);
* exposed for callers that need to re-run it manually. No-ops unless
* running in a browser with a `code` URL parameter and a stashed provider.
*
* When an auth client is available (explicit option or context), the
* session is established locally (`setAccessToken` + `setUser` +
* `initialize`). When no client is available, the server has already
* established the httpOnly-cookie session during the exchange, so a
* user-carrying response still counts as success.
*/
handleCallback: () => Promise<void>
}
CreatePasswordResetReturn
Return type for createPasswordReset primitive.
interface CreatePasswordResetReturn {
requestState: Accessor<PromiseState<void>>
confirmState: Accessor<PromiseState<void>>
requestReset: (data: PasswordResetRequest) => Promise<void>
confirmReset: (data: PasswordResetConfirm) => Promise<void>
reset: () => void
}
PlatformPrimitives
Platform primitives return type.
interface PlatformPrimitives {
platform: Platform
isNative: boolean
isMobile: boolean
isDesktop: boolean
isWeb: boolean
isDevelopment: boolean
isProduction: boolean
isPlatform: (...platforms: Platform[]) => boolean
}
CreatePromiseReturn
Promise state accessor with actions.
interface CreatePromiseReturn<T> {
state: () => PromiseState<T>
call: (...args: any[]) => Promise<T>
cancel: (message?: string) => void
reset: () => void
}
PushPrimitives
Push primitives return type.
interface PushPrimitives {
permission: Accessor<PermissionStatus | null>
token: Accessor<PushToken | null>
checkPermission: () => Promise<PermissionStatus>
requestPermission: () => Promise<PermissionStatus>
register: (options?: PushRegisterOptions) => Promise<PushToken>
unregister: () => Promise<void>
onNotificationReceived: (listener: NotificationReceivedListener) => () => void
onNotificationAction: (listener: NotificationActionListener) => () => void
onTokenChange: (listener: TokenChangeListener) => () => void
setBadge: (count: number) => Promise<void>
clearBadge: () => Promise<void>
}
CreateSignupReturn
Return type for createSignup primitive.
interface CreateSignupReturn<T = unknown> {
state: Accessor<PromiseState<AuthResult<T>>>
signup: (data: RegisterData) => Promise<AuthResult<T>>
reset: () => void
}
VersionPrimitives
Version primitives return type.
interface VersionPrimitives {
state: Accessor<VersionState>
isUpdateAvailable: Accessor<boolean>
isChecking: Accessor<boolean>
isServiceWorkerWaiting: Accessor<boolean>
newVersion: Accessor<string | undefined>
checkForUpdates: () => Promise<boolean>
applyUpdate: (options?: { force?: boolean }) => void
dismissUpdate: () => void
startPeriodicChecks: (options?: UpdateCheckOptions) => void
stopPeriodicChecks: () => void
}
MoleculeConfig
Configuration for molecule Solid context.
interface MoleculeConfig {
state?: StateProvider
auth?: AuthClient<unknown>
theme?: ThemeProvider
router?: Router
i18n?: I18nProvider
http?: HttpClient
storage?: StorageProvider
logger?: LoggerProvider
}
HttpState
State for async HTTP operations.
interface HttpState<T> {
data: T | null
loading: boolean
error: Error | null
}
StorageValueState
State for async storage values.
interface StorageValueState<T> {
value: T | undefined
loading: boolean
error: Error | null
}
AuthPrimitives
Auth primitives return type.
interface AuthPrimitives<T = unknown> {
state: Accessor<AuthState<T>>
user: Accessor<T | null>
isAuthenticated: Accessor<boolean>
isLoading: Accessor<boolean>
login: AuthClient<T>['login']
logout: AuthClient<T>['logout']
register: AuthClient<T>['register']
refresh: AuthClient<T>['refresh']
}
ThemePrimitives
Theme primitives return type.
interface ThemePrimitives {
theme: Accessor<Theme>
themeName: Accessor<string>
mode: Accessor<'light' | 'dark'>
setTheme: (name: string) => void
toggleTheme: () => void
}
RouterPrimitives
Router primitives return type.
interface RouterPrimitives {
location: Accessor<RouteLocation>
params: Accessor<RouteParams>
query: Accessor<QueryParams>
navigate: Router['navigate']
navigateTo: Router['navigateTo']
back: Router['back']
forward: Router['forward']
isActive: Router['isActive']
}
Types
Accessor
type Accessor<T> = () => T
Setter
type Setter<in out T> = {
<U extends T>(
...args: undefined extends T ? [] : [value: Exclude<U, Function> | ((prev: T) => U)]
): undefined extends T ? undefined : U
<U extends T>(value: (prev: T) => U): U
<U extends T>(value: Exclude<U, Function>): U
<U extends T>(value: Exclude<U, Function> | ((prev: T) => U)): U
}
RouteParams
URL path parameter key-value map extracted from dynamic route segments (e.g. { id: '123' }).
type RouteParams = Record<string, string>
QueryParams
URL query string parameter map (single values or arrays for repeated keys).
type QueryParams = Record<string, string | string[] | undefined>
Functions
getStateProvider()
Get the state provider from context.
function getStateProvider(): StateProvider
Returns: The state provider instance.
getAuthClient()
Get the auth client from context.
function getAuthClient(): AuthClient<T>
Returns: The auth client instance.
getThemeProvider()
Get the theme provider from context.
function getThemeProvider(): ThemeProvider
Returns: The theme provider instance.
getRouter()
Get the router from context.
function getRouter(): Router
Returns: The router instance.
getI18nProvider()
Get the i18n provider from context.
function getI18nProvider(): I18nProvider
Returns: The i18n provider instance.
getHttpClient()
Get the HTTP client from context.
function getHttpClient(): HttpClient
Returns: The HTTP client instance.
getStorageProvider()
Get the storage provider from context.
function getStorageProvider(): StorageProvider
Returns: The storage provider instance.
getLoggerProvider()
Get the logger provider from context.
function getLoggerProvider(): LoggerProvider
Returns: The logger provider instance.
createAsyncState(initialState)
Primitive like createSignal but accepts Promises and supports partial state extension.
function createAsyncState(initialState: T): CreateAsyncStateReturn<T>
initialState— Initial state value
Returns: The created instance.
createAuth()
Create auth primitives for authentication state and actions.
function createAuth(): AuthPrimitives<T>
Returns: Auth primitives object
createAuthGuard(redirectTo)
Create a guard primitive that redirects unauthenticated users.
function createAuthGuard(redirectTo: string): Accessor<boolean>
redirectTo— Path to redirect to
Returns: Accessor indicating if user is allowed
createAuthHelpers()
Creates a auth helpers.
function createAuthHelpers(): {
login: (credentials: LoginCredentials) => Promise<AuthResult<T>>
logout: () => Promise<void>
register: (data: RegisterData) => Promise<AuthResult<T>>
refresh: () => Promise<AuthResult<T>>
getUser: () => T | null
getToken: () => string | null
isAuthenticated: () => boolean
}
Returns: The created result.
createAuthFromClient(client)
Create auth primitives from a specific client.
function createAuthFromClient(client: AuthClient<T>): AuthPrimitives<T>
client— Auth client
Returns: Auth primitives
createCapacitorApp(options)
Create Capacitor app primitives for native app initialization.
Wraps the core createCapacitorApp coordinator with Solid signals,
automatically initializing and cleaning up on disposal.
function createCapacitorApp(options?: CapacitorAppOptions): CapacitorAppPrimitives
options— Capacitor app configuration options.
Returns: Capacitor app primitives object
createChangePassword()
Creates a change password primitive with async state tracking.
function createChangePassword(): CreateChangePasswordReturn
Returns: Change password state and action
createDevice()
Create device primitives for accessing device information.
This is a static primitive (no reactive signals) since device info does not change during the lifecycle of the app.
function createDevice(): DevicePrimitives
Returns: Device primitives object
createForm(provider, options)
Create form primitives for form state management and validation.
function createForm(provider: FormProvider, options: FormOptions<T>): CreateFormResult<T>
provider— Form provider that creates controllersoptions— Form configuration options
Returns: Form primitives object
createFieldSignal(controller, name)
Create a reactive accessor for a single field's state.
function createFieldSignal(
controller: FormController<T>,
name: keyof T,
): Accessor<FieldState<T[keyof T]>>
controller— Form controllername— Field name to track
Returns: Accessor for the field state
createWatchSignal(controller, name)
Create a reactive accessor that tracks a single field's value.
function createWatchSignal(controller: FormController<T>, name: K): Accessor<T[K]>
controller— Form controllername— Field name to watch
Returns: Accessor for the field value
createFormHelpers(provider)
Creates a form helpers.
function createFormHelpers(provider: FormProvider): {
createForm: <T extends Record<string, unknown>>(options: FormOptions<T>) => CreateFormResult<T>
}
provider— The provider implementation.
Returns: The created result.
createFormFromController(controller)
Create form primitives from an existing controller.
Useful when you have a controller created externally and want to wrap it with Solid reactivity.
function createFormFromController(controller: FormController<T>): CreateFormResult<T>
controller— An existing FormController
Returns: Form primitives object
createHttp()
Creates a http.
function createHttp(): {
get: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
post: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
put: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
patch: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
delete: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
request: <T>(config: FullRequestConfig) => Promise<HttpResponse<T>>
}
Returns: The created result.
useFetch(url, config)
Create a resource for fetching data.
function useFetch(url: string | Accessor<string>, config?: RequestConfig): Resource<T | undefined>
url— URL string or accessor returning a URL string.config— Optional request configuration.
Returns: Solid resource
useMutation()
Hook for mutation.
function useMutation(): {
mutate: (
url: string,
payload?: unknown,
method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE',
) => Promise<T>
isLoading: Accessor<boolean>
error: Accessor<Error | null>
data: Accessor<T | null>
reset: () => void
}
Returns: The result.
useLazyQuery()
Hook for lazy query.
function useLazyQuery(): {
execute: (url: string, config?: RequestConfig) => Promise<T>
data: () => T | null
isLoading: () => boolean
error: () => Error | null
reset: () => void
}
Returns: The result.
createHttpHelpers()
Creates a http helpers.
function createHttpHelpers(): {
get: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
post: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
put: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
patch: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
delete: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
setAuthToken: (token: string | null) => void
getAuthToken: () => string | null
}
Returns: The created result.
createHttpFromClient(client)
Creates a http from client.
function createHttpFromClient(client: HttpClient): {
get: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
post: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
put: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
patch: <T>(url: string, data?: unknown, config?: RequestConfig) => Promise<HttpResponse<T>>
delete: <T>(url: string, config?: RequestConfig) => Promise<HttpResponse<T>>
request: <T>(config: FullRequestConfig) => Promise<HttpResponse<T>>
}
client— The client instance.
Returns: The created result.
createI18n()
Creates a i18n.
function createI18n(): {
t: TranslateFunction
locale: Accessor<string>
setLocale: (newLocale: string) => Promise<void>
isReady: Accessor<boolean>
getLocales: () => LocaleConfig[]
hasKey: (key: string) => boolean
}
Returns: The created result.
useTranslate()
Get translate function.
function useTranslate(): TranslateFunction
Returns: Translate function
useLocale()
Get current locale as accessor.
function useLocale(): Accessor<string>
Returns: Accessor for current locale
useTranslation(key, values, options)
Create a reactive translation.
function useTranslation(
key: string,
values?: InterpolationValues,
options?: TranslateOptions,
): Accessor<string>
key— Translation keyvalues— Interpolation values for the translation.options— Translation options
Returns: Accessor for translated string
usePlural(key, count, values)
Create a reactive plural translation.
function usePlural(
key: string,
count: Accessor<number>,
values?: InterpolationValues,
): Accessor<string>
key— Translation keycount— Count accessor for pluralizationvalues— Interpolation values for the translation.
Returns: Accessor for translated string
createI18nHelpers()
Creates a i18n helpers.
function createI18nHelpers(): {
t: TranslateFunction
getLocale: () => string
setLocale: (locale: string) => Promise<void>
getLocales: () => LocaleConfig[]
hasKey: (key: string) => boolean
isReady: () => boolean
}
Returns: The created result.
createI18nFromProvider(provider)
Creates a i18n from provider.
function createI18nFromProvider(provider: I18nProvider): {
t: TranslateFunction
locale: Accessor<string>
setLocale: (newLocale: string) => Promise<void>
isReady: Accessor<boolean>
getLocales: () => LocaleConfig[]
hasKey: (key: string) => boolean
}
provider— The provider implementation.
Returns: The created result.
getLogger(name)
Get a logger instance.
function getLogger(name?: string): Logger
name— Logger name
Returns: Logger instance
createLogger(config)
Create a logger with custom configuration.
function createLogger(config: LoggerConfig): Logger
config— Logger configuration
Returns: Logger instance
getRootLogger()
Get the root logger.
function getRootLogger(): Logger
Returns: Root logger instance
getChildLogger(name, context)
Create a child logger with additional context.
function getChildLogger(name: string, context: Record<string, unknown>): Logger
name— Parent logger namecontext— Additional context
Returns: Child logger instance
useComponentLogger(componentName)
Create a component logger that includes component name in context.
function useComponentLogger(componentName: string): Logger
componentName— Name of the component
Returns: Logger configured for the component
createLoggerHelpers()
Creates a logger helpers.
function createLoggerHelpers(): {
getLogger: (name?: string) => Logger
createLogger: (config: LoggerConfig) => Logger
setLevel: (level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent') => void
getLevel: () => string
enable: () => void
disable: () => void
isEnabled: () => boolean
}
Returns: The created result.
createLoggerHelpersFromProvider(provider)
Creates a logger helpers from provider.
function createLoggerHelpersFromProvider(provider: LoggerProvider): {
getLogger: (name?: string) => Logger
createLogger: (config: LoggerConfig) => Logger
setLevel: (level: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent') => void
getLevel: () => string
enable: () => void
disable: () => void
isEnabled: () => boolean
}
provider— The provider implementation.
Returns: The created result.
createLoggerFromProvider(provider, name)
Create logger from a specific provider.
function createLoggerFromProvider(provider: LoggerProvider, name?: string): Logger
provider— Logger providername— Logger name
Returns: Logger instance
createLogin()
Creates a login primitive with async state tracking.
function createLogin(): CreateLoginReturn<T>
Returns: Login state and action
createOAuth(options)
Creates OAuth helpers.
Automatically handles OAuth callbacks by detecting code and state URL
parameters and exchanging them for a session:
- Inside a Solid owner (component setup /
createRoot), the callback handling is deferred toonMountso it runs client-side after mount. - Outside an owner (a plain function call, e.g. bootstrap code), it runs immediately at creation, browser-guarded.
function createOAuth(options?: CreateOAuthOptions): CreateOAuthReturn
options— OAuth configuration
Returns: The created instance.
createPasswordReset()
Creates a password reset primitive with async state tracking.
function createPasswordReset(): CreatePasswordResetReturn
Returns: Password reset state and actions
createPlatform()
Create platform primitives for detecting the current platform.
This is a static primitive (no reactive signals) since the platform does not change during the lifecycle of the app.
function createPlatform(): PlatformPrimitives
Returns: Platform primitives object
createPromise(asyncFn)
Primitive that wraps an async function with reactive state tracking.
function createPromise(asyncFn: T): CreatePromiseReturn<Awaited<ReturnType<T>>>
asyncFn— The async function to wrap
Returns: Object with state accessor, call, cancel, and reset functions
createPush()
Create push notification primitives.
function createPush(): PushPrimitives
Returns: Push primitives object
createRouter()
Create router primitives for navigation state and actions.
function createRouter(): RouterPrimitives
Returns: Router primitives object
useLocation()
Get current route location as accessor.
function useLocation(): Accessor<RouteLocation>
Returns: Accessor for current location
useParams()
Get current route params as accessor.
function useParams(): Accessor<RouteParams>
Returns: Accessor for route params
useQuery()
Get current query params as accessor.
function useQuery(): Accessor<QueryParams>
Returns: Accessor for query params
useNavigate()
Get navigate function.
function useNavigate(): (path: string, options?: NavigateOptions) => void
Returns: Navigate function
useMatch(pattern)
Create a match accessor for a path pattern.
function useMatch(pattern: string): Accessor<boolean>
pattern— Path pattern to match
Returns: Accessor indicating if current path matches
createIsActive(path, exact)
Create a reactive boolean accessor that tracks whether a given path is active.
Unlike useMatch which only accepts a static pattern, this factory returns
a signal that re-evaluates on every route change and supports the exact
parameter from the router's isActive method.
function createIsActive(path: string, exact?: boolean): Accessor<boolean>
path— Path to check against the current locationexact— Whether to require an exact match (default: false)
Returns: Accessor<boolean> that is true when the path is active
createRouterHelpers()
Creates a router helpers.
function createRouterHelpers(): {
navigate: (path: string, options?: NavigateOptions) => void
navigateTo: (
name: string,
params?: RouteParams,
query?: QueryParams,
options?: NavigateOptions,
) => void
back: () => void
forward: () => void
getLocation: () => RouteLocation
getParams: () => RouteParams
getQuery: () => QueryParams
isActive: (path: string) => boolean
}
Returns: The created result.
createRouterFromInstance(router)
Create router primitives from a specific router.
function createRouterFromInstance(router: Router): RouterPrimitives
router— Router instance
Returns: Router primitives
createSignup()
Creates a signup primitive with async state tracking.
function createSignup(): CreateSignupReturn<T>
Returns: Signup state and action
createStore(config)
Create a reactive store using Solid signals.
function createStore(config: StoreConfig<T>): Store<T>
config— Store configuration
Returns: Store instance
useStore(store, selector)
Use a store with optional selector, returning an accessor.
function useStore(store: Store<T>, selector?: (state: T) => S): Accessor<S>
store— Store to subscribe toselector— Optional selector function
Returns: Accessor for selected state
createSignalStore(initial)
Create a simple signal-based store without provider.
function createSignalStore(initial: T): [Accessor<T>, (value: T | ((prev: T) => T)) => void]
initial— Initial state
Returns: The created instance.
createPersistedStore(key, initial, storage)
Create a persisted signal store.
function createPersistedStore(
key: string,
initial: T,
storage: StorageAdapter,
): [Accessor<T>, (value: T | ((prev: T) => T)) => void]
key— Storage keyinitial— Initial valuestorage— Storage adapter (required - use localStorage, sessionStorage, or@molecule/app-storage)
Returns: Tuple of accessor and setter
createStateHelpers()
Creates a state helpers.
function createStateHelpers(): {
createStore: <T extends object>(config: StoreConfig<T>) => Store<T>
}
Returns: The created result.
createStateHelpersFromProvider(provider)
Creates a state helpers from provider.
function createStateHelpersFromProvider(provider: StateProvider): {
createStore: <T extends object>(config: StoreConfig<T>) => Store<T>
}
provider— The provider implementation.
Returns: The created result.
createStorageValue(key, defaultValue)
Create a storage value primitive.
function createStorageValue(
key: string,
defaultValue?: T,
): {
value: () => T | undefined
loading: () => boolean
error: () => Error | null
set: (value: T) => Promise<void>
remove: () => Promise<void>
refresh: () => Promise<T | undefined>
}
key— Storage keydefaultValue— Default value if not found
Returns: Storage value accessor and actions
createStorage()
Create storage primitives.
function createStorage(): {
get: <T>(key: string) => Promise<T | null>
set: <T>(key: string, value: T) => Promise<void>
remove: (key: string) => Promise<void>
clear: () => Promise<void>
keys: () => Promise<string[]>
}
Returns: Storage methods
usePersistedSignal(key, defaultValue)
Create a persisted signal that syncs with storage.
function usePersistedSignal(
key: string,
defaultValue: T,
): [Accessor<T | undefined>, (value: T | ((prev: T | undefined) => T)) => void]
key— Storage keydefaultValue— Default value
Returns: Tuple of accessor and setter
createStorageHelpers()
Create storage helpers from context.
function createStorageHelpers(): {
get: <T>(key: string) => Promise<T | null>
set: <T>(key: string, value: T) => Promise<void>
remove: (key: string) => Promise<void>
clear: () => Promise<void>
keys: () => Promise<string[]>
}
Returns: Storage helper functions
createStorageFromProvider(storage)
Create storage primitives from a specific provider.
function createStorageFromProvider(storage: StorageProvider): {
get: <T>(key: string) => Promise<T | null>
set: <T>(key: string, value: T) => Promise<void>
remove: (key: string) => Promise<void>
clear: () => Promise<void>
keys: () => Promise<string[]>
}
storage— Storage provider
Returns: Storage methods
createStorageValueFromProvider(storage, key, defaultValue)
Create storage value primitive from a specific provider.
function createStorageValueFromProvider(
storage: StorageProvider,
key: string,
defaultValue?: T,
): {
value: () => T | undefined
loading: () => boolean
error: () => Error | null
set: (value: T) => Promise<void>
remove: () => Promise<void>
}
storage— Storage providerkey— Storage keydefaultValue— Default value
Returns: Storage value accessor and actions
createTheme()
Create theme primitives for theme state and actions.
function createTheme(): ThemePrimitives
Returns: The created instance.
useMode()
Create a mode accessor.
function useMode(): Accessor<'light' | 'dark'>
Returns: Accessor for current mode
useThemeName()
Create a theme name accessor.
function useThemeName(): Accessor<string>
Returns: Accessor for current theme name
createThemeHelpers()
Creates a theme helpers.
function createThemeHelpers(): {
getTheme: () => Theme
setTheme: (name: string) => void
getMode: () => 'light' | 'dark'
toggleMode: () => void
getAvailableThemes: () => Theme[]
}
Returns: The created result.
createThemeFromProvider(provider)
Create theme primitives from a specific provider.
function createThemeFromProvider(provider: ThemeProvider): ThemePrimitives
provider— Theme provider
Returns: Theme primitives
createThemeColors(theme)
Create a colors accessor derived from a theme accessor.
function createThemeColors(theme: Accessor<Theme>): Accessor<ThemeColors>
theme— Theme accessor (e.g. from createTheme().theme)
Returns: Accessor for the current theme colors
applyThemeToDocument()
Apply theme CSS variables to document.
function applyThemeToDocument(): void
createVersion()
Create version primitives for tracking app updates.
function createVersion(): VersionPrimitives
Returns: Version primitives object
MoleculeProvider(props)
MoleculeProvider component that provides all molecule services to the component tree.
function MoleculeProvider(props: ParentProps<{ config: MoleculeConfig }>): JSX.Element
props— Component props containing the molecule config.
Returns: The nested provider tree wrapping children.
Constants
StateContext
Internal contexts for molecule providers.
const StateContext: Context<StateProvider | undefined>
AuthContext
const AuthContext: Context<AuthClient<unknown> | undefined>
ThemeContext
const ThemeContext: Context<ThemeProvider | undefined>
RouterContext
const RouterContext: Context<Router | undefined>
I18nContext
const I18nContext: Context<I18nProvider | undefined>
HttpContext
const HttpContext: Context<HttpClient | undefined>
StorageContext
const StorageContext: Context<StorageProvider | undefined>
LoggerContext
const LoggerContext: Context<LoggerProvider | undefined>
Injection Notes
Requirements
Peer dependencies:
@molecule/app-auth^1.0.1@molecule/app-device^1.0.1@molecule/app-forms^1.0.1@molecule/app-http^1.0.1@molecule/app-i18n^1.0.1@molecule/app-logger^1.0.1@molecule/app-platform^1.0.1@molecule/app-push^1.0.1@molecule/app-routing^1.0.1@molecule/app-state^1.0.1@molecule/app-storage^1.0.1@molecule/app-theme^1.0.1@molecule/app-ui^1.0.1@molecule/app-utilities^1.0.1@molecule/app-version^1.0.1solid-js^1.8.0
Runtime Dependencies
-
@molecule/app-auth -
@molecule/app-device -
@molecule/app-forms -
@molecule/app-http -
@molecule/app-i18n -
@molecule/app-logger -
@molecule/app-platform -
@molecule/app-push -
@molecule/app-routing -
@molecule/app-state -
@molecule/app-storage -
@molecule/app-theme -
@molecule/app-ui -
@molecule/app-utilities -
@molecule/app-version -
solid-js -
Primitives throw outside
MoleculeProvider— and per missing service.configwires ONLY the services you pass; callingcreateAuth()in a tree whose config lacksauththrows "getAuthClient must be used within a MoleculeProvider with auth configured". Fix the config, don't catch the error. -
Primitive results are Solid accessors — call them (
isAuthenticated(),theme(),user()), never read them bare; a baretheme.colorsis a type error, and a bareisAuthenticatedis always truthy. -
Call primitives at component setup (top level of the component function), not inside JSX callbacks, so subscriptions are established once.
Translations
Translation strings are provided by @molecule/app-locales-solid.