Comparing version 0.4.0-alpha.12 to 0.4.0-alpha.13
@@ -18,25 +18,25 @@ interface IndexAssignment { | ||
export type Assignment = IndexAssignment | MapAssignment | SetAssignment; | ||
export interface ParserContext { | ||
export interface Options { | ||
target: string | string[]; | ||
} | ||
export declare class ParserContext { | ||
refs: Map<unknown, number>; | ||
markedRefs: Record<number, number>; | ||
features: number; | ||
constructor(options?: Partial<Options>); | ||
} | ||
export interface SerializationContext { | ||
export interface SerializationOptions { | ||
markedRefs: Record<number, number>; | ||
features: number; | ||
} | ||
export declare class SerializationContext { | ||
stack: number[]; | ||
validRefs: number[]; | ||
refSize: number; | ||
markedRefs: Record<number, number>; | ||
vars: string[]; | ||
assignments: Assignment[]; | ||
features: number; | ||
} | ||
export interface Options { | ||
target: string | string[]; | ||
} | ||
export declare function createParserContext(options?: Partial<Options>): ParserContext; | ||
export interface SerializationOptions { | ||
markedRefs: Record<number, number>; | ||
features: number; | ||
constructor(options: SerializationOptions); | ||
} | ||
export declare function createSerializationContext(options: SerializationOptions): SerializationContext; | ||
/** | ||
@@ -43,0 +43,0 @@ * Increments the number of references the referenced value has |
@@ -1,5 +0,2 @@ | ||
import { ParserContext } from '../context'; | ||
import { BigIntTypedArrayValue, TypedArrayValue } from '../types'; | ||
import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalDateNode, SerovalPrimitiveNode, SerovalReferenceNode, SerovalRegExpNode, SerovalTypedArrayNode } from './types'; | ||
export declare function createPrimitiveNode(value: string | number | null): SerovalPrimitiveNode; | ||
import { SerovalPrimitiveNode } from './types'; | ||
export declare const TRUE_NODE: SerovalPrimitiveNode; | ||
@@ -12,7 +9,1 @@ export declare const FALSE_NODE: SerovalPrimitiveNode; | ||
export declare const NEG_INFINITY_NODE: SerovalPrimitiveNode; | ||
export declare function createBigIntNode(ctx: ParserContext, current: bigint): SerovalBigIntNode; | ||
export declare function createReferenceNode(id: number): SerovalReferenceNode; | ||
export declare function createDateNode(id: number, current: Date): SerovalDateNode; | ||
export declare function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode; | ||
export declare function createTypedArrayNode(ctx: ParserContext, id: number, current: TypedArrayValue): SerovalTypedArrayNode; | ||
export declare function createBigIntTypedArrayNode(ctx: ParserContext, id: number, current: BigIntTypedArrayValue): SerovalBigIntTypedArrayNode; |
@@ -1,2 +0,2 @@ | ||
import { PrimitiveValue } from '../types'; | ||
import { BigIntTypedArrayValue, PrimitiveValue, TypedArrayValue } from '../types'; | ||
export declare const enum SerovalNodeType { | ||
@@ -21,45 +21,53 @@ Primitive = 0, | ||
export interface SerovalBaseNode { | ||
t: SerovalNodeType; | ||
s: PrimitiveValue | undefined; | ||
i: number | undefined; | ||
l: number | undefined; | ||
c: string | undefined; | ||
d: SerovalDictionaryNode | undefined; | ||
m: string | undefined; | ||
n: SerovalNode | undefined; | ||
a: SerovalNode[] | undefined; | ||
t?: SerovalNodeType; | ||
s?: PrimitiveValue; | ||
i?: number; | ||
l?: number; | ||
c?: string; | ||
d?: SerovalDictionaryNode; | ||
m?: string; | ||
n?: SerovalNode; | ||
a?: SerovalNode[]; | ||
} | ||
export interface SerovalObjectRecordNode { | ||
export declare class SerovalObjectRecordNode { | ||
k: string[]; | ||
v: SerovalNode[]; | ||
s: number; | ||
constructor(k: string[], v: SerovalNode[], s: number); | ||
} | ||
export interface SerovalMapRecordNode { | ||
export declare class SerovalMapRecordNode { | ||
k: SerovalNode[]; | ||
v: SerovalNode[]; | ||
s: number; | ||
constructor(k: SerovalNode[], v: SerovalNode[], s: number); | ||
} | ||
export type SerovalDictionaryNode = SerovalObjectRecordNode | SerovalMapRecordNode; | ||
export interface SerovalPrimitiveNode extends SerovalBaseNode { | ||
export declare class SerovalPrimitiveNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Primitive; | ||
s: string | number | null; | ||
constructor(current: string | number | null); | ||
} | ||
export interface SerovalReferenceNode extends SerovalBaseNode { | ||
export declare class SerovalReferenceNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Reference; | ||
i: number; | ||
constructor(id: number); | ||
} | ||
export interface SerovalBigIntNode extends SerovalBaseNode { | ||
export declare class SerovalBigIntNode implements SerovalBaseNode { | ||
t: SerovalNodeType.BigInt; | ||
s: string; | ||
constructor(current: bigint); | ||
} | ||
export interface SerovalDateNode extends SerovalBaseNode { | ||
export declare class SerovalDateNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Date; | ||
i: number; | ||
s: string; | ||
constructor(id: number, current: Date); | ||
} | ||
export interface SerovalRegExpNode extends SerovalBaseNode { | ||
export declare class SerovalRegExpNode implements SerovalBaseNode { | ||
t: SerovalNodeType.RegExp; | ||
i: number; | ||
s: string; | ||
constructor(id: number, current: RegExp); | ||
} | ||
export interface SerovalTypedArrayNode extends SerovalBaseNode { | ||
export declare class SerovalTypedArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.TypedArray; | ||
@@ -70,4 +78,5 @@ i: number; | ||
c: string; | ||
constructor(id: number, current: TypedArrayValue); | ||
} | ||
export interface SerovalBigIntTypedArrayNode extends SerovalBaseNode { | ||
export declare class SerovalBigIntTypedArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.BigIntTypedArray; | ||
@@ -78,54 +87,64 @@ i: number; | ||
c: string; | ||
constructor(id: number, current: BigIntTypedArrayValue); | ||
} | ||
export type SerovalSemiPrimitiveNode = SerovalBigIntNode | SerovalDateNode | SerovalRegExpNode | SerovalTypedArrayNode | SerovalBigIntTypedArrayNode; | ||
export interface SerovalSetNode extends SerovalBaseNode { | ||
export declare class SerovalSetNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Set; | ||
i: number; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, a: SerovalNode[]); | ||
} | ||
export interface SerovalMapNode extends SerovalBaseNode { | ||
export declare class SerovalMapNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Map; | ||
i: number; | ||
d: SerovalMapRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalMapRecordNode); | ||
} | ||
export interface SerovalArrayNode extends SerovalBaseNode { | ||
export declare class SerovalArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Array; | ||
i: number; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, a: SerovalNode[]); | ||
} | ||
export interface SerovalObjectNode extends SerovalBaseNode { | ||
export declare class SerovalObjectNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Object; | ||
i: number; | ||
d: SerovalObjectRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode); | ||
} | ||
export interface SerovalNullConstructorNode extends SerovalBaseNode { | ||
export declare class SerovalNullConstructorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.NullConstructor; | ||
i: number; | ||
d: SerovalObjectRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode); | ||
} | ||
export interface SerovalPromiseNode extends SerovalBaseNode { | ||
export declare class SerovalPromiseNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Promise; | ||
i: number; | ||
n: SerovalNode; | ||
i: number; | ||
constructor(id: number, n: SerovalNode); | ||
} | ||
export interface SerovalErrorNode extends SerovalBaseNode { | ||
export declare class SerovalErrorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Error; | ||
i: number; | ||
c: string; | ||
m: string; | ||
d: SerovalObjectRecordNode | undefined; | ||
i: number; | ||
constructor(id: number, c: string, m: string, d: SerovalObjectRecordNode | undefined); | ||
} | ||
export interface SerovalAggregateErrorNode extends SerovalBaseNode { | ||
export declare class SerovalAggregateErrorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.AggregateError; | ||
i: number; | ||
m: string; | ||
d: SerovalObjectRecordNode | undefined; | ||
n: SerovalNode; | ||
i: number; | ||
constructor(id: number, m: string, d: SerovalObjectRecordNode | undefined, n: SerovalNode); | ||
} | ||
export interface SerovalIterableNode extends SerovalBaseNode { | ||
export declare class SerovalIterableNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Iterable; | ||
i: number; | ||
d: SerovalObjectRecordNode | undefined; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode | undefined, a: SerovalNode[]); | ||
} | ||
export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode; |
{ | ||
"name": "seroval", | ||
"type": "module", | ||
"version": "0.4.0-alpha.12", | ||
"version": "0.4.0-alpha.13", | ||
"files": [ | ||
@@ -67,3 +67,3 @@ "dist", | ||
}, | ||
"gitHead": "1154b39e7437e0f6bf9e1c3e814917bd308a2154" | ||
"gitHead": "3f71e898ce27170bade38120eddc9afe96390498" | ||
} |
@@ -0,1 +1,3 @@ | ||
/* eslint-disable prefer-object-spread */ | ||
/* eslint-disable max-classes-per-file */ | ||
import { parseTargets } from './compat'; | ||
@@ -29,23 +31,2 @@ import getIdentifier from './get-identifier'; | ||
export interface ParserContext { | ||
refs: Map<unknown, number>; | ||
markedRefs: Record<number, number>; | ||
features: number; | ||
} | ||
export interface SerializationContext { | ||
stack: number[]; | ||
// Map tree refs to actual refs | ||
validRefs: number[]; | ||
refSize: number; | ||
// Refs that are...referenced | ||
markedRefs: Record<number, number>; | ||
// Variables | ||
vars: string[]; | ||
// Array of assignments to be done (used for recursion) | ||
assignments: Assignment[]; | ||
// Supported features | ||
features: number; | ||
} | ||
export interface Options { | ||
@@ -59,10 +40,13 @@ target: string | string[]; | ||
export function createParserContext(options: Partial<Options> = {}): ParserContext { | ||
// eslint-disable-next-line prefer-object-spread | ||
const result = Object.assign({}, DEFAULT_OPTIONS, options || {}); | ||
return { | ||
markedRefs: {}, | ||
refs: new Map(), | ||
features: parseTargets(result.target), | ||
}; | ||
export class ParserContext { | ||
refs = new Map<unknown, number>(); | ||
markedRefs: Record<number, number> = {}; | ||
features: number; | ||
constructor(options: Partial<Options> = {}) { | ||
const result = Object.assign({}, DEFAULT_OPTIONS, options || {}); | ||
this.features = parseTargets(result.target); | ||
} | ||
} | ||
@@ -75,12 +59,26 @@ | ||
export function createSerializationContext(options: SerializationOptions): SerializationContext { | ||
return { | ||
stack: [], | ||
vars: [], | ||
assignments: [], | ||
validRefs: [], | ||
refSize: 0, | ||
features: options.features, | ||
markedRefs: options.markedRefs, | ||
}; | ||
export class SerializationContext { | ||
stack: number[] = []; | ||
// Map tree refs to actual refs | ||
validRefs: number[] = []; | ||
refSize = 0; | ||
// Variables | ||
vars: string[] = []; | ||
// Array of assignments to be done (used for recursion) | ||
assignments: Assignment[] = []; | ||
// Supported features | ||
features: number; | ||
// Refs that are...referenced | ||
markedRefs: Record<number, number>; | ||
constructor(options: SerializationOptions) { | ||
this.features = options.features; | ||
this.markedRefs = options.markedRefs; | ||
} | ||
} | ||
@@ -87,0 +85,0 @@ |
@@ -7,4 +7,3 @@ /* eslint-disable no-await-in-loop */ | ||
Options, | ||
createParserContext, | ||
createSerializationContext, | ||
ParserContext, | ||
} from './context'; | ||
@@ -74,5 +73,5 @@ import parseAsync from './tree/async'; | ||
) { | ||
const ctx = createParserContext(options); | ||
const ctx = new ParserContext(options); | ||
const [tree, rootID, isObject] = parseSync(ctx, source); | ||
const serial = createSerializationContext(ctx); | ||
const serial = new SerializationContext(ctx); | ||
const result = serializeTree(serial, tree); | ||
@@ -86,5 +85,5 @@ return finalize(serial, rootID, isObject, result); | ||
) { | ||
const ctx = createParserContext(options); | ||
const ctx = new ParserContext(options); | ||
const [tree, rootID, isObject] = await parseAsync(ctx, source); | ||
const serial = createSerializationContext(ctx); | ||
const serial = new SerializationContext(ctx); | ||
const result = serializeTree(serial, tree); | ||
@@ -111,3 +110,3 @@ return finalize(serial, rootID, isObject, result); | ||
) { | ||
const ctx = createParserContext(options); | ||
const ctx = new ParserContext(options); | ||
const [tree, root, isObject] = parseSync(ctx, source); | ||
@@ -127,3 +126,3 @@ return JSON.stringify([ | ||
) { | ||
const ctx = createParserContext(options); | ||
const ctx = new ParserContext(options); | ||
const [tree, root, isObject] = await parseAsync(ctx, source); | ||
@@ -141,3 +140,3 @@ return JSON.stringify([ | ||
const parsed = JSON.parse(source) as SerovalJSON; | ||
const serial = createSerializationContext({ | ||
const serial = new SerializationContext({ | ||
features: parsed[3], | ||
@@ -144,0 +143,0 @@ markedRefs: parsed[4], |
@@ -13,10 +13,5 @@ /* eslint-disable no-await-in-loop */ | ||
import { | ||
createBigIntNode, | ||
createBigIntTypedArrayNode, | ||
createDateNode, | ||
createPrimitiveNode, | ||
createReferenceNode, | ||
createRegExpNode, | ||
createTypedArrayNode, | ||
FALSE_NODE, | ||
INFINITY_NODE, | ||
NEG_INFINITY_NODE, | ||
NEG_ZERO_NODE, | ||
@@ -36,5 +31,9 @@ NULL_NODE, | ||
SerovalArrayNode, | ||
SerovalBigIntNode, | ||
SerovalBigIntTypedArrayNode, | ||
SerovalDateNode, | ||
SerovalErrorNode, | ||
SerovalIterableNode, | ||
SerovalMapNode, | ||
SerovalMapRecordNode, | ||
SerovalNode, | ||
@@ -45,4 +44,8 @@ SerovalNodeType, | ||
SerovalObjectRecordNode, | ||
SerovalPrimitiveNode, | ||
SerovalPromiseNode, | ||
SerovalReferenceNode, | ||
SerovalRegExpNode, | ||
SerovalSetNode, | ||
SerovalTypedArrayNode, | ||
} from './types'; | ||
@@ -97,13 +100,3 @@ | ||
): Promise<SerovalArrayNode> { | ||
return { | ||
t: SerovalNodeType.Array, | ||
i: id, | ||
a: await this.generateNodeList(current), | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
return new SerovalArrayNode(id, await this.generateNodeList(current)); | ||
} | ||
@@ -139,13 +132,3 @@ | ||
} | ||
return { | ||
t: SerovalNodeType.Map, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: { k: keyNodes, v: valueNodes, s: len }, | ||
n: undefined, | ||
}; | ||
return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len)); | ||
} | ||
@@ -175,13 +158,3 @@ | ||
} | ||
return { | ||
t: SerovalNodeType.Set, | ||
i: id, | ||
a: nodes, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
return new SerovalSetNode(id, nodes); | ||
} | ||
@@ -217,7 +190,3 @@ | ||
} | ||
return { | ||
k: keyNodes, | ||
v: valueNodes, | ||
s: size, | ||
}; | ||
return new SerovalObjectRecordNode(keyNodes, valueNodes, size); | ||
} | ||
@@ -231,16 +200,10 @@ | ||
const options = getIterableOptions(current); | ||
return { | ||
t: SerovalNodeType.Iterable, | ||
i: id, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
return new SerovalIterableNode( | ||
id, | ||
// Parse options first before the items | ||
d: options | ||
options | ||
? await this.generateProperties(options as Record<string, AsyncServerValue>) | ||
: undefined, | ||
a: await this.generateNodeList(Array.from(current)), | ||
n: undefined, | ||
}; | ||
await this.generateNodeList(Array.from(current)), | ||
); | ||
} | ||
@@ -253,14 +216,3 @@ | ||
assert(this.ctx.features & Feature.Promise, 'Unsupported type "Promise"'); | ||
return current.then(async (value) => ({ | ||
t: SerovalNodeType.Promise, | ||
i: id, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
// Parse options first before the items | ||
d: undefined, | ||
a: undefined, | ||
n: await this.parse(value), | ||
})); | ||
return current.then(async (value) => new SerovalPromiseNode(id, await this.parse(value))); | ||
} | ||
@@ -279,13 +231,7 @@ | ||
} | ||
return { | ||
t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object, | ||
i: id, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: await this.generateProperties(current as Record<string, AsyncServerValue>), | ||
a: undefined, | ||
n: undefined, | ||
}; | ||
const properties = await this.generateProperties(current as Record<string, AsyncServerValue>); | ||
if (empty) { | ||
return new SerovalNullConstructorNode(id, properties); | ||
} | ||
return new SerovalObjectNode(id, properties); | ||
} | ||
@@ -301,13 +247,8 @@ | ||
: undefined; | ||
return { | ||
t: SerovalNodeType.AggregateError, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: current.message, | ||
c: undefined, | ||
d: optionsNode, | ||
n: await this.parse(current.errors), | ||
}; | ||
return new SerovalAggregateErrorNode( | ||
id, | ||
current.message, | ||
optionsNode, | ||
await this.parse(current.errors), | ||
); | ||
} | ||
@@ -323,13 +264,3 @@ | ||
: undefined; | ||
return { | ||
t: SerovalNodeType.Error, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: current.message, | ||
c: getErrorConstructor(current), | ||
d: optionsNode, | ||
n: undefined, | ||
}; | ||
return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode); | ||
} | ||
@@ -344,3 +275,3 @@ | ||
case 'string': | ||
return createPrimitiveNode(quote(current)); | ||
return new SerovalPrimitiveNode(quote(current)); | ||
case 'number': | ||
@@ -351,10 +282,11 @@ if (Object.is(current, -0)) { | ||
if (Object.is(current, Infinity)) { | ||
return createPrimitiveNode('1/0'); | ||
return INFINITY_NODE; | ||
} | ||
if (Object.is(current, -Infinity)) { | ||
return createPrimitiveNode('-1/0'); | ||
return NEG_INFINITY_NODE; | ||
} | ||
return createPrimitiveNode(current); | ||
return new SerovalPrimitiveNode(current); | ||
case 'bigint': | ||
return createBigIntNode(this.ctx, current); | ||
assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"'); | ||
return new SerovalBigIntNode(current); | ||
case 'object': { | ||
@@ -368,3 +300,3 @@ if (!current) { | ||
if (this.ctx.markedRefs[id]) { | ||
return createReferenceNode(id); | ||
return new SerovalReferenceNode(id); | ||
} | ||
@@ -376,5 +308,5 @@ if (Array.isArray(current)) { | ||
case Date: | ||
return createDateNode(id, current as Date); | ||
return new SerovalDateNode(id, current as Date); | ||
case RegExp: | ||
return createRegExpNode(id, current as RegExp); | ||
return new SerovalRegExpNode(id, current as RegExp); | ||
case Promise: | ||
@@ -391,6 +323,11 @@ return this.generatePromiseNode(id, current as Promise<AsyncServerValue>); | ||
case Float64Array: | ||
return createTypedArrayNode(this.ctx, id, current as TypedArrayValue); | ||
assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`); | ||
return new SerovalTypedArrayNode(id, current as TypedArrayValue); | ||
case BigInt64Array: | ||
case BigUint64Array: | ||
return createBigIntTypedArrayNode(this.ctx, id, current as BigIntTypedArrayValue); | ||
assert( | ||
this.ctx.features & (Feature.BigIntTypedArray), | ||
`Unsupported value type "${current.constructor.name}"`, | ||
); | ||
return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue); | ||
case Map: | ||
@@ -397,0 +334,0 @@ return this.generateMapNode(id, current as Map<AsyncServerValue, AsyncServerValue>); |
@@ -1,147 +0,11 @@ | ||
import assert from '../assert'; | ||
import { Feature } from '../compat'; | ||
import { ParserContext } from '../context'; | ||
import { BigIntTypedArrayValue, TypedArrayValue } from '../types'; | ||
import { | ||
SerovalBigIntNode, | ||
SerovalBigIntTypedArrayNode, | ||
SerovalDateNode, | ||
SerovalNodeType, | ||
SerovalPrimitiveNode, | ||
SerovalReferenceNode, | ||
SerovalRegExpNode, | ||
SerovalTypedArrayNode, | ||
} from './types'; | ||
export function createPrimitiveNode( | ||
value: string | number | null, | ||
): SerovalPrimitiveNode { | ||
return { | ||
t: SerovalNodeType.Primitive, | ||
i: undefined, | ||
s: value, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
a: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export const TRUE_NODE = createPrimitiveNode('!0'); | ||
export const FALSE_NODE = createPrimitiveNode('!1'); | ||
export const UNDEFINED_NODE = createPrimitiveNode('void 0'); | ||
export const NULL_NODE = createPrimitiveNode(null); | ||
export const NEG_ZERO_NODE = createPrimitiveNode('-0'); | ||
export const INFINITY_NODE = createPrimitiveNode('1/0'); | ||
export const NEG_INFINITY_NODE = createPrimitiveNode('-1/0'); | ||
export function createBigIntNode( | ||
ctx: ParserContext, | ||
current: bigint, | ||
): SerovalBigIntNode { | ||
assert(ctx.features & Feature.BigInt, 'Unsupported type "BigInt"'); | ||
return { | ||
t: SerovalNodeType.BigInt, | ||
i: undefined, | ||
a: undefined, | ||
s: `${current}n`, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export function createReferenceNode(id: number): SerovalReferenceNode { | ||
return { | ||
t: SerovalNodeType.Reference, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export function createDateNode(id: number, current: Date): SerovalDateNode { | ||
return { | ||
t: SerovalNodeType.Date, | ||
i: id, | ||
a: undefined, | ||
s: current.toISOString(), | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode { | ||
return { | ||
t: SerovalNodeType.RegExp, | ||
i: id, | ||
a: undefined, | ||
s: String(current), | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export function createTypedArrayNode( | ||
ctx: ParserContext, | ||
id: number, | ||
current: TypedArrayValue, | ||
): SerovalTypedArrayNode { | ||
const constructor = current.constructor.name; | ||
assert(ctx.features & Feature.TypedArray, `Unsupported value type "${constructor}"`); | ||
return { | ||
t: SerovalNodeType.TypedArray, | ||
i: id, | ||
a: undefined, | ||
s: current.toString(), | ||
l: current.byteOffset, | ||
m: undefined, | ||
c: constructor, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export function createBigIntTypedArrayNode( | ||
ctx: ParserContext, | ||
id: number, | ||
current: BigIntTypedArrayValue, | ||
): SerovalBigIntTypedArrayNode { | ||
const constructor = current.constructor.name; | ||
assert( | ||
ctx.features & (Feature.BigIntTypedArray), | ||
`Unsupported value type "${constructor}"`, | ||
); | ||
let result = ''; | ||
const cap = current.length - 1; | ||
for (let i = 0; i < cap; i++) { | ||
result += `${current[i]}n,`; | ||
} | ||
result += `"${current[cap]}"`; | ||
return { | ||
t: SerovalNodeType.BigIntTypedArray, | ||
i: id, | ||
a: undefined, | ||
s: result, | ||
l: (current as BigInt64Array).byteOffset, | ||
m: undefined, | ||
c: constructor, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
} | ||
export const TRUE_NODE = new SerovalPrimitiveNode('!0'); | ||
export const FALSE_NODE = new SerovalPrimitiveNode('!1'); | ||
export const UNDEFINED_NODE = new SerovalPrimitiveNode('void 0'); | ||
export const NULL_NODE = new SerovalPrimitiveNode(null); | ||
export const NEG_ZERO_NODE = new SerovalPrimitiveNode('-0'); | ||
export const INFINITY_NODE = new SerovalPrimitiveNode('1/0'); | ||
export const NEG_INFINITY_NODE = new SerovalPrimitiveNode('-1/0'); |
@@ -8,10 +8,5 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ | ||
import { | ||
createBigIntNode, | ||
createBigIntTypedArrayNode, | ||
createDateNode, | ||
createPrimitiveNode, | ||
createReferenceNode, | ||
createRegExpNode, | ||
createTypedArrayNode, | ||
FALSE_NODE, | ||
INFINITY_NODE, | ||
NEG_INFINITY_NODE, | ||
NEG_ZERO_NODE, | ||
@@ -31,5 +26,9 @@ NULL_NODE, | ||
SerovalArrayNode, | ||
SerovalBigIntNode, | ||
SerovalBigIntTypedArrayNode, | ||
SerovalDateNode, | ||
SerovalErrorNode, | ||
SerovalIterableNode, | ||
SerovalMapNode, | ||
SerovalMapRecordNode, | ||
SerovalNode, | ||
@@ -40,3 +39,7 @@ SerovalNodeType, | ||
SerovalObjectRecordNode, | ||
SerovalPrimitiveNode, | ||
SerovalReferenceNode, | ||
SerovalRegExpNode, | ||
SerovalSetNode, | ||
SerovalTypedArrayNode, | ||
} from './types'; | ||
@@ -77,13 +80,3 @@ | ||
generateArrayNode(id: number, current: ServerValue[]): SerovalArrayNode { | ||
return { | ||
t: SerovalNodeType.Array, | ||
i: id, | ||
a: this.generateNodeList(current), | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
return new SerovalArrayNode(id, this.generateNodeList(current)); | ||
} | ||
@@ -119,13 +112,3 @@ | ||
} | ||
return { | ||
t: SerovalNodeType.Map, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: { k: keyNodes, v: valueNodes, s: len }, | ||
n: undefined, | ||
}; | ||
return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len)); | ||
} | ||
@@ -155,13 +138,3 @@ | ||
} | ||
return { | ||
t: SerovalNodeType.Set, | ||
i: id, | ||
a: nodes, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: undefined, | ||
n: undefined, | ||
}; | ||
return new SerovalSetNode(id, nodes); | ||
} | ||
@@ -208,16 +181,10 @@ | ||
const options = getIterableOptions(current); | ||
return { | ||
t: SerovalNodeType.Iterable, | ||
i: id, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
return new SerovalIterableNode( | ||
id, | ||
// Parse options first before the items | ||
d: options | ||
options | ||
? this.generateProperties(options as Record<string, ServerValue>) | ||
: undefined, | ||
a: this.generateNodeList(Array.from(current)), | ||
n: undefined, | ||
}; | ||
this.generateNodeList(Array.from(current)), | ||
); | ||
} | ||
@@ -233,13 +200,6 @@ | ||
} | ||
return { | ||
t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object, | ||
i: id, | ||
s: undefined, | ||
l: undefined, | ||
m: undefined, | ||
c: undefined, | ||
d: this.generateProperties(current), | ||
a: undefined, | ||
n: undefined, | ||
}; | ||
if (empty) { | ||
return new SerovalNullConstructorNode(id, this.generateProperties(current)); | ||
} | ||
return new SerovalObjectNode(id, this.generateProperties(current)); | ||
} | ||
@@ -255,13 +215,8 @@ | ||
: undefined; | ||
return { | ||
t: SerovalNodeType.AggregateError, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: current.message, | ||
c: undefined, | ||
d: optionsNode, | ||
n: this.parse(current.errors), | ||
}; | ||
return new SerovalAggregateErrorNode( | ||
id, | ||
current.message, | ||
optionsNode, | ||
this.parse(current.errors), | ||
); | ||
} | ||
@@ -277,13 +232,3 @@ | ||
: undefined; | ||
return { | ||
t: SerovalNodeType.Error, | ||
i: id, | ||
a: undefined, | ||
s: undefined, | ||
l: undefined, | ||
m: current.message, | ||
c: getErrorConstructor(current), | ||
d: optionsNode, | ||
n: undefined, | ||
}; | ||
return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode); | ||
} | ||
@@ -298,3 +243,3 @@ | ||
case 'string': | ||
return createPrimitiveNode(quote(current)); | ||
return new SerovalPrimitiveNode(quote(current)); | ||
case 'number': | ||
@@ -305,10 +250,11 @@ if (Object.is(current, -0)) { | ||
if (Object.is(current, Infinity)) { | ||
return createPrimitiveNode('1/0'); | ||
return INFINITY_NODE; | ||
} | ||
if (Object.is(current, -Infinity)) { | ||
return createPrimitiveNode('-1/0'); | ||
return NEG_INFINITY_NODE; | ||
} | ||
return createPrimitiveNode(current); | ||
return new SerovalPrimitiveNode(current); | ||
case 'bigint': | ||
return createBigIntNode(this.ctx, current); | ||
assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"'); | ||
return new SerovalBigIntNode(current); | ||
case 'object': { | ||
@@ -322,3 +268,3 @@ if (!current) { | ||
if (this.ctx.markedRefs[id]) { | ||
return createReferenceNode(id); | ||
return new SerovalReferenceNode(id); | ||
} | ||
@@ -330,5 +276,5 @@ if (Array.isArray(current)) { | ||
case Date: | ||
return createDateNode(id, current as Date); | ||
return new SerovalDateNode(id, current as Date); | ||
case RegExp: | ||
return createRegExpNode(id, current as RegExp); | ||
return new SerovalRegExpNode(id, current as RegExp); | ||
case Int8Array: | ||
@@ -343,6 +289,11 @@ case Int16Array: | ||
case Float64Array: | ||
return createTypedArrayNode(this.ctx, id, current as TypedArrayValue); | ||
assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`); | ||
return new SerovalTypedArrayNode(id, current as TypedArrayValue); | ||
case BigInt64Array: | ||
case BigUint64Array: | ||
return createBigIntTypedArrayNode(this.ctx, id, current as BigIntTypedArrayValue); | ||
assert( | ||
this.ctx.features & (Feature.BigIntTypedArray), | ||
`Unsupported value type "${current.constructor.name}"`, | ||
); | ||
return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue); | ||
case Map: | ||
@@ -349,0 +300,0 @@ return this.generateMapNode(id, current as Map<ServerValue, ServerValue>); |
@@ -1,2 +0,3 @@ | ||
import { PrimitiveValue } from '../types'; | ||
/* eslint-disable max-classes-per-file */ | ||
import { BigIntTypedArrayValue, PrimitiveValue, TypedArrayValue } from '../types'; | ||
@@ -24,31 +25,47 @@ export const enum SerovalNodeType { | ||
// Type of the node | ||
t: SerovalNodeType; | ||
t?: SerovalNodeType; | ||
// Serialized value | ||
s: PrimitiveValue | undefined; | ||
s?: PrimitiveValue; | ||
// Reference ID | ||
i: number | undefined; | ||
i?: number; | ||
// Size/Byte offset | ||
l: number | undefined; | ||
l?: number; | ||
// Constructor name | ||
c: string | undefined; | ||
c?: string; | ||
// dictionary | ||
d: SerovalDictionaryNode | undefined; | ||
d?: SerovalDictionaryNode; | ||
// message | ||
m: string | undefined; | ||
m?: string; | ||
// next node | ||
n: SerovalNode | undefined; | ||
n?: SerovalNode; | ||
// array of nodes | ||
a: SerovalNode[] | undefined; | ||
a?: SerovalNode[]; | ||
} | ||
export interface SerovalObjectRecordNode { | ||
export class SerovalObjectRecordNode { | ||
k: string[]; | ||
v: SerovalNode[]; | ||
s: number; | ||
constructor(k: string[], v: SerovalNode[], s: number) { | ||
this.k = k; | ||
this.v = v; | ||
this.s = s; | ||
} | ||
} | ||
export interface SerovalMapRecordNode { | ||
export class SerovalMapRecordNode { | ||
k: SerovalNode[]; | ||
v: SerovalNode[]; | ||
s: number; | ||
constructor(k: SerovalNode[], v: SerovalNode[], s: number) { | ||
this.k = k; | ||
this.v = v; | ||
this.s = s; | ||
} | ||
} | ||
@@ -60,42 +77,101 @@ | ||
export interface SerovalPrimitiveNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Primitive; | ||
export class SerovalPrimitiveNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Primitive = SerovalNodeType.Primitive; | ||
s: string | number | null; | ||
constructor(current: string | number | null) { | ||
this.s = current; | ||
} | ||
} | ||
export interface SerovalReferenceNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Reference; | ||
export class SerovalReferenceNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Reference = SerovalNodeType.Reference; | ||
i: number; | ||
constructor(id: number) { | ||
this.i = id; | ||
} | ||
} | ||
export interface SerovalBigIntNode extends SerovalBaseNode { | ||
t: SerovalNodeType.BigInt; | ||
export class SerovalBigIntNode implements SerovalBaseNode { | ||
t: SerovalNodeType.BigInt = SerovalNodeType.BigInt; | ||
s: string; | ||
constructor(current: bigint) { | ||
this.s = `${current}n`; | ||
} | ||
} | ||
export interface SerovalDateNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Date; | ||
export class SerovalDateNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Date = SerovalNodeType.Date; | ||
i: number; | ||
s: string; | ||
constructor(id: number, current: Date) { | ||
this.i = id; | ||
this.s = current.toISOString(); | ||
} | ||
} | ||
export interface SerovalRegExpNode extends SerovalBaseNode { | ||
t: SerovalNodeType.RegExp; | ||
export class SerovalRegExpNode implements SerovalBaseNode { | ||
t: SerovalNodeType.RegExp = SerovalNodeType.RegExp; | ||
i: number; | ||
s: string; | ||
constructor(id: number, current: RegExp) { | ||
this.i = id; | ||
this.s = String(current); | ||
} | ||
} | ||
export interface SerovalTypedArrayNode extends SerovalBaseNode { | ||
t: SerovalNodeType.TypedArray; | ||
export class SerovalTypedArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.TypedArray = SerovalNodeType.TypedArray; | ||
i: number; | ||
s: string; | ||
l: number; | ||
c: string; | ||
constructor(id: number, current: TypedArrayValue) { | ||
this.i = id; | ||
this.s = current.toString(); | ||
this.l = current.byteOffset; | ||
this.c = current.constructor.name; | ||
} | ||
} | ||
export interface SerovalBigIntTypedArrayNode extends SerovalBaseNode { | ||
t: SerovalNodeType.BigIntTypedArray; | ||
export class SerovalBigIntTypedArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.BigIntTypedArray = SerovalNodeType.BigIntTypedArray; | ||
i: number; | ||
s: string; | ||
l: number; | ||
c: string; | ||
constructor(id: number, current: BigIntTypedArrayValue) { | ||
let result = ''; | ||
const cap = current.length - 1; | ||
for (let i = 0; i < cap; i++) { | ||
result += `${current[i]}n,`; | ||
} | ||
result += `"${current[cap]}"`; | ||
this.i = id; | ||
this.s = result; | ||
this.l = current.byteOffset; | ||
this.c = current.constructor.name; | ||
} | ||
} | ||
@@ -110,59 +186,132 @@ | ||
export interface SerovalSetNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Set; | ||
export class SerovalSetNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Set = SerovalNodeType.Set; | ||
i: number; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, a: SerovalNode[]) { | ||
this.i = id; | ||
this.a = a; | ||
} | ||
} | ||
export interface SerovalMapNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Map; | ||
export class SerovalMapNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Map = SerovalNodeType.Map; | ||
i: number; | ||
d: SerovalMapRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalMapRecordNode) { | ||
this.i = id; | ||
this.d = d; | ||
} | ||
} | ||
export interface SerovalArrayNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Array; | ||
export class SerovalArrayNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Array = SerovalNodeType.Array; | ||
i: number; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, a: SerovalNode[]) { | ||
this.i = id; | ||
this.a = a; | ||
} | ||
} | ||
export interface SerovalObjectNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Object; | ||
export class SerovalObjectNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Object = SerovalNodeType.Object; | ||
i: number; | ||
d: SerovalObjectRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode) { | ||
this.i = id; | ||
this.d = d; | ||
} | ||
} | ||
export interface SerovalNullConstructorNode extends SerovalBaseNode { | ||
t: SerovalNodeType.NullConstructor; | ||
export class SerovalNullConstructorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.NullConstructor = SerovalNodeType.NullConstructor; | ||
i: number; | ||
d: SerovalObjectRecordNode; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode) { | ||
this.i = id; | ||
this.d = d; | ||
} | ||
} | ||
export interface SerovalPromiseNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Promise; | ||
export class SerovalPromiseNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Promise = SerovalNodeType.Promise; | ||
i: number; | ||
n: SerovalNode; | ||
i: number; | ||
constructor(id: number, n: SerovalNode) { | ||
this.i = id; | ||
this.n = n; | ||
} | ||
} | ||
export interface SerovalErrorNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Error; | ||
export class SerovalErrorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Error = SerovalNodeType.Error; | ||
i: number; | ||
c: string; | ||
m: string; | ||
d: SerovalObjectRecordNode | undefined; | ||
i: number; | ||
constructor(id: number, c: string, m: string, d: SerovalObjectRecordNode | undefined) { | ||
this.i = id; | ||
this.c = c; | ||
this.m = m; | ||
this.d = d; | ||
} | ||
} | ||
export interface SerovalAggregateErrorNode extends SerovalBaseNode { | ||
t: SerovalNodeType.AggregateError; | ||
export class SerovalAggregateErrorNode implements SerovalBaseNode { | ||
t: SerovalNodeType.AggregateError = SerovalNodeType.AggregateError; | ||
i: number; | ||
m: string; | ||
d: SerovalObjectRecordNode | undefined; | ||
n: SerovalNode; | ||
i: number; | ||
constructor(id: number, m: string, d: SerovalObjectRecordNode | undefined, n: SerovalNode) { | ||
this.i = id; | ||
this.m = m; | ||
this.d = d; | ||
this.n = n; | ||
} | ||
} | ||
export interface SerovalIterableNode extends SerovalBaseNode { | ||
t: SerovalNodeType.Iterable; | ||
export class SerovalIterableNode implements SerovalBaseNode { | ||
t: SerovalNodeType.Iterable = SerovalNodeType.Iterable; | ||
i: number; | ||
d: SerovalObjectRecordNode | undefined; | ||
a: SerovalNode[]; | ||
i: number; | ||
constructor(id: number, d: SerovalObjectRecordNode | undefined, a: SerovalNode[]) { | ||
this.i = id; | ||
this.d = d; | ||
this.a = a; | ||
} | ||
} | ||
@@ -169,0 +318,0 @@ |
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
445959
5942