npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alessiofrittoli/web-utils

v2.3.0

Published

Common TypeScript web utilities

Downloads

2,756

Readme

Table of Contents


Getting started

Run the following command to start using web-utils in your projects:

npm i @alessiofrittoli/web-utils

or using pnpm

pnpm i @alessiofrittoli/web-utils

What's Changed

Updates in the latest release 🎉

  • Add normalizeIndex utility function. See API Reference for more info.
  • Add getPreviousIndex utility function. See API Reference for more info.
  • Add getNextIndex utility function. See API Reference for more info.
  • Add insertAfter utility function. See API Reference for more info.

Old updates:


API Reference

Array utilities

arrayUnique

Removes duplicate values from an array.

| Parameter | Type | Description | | --------- | ----- | ---------------- | | array | T[] | The input array. |


Type: T[]

The filtered array.


Removes duplicates from array
import { arrayUnique } from "@alessiofrittoli/web-utils";

const pointer = {};
console.log(arrayUnique([pointer, "b", pointer, "c", "b"]));
// Outputs: [ {}, 'b', 'c' ]

arrayObjectUnique

Removes duplicate entries from an array referencing an object key.

| Parameter | Type | Description | | ---------- | --------- | -------------------------------- | | array | T[] | An array of objects. | | property | keyof T | The Object property to refer to. |


Type: T[]

The filtered array.


Removes duplicates from array with the same propery value
import { arrayObjectUnique } from "@alessiofrittoli/web-utils";

const arr = [
  { id: 1, name: "a" },
  { id: 2, name: "b" },
  { id: 1, name: "c" }, // duplicate `id`
  { id: 3, name: "d" },
  { id: 4, name: "a" }, // duplicate `name`
];

console.log(arrayObjectUnique(arr, "id"));
// Outputs: [
//     { id: 1, name: 'a' },
//     { id: 2, name: 'b' },
//     { id: 3, name: 'd' },
//     { id: 4, name: 'a' },
// ]

console.log(arrayObjectUnique(arr, "name"));
// Outputs: [
//     { id: 1, name: 'a' },
//     { id: 2, name: 'b' },
//     { id: 1, name: 'c' },
//     { id: 3, name: 'd' },
// ]

listToArray

Convert a stringified Array to Array object.

| Parameter | Type | Description | | --------- | -------- | -------------------- | | string | string | An array of objects. |


Type: string[]

The converted stringified Array to Array object.


Basic usage
import { listToArray } from "@alessiofrittoli/web-utils";

console.log(listToArray("1,2, 3, 4").map(Number));
// Outputs: [ 1, 2, 3, 4 ]

chunkInto

Split Array into chunks.

| Parameter | Default | Description | | --------- | ----------- | ----------------------- | | T | unknown[] | The input array type. |


| Parameter | Type | Description | | --------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------- | | array | T[] | The original Array. | | options | ChunkIntoOptions | An object defining split criteria. | | options.size | number | Will split the given Array in a way to ensure each chunk length is, whenever possible, equal to the given value. | | options.count | number | Will split the given Array in a way to ensure n chunks as the given value. |


Type: T[]

An Array of chunks.


Basic usage
import { chunkInto } from "@alessiofrittoli/web-utils";

console.log(chunkInto([1, 2, 3, 4, 5], { count: 2 }));
// Output: [ [ 1, 2, 3 ], [ 4, 5 ] ]

console.log(chunkInto([1, 2, 3, 4, 5], { size: 2 }));
// Output: [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]

shuffle

Shuffle the elements of an array in place using the Fisher-Yates algorithm.

Please note that this function modify the original given array.

| Parameter | Description | | --------- | --------------------------------------------------------- | | T | The automatically inferred type of elements in the array. |


| Parameter | Type | Description | | --------- | ---------- | --------------------- | | array | Array<T> | The array to shuffle. |


Type: Array<T>

The modified shuffled array.


import { shuffle } from "@alessiofrittoli/web-utils";

console.log(shuffle([1, 2, 3, 4, 5]));

shuffleCopy

Copy and shuffle the elements of an array in place using the Fisher-Yates algorithm.

Same API of shuffle is applied, but this function does not modify the original given array.


normalizeIndex

Normalize negative indexes to a positive value.

| Parameter | Type | Description | | --------- | -------- | ----------------- | | index | number | The index. | | length | number | The array length. |


Type: number

The normalized index.


import { normalizeIndex } from "@alessiofrittoli/web-utils";

const array = [0, 1, 2, 3];

console.log(normalizeIndex(2, array.length)); // Outputs: 2
console.log(normalizeIndex(-1, array.length)); // Outputs: 3
console.log(normalizeIndex(-3, array.length)); // Outputs: 1

getPreviousIndex

Get the previous index.

| Parameter | Type | Default | Description | | --------- | -------- | ------- | ----------------- | | length | number | - | The array length. | | index | number | 0 | The index. |


Type: number

The previous index.


import { getPreviousIndex } from "@alessiofrittoli/web-utils";

const array = [0, 1, 2, 3];

console.log(getPreviousIndex(array.length, 2)); // Outputs: 1
console.log(getPreviousIndex(array.length, -1)); // Outputs: 2
console.log(getPreviousIndex(array.length, -3)); // Outputs: 0

getNextIndex

Get the next index.

| Parameter | Type | Default | Description | | --------- | -------- | ------- | ----------------- | | length | number | - | The array length. | | index | number | 0 | The index. |


Type: number

The next index.


import { getNextIndex } from "@alessiofrittoli/web-utils";

const array = [0, 1, 2, 3];

console.log(getNextIndex(array.length, 2)); // Outputs: 3
console.log(getNextIndex(array.length, -1)); // Outputs: 0
console.log(getNextIndex(array.length, -3)); // Outputs: 2

insertAfter

Inserts one or more items into an array at the specified index position.

  • T The type of elements in the array.

| Parameter | Type | Default | Description | | --------- | -------- | ------- | --------------------------------------------- | | array | T[] | - | The original array to insert items into. | | item | T\|T[] | 0 | A single item or an array of items to insert. | | index | number | -1 | The index after which to insert the item(s). |


Type: T[]

A new array with the item(s) inserted at the specified position.


import { insertAfter } from "@alessiofrittoli/web-utils";

console.log(insertAfter([1, 2, 3, 4], 5)); // Outputs: [ 1, 2, 3, 4, 5 ]
console.log(insertAfter(["a", "c"], "b", 0)); // Outputs: [ 'a', 'b', 'c' ]
console.log(insertAfter(["a", "b", "c", "e"], "d", -2)); // Outputs: [ 'a', 'b', 'c', 'd', 'e' ]

findIndexBy

Finds the index of the first object whose selected field strictly equals the provided value.

  • T The object type stored in the array.
  • U The key of T used for the comparison.

| Parameter | Type | Description | | --------------- | --------------------------- | ------------------------------------------------- | | options | FindInxeByOptions<T, U> | The search options. | | options.items | T[] | The collection to search. | | options.field | U | The object field to compare against value. | | options.value | T[U] | The value that must match the selected field. |


Type: number

The index of the matching item, or -1 when no match is found.


import { findIndexBy } from "@alessiofrittoli/web-utils";

const users = [
  { id: 1, name: "Ada" },
  { id: 2, name: "Grace" },
  { id: 3, name: "Linus" },
];

console.log(findIndexBy({ items: users, field: "id", value: 2 })); // Outputs: 1
console.log(findIndexBy({ items: users, field: "name", value: "Linus" })); // Outputs: 2
console.log(findIndexBy({ items: users, field: "id", value: 9 })); // Outputs: -1

Blob utilities

downloadBlob

Create and download a blob object.

| Parameter | Type | Description | | ---------- | -------------- | ----------------------------------- | | filename | string | The download file name. | | data | BodyInit | The download file data. | | init | ResponseInit | (Optional) The ResponseInit object. |


Download file from HTTP Response
import { downloadBlob } from '@alessiofrittoli/web-utils'

fetch( ... )
  .then( response => response.formData() )
  .then( async data => {
    await Promise.all(
      Array.from( data.entries() )
        .map( async ( [, file ] ) => {
          if ( ! ( file instanceof File ) ) return
          await downloadBlob( file.name, file )
        } )
    )
  } )
  .catch( error => {
    console.error( error )
  } )

Dom utilities

Scroll utilities
blockScroll

Prevent Element Overflow.

It calculates the scrollbar width and the resulting value is applied to the target element right padding-right to prevent width grows.

It also applies the --scrollbar-size CSS variable that can be used to apply a padding-right to the position fixed elements inside the target.

| Parameter | Type | Default | Description | | --------- | ------------- | -------------------------- | ------------------------------ | | target | HTMLElement | Document.documentElement | (Optional) The target Element. |


Block Document HTML scroll when a popup is opened
import { blockScroll } from "@alessiofrittoli/web-utils";

const openPopUpHandler = () => {
  blockScroll();
  // ... handle popup
};
.modal-wrapper {
  position: fixed;
  inset: 0;
  padding-right: var(--scrollbar-size, 0);
}

Block scroll of a specific HTMLElement
import { blockScroll } from "@alessiofrittoli/web-utils";

const element = document.querySelector(".css-selector");

if (element) {
  blockScroll(element);
}

restoreScroll

Restore Element Overflow.

