Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

devalue

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

devalue - npm Package Compare versions

Comparing version 4.2.3 to 4.3.0

2

package.json
{
"name": "devalue",
"description": "Gets the job done when JSON.stringify can't",
"version": "4.2.3",
"version": "4.3.0",
"repository": "Rich-Harris/devalue",

@@ -6,0 +6,0 @@ "exports": {

@@ -12,2 +12,3 @@ # devalue

- `BigInt`
- custom types via replacers, reducers and revivers

@@ -25,3 +26,3 @@ Try it out [here](https://svelte.dev/repl/138d70def7a748ce9eda736ef1c71239?version=3.49.0).

- Human-readable output
- Stringifying functions or non-POJOs
- Stringifying functions

@@ -83,5 +84,48 @@ ## Usage

## Custom types
You can serialize and serialize custom types by passing a second argument to `stringify` containing an object of types and their _reducers_, and a second argument to `parse` or `unflatten` containing an object of types and their _revivers_:
```js
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
magnitude() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
const stringified = devalue.stringify(new Vector(30, 40), {
Vector: (value) => value instanceof Vector && [value.x, value.y]
});
console.log(stringified); // [["Vector",1],[2,3],30,40]
const vector = devalue.parse(stringified, {
Vector: ([x, y]) => new Vector(x, y)
});
console.log(vector.magnitude()); // 50
```
If a function passed to `stringify` returns a truthy value, it's treated as a match.
You can also use custom types with `uneval` by specifying a custom replacer:
```js
devalue.uneval(vector, (value, uneval) => {
if (value instanceof Vector) {
return `new Vector(${value.x},${value.y})`;
}
}); // `new Vector(30,40)`
```
Note that any variables referenced in the resulting JavaScript (like `Vector` in the example above) must be in scope when it runs.
## Error handling
If `uneval` or `stringify` encounters a function or a non-POJO, it will throw an error. You can find where in the input data the offending value lives by inspecting `error.path`:
If `uneval` or `stringify` encounters a function or a non-POJO that isn't handled by a custom replacer/reducer, it will throw an error. You can find where in the input data the offending value lives by inspecting `error.path`:

@@ -180,2 +224,3 @@ ```js

- [superjson](https://github.com/blitz-js/superjson) by Blitz
- [next-json](https://github.com/iccicci/next-json) by Daniele Ricci

@@ -182,0 +227,0 @@ ## License

@@ -13,12 +13,14 @@ import {

* @param {string} serialized
* @param {Record<string, (value: any) => any>} [revivers]
*/
export function parse(serialized) {
return unflatten(JSON.parse(serialized));
export function parse(serialized, revivers) {
return unflatten(JSON.parse(serialized), revivers);
}
/**
* Revive a value flattened with `devalue.flatten`
* Revive a value flattened with `devalue.stringify`
* @param {number | any[]} parsed
* @param {Record<string, (value: any) => any>} [revivers]
*/
export function unflatten(parsed) {
export function unflatten(parsed, revivers) {
if (typeof parsed === 'number') return hydrate(parsed, true);

@@ -34,3 +36,6 @@

/** @param {number} index */
/**
* @param {number} index
* @returns {any}
*/
function hydrate(index, standalone = false) {

@@ -55,2 +60,7 @@ if (index === UNDEFINED) return undefined;

const reviver = revivers?.[type];
if (reviver) {
return (hydrated[index] = reviver(hydrate(value[1])));
}
switch (type) {

@@ -96,2 +106,5 @@ case 'Date':

break;
default:
throw new Error(`Unknown type ${type}`);
}

@@ -98,0 +111,0 @@ } else {

@@ -20,4 +20,5 @@ import {

* @param {any} value
* @param {Record<string, (value: any) => any>} [reducers]
*/
export function stringify(value) {
export function stringify(value, reducers) {
/** @type {any[]} */

@@ -29,2 +30,8 @@ const stringified = [];

/** @type {Array<{ key: string, fn: (value: any) => any }>} */
const custom = [];
for (const key in reducers) {
custom.push({ key, fn: reducers[key] });
}
/** @type {string[]} */

@@ -52,2 +59,10 @@ const keys = [];

for (const { key, fn } of custom) {
const value = fn(thing);
if (value) {
stringified[index] = `["${key}",${flatten(value)}]`;
return index;
}
}
let str = '';

@@ -54,0 +69,0 @@

@@ -18,4 +18,5 @@ import {

* @param {any} value
* @param {(value: any) => string | void} [replacer]
*/
export function uneval(value) {
export function uneval(value, replacer) {
const counts = new Map();

@@ -26,2 +27,4 @@

const custom = new Map();
/** @param {any} thing */

@@ -41,2 +44,11 @@ function walk(thing) {

if (replacer) {
const str = replacer(thing);
if (typeof str === 'string') {
custom.set(thing, str);
return;
}
}
const type = get_type(thing);

@@ -123,2 +135,6 @@

if (custom.has(thing)) {
return custom.get(thing);
}
const type = get_type(thing);

@@ -181,2 +197,7 @@

if (custom.has(thing)) {
values.push(/** @type {string} */ (custom.get(thing)));
return;
}
if (is_primitive(thing)) {

@@ -183,0 +204,0 @@ values.push(stringify_primitive(thing));

/**
* Revive a value serialized with `devalue.stringify`
* @param {string} serialized
* @param {Record<string, (value: any) => any>} [revivers]
*/
export function parse(serialized: string): any;
export function parse(serialized: string, revivers?: Record<string, (value: any) => any>): any;
/**
* Revive a value flattened with `devalue.flatten`
* Revive a value flattened with `devalue.stringify`
* @param {number | any[]} parsed
* @param {Record<string, (value: any) => any>} [revivers]
*/
export function unflatten(parsed: number | any[]): any;
export function unflatten(parsed: number | any[], revivers?: Record<string, (value: any) => any>): any;
/**
* Turn a value into a JSON string that can be parsed with `devalue.parse`
* @param {any} value
* @param {Record<string, (value: any) => any>} [reducers]
*/
export function stringify(value: any): string;
export function stringify(value: any, reducers?: Record<string, (value: any) => any>): string;
/**
* Turn a value into the JavaScript that creates an equivalent value
* @param {any} value
* @param {(value: any) => string | void} [replacer]
*/
export function uneval(value: any): string;
export function uneval(value: any, replacer?: (value: any) => string | void): string;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc