rxdb
Version:
A local-first realtime NoSQL Database for JavaScript applications - https://rxdb.info/
147 lines (136 loc) • 3.7 kB
text/typescript
/**
* this plugin adds the json export/import capabilities to RxDB
*/
import {
createRxQuery,
queryCollection,
_getDefaultQuery
} from '../../rx-query.ts';
import {
newRxError
} from '../../rx-error.ts';
import type {
RxDatabase,
RxCollection,
RxPlugin,
RxDocumentData
} from '../../types/index.d.ts';
import {
flatClone,
getDefaultRevision,
now
} from '../../plugins/utils/index.ts';
function dumpRxDatabase(
this: RxDatabase,
collections?: string[]
): Promise<any> {
const json: any = {
name: this.name,
instanceToken: this.token,
collections: []
};
const useCollections = Object.keys(this.collections)
.filter(colName => !collections || collections.includes(colName))
.filter(colName => colName.charAt(0) !== '_')
.map(colName => this.collections[colName]);
return Promise.all(
useCollections
.map(col => col.exportJSON())
).then(cols => {
json.collections = cols;
return json;
});
}
const importDumpRxDatabase = function (
this: RxDatabase,
dump: any
) {
/**
* collections must be created before the import
* because we do not know about the other collection-settings here
*/
const missingCollections = dump.collections
.filter((col: any) => !this.collections[col.name])
.map((col: any) => col.name);
if (missingCollections.length > 0) {
throw newRxError('JD1', {
missingCollections
});
}
return Promise.all(
dump.collections
.map((colDump: any) => this.collections[colDump.name].importJSON(colDump))
);
};
const dumpRxCollection = async function (
this: RxCollection
) {
const json: any = {
name: this.name,
schemaHash: await this.schema.hash,
docs: []
};
const query = createRxQuery(
'find',
_getDefaultQuery(),
this
);
return queryCollection(query)
.then((docs: any) => {
json.docs = docs.map((docData: any) => {
docData = flatClone(docData);
delete docData._rev;
delete docData._attachments;
return docData;
});
return json;
});
};
async function importDumpRxCollection<RxDocType>(
this: RxCollection<RxDocType>,
exportedJSON: any
): Promise<any> {
// check schemaHash
if (exportedJSON.schemaHash !== await this.schema.hash) {
throw newRxError('JD2', {
schemaHash: exportedJSON.schemaHash,
own: this.schema.hash
});
}
const docs: RxDocType[] = exportedJSON.docs;
return this.storageInstance.bulkWrite(
docs.map(docData => {
const document: RxDocumentData<RxDocType> = Object.assign(
{},
docData,
{
_meta: {
lwt: now()
},
_rev: getDefaultRevision(),
_attachments: {},
_deleted: false
}
);
return {
document
};
}),
'json-dump-import'
);
}
export const RxDBJsonDumpPlugin: RxPlugin = {
name: 'json-dump',
rxdb: true,
prototypes: {
RxDatabase: (proto: any) => {
proto.exportJSON = dumpRxDatabase;
proto.importJSON = importDumpRxDatabase;
},
RxCollection: (proto: any) => {
proto.exportJSON = dumpRxCollection;
proto.importJSON = importDumpRxCollection;
}
},
overwritable: {}
};