| Parameter | Type | Default | Description | | --------- | ------------- | -------------------------- | ------------------------------ | | target | HTMLElement | Document.documentElement | (Optional) The target Element. |


Restore Document HTML scroll when a popup is closed
import { restoreScroll } from "@alessiofrittoli/web-utils";

const closePopUpHandler = () => {
  // ... handle close
  restoreScroll();
};

Restore scroll of a specific HTMLElement
import { restoreScroll } from "@alessiofrittoli/web-utils";

const element = document.querySelector(".css-selector");

if (element) {
  restoreScroll(element);
}

Stylesheet utilities
Types
UrlStylesheet

Represents a URL stylesheet as a simple URL input, URL object or as an object with URL and fetch configuration options.

type UrlStylesheet =
  | UrlInput
  | {
      /**
       * The URL string or a URL object of the stylesheet to load.
       *
       */
      url: UrlInput;
      /**
       * Indicates whether to fetch the given URL.
       *
       * @default false
       */
      fetch?: boolean;
    };

Style

Represents a style input.

type Style = UrlStylesheet | HTMLStyleElement | CSSStyleSheet | StyleSheetList;

Styles

Represents a single style object or an array of style objects.

type Styles = Style | Style[];

cloneStyleSheetList

Clones a StyleSheetList or array of CSSStyleSheets into an array of HTMLStyleElement objects.

This function extracts CSS rules from each stylesheet and creates corresponding <style> elements containing the serialized CSS text. If an error occurs while processing a stylesheet, the error is logged and that stylesheet is skipped.

| Parameter | Type | Description | | --------- | --------------------------------- | ------------------------------------------------------------------------- | | styles | StyleSheetList\|CSSStyleSheet[] | The source StyleSheetList or array of CSSStyleSheet objects to clone. |


Type: HTMLStyleElement[]

  • An array of HTMLStyleElement objects, each containing the CSS rules from the source stylesheets.
  • Failed stylesheets are filtered out and not included in the result.

import { cloneStyleSheetList } from "@alessiofrittoli/web-utils";

const styles = cloneStyleSheetList(document.styleSheets);
// do something with cloned stylesheets
// styles.forEach( style => shadowRoot.appendChild( style ) )

cloneStyleSheets

Clones style sheets from various sources into new HTMLStyleElement nodes.

  • When a URL stylesheet has fetch: true, the stylesheet content is fetched and embedded as inline CSS.
  • When fetch: false (default), a link element is created instead.
  • URL parsing is handled through the Url utility with support for both string and UrlInput object formats.

| Parameter | Type | Description | | --------- | -------- | ------------------------------------------------------------- | | styles | Styles | A style source or array of style sources. | | | | - See Styles type for a list of possible values. |


Type: Promise<CloneStyleSheetsReturn>

  • A promise that resolves to an array of cloned HTMLStyleElement and HTMLLinkElement nodes.
  • For inline styles and StyleSheetLists, returns HTMLStyleElement nodes.
  • For URL-based stylesheets, returns HTMLLinkElement nodes (or HTMLStyleElement if fetch is true).
  • Failed operations are silently ignored.

Cloning StyleSheetList
import { cloneStyleSheets } from "@alessiofrittoli/web-utils";

const styles = await cloneStyleSheets(document.styleSheets);
// do something with cloned dcoument stylesheets
// styles.forEach( style => shadowRoot.appendChild( style ) )

Cloning stylesheets from URL
import { cloneStyleSheets } from "@alessiofrittoli/web-utils";

const styles = await cloneStyleSheets("/path-to-stylesheet-file.css");

const styles = await cloneStyleSheets({
  url: "/path-to-stylesheet-file-2.css",
  fetch: true,
});

const styles = await cloneStyleSheets([
  "/path-to-stylesheet-file-3.css",
  { url: "/path-to-stylesheet-file-4.css", fetch: true },
]);

Generators utilities

isGeneratorFunction

Check if a function is a GeneratorFunction or AsyncGeneratorFunction.

| Parameter | Type | Description | | ----------- | --------- | ---------------------- | | reference | unknown | The function to check. |


Type: reference is GeneratorFunction | AsyncGeneratorFunction

  • true if the given reference is a GeneratorFunction or AsyncGeneratorFunction.
  • false otherwise.

isDefaultGeneratorFunction

Check if a function is a GeneratorFunction.

| Parameter | Type | Description | | ----------- | --------- | ---------------------- | | reference | unknown | The function to check. |


Type: reference is GeneratorFunction

  • true if the given reference is a GeneratorFunction.
  • false otherwise.

isAsyncGeneratorFunction

Check if a function is an AsyncGeneratorFunction.

| Parameter | Type | Description | | ----------- | --------- | ---------------------- | | reference | unknown | The function to check. |


