@frusal/library v0.0.33
The official library for connecting to frusal.com workspace.
The official library for connecting to frusal.com workspace. Depends on autobahn and rxjs.
š§ The project is in development and is not available for general public yet. // 2020-08-22
It is recommended to use Frusal CLI to install and manage declaration schema with this library, though not strictly required.
There are three flavours of this library: pre-packaged to be used in a browser or run under node, and not packaged to be used in a more advanced build setups.
NPM Package | Target Environment | Dependencies | Note |
---|---|---|---|
@frusal/library-for-browser | Browser | - | Ready to use bundle |
@frusal/library-for-node | Node | - | Ready to use bundle |
@frusal/library | any | autobahn, rxjs | Flexible |
Frameworks
For Angular, React and Vue.js frameworks, we recommend to use @frusal/library.
Code
Workspace Schema
The schema (class structure) could be created via frusal.com UI, or programmatically via a script. See this schema creation script example.
Session and Login
import { session } from '@frusal/library-for-browser';
await session.login({
loginId: 'john.citizen@example.com',
password: 'yM8yXA(jMbsUpy,=',
workspace: 'playground'
});
Stage and Transaction
await session.workspace.withTempStageAsyncExpression(async stage => {
await stage.transact(async transaction => {
const fruit = transaction.createEntity(Fruit);
fruit.name = 'Plum';
});
});
const owner = new Owner();
try {
const stage = await session.createStage(owner);
const transaction = this.stage.beginTransaction();
const actualWorkspace = transaction.getSingletonInstance(ActualWorkspace);
console.log(`actualWorkspace.name=${actualWorkspace.name}`);
const plum = await await this.stage.query({ q: 'b0o4cF', type: QPType.BY_ID }).promiseFirstOfType(Fruit);
plum.delete();
} finally {
owner.close();
}
Query
Get all instances of class Fruit
at indexed store:
const fruits = await this.stage.query({ q: Fruit.id, type: QPType.BY_CLASS_ID }).promiseArray() as Fruit[];
There are different queries possible, depends on the underlying store type. There are indexed store and consolidated store. Indexed store, stores entities in separate indexed (Lucene) documents and Consolidated store keeps all entities in one document (as JSON BLOB). As such, large tables which require complex queries should be stored in indexed store (Order, Order Line); and limited row tables like lookups (Product), properties, etc are best stored at a consolidated store.
Default store is configured on per class level.
Subscriptions
An auto-updating subscription below would make the client to subscribe to the server for live updates. Alternatively, depend on the requirements and performance limitations, entity.refresh()
can be called at times, or whole stage
reconstructed - which always takes the fresh values.
Instance level subscription:
fruit.subscribeToChanges(owner, { autoupdate: true, callback: evt => {
console.log(`Entity ${evt.entity.id} is changed.`);
}});
Class level subscription:
Fruit.classSpec.subscribeToCreatedAndDeleted(owner, { autoupdate: true, callback: evt => {
console.log(`Entity ${evt.entity.id} is ${evt.entity.deleted ? 'deleted' : 'created'}.`);
}});
Note that classSpec.subscribeToChanges
monitors the class object instance itself (as in class schema model) and has nothing to do with its instances and their changes.
instance.field_pv.subscribeToChanges(//... field level
instance.subscribeToChanges(//... instance level
classSpec.subscribeToCreatedAndDeleted(//... class level
store.subscribeToChanges(//... store level
Examples and Tutorials
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago