Skip to content

Commit 50b9d01

Browse files
committed
fix: handle dots in key names
1 parent 35c3d49 commit 50b9d01

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

_tests/smoke.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
proxyObjectRest,
1515
proxyArrayRest, isKnownObject
1616
} from '../src';
17+
import {unescapeKey} from "../src/escapeKey";
1718

1819
describe('proxy', () => {
1920
it('arrays', () => {
@@ -317,6 +318,20 @@ describe('proxy', () => {
317318
expect(o1.isPrototypeOf(trapped.state)).to.be.true;
318319
});
319320

321+
it('handles dots in names', () => {
322+
const o1 = {
323+
'test.object.1': 1
324+
};
325+
const o2 = {
326+
'test.object.2': 2
327+
};
328+
const trapped = proxyState(o1);
329+
expect(trapped.state['test.object.1']).to.be.equal(1);
330+
expect(trapped.affected).not.to.be.deep.equal(['.test.object.1']);
331+
expect(unescapeKey(trapped.affected[0])).to.be.equal('.test.object.1');
332+
expect(proxyEqual(o1, o2, trapped.affected)).to.be.equal(false);
333+
});
334+
320335
it('detect self', () => {
321336
const A = {a: 1};
322337
const B = proxyState(A).state;

src/escapeKey.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const dotReplacement = String.fromCharCode(1);
2+
// const symbolReplacement = String.fromCharCode(2);
3+
//
4+
// let escapeRefCount = 0;
5+
// const escapeReference = new WeakMap();
6+
7+
export const unescapeKey = (key) => {
8+
return key.replace(/\u0001/g, '.');
9+
};
10+
11+
export const escapeKey = (key) => {
12+
const type = typeof key;
13+
// if(type!=="string" || type!=="number"){
14+
// const ref = escapeReference.get(key);
15+
// if(ref) {
16+
// return ref;
17+
// }
18+
// escapeRefCount++;
19+
// escapeReference.set(key, escapeRefCount);
20+
// const keyCode = symbolReplacement+escapeRefCount;
21+
//
22+
// return keyCode
23+
// }
24+
if (type === "number") {
25+
return key;
26+
}
27+
28+
return String(key).replace(/\./g, dotReplacement);
29+
};

src/proxyEqual.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
/* eslint-disable no-control-regex */
2+
13
import {str as crc32_str} from "crc-32";
24

35
import {getCollectionHandlers, shouldInstrument} from "./shouldInstrument";
46
import {weakMemoizeArray} from "./weakMemoize";
57
import {EDGE, memoizedBuildTrie} from "./objectTrie";
68
import {addDiffer, resetDiffers} from "./differs";
79
import {proxyPolyfill} from './proxy-polyfill';
10+
import {escapeKey, unescapeKey} from "./escapeKey";
811

912
const hasProxy = typeof Proxy !== 'undefined';
1013
const ProxyConstructor = hasProxy ? Proxy : proxyPolyfill();
@@ -98,7 +101,7 @@ export function proxyfy(state, report, suffix = '', fingerPrint, ProxyMap, contr
98101
if (nextItem.done && !nextItem.value) {
99102
return;
100103
}
101-
return proxyValue(subKey, nextItem.value)
104+
return proxyValue(subKey, subKey, nextItem.value)
102105
}
103106
};
104107
};
@@ -110,8 +113,8 @@ export function proxyfy(state, report, suffix = '', fingerPrint, ProxyMap, contr
110113
}
111114
};
112115

113-
const proxyValue = (key, value) => {
114-
const thisId = report(suffix, key);
116+
const proxyValue = (key, reportValue, value) => {
117+
const thisId = report(suffix, reportValue);
115118
const type = typeof value;
116119

117120

@@ -122,9 +125,9 @@ export function proxyfy(state, report, suffix = '', fingerPrint, ProxyMap, contr
122125
if (hasCollectionHandlers) {
123126
switch (key) {
124127
case 'get':
125-
return key => proxyValue(key, state.get(key));
128+
return key => proxyValue(key, escapeKey(key), state.get(key));
126129
case 'has':
127-
return key => proxyValue(key, state.has(key));
130+
return key => proxyValue(key, escapeKey(key), state.has(key));
128131
case 'keys':
129132
return () => state.keys();
130133
case 'values':
@@ -173,7 +176,7 @@ export function proxyfy(state, report, suffix = '', fingerPrint, ProxyMap, contr
173176
}
174177

175178
if (typeof prop === 'string') {
176-
return proxyValue(prop, storedValue);
179+
return proxyValue(prop, escapeKey(prop), storedValue);
177180
}
178181

179182
return storedValue;
@@ -249,7 +252,7 @@ const memoizedCollectValuables = weakMemoizeArray(collectValuables);
249252
const get = (target, path) => {
250253
let result = target;
251254
for (let i = 1; i < path.length && result; ++i) {
252-
const key = path[i];
255+
const key = unescapeKey(path[i]);
253256
if (key[0] === '!') {
254257
if (key === objectKeysMarker) {
255258
return Object.keys(result).map(crc32_str).reduce((acc, x) => acc ^ x, 0);

0 commit comments

Comments
 (0)