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

@tim-code/dehydrate-calls

v0.1.1

Published

Allows sending JSON that encodes function calls.

Readme

dehydrate-calls

Allows sending JSON that encodes function calls.

First Time Setup

npm install @tim-code/my-util

What??

There are times when we want to send a JSON object to the server, but there are aspects to the JSON object that do not automatically serialize well to JSON. In general, in order to send this object we need to "dehydrate" it, meaning turn into well-formed JSON, and then on the server we can "rehydrate" it by turning the JSON back into what it was originally.

There are a lot of bespoke solutions to this problem such as implementing toJSON() for class instances and then writing a code on the server to call class constructors on certain properties. However, these patterns are more difficult to scale when adding additional "special" properties and require coordinating code changes on the client and the server.

The solution that this library supports is to write functions that when called with certain parameters, generate the non-serializable object (or function!). Then, instead of sending the output of these functions to the server, we send a record of what the function call was and the arguments were. The server can then hydrate the object and execute the function calls on its side.

Function calls are always applied from a "context", which is basically a whitelist of functions.

Toy Example

Suppose we want to sent {"a": Math.sqrt(2)} to the server but are concerned with loss of precision from sending the decimal value.

Using this library, we can do:

import { dehydrate } from "@tim-code/dehydrate-calls"
const request = dehydrate({ Math }, ($) => ({ a: $.Math.sqrt(2) }))

request is: {a: {_path: ["Math", "sqrt"], _args: [2]}}

and then on the server:

const result = hydrate(request, { Math })

result is: {a: 1.414...}

Client-Side Alternative

Instead of calling dehydrate(), we can instead create "fake" versions of the calls we want to do by using createCallCapturer():

const $ = createCallCapturer({ Math })
const request = { a: $.Math.sqrt(2) }

As before, request is: {a: {_path: ["Math", "sqrt"], _args: [2]}}.

This allows exporting fake versions of modules that can then be imported by code doing the requests:

export default createCallCapturer({ Math, Date })

Then in another file:

import $ from "..."
const request = { a: $.Math.sqrt(2) }

Function References

It is also possible to include function names instead of calls: {a: Math.sqrt}.

However, the result of

const request = dehydrate({ Math }, ($) => ({ a: $.Math.sqrt }))

is now: {a: <function>}, not a JSON object. This function though has a toJSON() method defined so after:

const intermediate = JSON.parse(JSON.stringify(request))

intermediate is :{a: {_path: ["Math", "sqrt"] }}

In most cases, the result of dehydrate will be stringified, so this detail shouldn't be noticeable.

Classes

This library also works with user-defined or third-party classes (not built-ins):

class Person {
  constructor(name) {
    this.name = name
  }
}
const request = dehydrate({ Person }, ($) => ({ a: new $.Person("John Smith") }))

request is: {a: {_path: ["Person"], _args: ["John Smith"], _class: true}}.

Note that it is required to still use new when calling the fake constructor.