Type: reference is AsyncGeneratorFunction

  • true if the given reference is an AsyncGeneratorFunction.
  • false otherwise.

isGeneratorObject<T>

Check if reference is a Generator or AsyncGenerator.

| Parameter | Type | Description | | ----------- | --------- | ----------------------- | | reference | unknown | The reference to check. |


Type: reference is Generator<T> | AsyncGenerator<T>

  • true if the given reference is a Generator or AsyncGenerator.
  • false otherwise.

isDefaultGeneratorObject<T>

Check if reference is a Generator.

| Parameter | Type | Description | | ----------- | --------- | ----------------------- | | reference | unknown | The reference to check. |


Type: reference is Generator<T>

  • true if the given reference is a Generator.
  • false otherwise.

isAsyncGeneratorObject<T>

Check if reference is an AsyncGenerator.

| Parameter | Type | Description | | ----------- | --------- | ----------------------- | | reference | unknown | The reference to check. |


Type: reference is AsyncGenerator<T>

  • true if the given reference is an AsyncGenerator.
  • false otherwise.

Map utilities

Interface TypedMap<T, P, K>

A type-safe extension of the Map class that enforces key-value relationships based on a provided type.

| Parameter | Type | Default | Description | | --------- | ------------------------- | --------- | ----------------------------------------------------------------------------------- | | T | Record<string, unknown> | unknown | The object type defining the key-value relationships. | | P | boolean | true | Defines whether the Map.get() method should return a possibily undefined value. | | K | keyof T | keyof T | Internal - The subset of keys in T that are allowed in the Map. |


getTypedMap<T, P, K>

Creates a new instance of a type-safe Map with the given type.


| Parameter | Type | Description | | ---------- | ------------------------------------------ | ------------------------------------------ | | iterable | Iterable<readonly [ K, T[ K ] ]> \| null | Initial Map constructor iterable object. |


Type: TypedMap<T, P, K>

A new instance of a type-safe Map.


Basic usage
import { getTypedMap } from "@alessiofrittoli/web-utils";

interface User {
  name: string;
  age: number;
  isActive: boolean;
}

const user = getTypedMap<User>([
  ["name", "Foo"],
  ["age", 27],
  ["isActive", true],
]);

console.log(user.get("name")); // type: `string | undefined`
console.log(user.get("age")); // type: `number | undefined`
console.log(user.get("isActive")); // type: `boolean | undefined`

Respect the given type
import { getTypedMap } from "@alessiofrittoli/web-utils";

interface User {
  name: string;
  age: number;
  isActive: boolean;
  banned?: boolean;
}

const user = getTypedMap<User, false>([
  ["name", "Foo"],
  ["age", 27],
  ["isActive", true],
]);

console.log(user.get("name")); // type: `string`
console.log(user.get("age")); // type: `number`
console.log(user.get("isActive")); // type: `boolean`
console.log(user.get("banned")); // type: `boolean | undefined`

Promises utilities

sleep

Await a void Promise that resolves after the given time.

| Parameter | Type | Description | | --------- | -------- | -------------------------------------------------------------- | | time | number | The sleep time in milliseconds after the Promise get resolved. |


Type: Promise<void>

A new Promise which get resolved after the specified time.


import { sleep } from "@alessiofrittoli/web-utils";

const fn = async () => {
  // ...
  await sleep(2000);
  // ...
};

deferTask

Defer task so main-thread is not blocked in order to quickly paint and respond to user interaction.

| Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------- | | T | The task function definition. unknown types will be inherited by your function type definition. | | U | The task function arguments. unknown types will be inherited by your function type. |


| Parameter | Type | Description | | --------- | ---- | ------------------------------------------------ | | task | T | The task callable function. | | ...args | U | Arguments required by the given task function. |


Type: Promise<Awaited<ReturnType<T>>>

A new Promise which returns the task result once fulfilled.


Basic usage
import { deferTask } from '@alessiofrittoli/web-utils'

const myLongTask = () => {
  ...
}

button.addEventListener( 'click', () => {
  deferTask( myLongTask )
} )

With custom arguments
import { deferTask } from '@alessiofrittoli/web-utils'

const myLongTask = ( target: HTMLButtonElement ) => {
  ...
}

button.addEventListener( 'click', event => {
  const target = event.target as HTMLButtonElement
  deferTask( myLongTask, target )
} )

deferCallback

Defer task handler so main-thread is not blocked in order to quickly paint and respond to user interaction.

| Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------- | | T | The task function definition. unknown types will be inherited by your function type definition. | | U | The task function arguments. unknown types will be inherited by your function type. |


| Parameter | Type | Description | | --------- | ---- | --------------------------- | | task | T | The task callable function. |


Type: ( ...args: U ) => Promise<Awaited<ReturnType<T>>>

