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
4 changes: 3 additions & 1 deletion packages/compass-crud/src/components/json-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ const JSONEditor: React.FunctionComponent<JSONEditorProps> = ({
}, []);

const onUpdate = useCallback(() => {
doc.apply(HadronDocument.FromEJSON(value || ''));
const newDoc = HadronDocument.FromEJSON(value || '');
newDoc.preserveTypes(doc);
doc.apply(newDoc);
void replaceDocument?.(doc);
}, [doc, replaceDocument, value]);

Expand Down
14 changes: 14 additions & 0 deletions packages/hadron-document/src/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ export class Document extends EventEmitter {
}
}

preserveTypes(other: Document): void {
const thisDoc = this.generateObject();

for (const key of Object.keys(thisDoc)) {
const thisElement = this.get(key);
const otherElement = other.get(key);
if (!thisElement || !otherElement) {
continue;
}

thisElement.preserveType(otherElement);
}
}

/**
* Generate the javascript object for this document.
*
Expand Down
34 changes: 34 additions & 0 deletions packages/hadron-document/src/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,46 @@ export class Element extends EventEmitter {
this.currentValue = value;
this.elements = undefined;
} else {
// if they are both integer types and equal if made the previous type, don't update.
this.currentValue = value;
}
this.setValid();
this._bubbleUp(Events.Edited, this);
}

preserveType(otherElement: Element): void {
switch (this.currentType) {
case 'Object': {
if (!this.elements) {
return;
}
for (const child of this.elements) {
const otherChild = otherElement.get(child.currentKey);
if (!otherChild) {
continue;
}
child.preserveType(otherChild);
}
break;
}
case 'Int32': {
const otherType = otherElement.currentType;
if (otherType === 'Double') {
this.changeType('Double');
}
if (otherType === 'Int64') {
this.changeType('Int64');
}
break;
}
default:
// NOTE: Purposefully leaving Array elements alone because deciding
// whether to turn on Int32 into a Double or Int64 or not is complex and
// error-prone. Also leaving every other type alone.
break;
}
}

changeType(newType: TypeCastTypes): void {
if (newType === 'Object') {
this._convertToEmptyObject();
Expand Down
66 changes: 66 additions & 0 deletions packages/hadron-document/test/document.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2392,6 +2392,72 @@ describe('Document', function () {
);
});
});

describe('#preserveTypes', function () {
it('keeps unnecessary double type', function () {
const oldDoc = new Document({
number: new Double(1),
different: new Double(1),
sameArray: [new Double(1), new Double(2)],
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
object: {
number: new Double(1),
different: new Double(1),
},
});
const newDoc = new Document({
number: new Double(2),
different: new Long(1),
sameArray: [new Int32(1), new Double(2.2)],
mixedArray: ['foo', new Double(1), new Int32(2), new Long(3)],
object: {
number: new Int32(1),
different: new Long(3),
},
});

newDoc.preserveTypes(oldDoc);

expect(newDoc.get('number')?.currentType).to.equal('Double');
expect(newDoc.get('different')?.currentType).to.equal('Int64');
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
'Double'
);
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
'Int64'
);
});

it('keeps unnecessary long type', function () {
const oldDoc = new Document({
number: new Long(1),
different: new Long(1),
object: {
number: new Long(1),
different: new Long(1),
},
});
const newDoc = new Document({
number: new Int32(2),
different: new Double(1),
object: {
number: new Int32(1),
different: new Double(3),
},
});

newDoc.preserveTypes(oldDoc);

expect(newDoc.get('number')?.currentType).to.equal('Int64');
expect(newDoc.get('different')?.currentType).to.equal('Double');
expect(newDoc.get('object')?.get('number')?.currentType).to.equal(
'Int64'
);
expect(newDoc.get('object')?.get('different')?.currentType).to.equal(
'Double'
);
});
});
});

context('when a document is expanded/collapsed', function () {
Expand Down
Loading