Skip to content

Commit cd27b0c

Browse files
Move logic to transformer
1 parent 5cfddf7 commit cd27b0c

File tree

3 files changed

+36
-42
lines changed

3 files changed

+36
-42
lines changed

src/accessDeep.ts

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,6 @@ const getNthKey = (
3030
return indexed[n];
3131
};
3232

33-
const rememberIndexedCollectionKeys = (
34-
before: unknown,
35-
after: unknown,
36-
context: AccessDeepContext
37-
) => {
38-
if (!isArray(before)) {
39-
return;
40-
}
41-
42-
if (isSet(after)) {
43-
context.set(after, before.slice());
44-
return;
45-
}
46-
47-
if (isMap(after)) {
48-
context.set(
49-
after,
50-
before.map(entry => (isArray(entry) ? entry[0] : undefined))
51-
);
52-
}
53-
};
54-
5533
function validatePath(path: (string | number)[]) {
5634
if (includes(path, '__proto__')) {
5735
throw new Error('__proto__ is not allowed as a property');
@@ -99,15 +77,13 @@ export const getDeep = (
9977
export const setDeep = (
10078
object: any,
10179
path: (string | number)[],
102-
mapper: (v: any) => any,
80+
mapper: (v: any, context: AccessDeepContext) => any,
10381
context: AccessDeepContext
10482
): any => {
10583
validatePath(path);
10684

10785
if (path.length === 0) {
108-
const mapped = mapper(object);
109-
rememberIndexedCollectionKeys(object, mapped, context);
110-
return mapped;
86+
return mapper(object, context);
11187
}
11288

11389
let parent = object;
@@ -148,14 +124,12 @@ export const setDeep = (
148124

149125
if (isArray(parent)) {
150126
const oldValue = parent[+lastKey];
151-
const newValue = mapper(oldValue);
127+
const newValue = mapper(oldValue, context);
152128
parent[+lastKey] = newValue;
153-
rememberIndexedCollectionKeys(oldValue, newValue, context);
154129
} else if (isPlainObject(parent)) {
155130
const oldValue = parent[lastKey];
156-
const newValue = mapper(oldValue);
131+
const newValue = mapper(oldValue, context);
157132
parent[lastKey] = newValue;
158-
rememberIndexedCollectionKeys(oldValue, newValue, context);
159133
}
160134

161135
if (isSet(parent)) {
@@ -166,8 +140,7 @@ export const setDeep = (
166140
}
167141
const oldValue = indexed[row];
168142

169-
const newValue = mapper(oldValue);
170-
rememberIndexedCollectionKeys(oldValue, newValue, context);
143+
const newValue = mapper(oldValue, context);
171144

172145
if (oldValue !== newValue) {
173146
if (row < parent.size) {
@@ -191,8 +164,7 @@ export const setDeep = (
191164

192165
switch (type) {
193166
case 'key': {
194-
const newKey = mapper(keyToRow);
195-
rememberIndexedCollectionKeys(keyToRow, newKey, context);
167+
const newKey = mapper(keyToRow, context);
196168
parent.set(newKey, parent.get(keyToRow));
197169

198170
if (!isVirtualRow && newKey !== keyToRow) {
@@ -205,8 +177,7 @@ export const setDeep = (
205177

206178
case 'value': {
207179
const oldValue = parent.get(keyToRow);
208-
const newValue = mapper(oldValue);
209-
rememberIndexedCollectionKeys(oldValue, newValue, context);
180+
const newValue = mapper(oldValue, context);
210181
parent.set(keyToRow, newValue);
211182
break;
212183
}

src/plainer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@ export function applyValueAnnotations(
7171
traverse(
7272
annotations,
7373
(type, path) => {
74-
plain = setDeep(plain, path, v => untransformValue(v, type, superJson), context);
74+
plain = setDeep(
75+
plain,
76+
path,
77+
(v, mapperContext) =>
78+
untransformValue(v, type, superJson, mapperContext),
79+
context
80+
);
7581
},
7682
version
7783
);

src/transformer.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from './is.js';
1717
import { findArr } from './util.js';
1818
import SuperJSON from './index.js';
19+
import type { AccessDeepContext } from './accessDeep.js';
1920

2021
export type PrimitiveTypeAnnotation = 'number' | 'undefined' | 'bigint';
2122

@@ -40,7 +41,11 @@ function simpleTransformation<I, O, A extends SimpleTypeAnnotation>(
4041
isApplicable: (v: any, superJson: SuperJSON) => v is I,
4142
annotation: A,
4243
transform: (v: I, superJson: SuperJSON) => O,
43-
untransform: (v: O, superJson: SuperJSON) => I
44+
untransform: (
45+
v: O,
46+
superJson: SuperJSON,
47+
context: AccessDeepContext
48+
) => I
4449
) {
4550
return {
4651
isApplicable,
@@ -127,13 +132,24 @@ const simpleRules = [
127132
// (sets only exist in es6+)
128133
// eslint-disable-next-line es5/no-es6-methods
129134
v => [...v.values()],
130-
v => new Set(v)
135+
(v, _, context) => {
136+
const untransformed = new Set(v);
137+
context?.set(untransformed, v.slice());
138+
return untransformed;
139+
}
131140
),
132141
simpleTransformation(
133142
isMap,
134143
'map',
135144
v => [...v.entries()],
136-
v => new Map(v)
145+
(v, _, context) => {
146+
const untransformed = new Map(v);
147+
context?.set(
148+
untransformed,
149+
v.map(entry => (isArray(entry) ? entry[0] : undefined))
150+
);
151+
return untransformed;
152+
}
137153
),
138154

139155
simpleTransformation<number, 'NaN' | 'Infinity' | '-Infinity', 'number'>(
@@ -345,7 +361,8 @@ simpleRules.forEach(rule => {
345361
export const untransformValue = (
346362
json: any,
347363
type: TypeAnnotation,
348-
superJson: SuperJSON
364+
superJson: SuperJSON,
365+
context: AccessDeepContext
349366
) => {
350367
if (isArray(type)) {
351368
switch (type[0]) {
@@ -366,6 +383,6 @@ export const untransformValue = (
366383
throw new Error('Unknown transformation: ' + type);
367384
}
368385

369-
return transformation.untransform(json as never, superJson);
386+
return transformation.untransform(json as never, superJson, context);
370387
}
371388
};

0 commit comments

Comments
 (0)