A new handler which returns a new Promise that returns the task result once fulfilled.


import { deferCallback } from '@alessiofrittoli/web-utils'

const myLongTask = ( event: Event ) => {
  ...
}

button.addEventListener( 'click', deferCallback( myLongTask ) )

Strings utilities

ucFirst

Make first letter uppercase.

| Parameter | Type | Description | | --------- | -------- | ---------------------------- | | input | string | The input string to convert. |


Type: string

The processed string.


import { ucFirst } from "@alessiofrittoli/web-utils";

console.log(ucFirst("String value")); // Outputs: 'String value'
console.log(ucFirst("string value")); // Outputs: 'String value'

lcFirst

Make first letter lowercase.

| Parameter | Type | Description | | --------- | -------- | ---------------------------- | | input | string | The input string to convert. |


Type: string

The processed string.


import { lcFirst } from "@alessiofrittoli/web-utils";

console.log(lcFirst("String value")); // Outputs: 'string value'
console.log(lcFirst("string value")); // Outputs: 'string value'

toCamelCase

Convert string to camelCase.

| Parameter | Type | Description | | --------- | -------- | ---------------------------- | | input | string | The input string to convert. |


Type: string

The converted string to camelCase.


import { toCamelCase } from "@alessiofrittoli/web-utils";

console.log(toCamelCase("font-family")); // Outputs: 'fontFamily'
console.log(toCamelCase("background-color")); // Outputs: 'backgroundColor'
console.log(toCamelCase("-webkit-align-content")); // Outputs: 'WebkitAlignContent'
console.log(toCamelCase("some value")); // Outputs: 'someValue'
console.log(toCamelCase("some_value")); // Outputs: 'someValue'
console.log(toCamelCase("some value_with mixed_Cases")); // Outputs: 'someValueWithMixedCases'
console.log(toCamelCase("-string@with#special$characters")); // Outputs: 'StringWithSpecialCharacters'

toKebabCase

Convert string to kebab-case string.

| Parameter | Type | Description | | --------- | -------- | ---------------------------- | | input | string | The input string to convert. |


Type: string

The converted string to kebab-case.


import { toKebabCase } from "@alessiofrittoli/web-utils";

console.log(toKebabCase("fontFamily")); // Outputs: 'font-family'
console.log(toKebabCase("backgroundColor")); // Outputs: 'background-color'
console.log(toKebabCase("string with spaces")); // Outputs: 'string-with-spaces'
console.log(toKebabCase("string_with_underscores")); // Outputs: 'string-with-underscores'
console.log(toKebabCase("WebkitAlignContent")); // Outputs: '-webkit-align-content'
console.log(toKebabCase("some value_with mixed_Cases")); // Outputs: 'some-value-with-mixed-cases'
console.log(toKebabCase("-string@with#special$characters")); // Outputs: '-string-with-special-characters

stringifyValue

Stringify value.

| Parameter | Type | Description | | --------- | ----- | ----------------------- | | input | any | The value to stringify. |


Type: string

The stringified input.


import { stringifyValue } from "@alessiofrittoli/web-utils";

console.log(stringifyValue(new Date("Sat, 20 Apr 2025 16:20:00 GMT")));
// Outputs: '2025-04-20T16:20:00.000Z'

console.log(stringifyValue(null));
// Outputs: 'null'

console.log(stringifyValue({ prop: "value", prop2: true }));
// Outputs: '{"prop":"value","prop2":true}'

console.log(stringifyValue([1, 2, true, null, () => {}]));
// Outputs: '[1,2,true,null,null]'

console.log(
  stringifyValue(
    new Map([
      ["key", "value"],
      ["key2", "value"],
    ]),
  ),
);
// Outputs: '[["key","value"],["key2","value"]]'

console.log(
  stringifyValue(
    new Headers({
      key: "value",
      key2: "value",
    }),
  ),
);
// Outputs: '[["key","value"],["key2","value"]]'

console.log(stringifyValue(true)); // Outputs: 'true'
console.log(stringifyValue(false)); // Outputs: 'false'
console.log(stringifyValue(0)); // Outputs: '0'
console.log(stringifyValue(420)); // Outputs: '420'

console.log(stringifyValue(undefined)); // Outputs: ''
console.log(stringifyValue(() => {})); // Outputs: ''
console.log(stringifyValue(new Promise<void>((resolve) => resolve()))); // Outputs: ''

parseValue

Parse stringified value.

| Parameter | Description | | --------- | --------------------------------- | | T | The expected returned value type. |


| Parameter | Type | Description | | --------- | -------- | ------------------- | | input | string | The value to parse. |


Type: T | undefined

  • The parsed input.
  • undefined if no input or empty string is given.

import { parseValue } from "@alessiofrittoli/web-utils";

console.log(parseValue<Date>(stringifyValue(new Date())));
// Outputs: current Date object.

console.log(parseValue<number>("12345")); // Outputs: 12345
console.log(parseValue()); // Outputs: undefined
console.log(parseValue(" ")); // Outputs: undefined

console.log(parseValue<true>(stringifyValue(true)));
// Outputs: true

console.log(parseValue(stringifyValue({ key: "value" })));
// Outputs: { key: 'value' }

console.log(parseValue(stringifyValue([1, 2, 3, 4, 5])));
// Outputs: [ 1, 2, 3, 4, 5 ]

console.log(parseValue("String value")); // Outputs: 'String value'

parameterized

Creates a parameterized string with placeholder values.

Types
ParameterizedValue

Represents a value that can be used as a parameter in string operations.

type ParameterizedValue = string | boolean | number | bigint;
Parameterized

Represents a parameterized string with its corresponding values.

type Parameterized = [string, ParameterizedValue[]];
import { parameterized } from "@alessiofrittoli/web-utils";

const data = {
  value: "parameterized",
};

console.log(parameterized`My string with ${data.value} values.`); // [ 'My string with ? values.', [ 'parameterized' ] ]

Types utilities

⚠️ Docs coming soon


Validation utilities

⚠️ Docs coming soon

Objects utilities

⚠️ Docs coming soon


Browser API utilities

getMediaMatches

Safely executes window.matchMedia() in server and browser environments.

| Parameter | Type | Description | | --------- | -------- | -------------------------------- | | query | string | The Media Query string to check. |


Type: boolean

  • false if window is not defined or if the document currently doesn't matches the given query.
  • true otherwise.

Check if current device is landscape oriented
import { getMediaMatches } from "@alessiofrittoli/web-utils";

console.log(!getMediaMatches("(orientation:portrait)"));

openBrowserPopUp

Opens a webpage in a browser PopUp.

The openBrowserPopUp uses Window.open() under the hood, but provides default options to make your work easier.

| Parameter | Type | Default | Description | | ------------------ | ------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | options | OpenBrowserPopUpOptions | - | An object defining custom PopUp options. | | options.url | UrlInput | - | The URL or path of the resource to be loaded. See UrlInput for more info about accepted formats. | | options.width | number | 600 | The PopUp width. | | options.height | number | 800 | The PopUp height. | | options.context | string | - | A string, without whitespace, specifying the name of the browsing context the resource is being loaded into. | | options.features | OptionsFeatures | - | Additional custom PopUp features. |


Type: WindowProxy | null

  • a WindowProxy object is returned if the browser successfully opens the new browsing context.
  • null is returned if the browser fails to open the new browsing context, for example because it was blocked by a browser popup blocker.

Re-focus a previously opened popup
import { openBrowserPopUp } from "@alessiofrittoli/web-utils";

let windowProxy: WindowProxy | null = null;

const clickHandler = () => {
  if (windowProxy && !windowProxy.closed) {
    return windowProxy.focus();
  }

  windowProxy = openBrowserPopUp({
    url: {
      pathname: "/",
      query: { key: "value" },
    },
  });
};

Re-use a popup
import { openBrowserPopUp } from "@alessiofrittoli/web-utils";

const clickHandler = () => {
  openBrowserPopUp({
    context: "some-context-name",
    url: {
      pathname: "/",
      query: { key: "value" },
    },
  });
};

const clickHandler2 = () => {
  openBrowserPopUp({
    context: "some-context-name",
    url: "/other-path",
  });
};

Document Picture-in-Picture
Types
OpenDocumentPictureInPictureOptions

Defines configuration options for opening a Document Picture-in-Picture window.

| Property | Type | Default | Description | | ------------------------------ | ----------------- | -------------- | ------------------------------------------------------------------------------------------ | | sizes | InputDimensions | [ 250, 250 ] | A tuple defining non-negative numbers representing the width and the height to set | | | | | for the Picture-in-Picture window's viewport, in pixels. | | | | | - See InputDimensions type for a list of possible values. | | disallowReturnToOpener | boolean | false | Hints to the browser that it should not display a UI control that enables the | | | | | user to return to the originating tab and close the Picture-in-Picture window. | | preferInitialWindowPlacement | boolean | false | Defines whether the Picture-in-Picture window will always appear back at the | | | | | position and size it initially opened at, when it is closed and then reopened. | | | | | By contrast, if preferInitialWindowPlacement is false the | | | | | Picture-in-Picture window's size and position will be remembered when closed | | | | | and reopened — it will reopen at its previous position and size, | | | | | for example as set by the user. | | styles | Styles | - | Custom styles to load inside the Picture-in-Picture window. | | | | | - See Styles type for a list of possible values. | | | | | ⚠️ To keep consistent styling with your web-app, document styles are automatically cloned. | | onQuit | () => void | - | A callback to execute when Picture-in-Picture window is closed. |


