Skip to content

Commit

Permalink
feat: serialize bigints for islands (#1317)
Browse files Browse the repository at this point in the history
  • Loading branch information
lino-levan authored Jun 17, 2023
1 parent ea6a742 commit 4d66f95
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/concepts/islands.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ care of automatically re-hydrating the island on the client.
Passing props to islands is supported, but only if the props are serializable.
Fresh can serialize the following types of values:

- Primitive types `string`, `boolean`, and `null`
- Primitive types `string`, `boolean`, `bigint`, and `null`
- Most `number`s (`Infinity`, `-Infinity`, and `NaN` are silently converted to
`null`, and `bigint`s are not supported)
`null`)
- Plain objects with string keys and serializable values
- Arrays containing serializable values
- Uint8Array
Expand Down
3 changes: 3 additions & 0 deletions src/runtime/deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export function deserialize(
if (v[KEY] === "s") {
return signal!(v.v);
}
if (v[KEY] === "b") {
return BigInt(v.d);
}
if (v[KEY] === "u8a") {
return b64decode(v.d);
}
Expand Down
2 changes: 2 additions & 0 deletions src/server/__snapshots__/serializer_test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export const snapshot = {};

snapshot[`serializer - primitives & plain objects 1`] = `'{"v":{"a":1,"b":"2","c":true,"d":null,"f":[1,2,3],"g":{"a":1,"b":2,"c":3}}}'`;

snapshot[`serializer - bigint 1`] = `'{"v":{"a":{"_f":"b","d":"999999999999999999"}}}'`;

snapshot[`serializer - Uint8Array 1`] = `'{"v":{"a":{"_f":"u8a","d":"AQID"}}}'`;

snapshot[`serializer - signals 1`] = `'{"v":{"a":1,"b":{"_f":"s","v":2}}}'`;
Expand Down
6 changes: 6 additions & 0 deletions src/server/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* - `null`
* - `boolean`
* - `number`
* - `bigint`
* - `string`
* - `array`
* - `object` (no prototypes)
Expand Down Expand Up @@ -134,6 +135,11 @@ export function serialize(data: unknown): SerializeResult {
const res = { [KEY]: "s", v: value.peek() };
parentStack.push(res);
return res;
} else if (typeof value === "bigint") {
requiresDeserializer = true;
const res = { [KEY]: "b", d: value.toString() };
parentStack.push(res);
return res;
} else if (value instanceof Uint8Array) {
requiresDeserializer = true;
const res = { [KEY]: "u8a", d: b64encode(value) };
Expand Down
10 changes: 10 additions & 0 deletions src/server/serializer_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ Deno.test("serializer - primitives & plain objects", async (t) => {
assertEquals(deserialized, data);
});

Deno.test("serializer - bigint", async (t) => {
const data = { a: 999999999999999999n };
const res = serialize(data);
assert(res.requiresDeserializer);
assert(!res.hasSignals);
await assertSnapshot(t, res.serialized);
const deserialized = deserialize(res.serialized);
assertEquals(deserialized, data);
});

Deno.test("serializer - Uint8Array", async (t) => {
const data = { a: new Uint8Array([1, 2, 3]) };
const res = serialize(data);
Expand Down

0 comments on commit 4d66f95

Please sign in to comment.