Options
All
  • Public
  • Public/Protected
  • All
Menu

@ducharmemp/mobstr

Index

Type aliases

CollectionName

CollectionName: PropertyKey

Private Constructor

Constructor<T>: object

Type parameters

  • T

Type declaration

IndexKey

IndexKey: PropertyKey

IndexValue

IndexValue: PropertyKey

PrimaryKey

PrimaryKey: PropertyKey

TriggerId

TriggerId: number

Variables

Const IntegrityError

IntegrityError: object = (IntegrityErrorConstructor as unknown) as Constructor<Error>

Type declaration

Const MultipleResultsFound

MultipleResultsFound: object = (MultipleResultsFoundConstructor as unknown) as Constructor<Error>

Type declaration

Const NoResultsFound

NoResultsFound: object = (NoResultsFoundConstructor as unknown) as Constructor<Error>

Type declaration

Const addAll

addAll: (Anonymous function) & IAction = action(<T>(store: ReturnType<typeof createStore>, entities: T[]) => {entities.forEach(entity => addOne(store, entity));})

Adds all entities in the list to the store in bulk.

export
function
param
param

Const addOne

addOne: (Anonymous function) & IAction = action(<T>(store: ReturnType<typeof createStore>, entity: T) => {ensureMeta(entity);ensureConstructorMeta(entity);ensureCollection(store, entity);ensureIndicies(store, entity);const currentMeta = getMeta(entity);const currentCollection = currentMeta.collectionName;const currentKey = currentMeta.key.get();const indicies = currentMeta.indicies;invariant(() => !!currentKey,"Primary key for model should not be falsy. This can lead to unexpected behavior");store.collections[currentCollection as string].set((entity[currentKey as keyof T] as unknown) as string,entity);indicies.forEach(index => {const currentPropertyValue = getIndexKey(entity[index as keyof T]);const currentIndexedProperties =store.indicies[currentCollection as string][index as string];if (!currentIndexedProperties.has(currentPropertyValue)) {currentIndexedProperties.set(currentPropertyValue, []);}const currentIndexedValues = currentIndexedProperties.get(currentPropertyValue) as PrimaryKey[];currentIndexedValues.push((entity[currentMeta.key.get() as keyof T] as unknown) as PropertyKey);});})

Adds a single entity to a collection in the store. If a collection does not exist in the store object, it will be created.

export
function
param

The store instance to add the entity into

param

The entity itself. Note that this does not require the constructing class.

Const createCollectionTrigger

createCollectionTrigger: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,trigger: IInterceptor<IValueWillChange<InstanceType<T>>> | Lambda,options: TriggerOptions = {}) => {ensureCollection(store, entityClass);const currentMeta = getMeta(entityClass);const triggerId = getNextId(store);const {eventTypes = new Set([TriggerQueryEvent.All]),triggerExecutionStrategy = TriggerExecutionStrategy.Observe} = options;store.triggers.set(triggerId,wrapTrigger(store.collections[currentMeta.collectionName as string],trigger,eventTypes,triggerExecutionStrategy));return triggerId;})

Creates a trigger scoped to a particular collection. This is a low-level primitive to basically map over mobx's intercept and observe for a particular collection

example

class Foo {
 @primaryKey
 id = ''

 name = 'fooName'
}

createCollectionTrigger(Foo, (change) => { console.log('Foo changed', change) });
addOne(new Foo());
export
function
param
param
param
param

Const createStore

createStore: (Anonymous function) & IAction = action((options: StoreOptions = {}): Store =>observable({collections: {},primaryKeys: new Map(),indicies: {},triggers: new Map(),nextId: 0,options}))

Creates a store for use with decorators and other helper functions. Meant to be used as a singleton, but can also be used to create multiple distinct storage areas.

export
function
returns

Const dropAllConstraints

dropAllConstraints: (Anonymous function) & IAction = dropAllTriggers

Syntactic sugar functions over dropping all constraint from the store. Since constraints are triggers, this will delete all underlying triggers from the store

Const dropAllTriggers

dropAllTriggers: (Anonymous function) & IAction = action((store: ReturnType<typeof createStore>) => {Array.from(store.triggers.keys()).forEach(key => dropTrigger(store, key));})

Drops all triggers from the store. Note: constraints are implemented as triggers, so this function will drop all constraints as well

export
function
param

Const dropConstraint

dropConstraint: (Anonymous function) & IAction = dropTrigger

Syntactic sugar functions over dropping a given constraint from the store. Since constraints are triggers, this will delete the underlying trigger from the store

Const dropTrigger

dropTrigger: (Anonymous function) & IAction = action((store: ReturnType<typeof createStore>, triggerId: number) => {// Call the disposer(store.triggers.get(triggerId) as Function)();store.triggers.delete(triggerId);})

Drops a single trigger from the store

export
function
param
param

Const ensureCollection

ensureCollection: (Anonymous function) & IAction = action((store: ReturnType<typeof createStore>, entityClass: any) => {const currentMeta = getMeta(entityClass);store.collections[currentMeta.collectionName as string] =store.collections[currentMeta.collectionName as string] ||observable.map();})

Ensures that the store contains a collection for this entityClass

export

Const ensureIndicies

ensureIndicies: (Anonymous function) & IAction = action((store: ReturnType<typeof createStore>, entityClass: any) => {const currentMeta = getMeta(entityClass);store.indicies[currentMeta.collectionName as string] =store.indicies[currentMeta.collectionName as string] || {};// Create all of the property indicies but only if they already existcurrentMeta.indicies.forEach(indexName => {store.indicies[currentMeta.collectionName as string][indexName as string] =store.indicies[currentMeta.collectionName as string][indexName as string] || observable.map();});})

Ensures that the store is populated with the index mappings for this entityClass

export

Const executeTrigger

executeTrigger: (Anonymous function) & IAction = action((trigger: any,eventTypes: Set<TriggerQueryEvent>,change: IObjectWillChange | IObjectDidChange): any | null => {if (!eventTypes.has(TriggerQueryEvent.All) &&!eventTypes.has(change.type as TriggerQueryEvent)) {// To ignore the value, we need to return the change by itself, otherwise we issue a ROLLBACKreturn change;}return trigger(change);})

Runs a given trigger, filtering out event types that aren't relevant to the current trigger

export
function
param
param
param

Const findAll

findAll: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,findClause: (arg0: T) => any = (entry: T) => entry): InstanceType<T>[] => {ensureMeta(entityClass);ensureCollection(store, entityClass);const currentCollection = getMeta(entityClass).collectionName;return Array.from(store.collections[currentCollection as string].values()).filter(findClause);})

Finds all entities in the store by a given findClause that acts as a filter. Default filter is the identity function, which ensures that all entities will be returned.

export
function
example

class Foo {
 @primaryKey
 id = uuid();
}

const foos = [new Foo(), new Foo(), new Foo()];
addAll(foos);
findAll(Foo) === foos;
param
param
param

The testing predicate for including entities

Const findAllBy

findAllBy: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,indexedProperty: PropertyKey,value: any): InstanceType<T>[] => {ensureMeta(entityClass);ensureCollection(store, entityClass);ensureIndicies(store, entityClass);const currentCollectionName = getMeta(entityClass).collectionName;const currentCollection = store.indicies[currentCollectionName as string];// Fall back to non-indexed lookupif (!hasIn(currentCollection, indexedProperty)) {logger.warn("Falling back to non-indexed filter for property");return findAll(store, entityClass, item =>isEqual(item[indexedProperty as keyof typeof item], value));}return (currentCollection[indexedProperty as string].get(getIndexKey(value)) as PrimaryKey[]).map(primaryKey =>findOne(store, entityClass, primaryKey));})

Finds all entries in the store by a given value. Similar to findAll, but without dependence on a primary key. Attempts to use indexes to find a particular value, falls back to non-indexed filter.

param
param
param
param

Const findOne

findOne: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,primaryKey: ReturnType<Meta["__meta__"]["key"]["get"]>): InstanceType<T> => {ensureMeta(entityClass);ensureCollection(store, entityClass);const currentCollection = getMeta(entityClass).collectionName;return store.collections[currentCollection as string].get(primaryKey as string) as InstanceType<T>;})

Finds a single entry in the store by a given primaryKey. This can be useful in situations where you know the primary key but don't wish to keep an object reference around, such as in callback functions or factory functions.

export
function
example

class Foo {
 @primaryKey
 id = uuid();
}

const foo = new Foo();
addOne(foo);
findOne(Foo, foo.id);
export
function
param
param
param

Const findOneBy

findOneBy: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,indexedProperty: keyof InstanceType<T>,value: any): InstanceType<T> => {return getOnlyOne(findAllBy(store, entityClass, indexedProperty, value));})

Finds a single instance by value. Throws if there are too many or too few entries retrieved. Single case of findAllBy

param
param
param
param

Const getNextId

getNextId: (Anonymous function) & IAction = action((store: ReturnType<typeof createStore>) => {store.nextId += 1;return store.nextId;})

Const join

join: (Anonymous function) & IAction = action(<T extends Constructor<{}>, K extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,joinClass: K): [InstanceType<T>, InstanceType<K>][] => {ensureMeta(entityClass);ensureMeta(joinClass);ensureCollection(store, entityClass);ensureCollection(store, joinClass);const entityCollectionName = getMeta(entityClass).collectionName;const entityCollection = Array.from(store.collections[entityCollectionName as string].values()) as InstanceType<T>[];const childCollectionName = getMeta(joinClass).collectionName;const childCollection = store.collections[childCollectionName as string];return flatMap(entityCollection, (entity: InstanceType<T>) => {const joinRelationships = Object.values(getMeta(entity).relationships).filter(({ type }) => type === joinClass);return flatMap(joinRelationships, ({ keys }: RelationshipEntry) =>keys.map((key: string) => [entity, childCollection.get(key)]));});})

Joins two collections based on their applicable relationships. Currently only works for left joins based on the parent entity.

example

class Bar {
  @primaryKey
  id = uuid();
}

class Foo {
  @primaryKey
  id = uuid();

  @relationship(type => Bar)
  friends = []
}

const f = new Foo();
f.push(new Bar(), new Bar(), new Bar());
// Works:
join(Foo, Bar);
// Doesn't work
join(Bar, Foo);
export
function
param
param
param
returns

Const removeAll

removeAll: (Anonymous function) & IAction = action(<T>(store: ReturnType<typeof createStore>, entities: T[]) => {entities.forEach(removeOne.bind(null, store));})

Removes all given entities from the store in bulk. Entities can be homogenous in type or multiple types. This will also cascade any deletions to the any children with cascade: true relationships

export
function
param
param

Const removeOne

removeOne: (Anonymous function) & IAction = action(<T>(store: ReturnType<typeof createStore>, entity: T) => {ensureMeta(entity);ensureMeta(Object.getPrototypeOf(entity));ensureCollection(store, entity);const currentMeta = getMeta(entity);const primaryKey = currentMeta.key.get() as keyof T;const cascadeRelationshipKeys = Object.values(currentMeta.relationships).filter(relationship => relationship.options.cascade);const currentCollection = currentMeta.collectionName;store.collections[currentCollection as string].delete(// TODO: Properly type this, we need to check this beforehand to make sure that we can handle composite keys(entity[primaryKey] as unknown) as PrimaryKey);// Clean up all references after the cascade. We do this after the initial delete to hopefully catch any circular relationshipscascadeRelationshipKeys.forEach(relationship => {relationship.keys.map(key => findOne(store, relationship.type as Constructor<{}>, key)).forEach(entity => removeOne(store, entity));});})

Removes the given entity from the store. This function will cause an auto-cascade on all relationships referencing this object if the relationship's options include cascade: true. This is a recursive function in the cascading case and will force update all other relationships referencing the same child entity.

export
function
param
param

Const truncateCollection

truncateCollection: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(store: ReturnType<typeof createStore>,entityClass: T,options: TruncateOptions = { cascade: false }) => {ensureMeta(entityClass);const currentMeta = getMeta(entityClass);const currentCollectionName = currentMeta.collectionName;// Trigger any observables watching the store for this collectionstore.collections[currentCollectionName as string].clear();store.indicies[currentCollectionName as string] = {};if (!options.cascade) {return;}Object.values(currentMeta.relationships).map(({ type }) => {truncateCollection(store, type as Constructor<{}>, options);});})

Truncates a given collection in the store and triggers any observables watching this particular collection. This is essentially a very fast form of mass deletion.

This does not automatically cascade to subsequent tables, since that's a fairly slow operation. This will leave items in referenced tables. However, if the cascade option is included, then it will truncate all tables that are referenced by this table, regardless of cascade options on the relationship.

export
function
param
param

Const wrapTrigger

wrapTrigger: (Anonymous function) & IAction = action(<T extends Constructor<{}>>(target: Map<PropertyKey, any>,trigger: Lambda | IInterceptor<IValueWillChange<InstanceType<T>>>,eventTypes: Set<TriggerQueryEvent>,triggerStrategy: TriggerExecutionStrategy) => {const wrapping =triggerStrategy === TriggerExecutionStrategy.Intercept? intercept: observe;return wrapping(target, executeTrigger.bind(null, trigger, eventTypes));})

Wraps a trigger for execution

export
function
param
param
param
param

Functions

castArray

  • castArray<T>(value: T | T[]): T[]
  • Type parameters

    • T

    Parameters

    • value: T | T[]

    Returns T[]

check

  • check<K, T>(store: ReturnType<(Anonymous function) & IAction>, entityClass: T, propertyNames: keyof InstanceType<T>[] | keyof InstanceType<T>, constraint: function): number
  • Creates a CHECK constraint against a collection in the store. CHECK constraints can be against multiple columns of the row, or a single column in the row

    export

    Type parameters

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • entityClass: T
    • propertyNames: keyof InstanceType<T>[] | keyof InstanceType<T>

      The name(s) of the columns to check

    • constraint: function
        • (...args: InstanceType<T>[keyof InstanceType<T>][]): boolean
        • Parameters

          • Rest ...args: InstanceType<T>[keyof InstanceType<T>][]

          Returns boolean

    Returns number

    The ID of the trigger, for reference when deleting

checkNotNull

  • checkNotNull<T>(store: ReturnType<(Anonymous function) & IAction>, entityClass: T, propertyName: keyof InstanceType<T>): number
  • Ensures that a given column in a row is not nullable. This constraint runs on every update to the collection (i.e. every time something is added to the collection)

    export

    Type parameters

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • entityClass: T
    • propertyName: keyof InstanceType<T>

    Returns number

    The ID of the trigger, for reference when deleting

checkNotUndefined

  • checkNotUndefined<T>(store: ReturnType<(Anonymous function) & IAction>, entityClass: T, propertyName: keyof InstanceType<T>): number
  • Ensures that a given property is not undefined. This constraint runs on every update to the collection (i.e. every time something is added to the collection)

    example
    class Foo {
    
    }
    notNull(Foo);
    export

    Type parameters

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • entityClass: T
    • propertyName: keyof InstanceType<T>

    Returns number

    The ID of the trigger, for reference when deleting

checkUnique

  • checkUnique<T>(store: ReturnType<(Anonymous function) & IAction>, entityClass: T, propertyName: keyof InstanceType<T>): number
  • Creates a unique constraint on a field in a given object. This implies that the field will be indexed.

    export

    Type parameters

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • entityClass: T
    • propertyName: keyof InstanceType<T>

    Returns number

    The ID of the trigger, for reference when deleting

ensureConstructorMeta

  • ensureConstructorMeta(target: any): void
  • Ensures that the prototype contains a __meta__ attribute

    export

    Parameters

    • target: any

    Returns void

ensureMeta

  • ensureMeta(target: any): void
  • Ensures that the current target has a meta attribute attached, and ensures that the meta is attached to the target itself and not its prototype

    export

    Parameters

    • target: any

    Returns void

ensureRelationship

  • ensureRelationship(target: any, propertyKey: string, type: function, options: any): void
  • Ensures that the entity has a relationship mapping in its __meta__ property

    export

    Parameters

    • target: any
    • propertyKey: string
    • type: function
        • (): any
        • Returns any

    • options: any

    Returns void

getBoxedValueOrValue

  • getBoxedValueOrValue<T>(value: IObservableValue<T> | T): T
  • Unboxes a value from a mobx observable.box

    Type parameters

    • T

    Parameters

    • value: IObservableValue<T> | T

    Returns T

getIndexKey

  • getIndexKey<T>(value: T): PropertyKey
  • Gets the key to use for indexing purposes. Primitives return as themselves, more complex objects return as string hashes.

    Type parameters

    • T

    Parameters

    • value: T

    Returns PropertyKey

getMeta

  • getMeta(target: unknown): object
  • export

    Parameters

    • target: unknown

    Returns object

getOnlyOne

  • getOnlyOne<T>(values: T[]): T
  • Gets only a single value from a list of values. Throws if there aren't any items present or if there are too many values present

    Type parameters

    • T

    Parameters

    • values: T[]

    Returns T

indexed

  • indexed(target: any, propertyKey: PropertyKey): void
  • Creates an indexed value in the store. This will be used for fast lookups in the case of specialized filters. Currently not implemented.

    export
    function

    Parameters

    • target: any
    • propertyKey: PropertyKey

    Returns void

initializeStore

  • Intializes a store and provides helper methods bound to that store for convenience. Note: calling this function multiple times will have no side effects, multiple stores will be returned for use by the user.

    Parameters

    Returns object

invariant

  • invariant(condition: function, message: string): void
  • Determines if an invariant condition has been met and throws an error if the precondition was falsy. Includes NODE_ENV checks for dead code elimination.

    Parameters

    • condition: function
        • (): boolean
        • Returns boolean

    • message: string

    Returns void

notNull

  • notNull<T>(store: ReturnType<(Anonymous function) & IAction>): (Anonymous function)
  • Checks that a field will never receive null as a value

    export

    Type parameters

    • T

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>

    Returns (Anonymous function)

notUndefined

  • notUndefined<T>(store: ReturnType<(Anonymous function) & IAction>): (Anonymous function)
  • Checks that a field will never receive undefined as a value

    export

    Type parameters

    • T

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>

    Returns (Anonymous function)

primaryKey

  • primaryKey<T>(target: any, propertyKey: PropertyKey): void
  • Defines a primary key for the current target. This primary key will be used for uniquely identifying the object in the store, as well as identifying the entity in any relationships. Each model must have a primary key for identification purposes.

    Note: currently the primary key must be a single value. This is due to limitations in the internal storage mechanism of ES6 Maps.

    example
    class FooModel {
     @primaryKey
     id: string = uuid();
    }
    export
    function

    Type parameters

    • T

    Parameters

    • target: any
    • propertyKey: PropertyKey

    Returns void

relationship

  • relationship<K>(store: ReturnType<(Anonymous function) & IAction>, type: function, options?: CascadeOptions): (Anonymous function)
  • Describes a relationship to another model. The related model will be referenced by its primary key for accessing purposes.

    When assigning to the relationship, all items are added to the store. When removing from the list, via pop or splice, all items removed are not necessarily removed from the store unless otherwise specified in the relationship options.

    Values can also be replaced in lists via indexing. While any new values will be added to the store, replaced values will not be removed from the store unless otherwise specified in the relationship options, similar to the approach for splice and pop.

    example
    
    class BarModel {
     @primaryKey
     id: string = uuid();
    }
    
    class FooModel {
     @primaryKey
     id: string = uuid();
    
     @relationship(type => BarModel)
     friends: Bar[];
    }
    
    const f = new FooModel();
    f.friends.push(new BarModel());
    export
    function

    Type parameters

    • K

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • type: function
        • (...args: any[]): K
        • Parameters

          • Rest ...args: any[]

          Returns K

    • Default value options: CascadeOptions = {}

    Returns (Anonymous function)

setCheck

  • setCheck<T>(store: ReturnType<(Anonymous function) & IAction>, checkConstraint: function): (Anonymous function)
  • Defines a custom check function to be used while adding this object to the store.

    export

    Type parameters

    • T

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>
    • checkConstraint: function
        • (...args: keyof T[]): boolean
        • Parameters

          • Rest ...args: keyof T[]

          Returns boolean

    Returns (Anonymous function)

unique

  • unique<T>(store: ReturnType<(Anonymous function) & IAction>): (Anonymous function)
  • Checks that the field has a unique value. Implies that an index will be created

    export

    Type parameters

    • T

    Parameters

    • store: ReturnType<(Anonymous function) & IAction>

    Returns (Anonymous function)

Generated using TypeDoc