OpenDocumentPictureInPicture

Defines the returned result of opening a Document Picture-in-Picture window.

| Property | Type | Description | | -------- | -------- | ------------------------------------------------------------------- | | window | Window | The browsing context inside the Document Picture-in-Picture window. |


isDocumentPictureInPictureSupported

Checks if the Document Picture-in-Picture API is supported by the current browser.

Type: boolean

  • true if Document Picture-in-Picture is supported.
  • false otherwise.

import { isDocumentPictureInPictureSupported } from "@alessiofrittoli/web-utils";

if ( isDocumentPictureInPictureSupported() ) {
  ...
}

requiresDocumentPictureInPictureAPI

Validates that the Document Picture-in-Picture API is supported by the current browser.

  • Throws a new Exception with code ErrorCode.DOCUMENT_PIP_NOT_SUPPORTED if the Document Picture-in-Picture API is not supported.
import { Exception } from "@alessiofrittoli/exception";
import { requiresDocumentPictureInPictureAPI, ErrorCode } from "@alessiofrittoli/web-utils";

const myFunction = () => {
  requiresDocumentPictureInPictureAPI()
  ...
}

try {
  myFunction()
} catch ( _err ) {
  const err = _err as Error

  const error = (
    Exception.isException<string, ErrorCode>(err)
      ? err
      : (
        new Exception(
          err.message,
          {
            code  : ErrorCode.UNKNOWN,
            name  : err.name,
            cause : err,
          }
        )
      )
  )

  switch ( error.code ) {
    case ErrorCode.DOCUMENT_PIP_NOT_SUPPORTED:
      console.warn( 'Document Picture-in-Picture is not supported.' )
      break
    default:
      console.error( 'Unknown error', error )
  }
}
openDocumentPictureInPicture

Opens a Document Picture-in-Picture window.

  • Throws a new Exception with code ErrorCode.DOCUMENT_PIP_NOT_SUPPORTED if the Document Picture-in-Picture API is not supported.

| Parameter | Type | Description | | --------- | ------------------------------------- | --------------------------------------------------------------------------- | | options | OpenDocumentPictureInPictureOptions | Configuration options for opening a new Document Picture-in-Picture window. |


Type: Promise<OpenDocumentPictureInPicture>

  • A new Promise that resolves to the Document Picture-in-Picture result containing the window of the new browsing context.

Simple usage
import { Exception } from "@alessiofrittoli/exception";
import {
  openDocumentPictureInPicture,
  ErrorCode,
} from "@alessiofrittoli/web-utils";

const openPictureInPicture = async () => {
  try {
    const content = document.createElement("div");

    const { window } = await openDocumentPictureInPicture();

    window.document.body.appendChild(content);
  } catch (_err) {
    const err = _err as Error;

    const error = Exception.isException<string, ErrorCode>(err)
      ? err
      : new Exception(err.message, {
          code: ErrorCode.UNKNOWN,
          name: err.name,
          cause: err,
        });

    switch (error.code) {
      case ErrorCode.DOCUMENT_PIP_NOT_SUPPORTED:
        console.warn("Document Picture-in-Picture is not supported.");
        break;
      default:
        console.error("Unknown error", error);
    }
  }
};

Load render blocking styles
import { Exception } from "@alessiofrittoli/exception";
import {
  openDocumentPictureInPicture,
  ErrorCode,
} from "@alessiofrittoli/web-utils";

const openPictureInPicture = async () => {
  try {
    const content = document.createElement("div");

    const { window } = await openDocumentPictureInPicture({
      styles: {
        url: "/important-stylesheet-fetched-before-opening.css",
        fetch: true,
      },
    });

    window.document.body.appendChild(content);
  } catch (error) {
    // ...
  }
};

Device utilities

isPortrait

Check if device is in portrait orientation.

Type: boolean

  • true if the device is in portrait orientation when this function is executed.
  • false otherwise.

Check if current device is landscape oriented
import { isPortrait } from "@alessiofrittoli/web-utils";

console.log(!isPortrait());

Network Information
Types
Connection interface

Defiens network status and NetworkInformation.

| Property | Type | Description | | --------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | network | NetworkInformation | The NetworkInformation interface of the Network Information API | | | | provides information about the connection a device is using to communicate | | | | with the network and provides a means for scripts to be notified if the connection type changes. | | | | ⚠️ Limited availability - See full compatibility | | onLine | boolean | Indicates whether the device is connected to the network. | | | | - See Listening for changes in network status. |


getConnection

Get current Network status and information.

Type: Connection

An object defining network status and NetworkInformation. See Connection interface for more info.


