New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

seroval

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

seroval - npm Package Compare versions

Comparing version 0.5.1 to 0.6.0

dist/types/tree/reference.d.ts

5

dist/types/compat.d.ts

@@ -19,4 +19,5 @@ /**

TypedArray = 2048,
BigIntTypedArray = 4096
BigIntTypedArray = 4096,
WebAPI = 8192
}
export declare const ALL_ENABLED = 8191;
export declare const ALL_ENABLED = 12287;

7

dist/types/context.d.ts

@@ -1,2 +0,1 @@

import { AsyncServerValue } from './types';
interface IndexAssignment {

@@ -34,3 +33,3 @@ t: 'index';

features: number;
valueMap: Map<number, AsyncServerValue>;
valueMap: Map<number, unknown>;
}

@@ -55,4 +54,4 @@ export interface Options {

export declare function getRefParam(ctx: SerializationContext, index: number): string;
export declare function getRootID(ctx: ParserContext, current: AsyncServerValue): number;
export declare function createRef(ctx: ParserContext, current: AsyncServerValue): number;
export declare function getRootID<T>(ctx: ParserContext, current: T): number;
export declare function createIndexedValue<T>(ctx: ParserContext, current: T): number;
export {};

@@ -1,9 +0,8 @@

import { Feature } from './compat';
import { Options } from './context';
import { SerovalNode } from './tree/types';
import { AsyncServerValue, PrimitiveValue, ServerValue, CommonServerValue, SemiPrimitiveValue, ErrorValue } from './types';
export { AsyncServerValue, ServerValue, PrimitiveValue, CommonServerValue, SemiPrimitiveValue, ErrorValue, Feature, };
export declare function serialize<T extends ServerValue>(source: T, options?: Partial<Options>): string;
export declare function serializeAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<string>;
export declare function deserialize<T extends AsyncServerValue>(source: string): T;
export { AsyncServerValue, ServerValue, PrimitiveValue, CommonServerValue, SemiPrimitiveValue, ErrorValue, } from './types';
export { Feature } from './compat';
export declare function serialize<T>(source: T, options?: Partial<Options>): string;
export declare function serializeAsync<T>(source: T, options?: Partial<Options>): Promise<string>;
export declare function deserialize<T>(source: string): T;
export interface SerovalJSON {

@@ -16,6 +15,7 @@ t: SerovalNode;

}
export declare function toJSON<T extends ServerValue>(source: T, options?: Partial<Options>): SerovalJSON;
export declare function toJSONAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<SerovalJSON>;
export declare function toJSON<T>(source: T, options?: Partial<Options>): SerovalJSON;
export declare function toJSONAsync<T>(source: T, options?: Partial<Options>): Promise<SerovalJSON>;
export declare function compileJSON(source: SerovalJSON): string;
export declare function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T;
export declare function fromJSON<T>(source: SerovalJSON): T;
export default serialize;
export { createReference } from './tree/reference';
import { ParserContext } from '../context';
import { AsyncServerValue } from '../types';
import { SerovalNode } from './types';
export default function parseAsync(ctx: ParserContext, current: AsyncServerValue): Promise<readonly [SerovalNode, number, boolean]>;
export default function parseAsync<T>(ctx: ParserContext, current: T): Promise<readonly [SerovalNode, number, boolean]>;
import { SerializationContext } from '../context';
import { AsyncServerValue } from '../types';
import { SerovalNode } from './types';
export default function deserializeTree(ctx: SerializationContext, node: SerovalNode): AsyncServerValue;
export default function deserializeTree(ctx: SerializationContext, node: SerovalNode): unknown;
import { ParserContext } from '../context';
import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
import { WellKnownSymbols } from './symbols';
import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalBooleanNode, SerovalDateNode, SerovalInfinityNode, SerovalNaNNode, SerovalNegativeInfinityNode, SerovalNegativeZeroNode, SerovalNullNode, SerovalNumberNode, SerovalReferenceNode, SerovalRegExpNode, SerovalStringNode, SerovalTypedArrayNode, SerovalUndefinedNode, SerovalWKSymbolNode } from './types';
import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalBooleanNode, SerovalDateNode, SerovalInfinityNode, SerovalNaNNode, SerovalNegativeInfinityNode, SerovalNegativeZeroNode, SerovalNullNode, SerovalNumberNode, SerovalIndexedValueNode, SerovalRegExpNode, SerovalStringNode, SerovalTypedArrayNode, SerovalUndefinedNode, SerovalWKSymbolNode, SerovalReferenceNode } from './types';
export declare const TRUE_NODE: SerovalBooleanNode;

@@ -16,3 +16,3 @@ export declare const FALSE_NODE: SerovalBooleanNode;

export declare function createBigIntNode(ctx: ParserContext, current: bigint): SerovalBigIntNode;
export declare function createReferenceNode(id: number): SerovalReferenceNode;
export declare function createIndexedValueNode(id: number): SerovalIndexedValueNode;
export declare function createDateNode(id: number, current: Date): SerovalDateNode;

@@ -22,2 +22,3 @@ export declare function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode;

export declare function createBigIntTypedArrayNode(ctx: ParserContext, id: number, current: BigIntTypedArrayValue): SerovalBigIntTypedArrayNode;
export declare function createWKSymbolNode(current: WellKnownSymbols): SerovalWKSymbolNode;
export declare function createWKSymbolNode(ctx: ParserContext, current: WellKnownSymbols): SerovalWKSymbolNode;
export declare function createReferenceNode<T>(id: number, ref: T): SerovalReferenceNode;
import { ParserContext } from '../context';
import { ServerValue } from '../types';
import { SerovalNode } from './types';
export default function parseSync(ctx: ParserContext, current: ServerValue): readonly [SerovalNode, number, boolean];
export default function parseSync<T>(ctx: ParserContext, current: T): readonly [SerovalNode, number, boolean];

@@ -13,3 +13,3 @@ import { Symbols } from './symbols';

BigInt = 9,
Reference = 10,
IndexedValue = 10,
Date = 11,

@@ -28,3 +28,6 @@ RegExp = 12,

BigIntTypedArray = 23,
WKSymbol = 24
WKSymbol = 24,
URL = 25,
URLSearchParams = 26,
Reference = 27
}

@@ -84,4 +87,4 @@ export interface SerovalBaseNode {

export type SerovalPrimitiveNode = SerovalNumberNode | SerovalStringNode | SerovalBooleanNode | SerovalNullNode | SerovalUndefinedNode | SerovalNegativeZeroNode | SerovalNegativeInfinityNode | SerovalInfinityNode | SerovalNaNNode;
export interface SerovalReferenceNode extends SerovalBaseNode {
t: SerovalNodeType.Reference;
export interface SerovalIndexedValueNode extends SerovalBaseNode {
t: SerovalNodeType.IndexedValue;
i: number;

@@ -177,2 +180,17 @@ }

}
export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode | SerovalWKSymbolNode;
export interface SerovalURLNode extends SerovalBaseNode {
t: SerovalNodeType.URL;
i: number;
s: string;
}
export interface SerovalURLSearchParamsNode extends SerovalBaseNode {
t: SerovalNodeType.URLSearchParams;
i: number;
s: string;
}
export interface SerovalReferenceNode extends SerovalBaseNode {
t: SerovalNodeType.Reference;
i: number;
s: string;
}
export type SerovalNode = SerovalPrimitiveNode | SerovalIndexedValueNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode | SerovalWKSymbolNode | SerovalURLNode | SerovalURLSearchParamsNode | SerovalReferenceNode;

@@ -6,3 +6,4 @@ import { WellKnownSymbols } from './tree/symbols';

export type BigIntTypedArrayValue = BigInt64Array | BigUint64Array;
export type SemiPrimitiveValue = RegExp | Date | TypedArrayValue | BigIntTypedArrayValue | bigint;
export type WebAPIValue = URL | URLSearchParams;
export type SemiPrimitiveValue = RegExp | Date | TypedArrayValue | BigIntTypedArrayValue | bigint | WebAPIValue;
export type CommonServerValue = PrimitiveValue | SemiPrimitiveValue | ErrorValue;

@@ -9,0 +10,0 @@ export type ServerValue = CommonServerValue | Array<ServerValue> | readonly ServerValue[] | Iterable<ServerValue> | {

{
"name": "seroval",
"type": "module",
"version": "0.5.1",
"version": "0.6.0",
"files": [

@@ -19,3 +19,3 @@ "dist",

"eslint": "^8.32.0",
"eslint-config-lxsmnsyc": "^0.4.8",
"eslint-config-lxsmnsyc": "^0.5.1",
"pridepack": "2.4.1",

@@ -68,3 +68,3 @@ "tslib": "^2.4.1",

},
"gitHead": "2154c039056b24f706dbb1c2006acd99383e9305"
"gitHead": "1d6e69079251612c6fc486e8517e225690363442"
}

@@ -189,2 +189,33 @@ # seroval

## Serializable references
There are values that has no way to be serializable at all, i.e. functions, but usually in an isomorphic code, functions can exist on both client and server-side. What if we can serialize these functions in such a way we can refer to their counterparts?
`seroval` has `createReference` that you can use to map user-defined strings to their references.
```js
import { createReference } from 'seroval';
const thisIsAnIsomorphicFunction = createReference(
// This is (ideally) a unique identifier
// that is used to map the serialized value
// to its actual reference (and vice versa)
'my-function',
() => {
// Ideally this function should exist on both
// server and client, but we want to add the ability
// to serialize and deserialize this reference on
// both sides
}
);
// we can now serialize this
const serialized = toJSON(thisIsAnIsomorphicFunction); // or any of the serializer
thisIsAnIsomorphicFunction === fromJSON(serialized); // true
```
> **Note**
> It can only accept objects, functions and symbols and it doesn't actually
> serialize their values but only the string you used to identify the reference
## Supports

@@ -236,3 +267,6 @@

- [Well-known symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties)
- [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)
- [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
- Cyclic references (both self and mutual)
- Isomorphic references (a reference that exist on both the serializer and deserializer side)

@@ -323,2 +357,6 @@ ## Compat

- Disables serialization of `BigInt64Array` and `BigUint64Array`
- `WebAPI`
- Throws and disables the following usage:
- [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL)
- [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)

@@ -325,0 +363,0 @@ ## Sponsors

@@ -22,4 +22,5 @@ /* eslint-disable guard-for-in */

