Skip to content

Commit 413eaf5

Browse files
committed
try and preserve Double and Long/Int64 types in the json editor
1 parent 3a41616 commit 413eaf5

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

packages/compass-crud/src/components/json-editor.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ const JSONEditor: React.FunctionComponent<JSONEditorProps> = ({
136136
}, []);
137137

138138
const onUpdate = useCallback(() => {
139-
doc.apply(HadronDocument.FromEJSON(value || ''));
139+
const newDoc = HadronDocument.FromEJSON(value || '');
140+
newDoc.preserveTypes(doc);
141+
doc.apply(newDoc);
140142
void replaceDocument?.(doc);
141143
}, [doc, replaceDocument, value]);
142144

packages/hadron-document/src/document.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ export class Document extends EventEmitter {
108108
}
109109
}
110110

111+
preserveTypes(other: Document): void {
112+
const thisDoc = this.generateObject();
113+
114+
for (const key of Object.keys(thisDoc)) {
115+
const thisElement = this.get(key);
116+
const otherElement = other.get(key);
117+
if (!thisElement || !otherElement) {
118+
continue;
119+
}
120+
121+
thisElement.preserveType(otherElement);
122+
}
123+
}
124+
111125
/**
112126
* Generate the javascript object for this document.
113127
*

packages/hadron-document/src/element.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,44 @@ export class Element extends EventEmitter {
193193
this.currentValue = value;
194194
this.elements = undefined;
195195
} else {
196+
// if they are both integer types and equal if made the previous type, don't update.
196197
this.currentValue = value;
197198
}
198199
this.setValid();
199200
this._bubbleUp(Events.Edited, this);
200201
}
201202

203+
preserveType(otherElement: Element): void {
204+
switch (this.currentType) {
205+
// NOTE: Purposefully leaving Array elements alone because deciding
206+
// whether to turn on Int32 into a Double or Int64 or not is complex and
207+
// error-prone.
208+
case 'Object': {
209+
if (!this.elements) {
210+
return;
211+
}
212+
for (const child of this.elements) {
213+
const otherChild = otherElement.get(child.currentKey);
214+
if (!otherChild) {
215+
continue;
216+
}
217+
child.preserveType(otherChild);
218+
}
219+
break;
220+
}
221+
case 'Int32': {
222+
const otherType = otherElement.currentType;
223+
if (otherType === 'Double') {
224+
this.changeType('Double');
225+
}
226+
if (otherType === 'Int64') {
227+
this.changeType('Int64');
228+
}
229+
break;
230+
}
231+
}
232+
}
233+
202234
changeType(newType: TypeCastTypes): void {
203235
if (newType === 'Object') {
204236
this._convertToEmptyObject();

packages/hadron-document/test/document.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,72 @@ describe('Document', function () {
23922392
);
23932393
});
23942394
});
2395+
2396+
describe('#preserveTypes', function () {
2397+
it('keeps unnecessary double type', function () {
2398+
const oldDoc = new Document({
2399+
number: new Double(1),
2400+
different: new Double(1),
2401+
sameArray: [new Double(1), new Double(2)],
2402+
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
2403+
object: {
2404+
number: new Double(1),
2405+
different: new Double(1),
2406+
},
2407+
});
2408+
const newDoc = new Document({
2409+
number: new Double(2),
2410+
different: new Long(1),
2411+
sameArray: [new Int32(1), new Double(2.2)],
2412+
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
2413+
object: {
2414+
number: new Int32(1),
2415+
different: new Long(3),
2416+
},
2417+
});
2418+
2419+
newDoc.preserveTypes(oldDoc);
2420+
2421+
expect(newDoc.get('number')?.currentType).to.equal('Double');
2422+
expect(newDoc.get('different')?.currentType).to.equal('Int64');
2423+
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
2424+
'Double'
2425+
);
2426+
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
2427+
'Int64'
2428+
);
2429+
});
2430+
2431+
it('keeps unnecessary long type', function () {
2432+
const oldDoc = new Document({
2433+
number: new Long(1),
2434+
different: new Long(1),
2435+
object: {
2436+
number: new Long(1),
2437+
different: new Long(1),
2438+
},
2439+
});
2440+
const newDoc = new Document({
2441+
number: new Int32(2),
2442+
different: new Double(1),
2443+
object: {
2444+
number: new Int32(1),
2445+
different: new Double(3),
2446+
},
2447+
});
2448+
2449+
newDoc.preserveTypes(oldDoc);
2450+
2451+
expect(newDoc.get('number')?.currentType).to.equal('Int64');
2452+
expect(newDoc.get('different')?.currentType).to.equal('Double');
2453+
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
2454+
'Int64'
2455+
);
2456+
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
2457+
'Double'
2458+
);
2459+
});
2460+
});
23952461
});
23962462

23972463
context('when a document is expanded/collapsed', function () {

0 commit comments

Comments
 (0)