Skip to content

Commit

Permalink
Call toJSON() on non-ext objects when it exists
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincennis committed Aug 21, 2021
1 parent 9770004 commit b04a351
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import type { ExtData } from "./ExtData";
export const DEFAULT_MAX_DEPTH = 100;
export const DEFAULT_INITIAL_BUFFER_SIZE = 2048;

const hastoJSON = (value: unknown): value is { toJSON: unknown } => {
return typeof value === 'object' && value !== null && 'toJSON' in value;
};

export class Encoder<ContextType = undefined> {
private pos = 0;
private view = new DataView(new ArrayBuffer(this.initialBufferSize));
Expand Down Expand Up @@ -194,7 +198,11 @@ export class Encoder<ContextType = undefined> {
} else if (ArrayBuffer.isView(object)) {
this.encodeBinary(object);
} else if (typeof object === "object") {
this.encodeMap(object as Record<string, unknown>, depth);
if (hastoJSON(object) && typeof object.toJSON === "function") {
this.doEncode(object.toJSON(), depth);
} else {
this.encodeMap(object as Record<string, unknown>, depth);
}
} else {
// symbol, function and other special object come here unless extensionCodec handles them.
throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);
Expand Down
39 changes: 39 additions & 0 deletions test/decodeAsync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,43 @@ describe("decodeAsync", () => {
const object = await decodeAsync(createStream());
assert.deepStrictEqual(object, { "foo": "bar" });
});

it("decodes objects with toJSON methods", async () => {
const object = {
string: "Hello, world!",
nested: {
int: -45,
json: {
toJSON() {
return {
float: Math.PI,
int64: Number.MIN_SAFE_INTEGER,
timestamp: new Date( 0 ),
custom: {
toJSON: () => "custom"
}
}
}
}
}
};

const createStream = async function* () {
for (const byte of encode(object)) {
yield [byte];
}
};
assert.deepStrictEqual(await decodeAsync(createStream()), {
string: "Hello, world!",
nested: {
int: -45,
json: {
float: Math.PI,
int64: Number.MIN_SAFE_INTEGER,
timestamp: new Date( 0 ),
custom: "custom"
}
}
});
});
});

0 comments on commit b04a351

Please sign in to comment.