BigIntTypedArray = 0x1000,
WebAPI = 0x2000,
}
export const ALL_ENABLED = 0x1FFF;
export const ALL_ENABLED = 0x2FFF;
import { ALL_ENABLED } from './compat';
import getIdentifier from './get-identifier';
import { AsyncServerValue } from './types';

@@ -52,3 +51,3 @@ interface IndexAssignment {

valueMap: Map<number, AsyncServerValue>;
valueMap: Map<number, unknown>;
}

@@ -122,5 +121,5 @@

export function getRootID(
export function getRootID<T>(
ctx: ParserContext,
current: AsyncServerValue,
current: T,
) {

@@ -134,5 +133,5 @@ const ref = ctx.refs.get(current);

export function createRef(
export function createIndexedValue<T>(
ctx: ParserContext,
current: AsyncServerValue,
current: T,
) {

@@ -139,0 +138,0 @@ const ref = ctx.refs.get(current);

@@ -15,10 +15,2 @@ /* eslint-disable no-await-in-loop */

import { SerovalNode } from './tree/types';
import {
AsyncServerValue,
PrimitiveValue,
ServerValue,
CommonServerValue,
SemiPrimitiveValue,
ErrorValue,
} from './types';

@@ -32,4 +24,4 @@ export {

ErrorValue,
Feature,
};
} from './types';
export { Feature } from './compat';

@@ -72,3 +64,3 @@ function finalize(

export function serialize<T extends ServerValue>(
export function serialize<T>(
source: T,

@@ -84,3 +76,3 @@ options?: Partial<Options>,

export async function serializeAsync<T extends AsyncServerValue>(
export async function serializeAsync<T>(
source: T,

@@ -96,3 +88,3 @@ options?: Partial<Options>,

export function deserialize<T extends AsyncServerValue>(source: string): T {
export function deserialize<T>(source: string): T {
// eslint-disable-next-line no-eval

@@ -110,3 +102,3 @@ return (0, eval)(source) as T;

export function toJSON<T extends ServerValue>(
export function toJSON<T>(
source: T,

@@ -126,3 +118,3 @@ options?: Partial<Options>,

export async function toJSONAsync<T extends AsyncServerValue>(
export async function toJSONAsync<T>(
source: T,

@@ -151,3 +143,3 @@ options?: Partial<Options>,

export function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T {
export function fromJSON<T>(source: SerovalJSON): T {
const serial = createSerializationContext({

@@ -161,1 +153,3 @@ features: source.f,

export default serialize;
export { createReference } from './tree/reference';

@@ -5,5 +5,5 @@ /* eslint-disable no-await-in-loop */

import { Feature } from '../compat';
import { createRef, getRootID, ParserContext } from '../context';
import { createIndexedValue, getRootID, ParserContext } from '../context';
import quote from '../quote';
import {
AsyncServerValue,
BigIntTypedArrayValue,

@@ -17,3 +17,3 @@ TypedArrayValue,

createNumberNode,
createReferenceNode,
createIndexedValueNode,
createRegExpNode,

@@ -31,3 +31,5 @@ createStringNode,

UNDEFINED_NODE,
createReferenceNode,
} from './primitives';
import { hasReferenceID } from './reference';
import {

@@ -39,3 +41,3 @@ getErrorConstructorName,

} from './shared';
import { INV_SYMBOL_REF } from './symbols';
import { WellKnownSymbols } from './symbols';
import {

@@ -55,2 +57,3 @@ SerovalAggregateErrorNode,

} from './types';
import { createURLNode, createURLSearchParamsNode } from './web-api';

@@ -64,14 +67,14 @@ type ObjectLikeNode =

type ObjectLikeValue =
| Record<string, AsyncServerValue>
| Iterable<AsyncServerValue>
| PromiseLike<AsyncServerValue>;
| Record<string, unknown>
| Iterable<unknown>
| PromiseLike<unknown>;
async function generateNodeList(
ctx: ParserContext,
current: AsyncServerValue[],
current: unknown[],
) {
const size = current.length;
const nodes = new Array<SerovalNode>(size);
const deferred = new Array<AsyncServerValue>(size);
let item: AsyncServerValue;
const deferred = new Array<unknown>(size);
let item: unknown;
for (let i = 0; i < size; i++) {

@@ -98,3 +101,3 @@ if (i in current) {

id: number,
current: AsyncServerValue[],
current: unknown[],
): Promise<SerovalArrayNode> {

@@ -117,3 +120,3 @@ return {

id: number,
current: Map<AsyncServerValue, AsyncServerValue>,
current: Map<unknown, unknown>,
): Promise<SerovalMapNode> {

@@ -124,4 +127,4 @@ assert(ctx.features & Feature.Map, 'Unsupported type "Map"');

const valueNodes = new Array<SerovalNode>(len);
const deferredKey = new Array<AsyncServerValue>(len);
const deferredValue = new Array<AsyncServerValue>(len);
const deferredKey = new Array<unknown>(len);
const deferredValue = new Array<unknown>(len);
let deferredSize = 0;

@@ -161,3 +164,3 @@ let nodeSize = 0;

id: number,
current: Set<AsyncServerValue>,
current: Set<unknown>,
): Promise<SerovalSetNode> {

@@ -167,3 +170,3 @@ assert(ctx.features & Feature.Set, 'Unsupported type "Set"');

const nodes = new Array<SerovalNode>(len);
const deferred = new Array<AsyncServerValue>(len);
const deferred = new Array<unknown>(len);
let deferredSize = 0;

@@ -198,3 +201,3 @@ let nodeSize = 0;

ctx: ParserContext,
properties: Record<string, AsyncServerValue>,
properties: Record<string, unknown>,
): Promise<SerovalObjectRecordNode> {

@@ -206,6 +209,6 @@ const keys = Object.keys(properties);

const deferredKeys = new Array<string>(size);
const deferredValues = new Array<AsyncServerValue>(size);
const deferredValues = new Array<unknown>(size);
let deferredSize = 0;
let nodesSize = 0;
let item: AsyncServerValue;
let item: unknown;
for (const key of keys) {

@@ -237,3 +240,3 @@ item = properties[key];

id: number,
current: Iterable<AsyncServerValue>,
current: Iterable<unknown>,
): Promise<SerovalIterableNode> {

@@ -252,3 +255,3 @@ assert(ctx.features & Feature.Symbol, 'Unsupported type "Iterable"');

d: options
? await generateProperties(ctx, options as Record<string, AsyncServerValue>)
? await generateProperties(ctx, options)
: undefined,

@@ -263,3 +266,3 @@ a: await generateNodeList(ctx, array),

id: number,
current: PromiseLike<AsyncServerValue>,
current: PromiseLike<unknown>,
): Promise<SerovalPromiseNode> {

@@ -291,3 +294,3 @@ assert(ctx.features & Feature.Promise, 'Unsupported type "Promise"');

if ('then' in current && typeof current.then === 'function') {
return generatePromiseNode(ctx, id, current as PromiseLike<AsyncServerValue>);
return generatePromiseNode(ctx, id, current as PromiseLike<unknown>);
}

@@ -301,3 +304,3 @@ return {

m: undefined,
d: await generateProperties(ctx, current as Record<string, AsyncServerValue>),
d: await generateProperties(ctx, current as Record<string, unknown>),
a: undefined,

@@ -323,5 +326,5 @@ f: undefined,

c: undefined,
m: current.message,
m: quote(current.message),
d: optionsNode,
a: await generateNodeList(ctx, current.errors as AsyncServerValue[]),
a: await generateNodeList(ctx, current.errors as unknown[]),
f: undefined,

@@ -346,3 +349,3 @@ };

c: getErrorConstructorName(current),
m: current.message,
m: quote(current.message),
d: optionsNode,

@@ -354,5 +357,5 @@ a: undefined,

async function parse(
async function parse<T>(
ctx: ParserContext,
current: AsyncServerValue,
current: T,
): Promise<SerovalNode> {

@@ -370,12 +373,12 @@ switch (typeof current) {

case -Infinity: return NEG_INFINITY_NODE;
default: break;
default:
// eslint-disable-next-line no-self-compare
if (current !== current) {
return NAN_NODE;
}
if (Object.is(current, -0)) {
return NEG_ZERO_NODE;
}
return createNumberNode(current);
}
// eslint-disable-next-line no-self-compare
if (current !== current) {
return NAN_NODE;
}
if (Object.is(current, -0)) {
return NEG_ZERO_NODE;
}
return createNumberNode(current);
case 'bigint':

@@ -389,6 +392,9 @@ return createBigIntNode(ctx, current);

// mostly because the values themselves are stateful
const id = createRef(ctx, current);
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createReferenceNode(id);
return createIndexedValueNode(id);
}
if (hasReferenceID(current)) {
return createReferenceNode(id, current);
}
if (Array.isArray(current)) {

@@ -399,7 +405,7 @@ return generateArrayNode(ctx, id, current);

case Date:
return createDateNode(id, current as Date);
return createDateNode(id, current as unknown as Date);
case RegExp:
return createRegExpNode(id, current as RegExp);
return createRegExpNode(id, current as unknown as RegExp);
case Promise:
return generatePromiseNode(ctx, id, current as Promise<AsyncServerValue>);
return generatePromiseNode(ctx, id, current as unknown as Promise<unknown>);
case Int8Array:

@@ -414,6 +420,6 @@ case Int16Array:

case Float64Array:
return createTypedArrayNode(ctx, id, current as TypedArrayValue);
return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
case BigInt64Array:
case BigUint64Array:
return createBigIntTypedArrayNode(ctx, id, current as BigIntTypedArrayValue);
return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
case Map:

@@ -423,3 +429,3 @@ return generateMapNode(

id,
current as Map<AsyncServerValue, AsyncServerValue>,
current as unknown as Map<unknown, unknown>,
);

@@ -430,3 +436,3 @@ case Set:

id,
current as Set<AsyncServerValue>,
current as unknown as Set<unknown>,
);

@@ -437,3 +443,3 @@ case Object:

id,
current as Record<string, AsyncServerValue>,
current as Record<string, unknown>,
false,

@@ -445,3 +451,3 @@ );

id,
current as Record<string, AsyncServerValue>,
current as Record<string, unknown>,
true,

@@ -451,5 +457,5 @@ );

if (ctx.features & Feature.AggregateError) {
return generateAggregateErrorNode(ctx, id, current as AggregateError);
return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
}
return generateErrorNode(ctx, id, current as AggregateError);
return generateErrorNode(ctx, id, current as unknown as AggregateError);
case Error:

@@ -462,3 +468,7 @@ case EvalError:

case URIError:
return generateErrorNode(ctx, id, current as Error);
return generateErrorNode(ctx, id, current as unknown as Error);
case URL:
return createURLNode(ctx, id, current as unknown as URL);
case URLSearchParams:
return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
default:

@@ -481,7 +491,7 @@ break;

if (Symbol.iterator in current) {
return generateIterableNode(ctx, id, current);
return generateIterableNode(ctx, id, current as Iterable<unknown>);
}
// For Promise-like objects
if ('then' in current && typeof current.then === 'function') {
return generatePromiseNode(ctx, id, current as PromiseLike<AsyncServerValue>);
return generatePromiseNode(ctx, id, current as PromiseLike<unknown>);
}

@@ -491,5 +501,18 @@ throw new Error('Unsupported type');

case 'symbol':
assert(ctx.features & Feature.Symbol, 'Unsupported type "symbol"');
assert(current in INV_SYMBOL_REF, 'seroval only supports well-known symbols');
return createWKSymbolNode(current);
if (hasReferenceID(current)) {
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createIndexedValueNode(id);
}
return createReferenceNode(id, current);
}
return createWKSymbolNode(ctx, current as WellKnownSymbols);
case 'function': {
assert(hasReferenceID(current), 'Cannot serialize function without reference ID.');
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createIndexedValueNode(id);
}
return createReferenceNode(id, current);
}
default:

@@ -500,5 +523,5 @@ throw new Error('Unsupported type');

export default async function parseAsync(
export default async function parseAsync<T>(
ctx: ParserContext,
current: AsyncServerValue,
current: T,
) {

@@ -505,0 +528,0 @@ const result = await parse(ctx, current);

@@ -7,2 +7,3 @@ /* eslint-disable @typescript-eslint/no-use-before-define */

import { AsyncServerValue } from '../types';
import { getReference } from './reference';
import { getErrorConstructor, getTypedArrayConstructor } from './shared';

@@ -27,3 +28,3 @@ import { SYMBOL_REF } from './symbols';

function assignRef<T extends AsyncServerValue>(
function assignIndexedValue<T>(
ctx: SerializationContext,

@@ -40,3 +41,3 @@ index: number,

node: SerovalArrayNode | SerovalIterableNode | SerovalAggregateErrorNode,
result: AsyncServerValue[],
result: unknown[],
) {

@@ -57,3 +58,3 @@ let item: SerovalNode;

) {
const result: AsyncServerValue[] = assignRef(
const result: AsyncServerValue[] = assignIndexedValue(
ctx,

@@ -72,3 +73,3 @@ node.i,

node: SerovalObjectRecordNode,
result: Record<string, AsyncServerValue>,
result: Record<string, unknown>,
) {

@@ -88,3 +89,7 @@ if (node.s === 0) {

) {
const result = assignRef(ctx, node.i, Object.create(null) as Record<string, AsyncServerValue>);
const result = assignIndexedValue(
ctx,
node.i,
Object.create(null) as Record<string, AsyncServerValue>,
);
ctx.stack.push(node.i);

@@ -100,3 +105,3 @@ deserializeProperties(ctx, node.d, result);

) {
const result = assignRef(ctx, node.i, {} as Record<string, AsyncServerValue>);
const result = assignIndexedValue(ctx, node.i, {} as Record<string, AsyncServerValue>);
ctx.stack.push(node.i);

@@ -112,3 +117,3 @@ deserializeProperties(ctx, node.d, result);

) {
const result = assignRef(ctx, node.i, new Set<AsyncServerValue>());
const result = assignIndexedValue(ctx, node.i, new Set<unknown>());
ctx.stack.push(node.i);

@@ -126,6 +131,6 @@ for (let i = 0, len = node.a.length; i < len; i++) {

) {
const result = assignRef(
const result = assignIndexedValue(
ctx,
node.i,
new Map<AsyncServerValue, AsyncServerValue>(),
new Map<unknown, unknown>(),
);

@@ -165,3 +170,3 @@ ctx.stack.push(node.i);

// Serialize the required arguments
const result = assignRef(ctx, node.i, new AggregateError([], node.m));
const result = assignIndexedValue(ctx, node.i, new AggregateError([], invQuote(node.m)));
ctx.stack.push(node.i);

@@ -181,3 +186,3 @@ result.errors = deserializeNodeList(ctx, node, new Array<AsyncServerValue>(node.l));

const ErrorConstructor = getErrorConstructor(node.c);
const result = assignRef(ctx, node.i, new ErrorConstructor(node.m));
const result = assignIndexedValue(ctx, node.i, new ErrorConstructor(invQuote(node.m)));
return deserializeDictionary(ctx, node, result);

@@ -187,4 +192,4 @@ }

interface Deferred {
resolve(value: AsyncServerValue): void;
promise: Promise<AsyncServerValue>;
resolve(value: unknown): void;
promise: Promise<unknown>;
}

@@ -209,3 +214,3 @@

const deferred = createDeferred();
const result = assignRef(ctx, node.i, deferred.promise);
const result = assignIndexedValue(ctx, node.i, deferred.promise);
deferred.resolve(deserializeTree(ctx, node.f));

@@ -221,3 +226,3 @@ return result;

const dummy = new TypedArray();
const result = assignRef(ctx, node.i, new TypedArray(
const result = assignIndexedValue(ctx, node.i, new TypedArray(
dummy.buffer,

@@ -240,3 +245,3 @@ node.l,

deserializeNodeList(ctx, node, values);
const result = assignRef(ctx, node.i, {
const result = assignIndexedValue(ctx, node.i, {
[Symbol.iterator]: () => values.values(),

@@ -250,3 +255,3 @@ });

node: SerovalNode,
): AsyncServerValue {
): unknown {
switch (node.t) {

@@ -272,3 +277,3 @@ case SerovalNodeType.Number:

return BigInt(node.s);
case SerovalNodeType.Reference:
case SerovalNodeType.IndexedValue:
return ctx.valueMap.get(node.i);

@@ -282,5 +287,5 @@ case SerovalNodeType.Array:

case SerovalNodeType.Date:
return assignRef(ctx, node.i, new Date(node.s));
return assignIndexedValue(ctx, node.i, new Date(node.s));
case SerovalNodeType.RegExp:
return assignRef(ctx, node.i, new RegExp(node.c, node.m));
return assignIndexedValue(ctx, node.i, new RegExp(node.c, node.m));
case SerovalNodeType.Set:

@@ -303,2 +308,8 @@ return deserializeSet(ctx, node);

return SYMBOL_REF[node.s];
case SerovalNodeType.URL:
return assignIndexedValue(ctx, node.i, new URL(node.s));
case SerovalNodeType.URLSearchParams:
return assignIndexedValue(ctx, node.i, new URLSearchParams(node.s));
case SerovalNodeType.Reference:
return assignIndexedValue(ctx, node.i, getReference(invQuote(node.s)));
default:

@@ -305,0 +316,0 @@ throw new Error('Unsupported type');

@@ -6,2 +6,3 @@ import assert from '../assert';

import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
import { getReferenceID } from './reference';
import { INV_SYMBOL_REF, WellKnownSymbols } from './symbols';

@@ -20,3 +21,3 @@ import {

SerovalNumberNode,
SerovalReferenceNode,
SerovalIndexedValueNode,
SerovalRegExpNode,

@@ -27,2 +28,3 @@ SerovalStringNode,

SerovalWKSymbolNode,
SerovalReferenceNode,
} from './types';

@@ -165,5 +167,5 @@

export function createReferenceNode(id: number): SerovalReferenceNode {
export function createIndexedValueNode(id: number): SerovalIndexedValueNode {
return {
t: SerovalNodeType.Reference,
t: SerovalNodeType.IndexedValue,
i: id,

@@ -264,4 +266,7 @@ s: undefined,

export function createWKSymbolNode(
ctx: ParserContext,
current: WellKnownSymbols,
): SerovalWKSymbolNode {
assert(ctx.features & Feature.Symbol, 'Unsupported type "symbol"');
assert(current in INV_SYMBOL_REF, 'seroval only supports well-known symbols');
return {

@@ -279,1 +284,18 @@ t: SerovalNodeType.WKSymbol,

}
export function createReferenceNode<T>(
id: number,
ref: T,
): SerovalReferenceNode {
return {
t: SerovalNodeType.Reference,
i: id,
s: quote(getReferenceID(ref)),
l: undefined,
c: undefined,
m: undefined,
d: undefined,
a: undefined,
f: undefined,
};
}

@@ -10,2 +10,3 @@ /* eslint-disable @typescript-eslint/no-use-before-define */

import quote from '../quote';
import { GLOBAL_KEY } from './reference';
import { isValidIdentifier } from './shared';

@@ -26,3 +27,3 @@ import { SYMBOL_STRING } from './symbols';

SerovalPromiseNode,
SerovalReferenceNode,
SerovalIndexedValueNode,
SerovalSetNode,

@@ -199,3 +200,3 @@ SerovalTypedArrayNode,

function assignRef(
function assignIndexedValue(
ctx: SerializationContext,

@@ -211,7 +212,7 @@ index: number,

function isReferenceInStack(
function isIndexedValueInStack(
ctx: SerializationContext,
node: SerovalNode,
): node is SerovalReferenceNode {
return node.t === SerovalNodeType.Reference && ctx.stack.includes(node.i);
): node is SerovalIndexedValueNode {
return node.t === SerovalNodeType.IndexedValue && ctx.stack.includes(node.i);
}

@@ -239,3 +240,3 @@

// Check if item is a parent
if (isReferenceInStack(ctx, item)) {
if (isIndexedValueInStack(ctx, item)) {
createArrayAssign(ctx, node.i, i, getRefParam(ctx, item.i));

@@ -261,3 +262,3 @@ isHoley = true;

ctx.stack.pop();
return assignRef(ctx, node.i, result);
return assignIndexedValue(ctx, node.i, result);
}

@@ -288,3 +289,3 @@

isIdentifier = check >= 0 || isValidIdentifier(key);
if (isReferenceInStack(ctx, val)) {
if (isIndexedValueInStack(ctx, val)) {
refParam = getRefParam(ctx, val.i);

@@ -369,7 +370,7 @@ if (isIdentifier && Number.isNaN(check)) {

if (assignments) {
return '(' + assignRef(ctx, i, init) + ',' + assignments + getRefParam(ctx, i) + ')';
return '(' + assignIndexedValue(ctx, i, init) + ',' + assignments + getRefParam(ctx, i) + ')';
}
}
}
return assignRef(ctx, i, init);
return assignIndexedValue(ctx, i, init);
}

@@ -388,3 +389,3 @@

) {
return assignRef(ctx, node.i, serializeProperties(ctx, node.i, node.d));
return assignIndexedValue(ctx, node.i, serializeProperties(ctx, node.i, node.d));
}

@@ -405,3 +406,3 @@

item = node.a[i];
if (isReferenceInStack(ctx, item)) {
if (isIndexedValueInStack(ctx, item)) {
createSetAdd(ctx, node.i, getRefParam(ctx, item.i));

@@ -419,3 +420,3 @@ } else {

}
return assignRef(ctx, node.i, serialized);
return assignIndexedValue(ctx, node.i, serialized);
}

@@ -441,7 +442,7 @@

val = node.d.v[i];
if (isReferenceInStack(ctx, key)) {
if (isIndexedValueInStack(ctx, key)) {
// Create reference for the map instance
keyRef = getRefParam(ctx, key.i);
// Check if value is a parent
if (isReferenceInStack(ctx, val)) {
if (isIndexedValueInStack(ctx, val)) {
valueRef = getRefParam(ctx, val.i);

@@ -463,3 +464,3 @@ // Register an assignment since

}
} else if (isReferenceInStack(ctx, val)) {
} else if (isIndexedValueInStack(ctx, val)) {
// Create ref for the Map instance

@@ -485,3 +486,3 @@ valueRef = getRefParam(ctx, val.i);

}
return assignRef(ctx, node.i, serialized);
return assignIndexedValue(ctx, node.i, serialized);
}

@@ -517,3 +518,3 @@

// Check if resolved value is a parent expression
if (isReferenceInStack(ctx, node.f)) {
if (isIndexedValueInStack(ctx, node.f)) {
// A Promise trick, reference the value

@@ -536,3 +537,3 @@ // inside the `then` expression so that

}
return assignRef(ctx, node.i, serialized);
return assignIndexedValue(ctx, node.i, serialized);
}

@@ -550,3 +551,3 @@

const args = '[' + result + ']' + (node.l !== 0 ? (',' + node.l) : '');
return assignRef(ctx, node.i, 'new ' + node.c + '(' + args + ')');
return assignIndexedValue(ctx, node.i, 'new ' + node.c + '(' + args + ')');
}

@@ -603,3 +604,3 @@

return node.s + 'n';
case SerovalNodeType.Reference:
case SerovalNodeType.IndexedValue:
return getRefParam(ctx, node.i);

@@ -613,5 +614,5 @@ case SerovalNodeType.Array:

case SerovalNodeType.Date:
return assignRef(ctx, node.i, 'new Date("' + node.s + '")');
return assignIndexedValue(ctx, node.i, 'new Date("' + node.s + '")');
case SerovalNodeType.RegExp:
return assignRef(ctx, node.i, '/' + node.c + '/' + node.m);
return assignIndexedValue(ctx, node.i, '/' + node.c + '/' + node.m);
case SerovalNodeType.Set:

@@ -634,2 +635,8 @@ return serializeSet(ctx, node);

return SYMBOL_STRING[node.s];
case SerovalNodeType.URL:
return assignIndexedValue(ctx, node.i, 'new URL("' + node.s + '")');
case SerovalNodeType.URLSearchParams:
return assignIndexedValue(ctx, node.i, node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams');
case SerovalNodeType.Reference:
return assignIndexedValue(ctx, node.i, GLOBAL_KEY + '.get("' + node.s + '")');
default:

@@ -636,0 +643,0 @@ throw new Error('Unsupported type');

/* eslint-disable @typescript-eslint/no-use-before-define */
import assert from '../assert';
import { Feature } from '../compat';
import { createRef, getRootID, ParserContext } from '../context';
import { BigIntTypedArrayValue, ServerValue, TypedArrayValue } from '../types';
import { createIndexedValue, getRootID, ParserContext } from '../context';
import quote from '../quote';
import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
import {

@@ -11,3 +12,3 @@ createBigIntNode,

createNumberNode,
createReferenceNode,
createIndexedValueNode,
createRegExpNode,

@@ -25,4 +26,8 @@ createStringNode,

UNDEFINED_NODE,
createReferenceNode,
} from './primitives';
import {
hasReferenceID,
} from './reference';
import {
getErrorConstructorName,

@@ -33,3 +38,3 @@ getErrorOptions,

} from './shared';
import { INV_SYMBOL_REF } from './symbols';
import { WellKnownSymbols } from './symbols';
import {

@@ -48,10 +53,11 @@ SerovalAggregateErrorNode,

} from './types';
import { createURLNode, createURLSearchParamsNode } from './web-api';
type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode | SerovalIterableNode;
function generateNodeList(ctx: ParserContext, current: ServerValue[]) {
function generateNodeList(ctx: ParserContext, current: unknown[]) {
const size = current.length;
const nodes = new Array<SerovalNode>(size);
const deferred = new Array<ServerValue>(size);
let item: ServerValue;
const deferred = new Array<unknown>(size);
let item: unknown;
for (let i = 0; i < size; i++) {

@@ -78,3 +84,3 @@ if (i in current) {

id: number,
current: ServerValue[],
current: unknown[],
): SerovalArrayNode {

@@ -97,3 +103,3 @@ return {

id: number,
current: Map<ServerValue, ServerValue>,
current: Map<unknown, unknown>,
): SerovalMapNode {

@@ -104,4 +110,4 @@ assert(ctx.features & Feature.Map, 'Unsupported type "Map"');

const valueNodes = new Array<SerovalNode>(len);
const deferredKey = new Array<ServerValue>(len);
const deferredValue = new Array<ServerValue>(len);
const deferredKey = new Array<unknown>(len);
const deferredValue = new Array<unknown>(len);
let deferredSize = 0;

@@ -141,3 +147,3 @@ let nodeSize = 0;

id: number,
current: Set<ServerValue>,
current: Set<unknown>,
): SerovalSetNode {

@@ -147,3 +153,3 @@ assert(ctx.features & Feature.Set, 'Unsupported type "Set"');

const nodes = new Array<SerovalNode>(len);
const deferred = new Array<ServerValue>(len);
const deferred = new Array<unknown>(len);
let deferredSize = 0;

@@ -178,3 +184,3 @@ let nodeSize = 0;

ctx: ParserContext,
properties: Record<string, ServerValue>,
properties: Record<string, unknown>,
): SerovalObjectRecordNode {

@@ -186,6 +192,6 @@ const keys = Object.keys(properties);

const deferredKeys = new Array<string>(size);
const deferredValues = new Array<ServerValue>(size);
const deferredValues = new Array<unknown>(size);
let deferredSize = 0;
let nodesSize = 0;
let item: ServerValue;
let item: unknown;
for (const key of keys) {

@@ -217,3 +223,3 @@ item = properties[key];

id: number,
current: Iterable<ServerValue>,
current: Iterable<unknown>,
): SerovalIterableNode {

@@ -232,3 +238,3 @@ assert(ctx.features & Feature.Symbol, 'Unsupported type "Iterable"');

d: options
? generateProperties(ctx, options as Record<string, ServerValue>)
? generateProperties(ctx, options)
: undefined,

@@ -243,3 +249,3 @@ a: generateNodeList(ctx, array),

id: number,
current: Record<string, ServerValue> | Iterable<ServerValue>,
current: Record<string, unknown> | Iterable<unknown>,
empty: boolean,

@@ -278,5 +284,5 @@ ): ObjectLikeNode {

c: undefined,
m: current.message,
m: quote(current.message),
d: optionsNode,
a: generateNodeList(ctx, current.errors as ServerValue[]),
a: generateNodeList(ctx, current.errors as unknown[]),
f: undefined,

@@ -301,3 +307,3 @@ };

c: getErrorConstructorName(current),
m: current.message,
m: quote(current.message),
d: optionsNode,

@@ -309,5 +315,5 @@ a: undefined,

function parse(
function parse<T>(
ctx: ParserContext,
current: ServerValue,
current: T,
): SerovalNode {

@@ -325,12 +331,12 @@ switch (typeof current) {

case -Infinity: return NEG_INFINITY_NODE;
default: break;
default:
// eslint-disable-next-line no-self-compare
if (current !== current) {
return NAN_NODE;
}
if (Object.is(current, -0)) {
return NEG_ZERO_NODE;
}
return createNumberNode(current);
}
// eslint-disable-next-line no-self-compare
if (current !== current) {
return NAN_NODE;
}
if (Object.is(current, -0)) {
return NEG_ZERO_NODE;
}
return createNumberNode(current);
case 'bigint':

@@ -344,6 +350,9 @@ return createBigIntNode(ctx, current);

// mostly because the values themselves are stateful
const id = createRef(ctx, current);
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createReferenceNode(id);
return createIndexedValueNode(id);
}
if (hasReferenceID(current)) {
return createReferenceNode(id, current);
}
if (Array.isArray(current)) {

@@ -354,5 +363,5 @@ return generateArrayNode(ctx, id, current);

case Date:
return createDateNode(id, current as Date);
return createDateNode(id, current as unknown as Date);
case RegExp:
return createRegExpNode(id, current as RegExp);
return createRegExpNode(id, current as unknown as RegExp);
case Int8Array:

@@ -367,19 +376,29 @@ case Int16Array:

case Float64Array:
return createTypedArrayNode(ctx, id, current as TypedArrayValue);
return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
case BigInt64Array:
case BigUint64Array:
return createBigIntTypedArrayNode(ctx, id, current as BigIntTypedArrayValue);
return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
case Map:
return generateMapNode(ctx, id, current as Map<ServerValue, ServerValue>);
return generateMapNode(ctx, id, current as unknown as Map<unknown, unknown>);
case Set:
return generateSetNode(ctx, id, current as Set<ServerValue>);
return generateSetNode(ctx, id, current as unknown as Set<unknown>);
case Object:
return generateObjectNode(ctx, id, current as Record<string, ServerValue>, false);
return generateObjectNode(
ctx,
id,
current as unknown as Record<string, unknown>,
false,
);
case undefined:
return generateObjectNode(ctx, id, current as Record<string, ServerValue>, true);
return generateObjectNode(
ctx,
id,
current as unknown as Record<string, unknown>,
true,
);
case AggregateError:
if (ctx.features & Feature.AggregateError) {
return generateAggregateErrorNode(ctx, id, current as AggregateError);
return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
}
return generateErrorNode(ctx, id, current as AggregateError);
return generateErrorNode(ctx, id, current as unknown as AggregateError);
case Error:

@@ -392,3 +411,7 @@ case EvalError:

case URIError:
return generateErrorNode(ctx, id, current as Error);
return generateErrorNode(ctx, id, current as unknown as Error);
case URL:
return createURLNode(ctx, id, current as unknown as URL);
case URLSearchParams:
return createURLSearchParamsNode(ctx, id, current as unknown as URLSearchParams);
default:

@@ -408,3 +431,3 @@ break;

if (Symbol.iterator in current) {
return generateIterableNode(ctx, id, current);
return generateIterableNode(ctx, id, current as Iterable<unknown>);
}

@@ -414,5 +437,18 @@ throw new Error('Unsupported type');

case 'symbol':
assert(ctx.features & Feature.Symbol, 'Unsupported type "symbol"');
assert(current in INV_SYMBOL_REF, 'seroval only supports well-known symbols');
return createWKSymbolNode(current);
if (hasReferenceID(current)) {
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createIndexedValueNode(id);
}
return createReferenceNode(id, current);
}
return createWKSymbolNode(ctx, current as WellKnownSymbols);
case 'function': {
assert(hasReferenceID(current), 'Cannot serialize function without reference ID.');
const id = createIndexedValue(ctx, current);
if (ctx.markedRefs.has(id)) {
return createIndexedValueNode(id);
}
return createReferenceNode(id, current);
}
default:

@@ -423,5 +459,5 @@ throw new Error('Unsupported type');

export default function parseSync(
export default function parseSync<T>(
ctx: ParserContext,
current: ServerValue,
current: T,
) {

@@ -428,0 +464,0 @@ const result = parse(ctx, current);

@@ -14,3 +14,3 @@ import { Symbols } from './symbols';

BigInt,
Reference,
IndexedValue,
Date,

@@ -30,2 +30,5 @@ RegExp,

WKSymbol,
URL,
URLSearchParams,
Reference,
}

@@ -120,4 +123,4 @@

export interface SerovalReferenceNode extends SerovalBaseNode {
t: SerovalNodeType.Reference;
export interface SerovalIndexedValueNode extends SerovalBaseNode {
t: SerovalNodeType.IndexedValue;
i: number;

@@ -237,5 +240,23 @@ }

export interface SerovalURLNode extends SerovalBaseNode {
t: SerovalNodeType.URL;
i: number;
s: string;
}
export interface SerovalURLSearchParamsNode extends SerovalBaseNode {
t: SerovalNodeType.URLSearchParams;
i: number;
s: string;
}
export interface SerovalReferenceNode extends SerovalBaseNode {
t: SerovalNodeType.Reference;
i: number;
s: string;
}
export type SerovalNode =
| SerovalPrimitiveNode
| SerovalReferenceNode
| SerovalIndexedValueNode
| SerovalSemiPrimitiveNode

@@ -251,2 +272,5 @@ | SerovalSetNode

| SerovalIterableNode
| SerovalWKSymbolNode;
| SerovalWKSymbolNode
| SerovalURLNode
| SerovalURLSearchParamsNode
| SerovalReferenceNode;

@@ -37,2 +37,6 @@ import { WellKnownSymbols } from './tree/symbols';

export type WebAPIValue =
| URL
| URLSearchParams;
export type SemiPrimitiveValue =

@@ -43,3 +47,4 @@ | RegExp

| BigIntTypedArrayValue
| bigint;
| bigint
| WebAPIValue;

@@ -46,0 +51,0 @@ export type CommonServerValue =

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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