common-entities v2.0.0
Common Entities
An extensible ORM that uses native JavaScript property descriptors, part of the Common Framework.
Installation
Install it from NPM:
npm install common-entities
Usage
Entity definition
Defining entity types that "just work" is the goal of the module. Entities can be defines as a collection of properties and an associated storage. Each entity type must be given a unique key:
let definition = commonEntities.defineEntity("ExampleType")
.defineProperties({
name: commonEntities.defineProperty().as({ primitive: "text" })
})
.associateStorage(someStorage);
The storage must be some object that extends the Storage
class from the Common Storage package.
To access the constructor function of the newly defined entity, use the .type
property of the definition. For convenience, all such automatically generated constructors implement the IReferenceable
interface from the Common Collections package.
Property definition
Properties are the unit by which entities serialize and deserialize values. They can be defined using the .defineProperty
method, and their type can be specified using .as(type)
. The type is an object of the following format:
{
primitive: <string>,
// For arrays
isArray: <boolean>,
// For entity references
isEntity: <boolean>
}
The value of the primitive
property corresponds to a type in PostgreSQL. In the case that the type is an entity reference, the primitive
value is a unique key for an entity type.
Local entity management
Because entities directly correspond to entries in storage, each must map to a unique key and vice versa. Implicitly, every entity can be identified by the combination of an entity type and key.
To fetch an entity, use the asynchronous .fetchEntity(definition, key)
method of Common Entities or the curried .fetchEntity(key)
on the definition itself.
Note that entities are cached indefinitely until manually dissociated. To forcibly acquire an entity from its storage (and likely cause unfixable divergences if an entity with the same key is already referenced elsewhere in the application) use the acquireEntity
methods in the same pattern. You may also use the .fetchEntityLocal
methods to get a cached entity without reverting to storage if it isn't present.
Entities will be cached indefinitely until manually dissociated. This functionality will be documented because per-type caching policies will be implemented in a future release.
De/serialization
Due to the fact that entities can be referenced by their type and key, references can be serialized. Utilities for serializing and deserializing references to entities are included. These references can be embedded deeply in objects and arrays and still be de/serialized. Use the .serialize(value)
and .deserialize(value)
methods. Note that deserialization is asynchronous because entities must be fetched.
Additionally, the methods .serializeTyped(value, type)
and .deserializeTyped(value, type)
are exposed in case you want to use type objects as specified above to constrain de/serialization.