-
-
Save fadookie/04fbd8a4b2a8782f5b5c089c80c8f632 to your computer and use it in GitHub Desktop.
Realm Mock backed by AsyncStorage to try to enable on-device debugging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; } | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is based on realm 2.12.0. Requires
#load
to be called before use.