@aj-shadow/z-abs-corelayer-server 0.0.0-aj-beta.221

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.
Files changed (87) hide show
  1. package/.gitattributes +26 -0
  2. package/LICENSE.txt +96 -0
  3. package/README.md +5 -0
  4. package/npm-shrinkwrap.json +13 -0
  5. package/package.json +10 -0
  6. package/project/server/_build/Server-CoreLayer-server.bld +12 -0
  7. package/project/server/_build/z-abs-corelayer-server.prj +12 -0
  8. package/project/server/communication/core-protocol/decoder.js +404 -0
  9. package/project/server/communication/core-protocol/encoder.js +503 -0
  10. package/project/server/communication/messages/messages-s-to-c/message-persistent-init-response.js +14 -0
  11. package/project/server/communication/messages/messages-s-to-c/message-persistent-publish.js +16 -0
  12. package/project/server/communication/messages/messages-s-to-c/message-ws-init.js +14 -0
  13. package/project/server/communication/messages/messages-s-to-s/service-init-request.js +17 -0
  14. package/project/server/communication/messages/messages-s-to-s/service-init-response.js +18 -0
  15. package/project/server/communication/messages/messages-s-to-s/service-offer-off.js +15 -0
  16. package/project/server/communication/messages/messages-s-to-s/service-offer-on.js +15 -0
  17. package/project/server/communication/messages/messages-s-to-s/worker-init-request.js +15 -0
  18. package/project/server/data-response.js +588 -0
  19. package/project/server/high-resolution-timestamp.js +36 -0
  20. package/project/server/log/log-config.js +107 -0
  21. package/project/server/log/log-types.js +14 -0
  22. package/project/server/log/logger-console.js +36 -0
  23. package/project/server/log/logger.js +114 -0
  24. package/project/server/node/channel-input.js +65 -0
  25. package/project/server/node/channel-output.js +39 -0
  26. package/project/server/node/clients.js +80 -0
  27. package/project/server/node/connection-address.js +24 -0
  28. package/project/server/node/connection-data-ip.js +82 -0
  29. package/project/server/node/connection-data.js +25 -0
  30. package/project/server/node/const.js +44 -0
  31. package/project/server/node/external-services.js +209 -0
  32. package/project/server/node/http-cache.js +109 -0
  33. package/project/server/node/http-proxy.js +97 -0
  34. package/project/server/node/http-request-handler.js +219 -0
  35. package/project/server/node/http-server.js +36 -0
  36. package/project/server/node/http2-server.js +67 -0
  37. package/project/server/node/https-server.js +63 -0
  38. package/project/server/node/ip-client.js +98 -0
  39. package/project/server/node/ip-server.js +63 -0
  40. package/project/server/node/ip-subscription.js +46 -0
  41. package/project/server/node/message-channel.js +98 -0
  42. package/project/server/node/node-admin.js +513 -0
  43. package/project/server/node/node-data.js +25 -0
  44. package/project/server/node/node-settings.js +352 -0
  45. package/project/server/node/node-worker.js +76 -0
  46. package/project/server/node/node.js +156 -0
  47. package/project/server/node/servers.js +168 -0
  48. package/project/server/node/ws-client.js +12 -0
  49. package/project/server/node/ws-server.js +20 -0
  50. package/project/server/node/ws-web-server.js +52 -0
  51. package/project/server/node/wss-server.js +20 -0
  52. package/project/server/node/wss-web-server.js +82 -0
  53. package/project/server/path/actor-path-build.js +29 -0
  54. package/project/server/path/actor-path-content.js +51 -0
  55. package/project/server/path/actor-path-creator.js +90 -0
  56. package/project/server/path/actor-path-data.js +487 -0
  57. package/project/server/path/actor-path-dist.js +132 -0
  58. package/project/server/path/actor-path-generated.js +202 -0
  59. package/project/server/path/actor-path-project.js +181 -0
  60. package/project/server/path/actor-path.js +57 -0
  61. package/project/server/path/paths/actor-content-paths.js +34 -0
  62. package/project/server/path/paths/actor-data-paths.js +302 -0
  63. package/project/server/path/paths/actor-generated-paths.js +99 -0
  64. package/project/server/path/paths/actor-paths.js +22 -0
  65. package/project/server/plugin-base-multi.js +484 -0
  66. package/project/server/plugin-base.js +233 -0
  67. package/project/server/plugin-component.js +92 -0
  68. package/project/server/plugin-data/client/plugin_data_ClientGet.js +18 -0
  69. package/project/server/plugin-data/dialog-file/plugin_data_DialogFileGet.js +197 -0
  70. package/project/server/plugin-data/platform/plugin_data_PlatformPing.js +19 -0
  71. package/project/server/plugin-factor-protocol.js +35 -0
  72. package/project/server/plugin-factory.js +127 -0
  73. package/project/server/plugin-lock.js +164 -0
  74. package/project/server/response-queue.js +46 -0
  75. package/project/server/responses.js +20 -0
  76. package/project/server/service/plugin-service.js +264 -0
  77. package/project/server/service/service-export.js +47 -0
  78. package/project/server/service/service-manager.js +270 -0
  79. package/project/server/service/service-requests.js +49 -0
  80. package/project/server/session-cache.js +39 -0
  81. package/project/server/session.js +23 -0
  82. package/project/server/worker/worker-channel.js +175 -0
  83. package/project/server/worker/worker-core.js +58 -0
  84. package/project/server/worker/worker-main.js +165 -0
  85. package/project/server/worker/worker-pool.js +94 -0
  86. package/project/server/worker/worker-thread.js +128 -0
  87. package/project/z-abs-corelayer-server.tree +99 -0
