Skip to content

Instantly share code, notes, and snippets.

@fadookie
Forked from hyb175/realmMock.js
Created September 18, 2018 00:09
Show Gist options
  • Save fadookie/04fbd8a4b2a8782f5b5c089c80c8f632 to your computer and use it in GitHub Desktop.
Save fadookie/04fbd8a4b2a8782f5b5c089c80c8f632 to your computer and use it in GitHub Desktop.
Realm Mock backed by AsyncStorage to try to enable on-device debugging
// https://github.com/realm/realm-js/issues/370#issuecomment-270849466
import { AsyncStorage } from "react-native"
const STORAGE_KEY = 'MockRealm';
export default class Realm {
constructor(params) {
this.schema = {};
this.callbackList = [];
this.data = {};
this.schemaCallbackList = {};
params.schema.forEach((schema) => {
this.data[schema.name] = {};
});
params.schema.forEach((schema) => {
this.schema[schema.name] = schema;
});
this.lastLookedUpModel = null;
this.addListener(null, this.onChange.bind(this));
}
async load() {
const storedDataString = await AsyncStorage.getItem(STORAGE_KEY);
if (storedDataString) {
const storedData = JSON.parse(storedDataString);
if (storedData) {
this.data = storedData;
console.log('MockRealm#load storedData:', storedData, 'LOAD_END');
}
}
}
onChange() {
console.log('MockRealm#onChange data:', this.data);
AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(this.data));
}
objects(schemaName) {
this.lastLookedUpModel = schemaName;
const objects = Object.values(this.data[schemaName]);
objects.values = () => objects;
objects.sorted = () => this.compareFunc ? objects.sort(this.compareFunc) : objects.sort();
objects.addListener = (cb) => {
if (this.schemaCallbackList[schemaName]) {
this.schemaCallbackList[schemaName].push(cb);
} else {
this.schemaCallbackList[schemaName] = [cb];
}
};
objects.removeListener = () => {};
objects.filtered = this.filtered ? this.filtered.bind(this, schemaName) : () => objects;
return objects;
}
write(fn) {
this.writing = true;
fn();
this.writing = false;
}
create(schemaName, object) {
const modelObject = object;
console.log('mockRealm#create args:', arguments, 'schemaName:', schemaName);
const properties = this.schema[schemaName].properties;
Object.keys(properties).forEach((key) => {
if (modelObject[key] && modelObject[key].model) {
this.data[modelObject[key].model][modelObject[key].id] = this.create(
modelObject[key].model, modelObject[key],
);
} else if (modelObject[key] && modelObject[key].length && modelObject[key][0].model) {
modelObject[key].forEach((obj) => {
this.data[modelObject[key][0].model][obj.id] = obj;
});
modelObject[key].filtered = this.filtered ? this.filtered : () => modelObject[key];
modelObject[key].sorted = () => modelObject[key].sort();
}
});
if (modelObject.id === undefined) {
modelObject.id = modelObject.key;
}
this.data[schemaName][modelObject.id] = modelObject;
if (this.writing) {
if (this.schemaCallbackList[schemaName]) {
this.schemaCallbackList[schemaName].forEach(cb => cb(schemaName, {
insertions: { length: 1 },
modifications: { length: 0 },
deletions: { length: 0 },
}));
}
this.callbackList.forEach((cb) => { cb(); });
}
return modelObject;
}
objectForPrimaryKey(model, id) {
this.lastLookedUpModel = model;
return this.data[model][id];
}
delete(object) {
if (this.lastLookedUpModel || object.model) {
const model = object.model ? object.model : this.lastLookedUpModel
if (Array.isArray(object)) {
object.forEach((item) => {
delete this.data[model][item.id];
});
}
delete this.data[model][object.id];
if (this.writing) {
if (this.schemaCallbackList[model]) {
this.schemaCallbackList[model].forEach(cb => cb(model, {
insertions: { length: 0 },
modifications: { length: 0 },
deletions: { length: 1 },
}));
}
this.callbackList.forEach((cb) => { cb(); });
}
}
}
deleteAll() {
Object.keys(this.schema).forEach((key) => {
if (this.writing && this.schemaCallbackList[this.schema[key].name]) {
this.schemaCallbackList[this.schema[key].name].forEach(cb => cb(key, {
insertions: { length: 0 },
modifications: { length: 0 },
deletions: { length: Object.values(this.data[this.schema[key].name]).length },
}));
}
this.data[this.schema[key].name] = {};
});
if (this.writing) this.callbackList.forEach((cb) => { cb(); });
}
addListener(event, callback) {
this.callbackList.push(callback);
}
prepareData(schemaName, objects) {
objects.forEach((object) => {
this.create(schemaName, object);
});
}
close() {
}
}
Realm.deleteFile = () => {
AsyncStorage.removeItem(STORAGE_KEY);
};
Realm.Object = class Object {
isValid() { return true; }
};
@fadookie
Copy link
Author

fadookie commented Sep 18, 2018

This is based on realm 2.12.0. Requires #load to be called before use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment