6.2.1 • Published 6 years ago

refdata-storage v6.2.1

Weekly downloads
1
License
Apache 2.0
Repository
-
Last release
6 years ago

Storage

Dynamic entity storage

Features

  • Versioning
  • Avro-style schema enforcement
  • Observable change events
  • Configurable adapters

Installation

npm install refdata-storage

Configuration

There are several ways a storage instance can be constructed. It is also possible to have multiple storage instances simultaneously within your application. Here are the main configuration setups with their respective use-cases.

Fully static setup

The storage instance always boots up from exactly the same externally controlled state. Ideal for test automation or as a source of static read-only reference data.

import createStorage from '@navarik/storage'

const storage = createStorage({
  schema: [ ...list of pre-defined schemas... ],
  data: [ ...list of pre-defined data objects (including their metadata portions)... ]
})

storage.init()

Note, that with this setup it is still possible to create schemas or entities, however these changes will not survive the application restart since the storage will be re-initialized from the static configuration each time storage.init() is called.

Static schema setup

Empty storage instance with pre-defined schemas. Entity persistance guarantee depends entirely on the provided entity changelog adapter. This setup most closely resembles classical RDBMS in the fact that schema changes would require code re-deployment and data changes would not.

import createStorage from '@navarik/storage'

const storage = createStorage({
  schema: [ ...list of pre-defined schemas... ],
  log: {
    schema: 'default',
    entity: myChangelogAdapterInstance
  }
})

storage.init()

Fully dynamic setup

Both, entity and schema persistance guarantee depends entirely on the given changelog adapter. The instance starts completely empty. Useful for multi-tenant services or user-controlled structured data storages.

import createStorage from '@navarik/storage'

const storage = createStorage({
  log: myChangelogAdapterInstance
})

storage.init()

Usage

import createStorage from '@navarik/storage'

const storage = createStorage()
storage.init()

async function main() {
  const schema = await storage.createSchema({
    name: 'test',
    fields: [
      { name: 'name', type: 'string' },
      { name: 'says', type: 'string' }
    ]
  })

  const entity = await storage.create('test', { name: 'doge', says: 'wow!' })

  console.log(entity)
}

main()

API

Factory & Configuration

Storage library's only export is factory function that is designed to generate storage instances based on provided configuration. Here are the configuratino options: schema: Array<Object> - provide static schemata in a form of an array of Avro-compatible schema definition JS objects. entity: Array<Object> - provide static entities in a form of an array of JS objects. log: 'default'|ChangeLogAdapter - global override for the change-log adapter log.schema: 'default'|ChangeLogAdapter - override for the schema change-log adapter log.entity: 'default'|ChangeLogAdapter - override for the entity change-log adapter index: 'default'|SearchIndexAdapter - global override for the local state's search index.schema: 'default'|SearchIndexAdapter - override for the schema search index adapter index.entity: 'default'|SearchIndexAdapter - override for the entity search index adapter

Instance API

init(): Promise<void> - initialize storage instance, read change-logs, re-generate search index. Usually this method is called once before any other API functions could be accessed.

isConnected(): boolean - returns true if all the adapters are connected and operational, false otherwize. Default in-memory adapters are always connected.

Schema management

getSchema: (name: string, [version: integer]): Promise<Schema> - returns schema for a given type name, undefined if no schema is found. Returns a specific version of the schema if version argument is provided, uses the latest version by default.

findSchema(filter: Object, [options: Object]): Promise<Array<Schema>> - looks for schemas that match provided filter. Supported search options: limit, offset. Returns empty array if there is no schemas matching the filter.

schemaNames(): Array<string> - returns a list of all registered entity types.

createSchema(body: Object): Promise<Schema> - registers new schema

updateSchema(name: string, body: Object): Promise<Schema> - updates existing schema

Entity management

get(id: string, [version: number, options = {}]): Promise<Entity> - fetches a single entity by its unique ID. Fetches a particular version if version argument is provided, otherwise uses the latest known version. Supported options: view ('brief' or 'canonical').

find(filter: Object, options: Object): Promise<Array<Entity>> - search for entities that match given filter. Supported search options: limit, offset, view ('brief' or 'canonical').

findContent(text: string, options: Object): Promise<Array<Entity>> - search for all the entities that have at least one field where the value includes given text. Supported options: view ('brief' or 'canonical').

count(filter: Object): Promise<number> - count the number of entities satisfying the given filter.

create(type: string, body: Object, options: Object): Promise<Entity> - create a new entity of a given type. Supported options: view ('brief' or 'canonical').

create(type: string, body: Array<Object>, options: Object): Promise<Array<Entity>> - bulk-create new entities of a given type. Supported options: view ('brief' or 'canonical').

update(id: string, body: Object, options: Object): Promise<Entity> - update existing entity. Supported options: view ('brief' or 'canonical').

validate(type: string, body: Object): string - validates given object against the schema of a given type and returns a string of discovered errors. Returns empty string.

isValid(type: string, body: Object): boolean - validates given object against the schema of a given type and returnd 'true' if the object is valid and 'false' otherwise.

observe(handler: (Entity) => void, [filter: Object]): void - give the system a callback to envoke on each entity change event. Optionally sets the filter allowing to trigger the callback only for matching entities.