Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:

strategy:
matrix:
node: [20.x, 18.x, 16.x]
node: [24.x, 22.x, 20.x, 18.x]

env:
CI: true
Expand All @@ -21,14 +21,6 @@ jobs:
with:
node-version: ${{ matrix.node }}

- name: Use cached node_modules
uses: actions/cache@v2
with:
path: node_modules
key: nodeModules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
nodeModules-

- name: Install dependencies
run: yarn install --frozen-lockfile

Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,16 @@ Deserializes the output of Superjson back into your original value.
```js
const { json, meta } = serialize(object);

deserialize({ json, meta });
deserialize({ json, meta }, { inPlace: true });
```

Options

- `inPlace: boolean`
- Default: `false`
- Mutate the input json object in place instead of returning a deep copy
- `inPlace: true` will be much more performant on large objects if it's safe to mutate it

Returns **`your original value`**.

### stringify
Expand Down
10 changes: 10 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,16 @@
expect(() => SuperJSON.deserialize(res)).toThrowError('index out of bounds');
});

// https://github.com/flightcontrolhq/superjson/issues/319
test('deserialize in place', () => {
const serialized = SuperJSON.serialize({ a: new Date() });
const deserializedCopy = SuperJSON.deserialize(serialized);
const deserializedInPlace = SuperJSON.deserialize(serialized, { inPlace: true });

Check failure on line 1278 in src/index.test.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `·inPlace:·true` with `⏎····inPlace:·true,⏎·`

Check failure on line 1278 in src/index.test.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Replace `·inPlace:·true` with `⏎····inPlace:·true,⏎·`
expect(deserializedInPlace).toBe(serialized.json);
expect(deserializedCopy).not.toBe(serialized.json);
expect(deserializedCopy).toEqual(deserializedInPlace);
});

test('#310 fixes backwards compat', () => {
expect(
SuperJSON.deserialize({
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
return res;
}

deserialize<T = unknown>(payload: SuperJSONResult): T {
deserialize<T = unknown>(payload: SuperJSONResult, options?: { inPlace?: boolean }): T {

Check failure on line 63 in src/index.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `payload:·SuperJSONResult,·options?:·{·inPlace?:·boolean·}` with `⏎····payload:·SuperJSONResult,⏎····options?:·{·inPlace?:·boolean·}⏎··`

Check failure on line 63 in src/index.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Replace `payload:·SuperJSONResult,·options?:·{·inPlace?:·boolean·}` with `⏎····payload:·SuperJSONResult,⏎····options?:·{·inPlace?:·boolean·}⏎··`
const { json, meta } = payload;

let result: T = copy(json) as any;
let result: T = options?.inPlace ? json : copy(json) as any;

Check failure on line 66 in src/index.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `copy(json)·as·any` with `(copy(json)·as·any)`

Check failure on line 66 in src/index.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Replace `copy(json)·as·any` with `(copy(json)·as·any)`

if (meta?.values) {
result = applyValueAnnotations(result, meta.values, meta.v ?? 0, this);
Expand All @@ -85,7 +85,7 @@
}

parse<T = unknown>(string: string): T {
return this.deserialize(JSON.parse(string));
return this.deserialize(JSON.parse(string), { inPlace: true });
Comment on lines 87 to +88
Copy link

Copilot AI Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the parse method to use inPlace: true by default is a breaking change that could affect existing users who rely on the original JSON object remaining unmodified. Consider making this configurable or documenting this behavior change prominently.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so, Copilot. JSON.parse is creating the object and it's safe to mutate it in place, because no other caller has access to it.

}

readonly classRegistry = new ClassRegistry();
Expand Down
Loading