A bunch of reactive utility types and functions, for building primitives with Solid.js
—
Environment detection, utility functions, and general-purpose helpers for common programming tasks. These utilities provide runtime environment information and common programming patterns that work well with Solid.js applications.
Constants and functions for detecting the runtime environment.
/**
* True when running on the server (from solid-js/web)
*/
const isServer: boolean;
/**
* True when running on the client (!isServer)
*/
const isClient: boolean;
/**
* True when in development mode on the client
*/
const isDev: boolean;
/**
* True when in production mode (!isDev)
*/
const isProd: boolean;Usage Examples:
import { isServer, isClient, isDev, isProd } from "@solid-primitives/utils";
// Conditional logic based on environment
if (isServer) {
console.log("Running on server");
} else {
console.log("Running on client");
}
// Development-only code
if (isDev) {
console.log("Debug information");
}
// Client-side only operations
if (isClient) {
localStorage.setItem("key", "value");
}
// Production optimizations
if (isProd) {
// Enable analytics, disable debug logs, etc.
}Common utility functions for everyday programming tasks.
/**
* No operation function
*/
function noop(...a: any[]): void;
/**
* Function that always returns true
*/
function trueFn(): boolean;
/**
* Function that always returns false
*/
function falseFn(): boolean;
/**
* @deprecated use equalFn from "solid-js"
*/
const defaultEquals: typeof equalFn;Usage Examples:
import { noop, trueFn, falseFn } from "@solid-primitives/utils";
// Default callback that does nothing
const handleClick = someCondition ? actualHandler : noop;
// Default predicates
const alwaysInclude = trueFn;
const alwaysExclude = falseFn;
// Filter arrays with utility functions
const items = [1, 2, 3, 4, 5];
const allItems = items.filter(trueFn); // [1, 2, 3, 4, 5]
const noItems = items.filter(falseFn); // []Pre-configured signal options for common patterns.
/**
* SignalOptions with equals: false
*/
const EQUALS_FALSE_OPTIONS: SignalOptions<unknown>;
/**
* SignalOptions with internal: true
*/
const INTERNAL_OPTIONS: SignalOptions<unknown>;Usage Examples:
import { createSignal } from "solid-js";
import { EQUALS_FALSE_OPTIONS, INTERNAL_OPTIONS } from "@solid-primitives/utils";
// Signal that always updates (bypasses equality check)
const [counter, setCounter] = createSignal(0, EQUALS_FALSE_OPTIONS);
// Internal signal (won't trigger dev warnings)
const [internalState, setInternalState] = createSignal(null, INTERNAL_OPTIONS);Functions for runtime type checking and validation.
/**
* Check if the value is an instance of a class
* @param v - Value to check
* @param c - Class constructor to check against
* @returns True if value is instance of class
*/
function ofClass(v: any, c: AnyClass): boolean;
/**
* Check if value is typeof "object" or "function"
* @param value - Value to check
* @returns True if value is an object
*/
function isObject(value: any): value is AnyObject;
/**
* Type guard for non-nullable values
* @param i - Value to check
* @returns True if value is not null or undefined
*/
function isNonNullable<T>(i: T): i is NonNullable<T>;
/**
* Filter array removing null and undefined values
* @param arr - Array to filter
* @returns New array with non-nullable values only
*/
function filterNonNullable<T extends readonly unknown[]>(arr: T): NonNullable<T[number]>[];Usage Examples:
import { ofClass, isObject, isNonNullable, filterNonNullable } from "@solid-primitives/utils";
// Class instance checking
class User {}
const user = new User();
console.log(ofClass(user, User)); // true
console.log(ofClass({}, User)); // false
// Object type checking
console.log(isObject({})); // true
console.log(isObject(null)); // false
console.log(isObject("string")); // false
// Null checking and filtering
const mixedArray = [1, null, "hello", undefined, {}, 0];
const nonNullable = filterNonNullable(mixedArray); // [1, "hello", {}, 0]
// Type guard usage
const value: string | null = getValue();
if (isNonNullable(value)) {
// value is definitely string here
console.log(value.toUpperCase());
}General-purpose utilities for working with arrays and comparing values.
/**
* Compare two values (-1, 0, 1)
* @param a - First value
* @param b - Second value
* @returns -1 if a < b, 1 if a > b, 0 if equal
*/
function compare(a: any, b: any): number;
/**
* Check shallow array equality
* @param a - First array
* @param b - Second array
* @returns True if arrays are shallow equal
*/
function arrayEquals(a: readonly unknown[], b: readonly unknown[]): boolean;
/**
* Convert value to array if not already array
* @param value - Value to convert
* @returns Array containing the value(s)
*/
function asArray<T>(value: T): (T extends any[] ? T[number] : NonNullable<T>)[];Usage Examples:
import { compare, arrayEquals, asArray } from "@solid-primitives/utils";
// Comparison function for sorting
const numbers = [3, 1, 4, 1, 5];
numbers.sort(compare); // [1, 1, 3, 4, 5]
// Array equality checking
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = [1, 2, 4];
console.log(arrayEquals(arr1, arr2)); // true
console.log(arrayEquals(arr1, arr3)); // false
// Convert to array
console.log(asArray("single")); // ["single"]
console.log(asArray([1, 2, 3])); // [1, 2, 3]
console.log(asArray(null)); // []Utilities for working with and combining functions.
/**
* Returns a function that will call all functions in the order they were chained
* @param callbacks - Iterable of callback functions
* @returns Combined function
*/
function chain<Args extends [] | any[]>(callbacks: {
[Symbol.iterator](): IterableIterator<((...args: Args) => any) | undefined>;
}): (...args: Args) => void;
/**
* Returns a function that will call all functions in reversed order
* @param callbacks - Array of callback functions
* @returns Combined function
*/
function reverseChain<Args extends [] | any[]>(
callbacks: (((...args: Args) => any) | undefined)[]
): (...args: Args) => void;Usage Examples:
import { chain, reverseChain } from "@solid-primitives/utils";
// Chain multiple callbacks
const callbacks = [
(msg: string) => console.log("First:", msg),
(msg: string) => console.log("Second:", msg),
(msg: string) => console.log("Third:", msg)
];
const chained = chain(callbacks);
chained("Hello"); // Logs: "First: Hello", "Second: Hello", "Third: Hello"
const reversed = reverseChain(callbacks);
reversed("World"); // Logs: "Third: World", "Second: World", "First: World"
// With undefined callbacks (safely handled)
const mixedCallbacks = [
(msg: string) => console.log("Valid:", msg),
undefined,
(msg: string) => console.log("Also valid:", msg)
];
const safeMixed = chain(mixedCallbacks);
safeMixed("Test"); // Only valid callbacks are calledEnhanced object utility functions with better type safety.
/**
* Get entries of an object with better typing
*/
const entries: <T extends object>(obj: T) => [keyof T, T[keyof T]][];
/**
* Get keys of an object with better typing
*/
const keys: <T extends object>(object: T) => (keyof T)[];Usage Examples:
import { entries, keys } from "@solid-primitives/utils";
const user = {
id: 1,
name: "Alice",
email: "alice@example.com"
};
// Typed object iteration
const userEntries = entries(user); // [["id", 1], ["name", "Alice"], ["email", "alice@example.com"]]
const userKeys = keys(user); // ["id", "name", "email"]
// Use in reactive contexts
import { createSignal, createMemo } from "solid-js";
const [userState, setUserState] = createSignal(user);
const userProperties = createMemo(() => keys(userState()));
const userValues = createMemo(() => entries(userState()).map(([, value]) => value));type AnyObject = Record<PropertyKey, any>;
type AnyClass = abstract new (...args: any) => any;
type Noop = (...a: any[]) => void;Install with Tessl CLI
npx tessl i tessl/npm-solid-primitives--utils