Skip to content

Instantly share code, notes, and snippets.

@stigi
Created January 10, 2018 19:14
Show Gist options
  • Select an option

  • Save stigi/20d4ee81d2c28e7fea751f1d16a75610 to your computer and use it in GitHub Desktop.

Select an option

Save stigi/20d4ee81d2c28e7fea751f1d16a75610 to your computer and use it in GitHub Desktop.
In memory realm mock with flow types
// @flow
// Adapted from https://gist.github.com/hyb175/beb9ceed4c34300ba7c77d3d6d44ae52
import type {ModelSchemaType} from '../schema'
type CallbackType = ()=>{}
type RealmObjectType = {
realmModelName: string
}
type ModelNameType = string
type ModelIDType = mixed
type DataType = {
[key: ModelNameType]: {
[key: ModelIDType]: RealmObjectType
}
}
type SchemaType = {
[key: ModelNameType]: ModelSchemaType
}
export default class Realm {
schema: SchemaType = {}
callbacks: CallbackType[] = []
data: DataType = {}
changesOnWrite: boolean = false
isInWrite: boolean = false
constructor(params: {schema: ModelSchemaType[]}) {
for (const modelSchema of params.schema) {
this.data[modelSchema.name] = {}
this.schema[modelSchema.name] = modelSchema
}
}
objects(modelName: string): mixed {
return Object.values(this.data[modelName])
}
write(fn: ()=>{}) {
console.assert(!this.isInWrite, "Nested write calls")
console.assert(!this.changesOnWrite, "changesOnWrite should have been reset on the end of write. Likely nested write calls.")
this.isInWrite = true
fn()
this.isInWrite = false
if (this.changesOnWrite) {
for (const cb of this.callbacks) { cb() }
}
this.changesOnWrite = false
}
idFromObject(object: RealmObjectType): ?mixed {
const pk = this.schema[object.realmModelName].primaryKey
if (pk) {
return object[pk]
}
}
create(modelName: string, object: Object): Object {
console.assert(this.isInWrite, "create must be called within a write.")
console.assert(object.realmModelName == undefined || object.realmModelName === modelName, "clash on realmModelName")
this.changesOnWrite = true
// Enrich the object with the model name. This is needed for deletes
let realmObject: RealmObjectType = {
realmModelName: modelName,
...object
}
const id = this.idFromObject(realmObject)
const existing = this.data[modelName][id]
if (existing) {
realmObject = {existing, ...realmObject}
}
this.data[modelName][id] = realmObject
return realmObject
}
objectForPrimaryKey(modelName: string, id: mixed): ?RealmObjectType {
return this.data[modelName][id]
}
delete(object: RealmObjectType | RealmObjectType[]) {
console.assert(this.isInWrite, "delete must be called within a write.")
if (Array.isArray(object)) {
object.forEach(this.delete)
} else {
const modelName = object.realmModelName
const id = this.idFromObject(object)
if (modelName !== undefined || id !== undefined) {
delete this.data[modelName][id]
}
}
}
deleteAll() {
console.assert(this.isInWrite, "deleteAll must be called within a write.")
this.data = {}
}
addListener(event: string, callback: CallbackType) {
console.assert(event == 'change', "Only change events supported")
this.callbacks.push(callback)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment