Skip to content

Commit b360ea4

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

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-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: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,46 @@ 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+
case 'Object': {
206+
if (!this.elements) {
207+
return;
208+
}
209+
for (const child of this.elements) {
210+
const otherChild = otherElement.get(child.currentKey);
211+
if (!otherChild) {
212+
continue;
213+
}
214+
child.preserveType(otherChild);
215+
}
216+
break;
217+
}
218+
case 'Int32': {
219+
const otherType = otherElement.currentType;
220+
if (otherType === 'Double') {
221+
this.changeType('Double');
222+
}
223+
if (otherType === 'Int64') {
224+
this.changeType('Int64');
225+
}
226+
break;
227+
}
228+
default:
229+
// NOTE: Purposefully leaving Array elements alone because deciding
230+
// whether to turn on Int32 into a Double or Int64 or not is complex and
231+
// error-prone. Also leaving every other type alone.
232+
break;
233+
}
234+
}
235+
202236
changeType(newType: TypeCastTypes): void {
203237
if (newType === 'Object') {
204238
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)