@@ -0,0 +1,92 @@
1
+
2
+ 'use strict';
3
+
4
+ const PluginFactory = require('./plugin-factory');
5
+
6
+
7
+ class PluginComponent {
8
+ constructor(client) {
9
+ this.componentName = this.constructor.name;
10
+ this.pluginService = null;
11
+ this.state = PluginComponent.STATE_NONE;
12
+ this.cb = null;
13
+ }
14
+
15
+ static STATE_NONE = 0;
16
+ static STATE_INITIALIZING = 1;
17
+ static STATE_RUNNING = 2;
18
+ static STATE_EXITING = 3;
19
+ static STATE_DONE = 4;
20
+
21
+ initData(pluginService) {
22
+ this.pluginService = pluginService;
23
+ }
24
+
25
+ init(cb) {
26
+ this.cb = cb;
27
+ this.state = PluginComponent.STATE_INITIALIZING;
28
+ try {
29
+ this.onInit();
30
+ }
31
+ catch(err) {
32
+ this._logError('initialize', err);
33
+ cb(err);
34
+ }
35
+ }
36
+
37
+ exit(cb) {
38
+ this.cb = cb;
39
+ this.state = PluginComponent.STATE_EXITING;
40
+ try {
41
+ this.onExit();
42
+ }
43
+ catch(err) {
44
+ this._logError('exit', err);
45
+ cb(err);
46
+ }
47
+ }
48
+
49
+ done(err) {
50
+ const cb = this.cb;
51
+ this.cb = null;
52
+ process.nextTick(() => {
53
+ if(PluginComponent.STATE_INITIALIZING === this.state) {
54
+ if(err) {
55
+ this._logError('initialize', err);
56
+ }
57
+ else {
58
+ this._logSuccess('initialized');
59
+ }
60
+ this.state = PluginComponent.STATE_RUNNING;
61
+ }
62
+ else if(PluginComponent.STATE_EXITING === this.state) {
63
+ if(err) {
64
+ this._logError('exit', err);
65
+ }
66
+ else {
67
+ this._logSuccess('exited');
68
+ }
69
+ this.state = PluginComponent.STATE_DONE;
70
+ }
71
+ else {
72
+ ddb.error('WRONG STATE:');
73
+ }
74
+ cb();
75
+ });
76
+ }
77
+
78
+ getService() {
79
+ return this.pluginService;
80
+ }
81
+
82
+ _logSuccess(phase) {
83
+ ddb.writelnTime(ddb.green('Component: '), this.componentName, ddb.green(' ' + phase + '.'));
84
+ }
85
+
86
+ _logError(phase, err) {
87
+ ddb.writelnTime(ddb.red('Component: ') + this.componentName, 'Could not', ddb.red(' ' + phase + '.'), err);
88
+ }
89
+ }
90
+
91
+
92
+ module.exports = PluginComponent;
@@ -0,0 +1,18 @@
1
+
2
+ 'use strict';
3
+
4
+ const PluginBaseMulti = require('../../plugin-base-multi');
5
+
6
+
7
+ class ClientStore extends PluginBaseMulti {
8
+ constructor() {
9
+ super(PluginBaseMulti.GET);
10
+ }
11
+
12
+ onRequest() {
13
+ return this.expectAsynchResponseSuccess('Hejsan hoppsan.');
14
+ }
15
+ }
16
+
17
+
18
+ module.exports = PluginsStore.export(ClientStore);
@@ -0,0 +1,197 @@
1
+
2
+ 'use strict';
3
+
4
+ const ActorPath = require('../../path/actor-path');
5
+ const ActorPathProject = require('../../path/actor-path-project');
6
+ const ActorPathData = require('../../path/actor-path-data');
7
+ const PluginBaseMulti = require('../../plugin-base-multi');
8
+ const Project = require('z-abs-corelayer-cs/clientServer/project');
9
+ const Fs = require('fs');
10
+ const Path = require('path');
11
+
12
+
13
+ class DialogFileGet extends PluginBaseMulti {
14
+ constructor() {
15
+ super(PluginBaseMulti.GET);
16
+ this.project = new Project();
17
+ this.pathFilters = [''];
18
+ this.existingFilters = [''];
19
+ this.rootName = '';
20
+ this.hasOrganization = !!Reflect.get(global, 'release-data@actorjs_global')?.organization;
21
+ }
22
+
23
+ onRequest(rootName, pathFilters, existingFilters, type, projectType, plugin, workspaceName) {
24
+ if('workspace' === type) {
25
+ this.getWorkspaceFolders(ActorPath.getActorParentPath(), (workspaces) => {
26
+ this.responsePartSuccess(workspaces);
27
+ });
28
+ }
29
+ else {
30
+ this.rootName = rootName;
31
+ const isExternalPlugin = this.hasOrganization && !!plugin;
32
+ const external = this.isExternal(this.rootName);
33
+ this.pathFilters = this._adjustFilters(pathFilters, projectType, external, isExternalPlugin);
34
+ this.existingFilters = this._adjustFilters(existingFilters, projectType, external, isExternalPlugin);
35
+ const rootPath = this.getRootPath(this.rootName, projectType, isExternalPlugin, workspaceName);
36
+ const relativeName = this.rootName.substring(2);
37
+ const node = this.project.addRootFolder(!external ? Path.parse(rootPath).base : relativeName, []);
38
+ this.project.type = projectType;
39
+ this.getFilesTree(rootPath, relativeName, type, node, external, workspaceName, (err) => {
40
+ if(!err) {
41
+ this.responsePartSuccess(this.project);
42
+ }
43
+ else {
44
+ this.responsePartError(`Could not get Dialog File: '${rootPath}'`);
45
+ }
46
+ });
47
+ }
48
+ }
49
+
50
+ getWorkspaceFolders(dir, done) {
51
+ Fs.readdir(dir, (err, files) => {
52
+ if(err) {
53
+ return done(err);
54
+ }
55
+ let pendings = files.length;
56
+ if(0 == pendings) {
57
+ done([]);
58
+ return;
59
+ }
60
+ const workspaces = [];
61
+ files.forEach((file) => {
62
+ const newDir = Path.resolve(dir, file);
63
+ Fs.stat(newDir, (err, stat) => {
64
+ if(stat && stat.isDirectory()) {
65
+ if(file.startsWith('actor') || file.startsWith('node-') || file.startsWith('persistant-node-') || file.startsWith('web-node-')) {
66
+ workspaces.push(file);
67
+ }
68
+ }
69
+ if(0 === --pendings) {
70
+ done(workspaces);
71
+ }
72
+ });
73
+ });
74
+ });
75
+ }
76
+
77
+ getFilesTree(dir, relativeName, type, node, external, workspaceName, done) {
78
+ Fs.readdir(dir, (err, files) => {
79
+ if(err) {
80
+ return done(err);
81
+ }
82
+ let pendings = files.length;
83
+ if(0 == pendings) {
84
+ done();
85
+ return;
86
+ }
87
+ files.forEach((file) => {
88
+ const newDir = Path.resolve(dir, file);
89
+ const relativeDir = Path.relative(Path.resolve(this.getRelativePath(this.rootName, workspaceName)), dir).replace(new RegExp('[\\\\]', 'g'), '/');
90
+ const relativeStart = `${relativeDir}/${file}`;
91
+ Fs.stat(newDir, (err, stat) => {
92
+ if(stat && stat.isDirectory()) {
93
+ let found = false;
94
+ this.pathFilters.forEach((folder) => {
95
+ if(folder === relativeDir) {
96
+ const foundFolderInFilter = this.existingFilters.find((fileFromExistingFilter) => {
97
+ return fileFromExistingFilter === relativeStart;
98
+ });
99
+ if(!foundFolderInFilter && 'folder' === type) {
100
+ this.project.addFolderToNode(file, `./${relativeName}`, [], node);
101
+ }
102
+ }
103
+ else if(folder.startsWith(relativeStart) && (folder === relativeStart || '/' === folder[relativeStart.length])) {
104
+ found = true;
105
+ const newNode = this.project.addFolderToNode(file, `./${relativeName}`, [], node);
106
+ this.getFilesTree(newDir, `${relativeName}/${file}`, type, newNode, external, workspaceName, (err) => {
107
+ if(0 === --pendings) {
108
+ done();
109
+ }
110
+ });
111
+ }
112
+ });
113
+ if(!found) {
114
+ if(0 === --pendings) {
115
+ done();
116
+ }
117
+ }
118
+ }
119
+ else if(stat && stat.isFile()) {
120
+ const foundFolder = this.pathFilters.find((folderFromPathFilter) => {
121
+ return folderFromPathFilter === relativeDir;
122
+ });
123
+ if(foundFolder) {
124
+ const foundFileInFilter = this.existingFilters.find((fileFromExistingFilter) => {
125
+ return fileFromExistingFilter === relativeStart;
126
+ });
127
+ if(!foundFileInFilter && 'file' === type) {
128
+ this.project.addFileToNode(file, `./${relativeName}`, file.substr(file.lastIndexOf('.') + 1, file.length), node);
129
+ }
130
+ }
131
+ if(0 === --pendings) {
132
+ done();
133
+ }
134
+ }
135
+ });
136
+ });
137
+ });
138
+ }
139
+
140
+ isExternal(pathName) {
141
+ switch(pathName) {
142
+ case './project':
143
+ case './Actors-global':
144
+ case './Actors-local':
145
+ case './Stacks-global':
146
+ case './Stacks-local':
147
+ return false;
148
+ default:
149
+ return true;
150
+ }
151
+ }
152
+
153
+ _adjustFilters(filters, projectType, external, isExternalPlugin) {
154
+ const adjustedFilters = [];
155
+ filters.forEach((filter) => {
156
+ adjustedFilters.push(ActorPathProject.getRelativePath(filter, projectType, isExternalPlugin).replace(new RegExp('[\\\\]', 'g'), '/'));
157
+ });
158
+ return adjustedFilters;
159
+ }
160
+
161
+ getRootPath(pathName, projectType, isExternalPlugin, workspaceName) {
162
+ switch(pathName) {
163
+ case './project':
164
+ return ActorPathProject.getCodeProjectFolder(null, null, workspaceName);
165
+ case './Actors-global':
166
+ return ActorPathData.getActorsGlobalFolder();
167
+ case './Actors-local':
168
+ return ActorPathData.getActorsLocalFolder();
169
+ case './Stacks-global':
170
+ return ActorPathData.getStacksGlobalFolder();
171
+ case './Stacks-local':
172
+ return ActorPathData.getStacksLocalFolder();
173
+ default:
174
+ return `${ActorPathProject.getRawPath(projectType, isExternalPlugin)}${pathName.substring(2)}${Path.sep}project`;
175
+ }
176
+ }
177
+
178
+ getRelativePath(pathName, workspaceName) {
179
+ switch(pathName) {
180
+ case './project':
181
+ return Path.normalize(`${ActorPathProject.getCodeProjectFolder(null, null, workspaceName)}/..`);
182
+ case './Actors-global':
183
+ return Path.normalize(`${ActorPathData.getActorsGlobalFolder()}/..`);
184
+ case './Actors-local':
185
+ return Path.normalize(`${ActorPathData.getActorsLocalFolder()}/..`);
186
+ case './Stacks-global':
187
+ return Path.normalize(`${ActorPathData.getStacksGlobalFolder()}/..`);
188
+ case './Stacks-local':
189
+ return Path.normalize(`${ActorPathData.getStacksLocalFolder()}/..`);
190
+ default:
191
+ return '';
192
+ }
193
+ }
194
+ }
195
+
196
+
197
+ module.exports = DialogFileGet;
@@ -0,0 +1,19 @@
1
+
2
+ 'use strict';
3
+
4
+ const PluginBase = require('../../plugin-base');
5
+
6
+
7
+ class PlatformPing extends PluginBase {
8
+ constructor() {
9
+ super(PluginBase.GET);
10
+ }
11
+
12
+ onRequest() {
13
+ return this.responsePartSuccess('ping');
14
+ }
15
+ }
16
+
17
+
18
+ module.exports = PlatformPing;
19
+
@@ -0,0 +1,35 @@
1
+
2
+ 'use strict';
3
+
4
+ const PluginFactory = require('./plugin-factory');
5
+
6
+
7
+ class PluginFactorProtocol {
8
+ constructor() {
9
+ this.pluginProtocolParams = [];
10
+ this.pluginProtocolFactory = new PluginFactory('protocol', this.pluginProtocolParams, 'clientServer');
11
+ this.protocols = [];
12
+ }
13
+
14
+ load(protocols, done) {
15
+ this.pluginProtocolFactory.setPaths(protocols);
16
+ this.pluginProtocolFactory.load(() => {
17
+ this.protocols = this.pluginProtocolFactory.createAll();
18
+ done();
19
+ });
20
+ }
21
+
22
+ register(channelInput, channelOutput) {
23
+ this.protocols.forEach((protocol) => {
24
+ if(channelInput) {
25
+ protocol.plugin.registerDeserializer(channelInput);
26
+ }
27
+ if(channelOutput) {
28
+ protocol.plugin.registerSerializer(channelOutput);
29
+ }
30
+ });
31
+ }
32
+ }
33
+
34
+
35
+ module.exports = PluginFactorProtocol;
@@ -0,0 +1,127 @@
1
+
2
+ 'use strict';
3
+
4
+ const ActorPathDist = require('./path/actor-path-dist');
5
+ const Logger = require('./log/logger');
6
+ const Fs = require('fs');
7
+ const Path = require('path');
8
+
9
+
10
+ class PluginFactory {
11
+ constructor(type, params, libType='server') {
12
+ this.libType = libType;
13
+ this.prefix = `plugin_${type}_`;
14
+ this.params = params;
15
+ this.prefix_length = this.prefix.length;
16
+ this.appSearchPath = `plugin-${type}`;
17
+ this.paths = [];
18
+ this.plugins = new Map();
19
+ }
20
+
21
+ create(name) {
22
+ const foundFactoryPath = this.plugins.get(name);
23
+ if(foundFactoryPath) {
24
+ const Plugin = require(foundFactoryPath.factoryPath);
25
+ try {
26
+ const plugin = new Plugin();
27
+ if(plugin.initData) {
28
+ plugin.initData(...this.params);
29
+ }
30
+ return plugin;
31
+ }
32
+ catch(e) {
33
+ ddb.error('Could not create plugin:', name);
34
+ console.log(e);
35
+ }
36
+ }
37
+ ddb.error('FACTORY ERROR: ' + name);
38
+ }
39
+
40
+ createAll() {
41
+ if(0 !== this.plugins.size) {
42
+ const all = [];
43
+ this.plugins.forEach((value, key) => {
44
+ const plugin = this.create(key);
45
+ all.push({libName: value.libName, plugin});
46
+ });
47
+ return all;
48
+ }
49
+ else {
50
+ return [];
51
+ }
52
+ }
53
+
54
+ _setPaths(path) {
55
+ this.paths.push(Path.join(ActorPathDist.getLayersPath(), path + `${Path.sep}${this.libType}`, this.appSearchPath));
56
+ }
57
+
58
+ setPaths(paths) {
59
+ if(Array.isArray(paths)) {
60
+ paths.forEach((path) => {
61
+ this._setPaths(path);
62
+ });
63
+ }
64
+ else {
65
+ this._setPaths(paths);
66
+ }
67
+ }
68
+
69
+ load(done, path) {
70
+ const loadPath = path ? this.paths.concat(path) : this.paths;
71
+ let pendings = loadPath.length;
72
+ if(0 === pendings) {
73
+ return done(this.plugins.size);
74
+ }
75
+ loadPath.forEach((p) => {
76
+ this.loadPlugins(p, () => {
77
+ if(0 === --pendings) {
78
+ done(this.plugins.size);
79
+ }
80
+ });
81
+ });
82
+ }
83
+
84
+ loadPlugins(path, done) {
85
+ Fs.lstat(path, (err, stat) => {
86
+ if(err) {
87
+ return done();
88
+ }
89
+ if(stat.isDirectory()) {
90
+ // We have a directory: do a tree walk
91
+ Fs.readdir(path, (err, files) => {
92
+ let file, length = files.length;
93
+ let pendings = length;
94
+ if(0 === pendings) {
95
+ done();
96
+ }
97
+ else {
98
+ for(let i = 0; i < length; ++i) {
99
+ file = Path.join(path, files[i]);
100
+ this.loadPlugins(file, () => {
101
+ if(0 === --pendings) {
102
+ done();
103
+ }
104
+ });
105
+ }
106
+ }
107
+ });
108
+ }
109
+ else if(stat.isFile()) {
110
+ const splitFilePath = path.split(Path.sep);
111
+ const libName = splitFilePath[splitFilePath.length - 4];
112
+ const filePath = splitFilePath[splitFilePath.length - 2];
113
+ const fileName = splitFilePath[splitFilePath.length - 1];
114
+ const names = fileName.split('.');
115
+ if(names[0].startsWith(this.prefix)) {
116
+ const name = names[0].substring(this.prefix_length);
117
+ const factoryPath = path.substring(0, path.lastIndexOf(Path.sep)) + Path.sep + names[0];
118
+ this.plugins.set(name, {libName, factoryPath});
119
+ }
120
+ done();
121
+ }
122
+ });
123
+ }
124
+ }
125
+
126
+
127
+ module.exports = PluginFactory;
@@ -0,0 +1,164 @@
1
+
2
+ 'use strict';
3
+
4
+
5
+ class PluginLock {
6
+ constructor() {
7
+ this.lockedReads = new Map();
8
+ this.lockedWrites = new Map();
9
+ this.queuedReads = new Map();
10
+ this.queuedWrites = new Map();
11
+ }
12
+
13
+ readLock(name, cb) {
14
+ if(!this._emptyLockedWrite(name)) {
15
+ this._addQueuedRead(name, cb);
16
+ }
17
+ else if(!this._emptyQueuedWrite(name)) {
18
+ this._addQueuedRead(name, cb);
19
+ }
20
+ else {
21
+ this._addLockedRead(name);
22
+ process.nextTick(() => {
23
+ cb(() => {
24
+ this._readLockDone(name);
25
+ });
26
+ });
27
+ }
28
+ }
29
+
30
+ writeLock(name, cb) {
31
+ if(!this._emptyLockedWrite(name)) {
32
+ this._addQueuedWrite(name, cb);
33
+ }
34
+ else if(!this._emptyLockedRead(name)) {
35
+ this._addQueuedWrite(name, cb);
36
+ }
37
+ else {
38
+ this._addLockedWrite(name);
39
+ process.nextTick(() => {
40
+ cb(() => {
41
+ this._writeLockDone(name);
42
+ });
43
+ });
44
+ }
45
+ }
46
+
47
+ _writeLockDone(name) {
48
+ this._removeLockedWrite(name);
49
+ if(!this._emptyQueuedWrite(name)) {
50
+ this.writeLock(name, this._removeQueuedWrite(name));
51
+ }
52
+ else {
53
+ while(!this._emptyQueuedRead(name)) {
54
+ this.readLock(name, this._removeQueuedRead(name));
55
+ }
56
+ }
57
+ }
58
+
59
+ _readLockDone(name) {
60
+ this._removeLockedRead(name);
61
+ if(this._emptyLockedRead(name)) {
62
+ if(!this._emptyQueuedWrite(name)) {
63
+ this.writeLock(name, this._removeQueuedWrite(name));
64
+ }
65
+ }
66
+ }
67
+
68
+ _addLocked(name, map) {
69
+ if(map.has(name)) {
70
+ const q = map.get(name);
71
+ ++q.size;
72
+ }
73
+ else {
74
+ map.set(name, {
75
+ size: 1
76
+ });
77
+ }
78
+ }
79
+
80
+ _removeLocked(name, map) {
81
+ const q = map.get(name);
82
+ if(0 === --q.size) {
83
+ map.delete(name);
84
+ }
85
+ }
86
+
87
+ _addQueued(name, cb, map) {
88
+ if(map.has(name)) {
89
+ const q = map.get(name);
90
+ q.cbs.push(cb);
91
+ ++q.size;
92
+ }
93
+ else {
94
+ map.set(name, {
95
+ cbs: [cb],
96
+ size: 1
97
+ });
98
+ }
99
+ }
100
+
101
+ _removeQueued(name, map) {
102
+ const q = map.get(name);
103
+ if(0 === --q.size) {
104
+ map.delete(name);
105
+ }
106
+ return q.cbs.splice(0, 1)[0];
107
+ }
108
+
109
+ _empty(name, map) {
110
+ const q = map.get(name);
111
+ return undefined === q;
112
+ }
113
+
114
+ _addLockedRead(name) {
115
+ this._addLocked(name, this.lockedReads);
116
+ }
117
+
118
+ _removeLockedRead(name) {
119
+ this._removeLocked(name, this.lockedReads);
120
+ }
121
+
122
+ _emptyLockedRead(name) {
123
+ return this._empty(name, this.lockedReads);
124
+ }
125
+
126
+ _addLockedWrite(name) {
127
+ this._addLocked(name, this.lockedWrites);
128
+ }
129
+
130
+ _removeLockedWrite(name) {
131
+ this._removeLocked(name, this.lockedWrites);
132
+ }
133
+
134
+ _emptyLockedWrite(name) {
135
+ return this._empty(name, this.lockedWrites);
136
+ }
137
+
138
+ _addQueuedRead(name, cb) {
139
+ this._addQueued(name, cb, this.queuedReads);
140
+ }
141
+
142
+ _removeQueuedRead(name) {
143
+ return this._removeQueued(name, this.queuedReads);
144
+ }
145
+
146
+ _emptyQueuedRead(name) {
147
+ return this._empty(name, this.queuedReads);
148
+ }
149
+
150
+ _addQueuedWrite(name, cb) {
151
+ this._addQueued(name, cb, this.queuedWrites);
152
+ }
153
+
154
+ _removeQueuedWrite(name) {
155
+ return this._removeQueued(name, this.queuedWrites);
156
+ }
157
+
158
+ _emptyQueuedWrite(name) {
159
+ return this._empty(name, this.queuedWrites);
160
+ }
161
+ }
162
+
163
+
164
+ module.exports = new PluginLock();
@@ -0,0 +1,46 @@
1
+
2
+ 'use strict';
3
+
4
+ const Responses = require('./responses');
5
+
6
+
7
+ class ResponseQueue {
8
+ constructor(cb, externalCb, id) {
9
+ this.instanceId = ++ResponseQueue.id;
10
+ this.calls = 0;
11
+ this.cb = cb;
12
+ this.externalCb = externalCb;
13
+ this.id = id;
14
+ this.responses = new Responses(id);
15
+ this.token = null;
16
+ }
17
+
18
+ static id = 0;
19
+
20
+ add() {
21
+ ++this.calls;
22
+ }
23
+
24
+ remove() {
25
+ if(0 == --this.calls) {
26
+ this.cb(this.responses, this.externalCb);
27
+ }
28
+ }
29
+
30
+ setToken(token) {
31
+ this.token = token;
32
+ }
33
+
34
+ done(response) {
35
+ this.responses.add(response);
36
+ if(0 === --this.calls) {
37
+ this.responses.responses.sort((a, b) => {
38
+ return a.index - b.index;
39
+ });
40
+ this.cb(this.responses, this.externalCb, this.token);
41
+ }
42
+ }
43
+ }
44
+
45
+
46
+ module.exports = ResponseQueue;