import { getConnection } from "@alessiofrittoli/web-utils";

const { network } = getConnection();

console.log(network?.effectiveType);

Storage utilities

Cookie Class
import { Priority, SameSite } from "@alessiofrittoli/web-utils";

import type {
  RawCookie,
  ParsedCookie,
  ParsedCookieMap,
} from "@alessiofrittoli/web-utils";

Priority Enum

The Cookie Priority.

| Constant | Value | Description | | -------- | ------ | -------------------------- | | Low | Low | Low priority. | | Medium | Medium | Medium priority (default). | | High | High | High priority. |


SameSite Enum

Controls whether or not a cookie is sent with cross-site requests, providing some protection against cross-site request forgery attacks (CSRF).

| Constant | Value | Description | | -------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Strict | Strict | The browser sends the cookie only for same-site requests. | | Lax | Lax | The cookie is not sent on cross-site requests, such as on requests to load images or frames, but is sent when a user is navigating to the origin site from an external site. | | None | None | The browser sends the cookie with both cross-site and same-site requests. |


RawCookie<K, V>

Interface representing Cookie properties before it get parsed.

| Property | Type | Description | | ------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | K | The Cookie name. | | value | V | The Cookie value. | | domain | string | Defines the host to which the cookie will be sent. | | expires | string \| number \| Date | Indicates the maximum lifetime of the cookie. | | httpOnly | boolean | Forbids JavaScript from accessing the cookie, for example, through the Document.cookie property. | | maxAge | number | Indicates the number of seconds until the cookie expires. If set, expires is ignored. | | partitioned | boolean | Indicates that the cookie should be stored using partitioned storage. | | path | string | Indicates the path that must exist in the requested URL for the browser to send the Cookie header. | | sameSite | SameSite | Controls whether or not a cookie is sent with cross-site requests, providing some protection against cross-site request forgery attacks (CSRF). | | secure | boolean | Indicates that the cookie is sent to the server only when a request is made with the https: scheme. | | priority | Priority | Defines the Cookie priority. |


ParsedCookie<K, V>

Interface representing Cookie properties after it get parsed.

| Property | Type | Description | | --------- | ------ | --------------------------------------------- | | expires | Date | Indicates the maximum lifetime of the cookie. |


ParsedCookieMap<K, V>

Map representation of a parsed Cookie.


Cookie.parse<K, V>()

Parse the given cookie parameters to a Cookie Map.

| Parameter | Description | | --------- | ----------------------------- | | K | The typed cookie name. | | V | The type of the cookie value. |


| Parameter | Type | Description | | --------- | ------------------------------------------ | ------------------------------------------ | | options | RawCookie<K, V> \| ParsedCookieMap<K, V> | The cookie options or a parsed Cookie Map. |


Type: ParsedCookieMap<K, V>

The parsed Cookie Map.


import { Cookie } from "@alessiofrittoli/web-utils";

const cookie = Cookie.parse({
  name: "cookiename",
  value: { test: "value" },
  path: "/specific-path",
  priority: Priority.High,
  expires: Date.now() + 20 * 60 * 1000,
  domain: "example.com",
  secure: true,
  httpOnly: true,
  sameSite: SameSite.Lax,
  maxAge: Date.now() + 30 * 60 * 1000,
  partitioned: true,
});

Cookie.toString<K, V>()

Stringify a Cookie ready to be stored.

| Parameter | Description | | --------- | ----------------------------- | | K | The typed cookie name. | | V | The type of the cookie value. |


| Parameter | Type | Description | | --------- | ------------------------------------------ | ------------------------------------------ | | options | RawCookie<K, V> \| ParsedCookieMap<K, V> | The cookie options or a parsed Cookie Map. |


Type: string

The stringified Cookie ready to be stored.


import { Cookie } from "@alessiofrittoli/web-utils";

document.cookie = Cookie.toString({
  name: "cookiename",
  value: { test: "value" },
  path: "/specific-path",
  priority: Priority.High,
  expires: Date.now() + 20 * 60 * 1000,
  domain: "example.com",
  secure: true,
  httpOnly: false,
  sameSite: SameSite.Lax,
  maxAge: Date.now() + 30 * 60 * 1000,
  partitioned: true,
});

Cookie.fromString<K, V>()

Parse a cookie string to a Cookie Map.

| Parameter | Description | | --------- | ------------------------------- | | K | The typed cookie name. | | V | The expected cookie value type. |


| Parameter | Type | Description | | --------- | -------- | ------------------ | | cookie | string | The cookie string. |


Type: ParsedCookieMap<K, V> | null

The parsed Cookie Map or null if parsing fails.


import { Cookie } from "@alessiofrittoli/web-utils";

const cookies = document.cookie
  .split("; ")
  .map(Cookie.fro