@soundworks/core 3.0.4 → 3.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _parameters = _interopRequireDefault(require("@ircam/parameters"));
8
+ var _ParameterBag = _interopRequireDefault(require("./ParameterBag.js"));
9
9
 
10
10
  var _lodash = _interopRequireDefault(require("lodash.clonedeep"));
11
11
 
@@ -22,92 +22,133 @@ class SharedStatePrivate {
22
22
  constructor(id, schemaName, schema, manager, initValues = {}) {
23
23
  this.id = id;
24
24
  this.schemaName = schemaName;
25
- this._schema = (0, _lodash.default)(schema);
26
25
  this._manager = manager;
27
- this._parameters = (0, _parameters.default)(schema, initValues);
26
+ this._parameters = new _ParameterBag.default(schema, initValues);
28
27
  this._attachedClients = new Map(); // other peers interested in watching / controlling the state
29
28
 
30
29
  this._creatorRemoteId = null;
31
30
  this._creatorId = null;
32
31
  }
33
32
 
34
- _attachClient(remoteId, client, isCreator = false) {
33
+ _attachClient(remoteId, client, isOwner = false) {
35
34
  this._attachedClients.set(remoteId, client);
36
35
 
37
- if (isCreator) {
36
+ if (isOwner) {
38
37
  this._creatorRemoteId = remoteId;
39
38
  this._creatorId = client.id;
40
39
  } // attach client listeners
41
40
 
42
41
 
43
- client.transport.addListener(`${_sharedStateUtils.UPDATE_REQUEST}-${this.id}-${remoteId}`, (reqId, updates) => {
44
- const updated = {};
45
- let dirty = false;
42
+ client.transport.addListener(`${_sharedStateUtils.UPDATE_REQUEST}-${this.id}-${remoteId}`, async (reqId, updates, context) => {
43
+ // apply registered hooks
44
+ const hooks = this._manager._hooksBySchemaName.get(this.schemaName);
46
45
 
47
- for (let name in updates) {
48
- const currentValue = this._parameters.get(name); // get new value this way to store events return values
46
+ const values = this._parameters.getValues();
49
47
 
48
+ let hookAborted = false; // cf. https://github.com/collective-soundworks/soundworks/issues/45
50
49
 
51
- const newValue = this._parameters.set(name, updates[name]); // we check the `schema[name].type === 'any'`, to always consider
52
- // objects as dirty, because if the state is attached locally, we
53
- // compare the Object instances instead of their values.
54
- // @todo - this should be made more robust but how?
50
+ for (let hook of hooks.values()) {
51
+ const result = await hook(updates, values, context);
55
52
 
56
-
57
- if (newValue !== currentValue || this._schema[name].type === 'any') {
58
- updated[name] = newValue;
59
- dirty = true;
53
+ if (result === null) {
54
+ // explicit abort if hook returns null
55
+ hookAborted = true;
56
+ break;
57
+ } else if (result === undefined) {
58
+ // implicit continue if hook returns undefined
59
+ continue;
60
+ } else {
61
+ // the hook returned an updates object
62
+ updates = result;
60
63
  }
61
64
  }
62
65
 
63
- if (dirty) {
64
- // send response to requester
65
- // client.transport.emit(`${UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, updated);
66
- // @note: we propagate server-side last, because as the server transport
67
- // is synchronous it can break ordering if a subscription function makes
68
- // itself an update in reaction to an update, therefore network messages
69
- // order would be broken,
70
- // we need to handle cases where:
71
- // client state (client.id: 2) sends a request
72
- // server attached state (client.id: -1) spot a problem and overrides the value
73
- // we want the remote client (id: 2) to receive in the right order:
74
- // * 1. the value it requested,
75
- // * 2. the value overriden by the server-side attached state (id: -1)
76
- // this problem could be solved properly with a reducer system:
77
- // if (dirty) {
78
- // -> call (async) reducer
79
- // -> get values from reducer
80
- //. -> dispatch to everybody
81
- // }
82
- for (let [peerRemoteId, peer] of this._attachedClients.entries()) {
83
- // propagate notification to all other attached clients except server
84
- if (remoteId !== peerRemoteId && peer.id !== -1) {
85
- peer.transport.emit(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${this.id}-${peerRemoteId}`, updated);
66
+ if (hookAborted === false) {
67
+ const filteredUpdates = {};
68
+ let hasUpdates = false;
69
+
70
+ for (let name in updates) {
71
+ // from v3.1.0 - the `filteredUpdates` check is made using 'fast-deep-equal'
72
+ // cf. https://github.com/epoberezkin/fast-deep-equal
73
+ // therefore unchanged objects are not considered changed
74
+ // nor propagated anymore.
75
+ // until v3.0.4 - we checked the `schema[name].type === 'any'`, to always consider
76
+ // objects as dirty, because if the state is attached locally, we
77
+ // compare the Object instances instead of their values.
78
+ // @note - this should be made more robust but how?
79
+ const [newValue, changed] = this._parameters.set(name, updates[name]); // if `filterChange` is set to `false` we don't check if the value
80
+ // has been changed or not, it is always propagated to client states
81
+
82
+
83
+ const {
84
+ filterChange
85
+ } = this._parameters.getSchema(name);
86
+
87
+ if (filterChange && changed || !filterChange) {
88
+ filteredUpdates[name] = newValue;
89
+ hasUpdates = true;
86
90
  }
87
91
  }
88
92
 
89
- if (client.id !== -1) {
90
- client.transport.emit(`${_sharedStateUtils.UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, updated);
91
- }
93
+ if (hasUpdates) {
94
+ // send response to requester
95
+ // client.transport.emit(`${UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, filteredUpdates);
96
+ // @note: we propagate server-side last, because as the server transport
97
+ // is synchronous it can break ordering if a subscription function makes
98
+ // itself an update in reaction to an update, therefore network messages
99
+ // order would be broken,
100
+ // we need to handle cases where:
101
+ // client state (client.id: 2) sends a request
102
+ // server attached state (client.id: -1) spot a problem and overrides the value
103
+ // we want the remote client (id: 2) to receive in the right order:
104
+ // * 1. the value it requested,
105
+ // * 2. the value overriden by the server-side attached state (id: -1)
106
+ // this problem could be solved properly with a reducer system:
107
+ // if (dirty) {
108
+ // -> call (async) reducer
109
+ // -> get values from reducer
110
+ //. -> dispatch to everybody
111
+ // }
112
+ for (let [peerRemoteId, peer] of this._attachedClients.entries()) {
113
+ // propagate notification to all other attached clients except server
114
+ if (remoteId !== peerRemoteId && peer.id !== -1) {
115
+ peer.transport.emit(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${this.id}-${peerRemoteId}`, filteredUpdates, context);
116
+ }
117
+ }
92
118
 
93
- for (let [peerRemoteId, peer] of this._attachedClients.entries()) {
94
- // propagate notification to server
95
- if (remoteId !== peerRemoteId && peer.id === -1) {
96
- peer.transport.emit(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${this.id}-${peerRemoteId}`, updated);
119
+ if (client.id !== -1) {
120
+ client.transport.emit(`${_sharedStateUtils.UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, filteredUpdates, context);
121
+ }
122
+
123
+ for (let [peerRemoteId, peer] of this._attachedClients.entries()) {
124
+ // propagate notification to server
125
+ if (remoteId !== peerRemoteId && peer.id === -1) {
126
+ peer.transport.emit(`${_sharedStateUtils.UPDATE_NOTIFICATION}-${this.id}-${peerRemoteId}`, filteredUpdates, context);
127
+ }
97
128
  }
98
- }
99
129
 
100
- if (client.id === -1) {
101
- client.transport.emit(`${_sharedStateUtils.UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, updated);
130
+ if (client.id === -1) {
131
+ client.transport.emit(`${_sharedStateUtils.UPDATE_RESPONSE}-${this.id}-${remoteId}`, reqId, filteredUpdates, context);
132
+ }
133
+ } else {
134
+ // propagate back to the requester that the update has been aborted
135
+ // ignore all other attached clients.
136
+ client.transport.emit(`${_sharedStateUtils.UPDATE_ABORT}-${this.id}-${remoteId}`, reqId, updates, context);
102
137
  }
103
138
  } else {
104
- // propagate back to the requester that the update has been aborted
105
- // ignore all other attached clients.
106
- client.transport.emit(`${_sharedStateUtils.UPDATE_ABORT}-${this.id}-${remoteId}`, reqId, updates);
139
+ // retrieve values from inner state (also handle immediate approriately)
140
+ const oldValues = {};
141
+
142
+ for (let name in updates) {
143
+ oldValues[name] = this._parameters.get(name);
144
+ } // aborted by hook (updates have been overriden to {})
145
+
146
+
147
+ client.transport.emit(`${_sharedStateUtils.UPDATE_ABORT}-${this.id}-${remoteId}`, reqId, oldValues, context);
107
148
  }
108
149
  });
109
150
 
110
- if (isCreator) {
151
+ if (isOwner) {
111
152
  // delete only if creator
112
153
  client.transport.addListener(`${_sharedStateUtils.DELETE_REQUEST}-${this.id}-${remoteId}`, reqId => {
113
154
  this._manager._serverStatesById.delete(this.id); // --------------------------------------------------------------------
@@ -3,11 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.UPDATE_RESPONSE = exports.UPDATE_REQUEST = exports.UPDATE_NOTIFICATION = exports.UPDATE_ABORT = exports.SERVER_ID = exports.OBSERVE_RESPONSE = exports.OBSERVE_REQUEST = exports.OBSERVE_NOTIFICATION = exports.DETACH_RESPONSE = exports.DETACH_REQUEST = exports.DETACH_ERROR = exports.DELETE_SCHEMA = exports.DELETE_RESPONSE = exports.DELETE_REQUEST = exports.DELETE_NOTIFICATION = exports.DELETE_ERROR = exports.CREATE_RESPONSE = exports.CREATE_REQUEST = exports.CREATE_ERROR = exports.ATTACH_RESPONSE = exports.ATTACH_REQUEST = exports.ATTACH_ERROR = void 0;
6
7
  exports.idGenerator = idGenerator;
7
- exports.storeRequestPromise = storeRequestPromise;
8
- exports.resolveRequest = resolveRequest;
9
8
  exports.rejectRequest = rejectRequest;
10
- exports.UPDATE_NOTIFICATION = exports.UPDATE_ABORT = exports.UPDATE_RESPONSE = exports.UPDATE_REQUEST = exports.OBSERVE_NOTIFICATION = exports.OBSERVE_RESPONSE = exports.OBSERVE_REQUEST = exports.DETACH_ERROR = exports.DETACH_RESPONSE = exports.DETACH_REQUEST = exports.ATTACH_ERROR = exports.ATTACH_RESPONSE = exports.ATTACH_REQUEST = exports.DELETE_NOTIFICATION = exports.DELETE_ERROR = exports.DELETE_RESPONSE = exports.DELETE_REQUEST = exports.CREATE_ERROR = exports.CREATE_RESPONSE = exports.CREATE_REQUEST = exports.SERVER_ID = void 0;
9
+ exports.resolveRequest = resolveRequest;
10
+ exports.storeRequestPromise = storeRequestPromise;
11
11
  // id of the server when owner of a state
12
12
  const SERVER_ID = -1;
13
13
  exports.SERVER_ID = SERVER_ID;
@@ -35,8 +35,7 @@ const DETACH_REQUEST = 's:dt:req';
35
35
  exports.DETACH_REQUEST = DETACH_REQUEST;
36
36
  const DETACH_RESPONSE = 's:dt:res';
37
37
  exports.DETACH_RESPONSE = DETACH_RESPONSE;
38
- const DETACH_ERROR = 's:dt:err'; // usefull
39
-
38
+ const DETACH_ERROR = 's:dt:err';
40
39
  exports.DETACH_ERROR = DETACH_ERROR;
41
40
  const OBSERVE_REQUEST = 's:o:req';
42
41
  exports.OBSERVE_REQUEST = OBSERVE_REQUEST;
@@ -52,6 +51,8 @@ const UPDATE_ABORT = 's:u:ab';
52
51
  exports.UPDATE_ABORT = UPDATE_ABORT;
53
52
  const UPDATE_NOTIFICATION = 's:u:not';
54
53
  exports.UPDATE_NOTIFICATION = UPDATE_NOTIFICATION;
54
+ const DELETE_SCHEMA = 's:d:s';
55
+ exports.DELETE_SCHEMA = DELETE_SCHEMA;
55
56
 
56
57
  function* idGenerator() {
57
58
  for (let i = 0; true; i++) {
@@ -4,8 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.packBinaryMessage = packBinaryMessage;
7
- exports.unpackBinaryMessage = unpackBinaryMessage;
8
7
  exports.packStringMessage = packStringMessage;
8
+ exports.unpackBinaryMessage = unpackBinaryMessage;
9
9
  exports.unpackStringMessage = unpackStringMessage;
10
10
 
11
11
  require("fast-text-encoding");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soundworks/core",
3
- "version": "3.0.4",
3
+ "version": "3.1.0-beta.3",
4
4
  "description": "full-stack javascript framework for distributed audio visual experiences on the web",
5
5
  "authors": [
6
6
  "Benjamin Matuszewski",
@@ -18,10 +18,10 @@
18
18
  "main": "",
19
19
  "scripts": {
20
20
  "clean": "rm -Rf client && rm -Rf server && rm -Rf common",
21
- "docs": "rm -Rf docs && jsdoc -c .jsdoc.json --verbose && cp -R assets docs/",
21
+ "doc": "rm -Rf docs && jsdoc -c .jsdoc.json --verbose && cp -R assets docs/",
22
22
  "prepublishOnly": "npm run build",
23
23
  "toc": "markdown-toc -i README.md",
24
- "version": "npm run toc && npm run docs && git add docs",
24
+ "version": "npm run toc && npm run doc && git add docs",
25
25
  "build:client": "babel src/client --out-dir client",
26
26
  "build:server": "babel src/server --out-dir server",
27
27
  "build:common": "babel src/common --out-dir common",
@@ -32,37 +32,38 @@
32
32
  "dev": "npm run build && (npm run dev:client & npm run dev:server & npm run dev:common)"
33
33
  },
34
34
  "dependencies": {
35
- "@ircam/parameters": "^1.2.2",
36
- "braintree-jsdoc-template": "^3.3.0",
37
- "chalk": "^2.4.2",
35
+ "chalk": "^4.1.2",
38
36
  "columnify": "^1.5.4",
39
37
  "compression": "^1.7.1",
40
38
  "debug": "^4.1.1",
39
+ "fast-deep-equal": "^3.1.3",
41
40
  "fast-text-encoding": "^1.0.0",
42
41
  "isomorphic-ws": "^4.0.1",
43
- "jsdoc-template": "^1.2.0",
44
- "keyv": "^3.1.0",
45
- "keyv-file": "^0.1.13",
42
+ "keyv": "^4.0.3",
43
+ "keyv-file": "^0.2.0",
46
44
  "lodash.clonedeep": "^4.5.0",
47
45
  "lodash.merge": "^4.6.2",
48
46
  "pem": "^1.12.5",
49
47
  "polka": "^0.5.2",
50
48
  "serve-static": "^1.13.2",
51
- "uuidv4": "^4.0.0",
49
+ "uuid": "^8.3.2",
52
50
  "window-or-global": "^1.0.1",
53
- "ws": "^7.0.0"
51
+ "ws": "^8.2.3"
54
52
  },
55
53
  "devDependencies": {
56
54
  "@babel/cli": "^7.4.4",
57
55
  "@babel/core": "^7.4.5",
58
- "@babel/plugin-proposal-export-default-from": "^7.5.2",
59
56
  "@babel/preset-env": "^7.4.5",
60
57
  "chai": "^4.2.0",
61
58
  "chokidar": "^3.0.1",
62
- "chokidar-cli": "^1.2.2",
59
+ "chokidar-cli": "^3.0.0",
63
60
  "docdash": "^1.2.0",
64
61
  "jsdoc": "^3.6.2",
65
62
  "markdown-toc": "^1.2.0",
66
- "mocha": "^8.1.3"
63
+ "mocha": "^9.1.3"
64
+ },
65
+ "optionalDependencies": {
66
+ "bufferutil": "^4.0.5",
67
+ "utf-8-validate": "^5.0.7"
67
68
  }
68
69
  }
package/server/Client.js CHANGED
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _uuidv = _interopRequireDefault(require("uuidv4"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
+ var _uuid = require("uuid");
11
9
 
12
10
  function* idGenerator() {
13
11
  for (let i = 0; true; i++) {
@@ -47,7 +45,7 @@ class Client {
47
45
  * @type {String}
48
46
  */
49
47
 
50
- this.uuid = (0, _uuidv.default)();
48
+ this.uuid = (0, _uuid.v4)();
51
49
  /**
52
50
  * Socket connection with the remote {@link client.Client}.
53
51
  * @type {server.Socket}
@@ -86,7 +86,8 @@ class PluginManager {
86
86
 
87
87
  register(name, factory = null, options = {}, deps = []) {
88
88
  if (this._registeredPlugins[name]) {
89
- throw new Error(`Plugin "${name}" already registered`);
89
+ const ctor = factory(_AbstractPlugin.default);
90
+ throw new Error(`[soundworks:core] Plugin "${name}" of type "${ctor.name}" already registered`);
90
91
  }
91
92
 
92
93
  const ctor = factory(_AbstractPlugin.default);
@@ -105,7 +106,7 @@ class PluginManager {
105
106
 
106
107
  get(name, _experience = null) {
107
108
  if (!this._registeredPlugins[name]) {
108
- throw new Error(`Cannot get or require plugin "${name}", plugin is not registered
109
+ throw new Error(`[soundworks:core] Cannot get or require plugin "${name}", plugin is not registered
109
110
  > registered plugins are:
110
111
  ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
111
112
  `);
@@ -113,7 +114,7 @@ ${Object.keys(this._registeredPlugins).map(n => `> - ${n}\n`).join('')}
113
114
 
114
115
 
115
116
  if (_experience && this.signals.start.value === true) {
116
- throw new Error(`Plugin "${name}" required after pluginManager start`);
117
+ throw new Error(`[soundworks:core] Plugin "${name}" required after pluginManager start`);
117
118
  }
118
119
 
119
120
  if (!this._instances[name]) {
package/server/Server.js CHANGED
@@ -35,12 +35,17 @@ var _Sockets = _interopRequireDefault(require("./Sockets.js"));
35
35
 
36
36
  var _SharedStateManagerServer = _interopRequireDefault(require("../common/SharedStateManagerServer.js"));
37
37
 
38
- var _Db = _interopRequireDefault(require("./utils/Db.js"));
39
-
40
38
  var _logger = _interopRequireDefault(require("./utils/logger.js"));
41
39
 
40
+ var _keyv = _interopRequireDefault(require("keyv"));
41
+
42
+ var _keyvFile = _interopRequireDefault(require("keyv-file"));
43
+
42
44
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
45
 
46
+ let _dbNamespaces = new Set();
47
+
48
+ let _dbStore = null;
44
49
  /**
45
50
  * Server side entry point for a `soundworks` application.
46
51
  *
@@ -58,6 +63,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
58
63
  * const myExperience = new MyExperience();
59
64
  * soundworks.server.start();
60
65
  */
66
+
61
67
  class Server {
62
68
  constructor() {
63
69
  /**
@@ -98,7 +104,7 @@ class Server {
98
104
  * @private
99
105
  */
100
106
 
101
- this.db = new _Db.default();
107
+ this.db = this.createNamespacedDb('core');
102
108
  /**
103
109
  * The {@link server.Sockets} instance. A small wrapper around
104
110
  * [`ws`](https://github.com/websockets/ws) server.
@@ -320,8 +326,8 @@ class Server {
320
326
  }
321
327
  } else {
322
328
  return new Promise(async (resolve, reject) => {
323
- const key = await this.db.get('server:httpsKey');
324
- const cert = await this.db.get('server:httpsCert');
329
+ const key = await this.db.get('httpsKey');
330
+ const cert = await this.db.get('httpsCert');
325
331
 
326
332
  if (key && cert) {
327
333
  this._httpsInfos = {
@@ -346,8 +352,8 @@ class Server {
346
352
  key: keys.serviceKey,
347
353
  cert: keys.certificate
348
354
  };
349
- await this.db.set('server:httpsKey', this._httpsInfos.key);
350
- await this.db.set('server:httpsCert', this._httpsInfos.cert);
355
+ await this.db.set('httpsKey', this._httpsInfos.key);
356
+ await this.db.set('httpsCert', this._httpsInfos.cert);
351
357
 
352
358
  const httpsServer = _https.default.createServer(this._httpsInfos);
353
359
 
@@ -566,6 +572,44 @@ class Server {
566
572
  });
567
573
  });
568
574
  }
575
+ /**
576
+ * Create namespaced databases for core and plugins
577
+ * (kind of experiemental API do not expose in doc for now)
578
+ *
579
+ * @note - introduced in v3.1.0-beta.1
580
+ * @note - used by core and plugin-audio-streams
581
+ * @private
582
+ */
583
+
584
+
585
+ createNamespacedDb(namespace = null) {
586
+ if (namespace === null || !(typeof namespace === 'string')) {
587
+ throw new Error(`[soundworks:core] Invalid namespace for ".createNamespacedDb(namespace)", namespace is mandatory and should be a string`);
588
+ }
589
+
590
+ if (_dbNamespaces.has(namespace)) {
591
+ throw new Error(`[soundworks:core] Invalid namespace for ".createNamespacedDb(namespace)", namespace "${namespace}" already exists`);
592
+ }
593
+
594
+ const dbDirectory = _path.default.join(process.cwd(), '.data');
595
+
596
+ if (!_fs.default.existsSync(dbDirectory)) {
597
+ _fs.default.mkdirSync(dbDirectory);
598
+ }
599
+
600
+ const filename = _path.default.join(dbDirectory, `soundworks-${namespace}.db`); // at note keyv-file doesn't seems to works
601
+
602
+
603
+ const store = new _keyvFile.default({
604
+ filename
605
+ });
606
+ const db = new _keyv.default({
607
+ namespace,
608
+ store
609
+ });
610
+ db.on('error', err => console.log(chalk.red('[soundworks:core] db ${namespace} error:'), err));
611
+ return db;
612
+ }
569
613
 
570
614
  }
571
615
 
@@ -1,67 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _keyv = _interopRequireDefault(require("keyv"));
9
-
10
- var _keyvFile = _interopRequireDefault(require("keyv-file"));
11
-
12
- var _path = _interopRequireDefault(require("path"));
13
-
14
- var _fs = _interopRequireDefault(require("fs"));
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- /**
19
- * Simple in file key / value database.
20
- * Do not expose for now, may not be the right way to go...
21
- *
22
- * @todo - implement options to change storage solution.
23
- * cf. https://github.com/lukechilds/keyv
24
- *
25
- * @memberof server
26
- * @private
27
- */
28
- class Db {
29
- constructor(options = {}) {
30
- const dbDirectory = _path.default.join(process.cwd(), '.data');
31
-
32
- if (!_fs.default.existsSync(dbDirectory)) {
33
- _fs.default.mkdirSync(dbDirectory);
34
- }
35
-
36
- const filename = _path.default.join(dbDirectory, 'soundworks.db');
37
-
38
- this.keyv = new _keyv.default({
39
- namespace: 'soundworks',
40
- store: new _keyvFile.default({
41
- filename
42
- })
43
- });
44
- this.keyv.on('error', err => console.log('Connection Error', err));
45
- }
46
-
47
- async get(key) {
48
- const value = await this.keyv.get(key);
49
- return value;
50
- }
51
-
52
- async set(key, value, expireDelayMs = undefined) {
53
- await this.keyv.set(key, value, expireDelayMs);
54
- }
55
-
56
- async delete(key) {
57
- await this.keyv.delete(key);
58
- }
59
-
60
- async clear() {
61
- await this.keyv.clear();
62
- }
63
-
64
- }
65
-
66
- var _default = Db;
67
- exports.default = _default;