{"id":13510260,"url":"https://github.com/metarhia/globalstorage","last_synced_at":"2025-04-11T12:12:01.556Z","repository":{"id":8268899,"uuid":"54853532","full_name":"metarhia/globalstorage","owner":"metarhia","description":"Distributed Data Warehouse 🌍","archived":false,"fork":false,"pushed_at":"2025-03-12T15:58:43.000Z","size":2012,"stargazers_count":61,"open_issues_count":76,"forks_count":6,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-25T08:38:14.006Z","etag":null,"topics":["big-data","cloud","cluster","database","db","dbms","globalstorage","highload","in-memory","js","jstp","memory","metadata","metarhia","node","nodejs","realtime","schema","storage"],"latest_commit_sha":null,"homepage":"https://metarhia.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metarhia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-27T23:55:43.000Z","updated_at":"2025-03-15T14:17:54.000Z","dependencies_parsed_at":"2023-01-11T20:10:52.080Z","dependency_job_id":null,"html_url":"https://github.com/metarhia/globalstorage","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metarhia%2Fglobalstorage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metarhia%2Fglobalstorage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metarhia%2Fglobalstorage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metarhia%2Fglobalstorage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metarhia","download_url":"https://codeload.github.com/metarhia/globalstorage/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248398369,"owners_count":21097292,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["big-data","cloud","cluster","database","db","dbms","globalstorage","highload","in-memory","js","jstp","memory","metadata","metarhia","node","nodejs","realtime","schema","storage"],"created_at":"2024-08-01T02:01:30.967Z","updated_at":"2025-04-11T12:12:01.533Z","avatar_url":"https://github.com/metarhia.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","big-data"],"sub_categories":[],"readme":"# GlobalStorage\n\n[![TravisCI](https://travis-ci.org/metarhia/globalstorage.svg?branch=master)](https://travis-ci.org/metarhia/globalstorage)\n[![NPM Version](https://badge.fury.io/js/globalstorage.svg)](https://badge.fury.io/js/globalstorage)\n[![NPM Downloads/Month](https://img.shields.io/npm/dm/globalstorage.svg)](https://www.npmjs.com/package/globalstorage)\n[![NPM Downloads](https://img.shields.io/npm/dt/globalstorage.svg)](https://www.npmjs.com/package/globalstorage)\n\n## The Concept\n\nThis is a distributed DBMS for technological stack [Metarhia](https://github.com/metarhia/Metarhia) and it is built with following assumptions:\n\n- GS is designed to be built-in DBMS, to work inside [Impress Applications Server](https://github.com/metarhia/impress); it is needed to avoid or minimize interprocess communication to access DB;\n- GS is compatible with JSTP [JavaScript Transfer Protocol](https://github.com/metarhia/jstp), all data slould be stored, stansmitted, handled and placed in RAM in the same format;\n- All data structures can be reduced to array representation to redice size by removing key names, we can do that with the help of metadata schemas and we can dynamicaly build prototypes from schemas and assign them to arrays, so getters/setters will convert access by name (hash) to assess by position (array);\n- Maximum memory usage, read-ahead and lazy-write, minimizing data conversion;\n- Using metadata everywhere, special declarative format for subject domein representation including fields, relations, and indices so we can automatically build a storage scheme in the relational database, memory structures and structure for the database, different the GUI, API server, etc.\n- The same API for client-side runtime and server-side runtime:\n  - server-side storage engine;\n  - client-side storage engine (multiple implementations for different platforms including mobile, desktop and browser);\n  - sharding for distributed storage of large data amounts, geo-distribution, save backup copies, access load balancing;\n  - allows user to exchange data in P2P mode;\n- Syncronization between client and server in realtime (close to realtime) and in lazy mode; so applications can work in online and offline (with locally stored data); having bidirectional data sync and hieratchical versioning like git have;\n- Global data structures unification for applications working with [Metarhia](https://github.com/metarhia/Metarhia) technological stack: [GlobalStorage](https://github.com/metarhia/globalgtorage), [Impress](https://github.com/metarhia/impress), [JSTP](https://github.com/metarhia/jstp) and [Console](https://github.com/metarhia/console) through moderated distributed metadata repositories;\n- Ability to work with non-unified data structures (custom schemas), specific to certain subject domain;\n- GlobalStorage provides DAC (data access layer) abstraction, it substitutes ORM but it does not necessarily make maping on the relational model (though RDBMS are also supported);\n- Data structures have global distributed identification system, so data can be inserted anywhere and will not bring ID conflicts;\n- Data reliability is provided by distributed storage facilities, so each data structure should have master server and multiple backup and cache servers; using those servers GlobalStorage supports addressing, versioning and branching.\n\n## Metamodel Definition Language\n\nUsing this domain specific language we will describe subject domain in declarative format. To build GUI, API, business-loguic, data structures dynamically in runtime. For example we can build JavaScript prototype and assign it to positional array to access fields by name, so arrays will work like objects.\n\nExample:\n\n```js\n{\n  code: { type: 'string', primary: true },\n  name: {\n    caption: 'City',\n    type: 'string',\n    size: 32,\n    nullable: false,\n    index: { unique: false },\n    master: { dataset: 'Cities', key: 'name' }\n  },\n  birth: 'Date',\n  city: 'string',\n  addresses: {\n    type: { array: 'Address' }\n  },\n  gender: {\n    type: 'char',\n    lookup: { dictionary: { M: 'Male', F: 'Female' } }\n  },\n  age: function() {\n    var difference = new Date() - this.birth;\n    return Math.floor(difference / 31536000000);\n  }\n}\n```\n\nData types:\n\n- Built-in JavaScript types: string, number, boolean, Date, etc.\n- Global Storage types: id, uid, tree, ip, etc.\n- RDBMS data types: char, int, real, text, money, time, date...\n- Links to other data structures in GlobalStorage\n- Links to other data structures in Application\n\n## JavaScript Query Language\n\nJSQL is a query language for data structures manipulation. JSQL have syntax for:\nfilter, projection, dataset join and set operations. We have a separate\nrepository for examples and specification:\n[metarhia/JSQL](https://github.com/metarhia/JSQL). Current Implementation can\nbe found in [`lib/transformations.js`](lib/transformations.js).\n\n## Contributors\n\nSee github for full [contributors list](https://github.com/metarhia/globalstorage/graphs/contributors)\n\n## API\n\n### gs(provider, options)\n\n- `provider`: [`\u003cstring\u003e`][string] provider name\n- `options`: [`\u003cObject\u003e`][object]\n  - `serverSuffix`: [`\u003cUint64\u003e`][uint64] optional\n  - `serverBitmask`: [`\u003cUint64\u003e`][uint64] optional\n  - `systemSuffix`: [`\u003cUint64\u003e`][uint64] optional\n  - `systemBitmas`: [`\u003cUint64\u003e`][uint64] optional\n\nCreate provider\n\n#### gs.schemaConfig\n\n- [`\u003cObject\u003e`][object] metaschema config\n\n### class Cursor\n\n#### Cursor.prototype.constructor(options)\n\n#### Cursor.prototype.definition(schema, category)\n\n- `schema`: [`\u003cMetaschema\u003e`][metaschema]\n- `category`: [`\u003cstring\u003e`][string] schema name\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nAttach schema\n\n#### Cursor.prototype.enableLogging(provider, ctx, args)\n\n#### Cursor.prototype.copy()\n\n_Returns:_ [`\u003cCursor\u003e`][cursor] new instance\n\nCopy references to new dataset\n\n#### Cursor.prototype.clone()\n\n_Returns:_ [`\u003cCursor\u003e`][cursor] new instance\n\nClone all dataset objects\n\n#### Cursor.prototype.enroll(jsql)\n\n- `jsql`: [`\u003cArray\u003e`][array] commands array\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nApply JSQL commands to dataset\n\n#### Cursor.prototype.empty()\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nRemove all instances from dataset\n\n#### Cursor.prototype.from(arr)\n\n- `arr`: [`\u003cIterable\u003e`][iterable]\n\n_Returns:_ [`\u003cCursor\u003e`][cursor] new instance\n\nSynchronous virtualization converts Array to Cursor\n\n#### Cursor.prototype.map(fn)\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nLazy map\n\nfn - [`\u003cFunction\u003e`][function], map function\n\n#### Cursor.prototype.projection(fields)\n\n- `fields`: [`\u003cstring[]\u003e`][string]|[`\u003cObject\u003e`][object] projection metadata\n  array of field names or object with structure:\n  `{ toKey: [ fromKey, functions... ] }`\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nDeclarative lazy projection\n\n#### Cursor.prototype.filter(fn)\n\n- `fn`: [`\u003cFunction\u003e`][function] filtering function\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nLazy functional filter\n\n#### Cursor.prototype.select(query)\n\n- `query`: [`\u003cFunction\u003e`][function] filtering expression\n\n_Returns:_ [`\u003cCursor\u003e`][cursor] new instance\n\nDeclarative lazy filter\n\n#### Cursor.prototype.distinct()\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nLazy functional distinct filter\n\n#### Cursor.prototype.sort(fn)\n\n- `fn`: [`\u003cFunction\u003e`][function] comparing function\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nLazy functional sort\n\n#### Cursor.prototype.order(fields)\n\n- `fields`: [`\u003cstring\u003e`][string]|[`\u003cstring[]\u003e`][string]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nDeclarative lazy ascending sort\n\n#### Cursor.prototype.desc(fields)\n\n- `fields`: [`\u003cstring\u003e`][string]|[`\u003cstring[]\u003e`][string]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nDeclarative lazy descending sort\n\n#### Cursor.prototype.count(\\[field\\])\n\n- `field`: [`\u003cstring\u003e`][string] field to use for count, optional\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate count\n\n#### Cursor.prototype.sum(field)\n\n- `field`: [`\u003cstring\u003e`][string] field to use for sum\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate sum\n\n#### Cursor.prototype.avg(field)\n\n- `field`: [`\u003cstring\u003e`][string] field to use for avg\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate avg\n\n#### Cursor.prototype.max(field)\n\n- `field`: [`\u003cstring\u003e`][string] field to use for max\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate max\n\n#### Cursor.prototype.min(field)\n\n- `field`: [`\u003cstring\u003e`][string] field to use for min\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate min\n\n#### Cursor.prototype.col()\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nConvert first column of dataset to Array\n\n#### Cursor.prototype.row()\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nReturn first row from dataset\n\n#### Cursor.prototype.one()\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nGet single first record from dataset\n\n#### Cursor.prototype.limit(count)\n\n- `count`: [`\u003cnumber\u003e`][number]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nGet first n records from dataset\n\n#### Cursor.prototype.offset(offset)\n\n- `offset`: [`\u003cnumber\u003e`][number]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nOffset into the dataset\n\n#### Cursor.prototype.union(cursor)\n\n- `cursor`: [`\u003cCursor\u003e`][cursor]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate union and put results to this Cursor instance\n\n#### Cursor.prototype.intersection(cursor)\n\n- `cursor`: [`\u003cCursor\u003e`][cursor]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate intersection and put results to this Cursor instance\n\n#### Cursor.prototype.difference(cursor)\n\n- `cursor`: [`\u003cCursor\u003e`][cursor]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate difference and put results to this Cursor instance\n\n#### Cursor.prototype.complement(cursor)\n\n- `cursor`: [`\u003cCursor\u003e`][cursor]\n\n_Returns:_ [`\u003cthis\u003e`][this]\n\nCalculate complement and put results to this Cursor instance\n\n#### Cursor.prototype.selectToMemory(query)\n\n#### async Cursor.prototype.continue(data)\n\n- `data`: [`\u003cArray\u003e`][array] rows to date\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nContinue computations via i.e. MemoryCursor or other cursor\n\nto handle remaining operations unsupported by current cursor\n\n#### async Cursor.prototype.fetch(\\[permissionChecker\\])\n\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet results after applying consolidated jsql\n\n### class StorageProvider\n\nAbstract Storage Provider\n\n#### StorageProvider.prototype.constructor(options)\n\n- `options`: [`\u003cObject\u003e`][object]\n  - `serverSuffix`: [`\u003cUint64\u003e`][uint64] optional\n  - `serverBitmask`: [`\u003cUint64\u003e`][uint64] optional\n  - `systemSuffix`: [`\u003cUint64\u003e`][uint64] optional\n  - `systemBitmas`: [`\u003cUint64\u003e`][uint64] optional\n\nCreate StorageProvider\n\n#### async StorageProvider.prototype.open(options)\n\n- `options`: [`\u003cObject\u003e`][object]\n  - `schema`: [`\u003cMetaschema\u003e`][metaschema]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nOpen StorageProvider\n\n#### async StorageProvider.prototype.close()\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nClose StorageProvider\n\n#### async StorageProvider.prototype.setup(options)\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nSetup StorageProvider\n\n#### StorageProvider.prototype.enableLogging(ctx)\n\n#### StorageProvider.prototype.error(name, ...ctx)\n\n- `name`: [`\u003cstring\u003e`][string] error name that must be equal to one of the\n  values from the Action's Errors field\n- `ctx`: [`\u003cArray\u003e`][array]\n\nUtility method to generate `\u003cActionError\u003e` from inside the Action\n\n#### async StorageProvider.prototype.takeId()\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGenerate globally unique id\n\n#### async StorageProvider.prototype.get(id\\[, permissionChecker\\])\n\n- `id`: [`\u003cstring\u003e`][string] globally unique object id\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet object from GlobalStorage\n\n#### async StorageProvider.prototype.getDetails(category, id, fieldName\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to get details in\n- `id`: [`\u003cstring\u003e`][string] object id\n- `fieldName`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet details for many-to-many link from GlobalStorage\n\n#### async StorageProvider.prototype.set(obj\\[, permissionChecker\\])\n\n- `obj`: [`\u003cObject\u003e`][object] to be stored\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nSet object in GlobalStorage\n\n#### async StorageProvider.prototype.create(category, obj\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to store the object in\n- `obj`: [`\u003cObject\u003e`][object] to be stored\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nCreate object in GlobalStorage\n\n#### async StorageProvider.prototype.update(category, query, patch\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to update the records in\n- `query`: [`\u003cObject\u003e`][object] example: `{ Id }`\n- `patch`: [`\u003cObject\u003e`][object] fields to update\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUpdate object in GlobalStorage\n\n#### async StorageProvider.prototype.delete(category, query\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to delete the records from\n- `query`: [`\u003cObject\u003e`][object] example: `{ Id }`\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nDelete object in GlobalStorage\n\n#### async StorageProvider.prototype.linkDetails(category, field, fromId, toIds\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nLink records with Many relation between them\n\n#### async StorageProvider.prototype.unlinkDetails(category, field, fromId, toIds\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUnlink records with Many relation between them\n\n#### StorageProvider.prototype.select(category, query\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to select the records from\n- `query`: [`\u003cObject\u003e`][object] fields conditions\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cCursor\u003e`][cursor]\n\nSelect objects from GlobalStorage\n\n#### async StorageProvider.prototype.execute(category, action, actionArgs\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string]|[`\u003cnull\u003e`][null] category name or null to\n  execute public action\n- `action`: [`\u003cstring\u003e`][string] action name\n- `actionArgs`: [`\u003cObject\u003e`][object]\n  - `context`: [`\u003cObject\u003e`][object]\n  - `args`: [`\u003cObject\u003e`][object]\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `action`: [`\u003cstring\u003e`][string]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nExecute an action\n\n#### StorageProvider.prototype.log(op, args, ctx, response)\n\n#### StorageProvider.prototype.getSystemSuffix(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cUint64\u003e`][uint64]\n\nGet system suffix for given id\n\n#### StorageProvider.prototype.curSystem(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cboolean\u003e`][boolean]\n\nCheck whether data with given id is stored on this system\n\n#### StorageProvider.prototype.getServerSuffix(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cUint64\u003e`][uint64]\n\nGet server suffix for given id\n\n#### StorageProvider.prototype.curServer(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cboolean\u003e`][boolean]\n\nCheck whether data with given id is stored on this server\n\n#### StorageProvider.prototype.getLocalId(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cUint64\u003e`][uint64]\n\nGet id without system and server suffix\n\n#### StorageProvider.prototype.parseId(id)\n\n- `id`: [`\u003cUint64\u003e`][uint64]\n\n_Returns:_ [`\u003cObject\u003e`][object]\n\n- `systemSuffix`: [`\u003cUint64\u003e`][uint64] system suffix for given id\n- `serverSuffix`: [`\u003cUint64\u003e`][uint64] server suffix for given id\n- `localId`: [`\u003cUint64\u003e`][uint64] id without system and server suffix\n\nParse id\n\n#### async StorageProvider.prototype.listApplications(\\[filtererByRoles\\])\n\n- `filtererByRoles`: [`\u003cFunction\u003e`][function] optional\n  - `applications`: [`\u003cstring[]\u003e`][string]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nList all available applications\n\n#### async StorageProvider.prototype.listCategories(\\[filtererByPermission\\])\n\n- `filtererByPermission`: [`\u003cFunction\u003e`][function] optional\n  - `categories`: [`\u003cstring[]\u003e`][string]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nList all available categories\n\n#### async StorageProvider.prototype.listActions(\\[filtererByPermission\\])\n\n- `filtererByPermission`: [`\u003cFunction\u003e`][function] optional\n  - `actions`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nList all available actions\n\n#### StorageProvider.prototype.createJstpApi()\n\n#### async StorageProvider.prototype.getSchemaSources({ categoryList, actionLists, appList } = {})\n\n#### async StorageProvider.prototype.getCategoryL10n(langTag, category)\n\n#### async StorageProvider.prototype.getDomainsL10n(langTag)\n\n#### async StorageProvider.prototype.getCommonL10n(langTag)\n\n#### async StorageProvider.prototype.getFormL10n(langTag, category, form)\n\n#### async StorageProvider.prototype.getActionL10n(langTag, category, action)\n\n### class FsProvider extends [StorageProvider][storageprovider]\n\n#### FsProvider.prototype.constructor(options // { path } where path is database location)\n\n#### FsProvider.prototype.readStat(callback)\n\n#### FsProvider.prototype.open(options, callback)\n\n#### FsProvider.prototype.writeStat(callback)\n\n#### FsProvider.prototype.close(callback)\n\n#### FsProvider.prototype.takeId(callback)\n\n#### FsProvider.prototype.get(id, callback)\n\n#### FsProvider.prototype.create(obj, callback)\n\n#### FsProvider.prototype.update(obj, callback)\n\n#### FsProvider.prototype.delete(id, callback)\n\n#### FsProvider.prototype.select(query, options, callback)\n\n### class MemoryProvider extends [StorageProvider][storageprovider]\n\n#### MemoryProvider.prototype.constructor(callback)\n\n#### MemoryProvider.prototype.close(callback)\n\n#### MemoryProvider.prototype.create(obj, callback)\n\n### class PostgresProvider extends [StorageProvider][storageprovider]\n\n#### PostgresProvider.prototype.constructor()\n\nCreate PostgresProvider\n\n#### async PostgresProvider.prototype.open(options)\n\n- `options`: [`\u003cObject\u003e`][object] to be passed to pg\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nOpen PostgresProvider\n\n#### async PostgresProvider.prototype.close()\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nClose PostgresProvider\n\n#### async PostgresProvider.prototype.setup(options)\n\n- `options`: [`\u003cObject\u003e`][object]\n  - `maxIdCount`: [`\u003cnumber\u003e`][number]\n  - `refillPercent`: [`\u003cnumber\u003e`][number]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nSetup StorageProvider\n\n#### async PostgresProvider.prototype.takeId(client)\n\n- `client`: [`\u003cpg.Pool\u003e`][pg.pool]|[`\u003cpg.Client\u003e`][pg.client]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGenerate globally unique id\n\n#### async PostgresProvider.prototype.getCategoryById(id)\n\n#### async PostgresProvider.prototype.beginTx(\\[options\\])\n\n- `options`: [`\u003cObject\u003e`][object] transaction options\n  - `isolationLevel`: [`\u003cstring\u003e`][string] 'committed', 'repeatable', or\n    'serializable'\n  - `readOnly`: [`\u003cboolean\u003e`][boolean]\n  - `deferrable`: [`\u003cboolean\u003e`][boolean]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nBegin transaction, returns a Promise that resolves in an object containing\n\nsome of the methods of the current provider and also the methods `commit()`,\n`rollback()`, and `release()`. For more detailed description of the options see\nhttps://www.postgresql.org/docs/current/sql-set-transaction.html\n\n#### async PostgresProvider.prototype.get(id\\[, permissionChecker\\])\n\n- `id`: [`\u003cstring\u003e`][string] globally unique object id\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet object from GlobalStorage\n\n#### async PostgresProvider.prototype.getDetails(category, id, fieldName\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to get details in\n- `id`: [`\u003cstring\u003e`][string] object id\n- `fieldName`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet details for many-to-many link from GlobalStorage\n\n#### async PostgresProvider.prototype.set(obj\\[, permissionChecker\\])\n\n- `obj`: [`\u003cObject\u003e`][object] to be stored\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nSet object in GlobalStorage\n\n#### async PostgresProvider.prototype.create(category, obj\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to store the object in\n- `obj`: [`\u003cObject\u003e`][object] to be stored\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nCreate object in GlobalStorage\n\n#### async PostgresProvider.prototype.update(category, query, patch\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to update the records in\n- `query`: [`\u003cObject\u003e`][object] example: `{ Id }`\n- `patch`: [`\u003cObject\u003e`][object] fields to update\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUpdate object in GlobalStorage\n\n#### async PostgresProvider.prototype.delete(category, query\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category to delete the records from\n- `query`: [`\u003cObject\u003e`][object] example: `{ Id }`\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nDelete object in GlobalStorage\n\n#### async PostgresProvider.prototype.linkDetails(category, field, fromId, toIds\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nLink records with Many relation between them\n\n#### async PostgresProvider.prototype.unlinkDetails(category, field, fromId, toIds\\[, permissionChecker\\])\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n- `permissionChecker`: [`\u003cFunction\u003e`][function] optional\n  - `category`: [`\u003cstring\u003e`][string]\n  - `options`: [`\u003cObject\u003e`][object]\n- _Returns:_ [`\u003cPromise\u003e`][promise]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUnlink records with Many relation between them\n\n#### PostgresProvider.prototype.select(category, query)\n\n- `category`: [`\u003cstring\u003e`][string] category to select the records from\n- `query`: [`\u003cObject\u003e`][object] fields conditions\n\n_Returns:_ [`\u003cCursor\u003e`][cursor]\n\nSelect objects from GlobalStorage\n\n### class RemoteProvider extends [StorageProvider][storageprovider]\n\n#### RemoteProvider.prototype.constructor(options = {})\n\n#### async RemoteProvider.prototype.open(options)\n\n- `options`: [`\u003cObject\u003e`][object] options for jstp connection\n  - `transport`: [`\u003cstring\u003e`][string] jstp transport name\n  - `connectionArgs`: [`\u003cArray\u003e`][array] arguments to be passed to corresponding\n    transport's connect method\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nOpen RemoteProvider\n\n#### async RemoteProvider.prototype.close()\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nClose RemoteProvider\n\n#### async RemoteProvider.prototype.get(id)\n\n- `id`: [`\u003cstring\u003e`][string] globally unique record id\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet record from GlobalStorage\n\n#### async RemoteProvider.prototype.getDetails(category, id, fieldName)\n\n- `category`: [`\u003cstring\u003e`][string] category to get details in\n- `id`: [`\u003cstring\u003e`][string] object id\n- `fieldName`: [`\u003cstring\u003e`][string] field with the Many decorator\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nGet details for many-to-many link from GlobalStorage\n\n#### async RemoteProvider.prototype.set(record)\n\n- `record`: [`\u003cObject\u003e`][object] record to be stored\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nSet record in GlobalStorage\n\n#### async RemoteProvider.prototype.create(category, record)\n\n- `category`: [`\u003cstring\u003e`][string] category of record\n- `record`: [`\u003cObject\u003e`][object] record to be stored\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nCreate record in GlobalStorage\n\n#### async RemoteProvider.prototype.update(category, query, patch)\n\n- `category`: [`\u003cstring\u003e`][string] category of record\n- `query`: [`\u003cObject\u003e`][object] record, example: `{ Id }`\n- `patch`: [`\u003cObject\u003e`][object] record, fields to update\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUpdate record in GlobalStorage\n\n#### async RemoteProvider.prototype.delete(category, query)\n\n- `category`: [`\u003cstring\u003e`][string] category of record\n- `query`: [`\u003cObject\u003e`][object] record, example: `{ Id }`\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nDelete record in GlobalStorage\n\n#### async RemoteProvider.prototype.unlinkDetails(category, field, fromId, toIds)\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nUnlink records with Many relation between them\n\n#### async RemoteProvider.prototype.linkDetails(category, field, fromId, toIds)\n\n- `category`: [`\u003cstring\u003e`][string] category with field having the Many decorator\n- `field`: [`\u003cstring\u003e`][string] field with the Many decorator\n- `fromId`: [`\u003cUint64\u003e`][uint64] Id of the record in category specified in the\n  first argument\n- `toIds`: [`\u003cUint64\u003e`][uint64]|[`\u003cUint64[]\u003e`][uint64] Id(s) of the record(s) in\n  category specified in the Many decorator of the specified field\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nLink records with Many relation between them\n\n#### RemoteProvider.prototype.select(category, query)\n\n- `category`: [`\u003cstring\u003e`][string] category of record\n- `query`: [`\u003cObject\u003e`][object] fields conditions\n\n_Returns:_ [`\u003cCursor\u003e`][cursor] cursor\n\nSelect record from GlobalStorage\n\n#### async RemoteProvider.prototype.execute(category, action, actionArgs)\n\n- `category`: [`\u003cstring\u003e`][string]|[`\u003cnull\u003e`][null] category name or null to\n  execute public action\n- `action`: [`\u003cstring\u003e`][string] action name\n- `actionArgs`: [`\u003cObject\u003e`][object]\n  - `context`: [`\u003cObject\u003e`][object]\n  - `args`: [`\u003cObject\u003e`][object]\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nExecute an action\n\n#### async RemoteProvider.prototype.getSchemaSources()\n\n#### async RemoteProvider.prototype.listCategories()\n\n#### async RemoteProvider.prototype.listCategoriesPermissions()\n\n_Returns:_ [`\u003cPromise\u003e`][promise]\n\nList categories permission flags\n\n#### async RemoteProvider.prototype.listActions()\n\n#### async RemoteProvider.prototype.listApplications()\n\n#### async RemoteProvider.prototype.getCategoryL10n(langTag, category)\n\n#### async RemoteProvider.prototype.getDomainsL10n(langTag)\n\n#### async RemoteProvider.prototype.getCommonL10n(langTag)\n\n#### async RemoteProvider.prototype.getFormL10n(langTag, category, form)\n\n#### async RemoteProvider.prototype.getActionL10n(langTag, category, action)\n\n[pg.pool]: https://github.com/brianc/node-pg-pool\n[pg.client]: https://github.com/brianc/node-postgres\n[uint64]: https://github.com/metarhia/common#class-uint64\n[metaschema]: https://github.com/metarhia/metaschema#class-metaschema\n[cursor]: #class-cursor\n[storageprovider]: #class-storageprovider\n[object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object\n[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function\n[promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise\n[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array\n[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\n[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Null_type\n[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type\n[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type\n[iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols\n[this]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetarhia%2Fglobalstorage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetarhia%2Fglobalstorage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetarhia%2Fglobalstorage/lists"}