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

@wix/site-service-warmup-data

v1.0.6

Published

A site service for reusing data that was fetched during SSR on the client.

Readme

@wix/site-service-warmup-data

A site service for reusing data that was fetched during SSR on the client.

The service is a thin adapter over host-provided warmup-data accessors. It does not own serialization, HTML extraction, or storage; the host provides those through getData and setData.

Install

pnpm add @wix/site-service-warmup-data

Usage

import { WarmupDataDefinition } from '@wix/site-service-warmup-data/definition'

const warmupData = servicesManager.getService(WarmupDataDefinition)

const key = `my-feature:product:${slug ?? 'fallback'}`
const cached = await warmupData.get<ProductContextData>(key)

if (cached !== null) {
    return cached
}

const data = await fetchProductContextData(slug)

if (typeof window === 'undefined') {
    warmupData.set(key, data)
}

return data

Host Registration

Hosts register the service with accessors that connect it to their warmup-data implementation.

import { createServicesMap } from '@wix/services-manager'
import { WarmupDataDefinition } from '@wix/site-service-warmup-data/definition'
import { WarmupDataService } from '@wix/site-service-warmup-data/implementations'

createServicesMap().addService(WarmupDataDefinition, WarmupDataService, {
    getData: async key => warmupDataStore.get(key) ?? null,
    setData: (key, value) => warmupDataStore.set(key, value),
})

API

| Member | Type | Description | |---|---|---| | get | <T = unknown>(key: string) => Promise<T \| null> | Reads warmup data for key. Returns null when no data exists. | | set | (key: string, data: unknown) => void | Stores warmup data for key through the host implementation. Intended for SSR writes. |

Configuration

IWarmupDataServiceConfig:

type IWarmupDataServiceConfig = {
    getData: (key: string) => Promise<unknown | null>
    setData: (key: string, data: unknown) => void
}

Keying

Consumers must use stable, unique keys. Prefer namespaced keys that include the package or feature name and the resource identity:

const key = `stores-product-page:product-context-data:${slug ?? 'fallback'}`

Avoid generic keys such as product or data; warmup data is shared through the host and key collisions can return the wrong payload.

SSR And Client Behavior

The intended flow is:

  1. During SSR, fetch the data and call set(key, data).
  2. The host serializes the stored value into warmup data.
  3. On the client, call get(key) before fetching.
  4. If get(key) returns null, fall back to the normal fetch path.

Client-side writes are not part of the warmup-data contract. Consumers should call set only during SSR. Host implementations may ignore or reject client writes.

Thunderbolt Integration

Thunderbolt registers this service through feature-warmup-data.

On SSR, Thunderbolt provides a request-local service store. Calls to set(key, data) write into that store. During warmup-data aggregation, the store is serialized under the top-level warmup-data key builderComponentsWarmupData:

{
    builderComponentsWarmupData: {
        [key]: data,
    },
}

On the client, Thunderbolt reads the serialized warmup-data JSON from the wix-warmup-data script element after DOM ready. Calls to get(key) wait for that warmup-data promise and then read builderComponentsWarmupData[key]. Missing keys return null.

Thunderbolt does not provide the request-local service store in the browser, so calling set on the client throws:

Setting builder component warmup data is only supported during SSR

Consumer code should therefore guard writes with an SSR check, or wrap set so warmup-data failures do not break rendering. Reads should also keep the normal fetch path as a fallback when get(key) returns null.

Async Reads And Performance

get(key) returns a promise because the serialized warmup-data payload may not be available when the component code starts running on the client. In Thunderbolt streaming mode, component JavaScript can run before the full document, including the wix-warmup-data script element, has arrived. In that case, get(key) waits for the host warmup-data promise before it can read builderComponentsWarmupData[key].

Waiting for warmup data is not always faster than fetching again. As the warmup-data payload grows, especially on pages with many components using warmup data, the warmup-data promise may resolve later than a cheap client fetch would. Warmup data should be treated as an optimization that needs measurement, not as a guaranteed performance improvement.

Prefer awaiting get(key) when:

  1. The original fetch is expensive or slow.
  2. Duplicating the fetch has meaningful server, quota, or side-effect cost.
  3. Measurements show the warmup-data promise usually resolves before a client fetch would finish.

Consider bounding the wait or skipping warmup data when:

  1. The client fetch is usually very fast.
  2. The page can contain many warmup-data consumers.
  3. Suspending rendering or hydration while waiting for warmup data is more expensive than refetching.

For latency-sensitive flows, measure how long get(key) takes and consider racing it with a small timeout:

function timeout(ms: number): Promise<null> {
    return new Promise(resolve => setTimeout(() => resolve(null), ms))
}

const start = performance.now()
const cached = await Promise.race([warmupData.get<ProductContextData>(key), timeout(50)])
const warmupWaitMs = performance.now() - start

reportWarmupDataTiming({ key, warmupWaitMs, hit: cached !== null })

if (cached !== null) {
    return cached
}

return fetchProductContextData(slug)

Tune the timeout per use case. A good timeout for one component may be wrong for another.

Optional Rollout

When supporting hosts that may not load this service yet, treat it as an optimization:

import { WarmupDataDefinition } from '@wix/site-service-warmup-data/definition'

function getOptionalWarmupData(servicesManager: ServicesManager) {
    try {
        return servicesManager.getService(WarmupDataDefinition)
    } catch {
        return null
    }
}

If the service is unavailable, continue with the existing fetch path.