fable 3.0.86 → 3.0.87
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.
- package/debug/Harness.js +8 -10
- package/package.json +2 -2
- package/retold-harness/bookstore-serve-api.js +2 -2
- package/source/Fable.js +187 -50
- package/source/services/Fable-Service-Anticipate.js +1 -1
- package/source/services/Fable-Service-DataGeneration.js +1 -1
- package/source/services/Fable-Service-EnvironmentData-Web.js +1 -1
- package/source/services/Fable-Service-EnvironmentData.js +1 -1
- package/source/services/Fable-Service-FilePersistence-Web.js +2 -1
- package/source/services/Fable-Service-FilePersistence.js +25 -7
- package/source/services/Fable-Service-MetaTemplate.js +1 -1
- package/source/services/Fable-Service-Operation-DefaultSettings.js +4 -6
- package/source/services/Fable-Service-Operation.js +97 -2
- package/source/services/Fable-Service-RestClient.js +1 -1
- package/source/services/Fable-Service-Template.js +1 -1
- package/source/services/Fable-Service-Utility.js +3 -3
- package/test/Anticipate_tests.js +2 -2
- package/test/CSVParser_tests.js +1 -1
- package/test/Cache_tests.js +1 -1
- package/test/DataGeneration_tests.js +7 -7
- package/test/DateManipulation_tests.js +1 -1
- package/test/FableOperation_tests.js +33 -4
- package/test/FableServiceManager_tests.js +51 -51
- package/test/FilePersistence_tests.js +9 -9
- package/test/Manifest_tests.js +1 -1
- package/test/MetaTemplating_tests.js +1 -1
- package/test/RestClient_test.js +6 -6
- package/dist/fable.compatible.js +0 -3353
- package/dist/fable.compatible.min.js +0 -12
- package/dist/fable.compatible.min.js.map +0 -1
- package/dist/fable.js +0 -3353
- package/dist/fable.min.js +0 -12
- package/dist/fable.min.js.map +0 -1
- package/source/Fable-ServiceManager.js +0 -164
package/debug/Harness.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
let libBookstore = require('../retold-harness/bookstore-serve-meadow-endpoint-apis-run.js');
|
|
2
|
-
/*
|
|
1
|
+
//let libBookstore = require('../retold-harness/bookstore-serve-meadow-endpoint-apis-run.js');
|
|
3
2
|
const libFable = require('../source/Fable.js');
|
|
4
3
|
|
|
5
4
|
class SimpleService extends libFable.ServiceProviderBase
|
|
@@ -19,21 +18,21 @@ class SimpleService extends libFable.ServiceProviderBase
|
|
|
19
18
|
|
|
20
19
|
let testFable = new libFable({"Product": "FableDebugHarness"});
|
|
21
20
|
|
|
22
|
-
testFable.
|
|
21
|
+
testFable.addServiceType('SimpleService', SimpleService);
|
|
23
22
|
|
|
24
|
-
testFable.
|
|
23
|
+
testFable.instantiateServiceProvider('SimpleService', {SomeOption: true}, 'SimpleService-123');
|
|
25
24
|
|
|
26
25
|
|
|
27
|
-
testFable.
|
|
26
|
+
testFable.servicesMap['SimpleService']['SimpleService-123'].doSomething();
|
|
28
27
|
|
|
29
|
-
testFable.
|
|
28
|
+
testFable.SimpleService.doSomething();
|
|
30
29
|
|
|
31
|
-
console.log(`Initialized Service ${testFable.
|
|
30
|
+
console.log(`Initialized Service ${testFable.servicesMap['SimpleService']['SimpleService-123'].serviceType} as UUID ${testFable.servicesMap['SimpleService']['SimpleService-123'].UUID} with hash ${testFable.servicesMap['SimpleService']['SimpleService-123'].Hash}`);
|
|
32
31
|
|
|
33
|
-
testFable.
|
|
32
|
+
testFable.servicesMap['SimpleService']['SimpleService-123'].doSomething();
|
|
34
33
|
|
|
35
34
|
// Instantiate the RestClient Service Provider
|
|
36
|
-
let tmpRestClient = testFable.
|
|
35
|
+
let tmpRestClient = testFable.instantiateServiceProvider('RestClient', {TraceLog: true}, 'RestClient-99');
|
|
37
36
|
|
|
38
37
|
// Download the wiktionary entry for dog!
|
|
39
38
|
tmpRestClient.getJSON('https://en.wiktionary.org/w/api.php?action=parse&prop=wikitext&format=json&page=dog',
|
|
@@ -41,4 +40,3 @@ tmpRestClient.getJSON('https://en.wiktionary.org/w/api.php?action=parse&prop=wik
|
|
|
41
40
|
{
|
|
42
41
|
testFable.log.info('Response received!');
|
|
43
42
|
});
|
|
44
|
-
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fable",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.87",
|
|
4
4
|
"description": "An entity behavior management and API bundling library.",
|
|
5
5
|
"main": "source/Fable.js",
|
|
6
6
|
"scripts": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"data-arithmatic": "^1.0.7",
|
|
62
62
|
"dayjs": "^1.11.10",
|
|
63
63
|
"fable-log": "^3.0.12",
|
|
64
|
-
"fable-serviceproviderbase": "^3.0.
|
|
64
|
+
"fable-serviceproviderbase": "^3.0.12",
|
|
65
65
|
"fable-settings": "^3.0.8",
|
|
66
66
|
"fable-uuid": "^3.0.5",
|
|
67
67
|
"manyfest": "^1.0.25",
|
|
@@ -3,9 +3,9 @@ const _Settings = require('./configuration-bookstore-serve-api.js');
|
|
|
3
3
|
const libFable = require('fable');
|
|
4
4
|
|
|
5
5
|
_Fable = new libFable(_Settings);
|
|
6
|
-
_Fable.
|
|
6
|
+
_Fable.addServiceType('RetoldDataService', require('retold-data-service'));
|
|
7
7
|
// The RetoldDataService defaults to process.cwd() but we want to run this from wherever.
|
|
8
|
-
_Fable.
|
|
8
|
+
_Fable.instantiateServiceProvider('RetoldDataService',
|
|
9
9
|
{
|
|
10
10
|
"FullMeadowSchemaPath": `${__dirname}/model/`,
|
|
11
11
|
"DALMeadowSchemaPath": `${__dirname}/model/meadow/`
|
package/source/Fable.js
CHANGED
|
@@ -7,57 +7,74 @@ const libFableSettings = require('fable-settings');
|
|
|
7
7
|
const libFableUUID = require('fable-uuid');
|
|
8
8
|
const libFableLog = require('fable-log');
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const libFableServiceBase = require('fable-serviceproviderbase');
|
|
11
11
|
|
|
12
|
-
class Fable
|
|
12
|
+
class Fable extends libFableServiceBase.CoreServiceProviderBase
|
|
13
13
|
{
|
|
14
14
|
constructor(pSettings)
|
|
15
15
|
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
super(pSettings);
|
|
17
|
+
|
|
18
|
+
// Initialization Phase 0: Set up the lowest level state (fable is a utility service manager at heart)
|
|
19
|
+
this.serviceType = 'ServiceManager';
|
|
20
|
+
|
|
21
|
+
// An array of the types of services available
|
|
22
|
+
this.serviceTypes = [];
|
|
23
|
+
// A map of instantiated services
|
|
24
|
+
this.servicesMap = {};
|
|
25
|
+
// A map of the default instantiated service by type
|
|
26
|
+
this.services = {};
|
|
27
|
+
|
|
28
|
+
// A map of class constructors for services
|
|
29
|
+
this.serviceClasses = {};
|
|
30
|
+
|
|
31
|
+
// If we need extra service initialization capabilities
|
|
32
|
+
this.extraServiceInitialization = false;
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// Initialization Phase 1: Set up the core utility services
|
|
36
|
+
// These are things like power, water, and sewage. They are required for fable to run (e.g. logging, settings, etc)
|
|
21
37
|
|
|
22
38
|
// Instantiate the default Settings Manager
|
|
23
|
-
this.
|
|
39
|
+
this.SettingsManager = new libFableSettings(pSettings);
|
|
40
|
+
this.SettingsManager = this.SettingsManager;
|
|
24
41
|
// Instantiate the UUID generator
|
|
25
|
-
this.
|
|
42
|
+
this.UUID = new libFableUUID(this.SettingsManager.settings);
|
|
26
43
|
// Instantiate the logging system
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
44
|
+
this.Logging = new libFableLog(this.SettingsManager.settings);
|
|
45
|
+
this.Logging.initialize();
|
|
29
46
|
|
|
30
|
-
// Initialization Phase 1: Instantiate the service manager
|
|
31
|
-
// This is the start actual bootstrapping point for fable
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
// Bootstrapping of fable into the Service Manager is complete
|
|
47
|
+
// Initialization Phase 1.5: Instantiate the service manager
|
|
48
|
+
// This is the start actual bootstrapping point for fable.
|
|
49
|
+
// For consistency fable is treated as a service.
|
|
50
|
+
this.ServiceManager = this;
|
|
51
|
+
this.connectFable(this);
|
|
52
|
+
// --> Bootstrapping of fable into the Service Manager is complete
|
|
36
53
|
|
|
37
54
|
// Initialization Phase 2: Map in the default services.
|
|
38
55
|
// They will then be available in the Default service provider set as well.
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
this.serviceManager.connectPreinitServiceProviderInstance(this._coreServices.SettingsManager);
|
|
56
|
+
this.connectPreinitServiceProviderInstance(this.UUID);
|
|
57
|
+
this.connectPreinitServiceProviderInstance(this.Logging);
|
|
58
|
+
this.connectPreinitServiceProviderInstance(this.SettingsManager);
|
|
43
59
|
|
|
44
60
|
// Initialize and instantiate the default baked-in Data Arithmatic service
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
58
|
-
this.
|
|
61
|
+
this.addAndInstantiateServiceType('EnvironmentData', require('./services/Fable-Service-EnvironmentData.js'));
|
|
62
|
+
this.addServiceType('Template', require('./services/Fable-Service-Template.js'));
|
|
63
|
+
this.addServiceType('MetaTemplate', require('./services/Fable-Service-MetaTemplate.js'));
|
|
64
|
+
this.addServiceType('Anticipate', require('./services/Fable-Service-Anticipate.js'));
|
|
65
|
+
this.addAndInstantiateServiceType('Dates', require('./services/Fable-Service-DateManipulation.js'));
|
|
66
|
+
this.addAndInstantiateServiceType('DataFormat', require('./services/Fable-Service-DataFormat.js'));
|
|
67
|
+
this.addAndInstantiateServiceType('DataGeneration', require('./services/Fable-Service-DataGeneration.js'));
|
|
68
|
+
this.addAndInstantiateServiceType('Utility', require('./services/Fable-Service-Utility.js'));
|
|
69
|
+
this.addServiceType('Operation', require('./services/Fable-Service-Operation.js'));
|
|
70
|
+
this.addServiceType('RestClient', require('./services/Fable-Service-RestClient.js'));
|
|
71
|
+
this.addServiceType('CSVParser', require('./services/Fable-Service-CSVParser.js'));
|
|
72
|
+
this.addServiceType('Manifest', require('manyfest'));
|
|
73
|
+
this.addServiceType('ObjectCache', require('cachetrax'));
|
|
74
|
+
this.addServiceType('FilePersistence', require('./services/Fable-Service-FilePersistence.js'));
|
|
59
75
|
}
|
|
60
76
|
|
|
77
|
+
/* State Accessors */
|
|
61
78
|
get isFable()
|
|
62
79
|
{
|
|
63
80
|
return true;
|
|
@@ -65,38 +82,158 @@ class Fable
|
|
|
65
82
|
|
|
66
83
|
get settings()
|
|
67
84
|
{
|
|
68
|
-
return this.
|
|
85
|
+
return this.SettingsManager.settings;
|
|
69
86
|
}
|
|
70
87
|
|
|
71
88
|
get settingsManager()
|
|
72
89
|
{
|
|
73
|
-
return this.
|
|
90
|
+
return this.SettingsManager;
|
|
74
91
|
}
|
|
75
92
|
|
|
76
|
-
|
|
93
|
+
// For backwards compatibility
|
|
94
|
+
getUUID()
|
|
77
95
|
{
|
|
78
|
-
return this.
|
|
96
|
+
return this.UUID.getUUID();
|
|
79
97
|
}
|
|
80
98
|
|
|
81
|
-
|
|
99
|
+
/* Service Manager Methods */
|
|
100
|
+
addServiceType(pServiceType, pServiceClass)
|
|
82
101
|
{
|
|
83
|
-
|
|
102
|
+
if (this.servicesMap.hasOwnProperty(pServiceType))
|
|
103
|
+
{
|
|
104
|
+
// TODO: Check if any services are running?
|
|
105
|
+
this.log.warn(`Adding a service type [${pServiceType}] that already exists.`);
|
|
106
|
+
}
|
|
107
|
+
else
|
|
108
|
+
{
|
|
109
|
+
// Add the container for instantiated services to go in
|
|
110
|
+
this.servicesMap[pServiceType] = {};
|
|
111
|
+
|
|
112
|
+
// Add the type to the list of types
|
|
113
|
+
this.serviceTypes.push(pServiceType);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Using the static member of the class is a much more reliable way to check if it is a service class than instanceof
|
|
117
|
+
if ((typeof(pServiceClass) == 'function') && (pServiceClass.isFableService))
|
|
118
|
+
{
|
|
119
|
+
// Add the class to the list of classes
|
|
120
|
+
this.serviceClasses[pServiceType] = pServiceClass;
|
|
121
|
+
}
|
|
122
|
+
else
|
|
123
|
+
{
|
|
124
|
+
// Add the base class to the list of classes
|
|
125
|
+
this.log.error(`Attempted to add service type [${pServiceType}] with an invalid class. Using base service class, which will not crash but won't provide meaningful services.`);
|
|
126
|
+
this.serviceClasses[pServiceType] = libFableServiceBase;
|
|
127
|
+
}
|
|
84
128
|
}
|
|
85
129
|
|
|
86
|
-
|
|
130
|
+
// This is for the services that are meant to run mostly single-instance so need a default at initialization
|
|
131
|
+
addAndInstantiateServiceType(pServiceType, pServiceClass)
|
|
87
132
|
{
|
|
88
|
-
|
|
133
|
+
this.addServiceType(pServiceType, pServiceClass);
|
|
134
|
+
return this.instantiateServiceProvider(pServiceType, {}, `${pServiceType}-Default`);
|
|
89
135
|
}
|
|
90
136
|
|
|
91
|
-
|
|
137
|
+
// Some services expect to be overloaded / customized class.
|
|
138
|
+
instantiateServiceProviderFromPrototype(pServiceType, pOptions, pCustomServiceHash, pServicePrototype)
|
|
139
|
+
{
|
|
140
|
+
// Instantiate the service
|
|
141
|
+
let tmpService = new pServicePrototype(this, pOptions, pCustomServiceHash);
|
|
142
|
+
|
|
143
|
+
if (this.extraServiceInitialization)
|
|
144
|
+
{
|
|
145
|
+
tmpService = this.extraServiceInitialization(tmpService);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Add the service to the service map
|
|
149
|
+
this.servicesMap[pServiceType][tmpService.Hash] = tmpService;
|
|
150
|
+
|
|
151
|
+
// If this is the first service of this type, make it the default
|
|
152
|
+
if (!this.services.hasOwnProperty(pServiceType))
|
|
153
|
+
{
|
|
154
|
+
this.setDefaultServiceInstantiation(pServiceType, tmpService.Hash)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return tmpService;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
instantiateServiceProvider(pServiceType, pOptions, pCustomServiceHash)
|
|
161
|
+
{
|
|
162
|
+
// Instantiate the service
|
|
163
|
+
let tmpService = this.instantiateServiceProviderWithoutRegistration(pServiceType, pOptions, pCustomServiceHash);
|
|
164
|
+
|
|
165
|
+
// Add the service to the service map
|
|
166
|
+
this.servicesMap[pServiceType][tmpService.Hash] = tmpService;
|
|
167
|
+
|
|
168
|
+
// If this is the first service of this type, make it the default
|
|
169
|
+
if (!this.services.hasOwnProperty(pServiceType))
|
|
170
|
+
{
|
|
171
|
+
this.setDefaultServiceInstantiation(pServiceType, tmpService.Hash)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return tmpService;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Create a service provider but don't register it to live forever in fable.services
|
|
178
|
+
instantiateServiceProviderWithoutRegistration(pServiceType, pOptions, pCustomServiceHash)
|
|
179
|
+
{
|
|
180
|
+
// Instantiate the service
|
|
181
|
+
let tmpService = new this.serviceClasses[pServiceType](this, pOptions, pCustomServiceHash);
|
|
182
|
+
if (this.extraServiceInitialization)
|
|
183
|
+
{
|
|
184
|
+
tmpService = this.extraServiceInitialization(tmpService);
|
|
185
|
+
}
|
|
186
|
+
return tmpService;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Connect an initialized service provider that came before Fable was initialized
|
|
190
|
+
connectPreinitServiceProviderInstance(pServiceInstance)
|
|
92
191
|
{
|
|
93
|
-
|
|
192
|
+
let tmpServiceType = pServiceInstance.serviceType;
|
|
193
|
+
let tmpServiceHash = pServiceInstance.Hash;
|
|
194
|
+
|
|
195
|
+
// The service should already be instantiated, so just connect it to fable
|
|
196
|
+
pServiceInstance.connectFable(this);
|
|
197
|
+
|
|
198
|
+
// Add the service type to the map if it isn't there yet
|
|
199
|
+
if (!this.servicesMap.hasOwnProperty(tmpServiceType))
|
|
200
|
+
{
|
|
201
|
+
// If the core service hasn't registered itself yet, create the service container for it.
|
|
202
|
+
// This means you couldn't register another with this type unless it was later registered with a constructor class.
|
|
203
|
+
this.servicesMap[tmpServiceType] = {};
|
|
204
|
+
}
|
|
205
|
+
// Add the service to the service map
|
|
206
|
+
this.servicesMap[tmpServiceType][tmpServiceHash] = pServiceInstance;
|
|
207
|
+
|
|
208
|
+
// If this is the first service of this type, make it the default
|
|
209
|
+
if (!this.services.hasOwnProperty(tmpServiceType))
|
|
210
|
+
{
|
|
211
|
+
this.setDefaultServiceInstantiation(tmpServiceType, tmpServiceHash, false);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return pServiceInstance;
|
|
94
215
|
}
|
|
95
216
|
|
|
96
|
-
|
|
217
|
+
setDefaultServiceInstantiation(pServiceType, pServiceHash, pOverwriteService)
|
|
97
218
|
{
|
|
98
|
-
|
|
99
|
-
|
|
219
|
+
// Overwrite services by default, unless told not to
|
|
220
|
+
let tmpOverwriteService = (typeof(pOverwriteService) === 'undefined') ? true : pOverwriteService;
|
|
221
|
+
// Make sure the service exists
|
|
222
|
+
if (this.servicesMap[pServiceType].hasOwnProperty(pServiceHash))
|
|
223
|
+
{
|
|
224
|
+
if (!this.hasOwnProperty(pServiceType) || tmpOverwriteService)
|
|
225
|
+
{
|
|
226
|
+
this[pServiceType] = this.servicesMap[pServiceType][pServiceHash];
|
|
227
|
+
}
|
|
228
|
+
if (!this.services.hasOwnProperty(pServiceType) || tmpOverwriteService)
|
|
229
|
+
{
|
|
230
|
+
this.services[pServiceType] = this.servicesMap[pServiceType][pServiceHash];
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
100
237
|
}
|
|
101
238
|
|
|
102
239
|
// This is for backwards compatibility
|
|
@@ -109,7 +246,7 @@ module.exports = Fable;
|
|
|
109
246
|
module.exports.new = autoConstruct;
|
|
110
247
|
|
|
111
248
|
module.exports.LogProviderBase = libFableLog.LogProviderBase;
|
|
112
|
-
module.exports.ServiceProviderBase =
|
|
113
|
-
module.exports.CoreServiceProviderBase =
|
|
249
|
+
module.exports.ServiceProviderBase = libFableServiceBase;
|
|
250
|
+
module.exports.CoreServiceProviderBase = libFableServiceBase.CoreServiceProviderBase;
|
|
114
251
|
|
|
115
252
|
module.exports.precedent = libFableSettings.precedent;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const libFableServiceBase = require('
|
|
1
|
+
const libFableServiceBase = require('fable-serviceproviderbase');
|
|
2
2
|
//const libLokiDB = require('@lokidb/loki');
|
|
3
3
|
|
|
4
4
|
class FableServiceFilePersistence extends libFableServiceBase
|
|
@@ -13,6 +13,7 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
13
13
|
existsSync(pPath)
|
|
14
14
|
{
|
|
15
15
|
//return libFS.existsSync(pPath);
|
|
16
|
+
console.log('I SHOULD BE IN YOUR BUILD YO');
|
|
16
17
|
return false;
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const libFableServiceBase = require('
|
|
1
|
+
const libFableServiceBase = require('fable-serviceproviderbase');
|
|
2
2
|
|
|
3
3
|
const libFS = require('fs');
|
|
4
4
|
const libPath = require('path');
|
|
@@ -40,12 +40,6 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
40
40
|
return fCallback(null, tmpFileExists);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
writeFileSync(pFileName, pFileContent, pOptions)
|
|
44
|
-
{
|
|
45
|
-
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
46
|
-
return libFS.writeFileSync(pFileName, pFileContent, tmpOptions);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
43
|
appendFileSync(pFileName, pAppendContent, pOptions)
|
|
50
44
|
{
|
|
51
45
|
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
@@ -62,6 +56,24 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
62
56
|
return libFS.rmdirSync(pFileName);
|
|
63
57
|
}
|
|
64
58
|
|
|
59
|
+
readFileSync(pFilePath, pOptions)
|
|
60
|
+
{
|
|
61
|
+
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
62
|
+
return libFS.readFileSync(pFilePath, tmpOptions);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
readFile(pFilePath, pOptions, fCallback)
|
|
66
|
+
{
|
|
67
|
+
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
68
|
+
return libFS.readFile(pFilePath, tmpOptions, fCallback);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
writeFileSync(pFileName, pFileContent, pOptions)
|
|
72
|
+
{
|
|
73
|
+
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
74
|
+
return libFS.writeFileSync(pFileName, pFileContent, tmpOptions);
|
|
75
|
+
}
|
|
76
|
+
|
|
65
77
|
writeFileSyncFromObject(pFileName, pObject)
|
|
66
78
|
{
|
|
67
79
|
return this.writeFileSync(pFileName, JSON.stringify(pObject, null, 4));
|
|
@@ -83,6 +95,12 @@ class FableServiceFilePersistence extends libFableServiceBase
|
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
|
|
98
|
+
writeFile(pFileName, pFileContent, pOptions, fCallback)
|
|
99
|
+
{
|
|
100
|
+
let tmpOptions = (typeof(pOptions) === 'undefined') ? 'utf8' : pOptions;
|
|
101
|
+
return libFS.writeFile(pFileName, pFileContent, tmpOptions, fCallback);
|
|
102
|
+
}
|
|
103
|
+
|
|
86
104
|
lineReaderFactory(pFilePath, fOnLine, fOnComplete, fOnError)
|
|
87
105
|
{
|
|
88
106
|
let tmpLineReader = {};
|
|
@@ -4,7 +4,7 @@ module.exports = (
|
|
|
4
4
|
"UUID": false,
|
|
5
5
|
"Hash": false,
|
|
6
6
|
|
|
7
|
-
"
|
|
7
|
+
"Name": "",
|
|
8
8
|
"Summary": "",
|
|
9
9
|
|
|
10
10
|
"Version": 0
|
|
@@ -15,12 +15,10 @@ module.exports = (
|
|
|
15
15
|
"CompletionProgress": 0,
|
|
16
16
|
"CompletionTimeElapsed": 0,
|
|
17
17
|
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"StartTime": 0,
|
|
22
|
-
"EndTime": 0
|
|
18
|
+
"TimeStart": 0,
|
|
19
|
+
"TimeEnd": 0
|
|
23
20
|
},
|
|
21
|
+
"Steps": [],
|
|
24
22
|
"Errors": [],
|
|
25
23
|
"Log": []
|
|
26
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const libFableServiceBase = require('
|
|
1
|
+
const libFableServiceBase = require('fable-serviceproviderbase');
|
|
2
2
|
|
|
3
3
|
const _OperationStatePrototypeString = JSON.stringify(require('./Fable-Service-Operation-DefaultSettings.js'));
|
|
4
4
|
|
|
@@ -18,15 +18,108 @@ class FableOperation extends libFableServiceBase
|
|
|
18
18
|
|
|
19
19
|
this.state = JSON.parse(_OperationStatePrototypeString);
|
|
20
20
|
|
|
21
|
+
this.stepMap = {};
|
|
22
|
+
this.stepFunctions = {};
|
|
23
|
+
|
|
21
24
|
// Match the service instantiation to the operation.
|
|
22
25
|
this.state.Metadata.Hash = this.Hash;
|
|
23
26
|
this.state.Metadata.UUID = this.UUID;
|
|
24
27
|
|
|
25
|
-
this.
|
|
28
|
+
this.state.Metadata.Name = (typeof(this.options.Name) == 'string') ? this.options.Name : `Unnamed Operation ${this.state.Metadata.UUID}`;
|
|
29
|
+
this.name = this.state.Metadata.Name;
|
|
26
30
|
|
|
27
31
|
this.log = this;
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
execute(fExecutionCompleteCallback)
|
|
35
|
+
{
|
|
36
|
+
if (this.state.Status.TimeStart)
|
|
37
|
+
{
|
|
38
|
+
return fExecutionCompleteCallback(new Error(`Operation [${this.state.Metadata.UUID}] ${this.state.Metadata.Name} has already been executed!`));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.state.Status.TimeStart = +new Date();
|
|
42
|
+
|
|
43
|
+
let tmpAnticipate = this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < this.state.Steps; i++)
|
|
46
|
+
{
|
|
47
|
+
tmpAnticipate.anticipate(this.stepFunctions[this.state.Steps[i].GUIDStep].bind(this));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Wait for the anticipation to complete
|
|
51
|
+
tmpAnticipate.wait(
|
|
52
|
+
(pError) =>
|
|
53
|
+
{
|
|
54
|
+
this.state.Status.TimeEnd = +new Date();
|
|
55
|
+
return fExecutionCompleteCallback();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
TODO: I've gone back and forth on whether this should be an object, JSON
|
|
61
|
+
object prototype, or set of functions here. Discuss with colleagues!
|
|
62
|
+
*/
|
|
63
|
+
addStep(pGUIDStep, fStepFunction, pStepName, pStepDescription, pStepMetadata)
|
|
64
|
+
{
|
|
65
|
+
let tmpStep = {};
|
|
66
|
+
tmpStep.GUIDStep = (typeof(pGUIDStep) !== 'undefined') ? pGUIDStep : `STEP-${this.state.Steps.length}-${this.fable.DataGeneration.randomNumericString()}`;
|
|
67
|
+
tmpStep.Name = (typeof(pStepName) !== 'undefined') ? pStepName : `Step [${tmpStep.GUIDStep}]`;
|
|
68
|
+
tmpStep.Description = (typeof(pStepDescription) !== 'undefined') ? pStepDescription : `Step execution of ${tmpStep.Name}.`;
|
|
69
|
+
// TODO: Right now this allows an Array... do we want to block that?
|
|
70
|
+
tmpStep.Metadata = (typeof(pStepMetadata) === 'object') ? pStepMetadata : {};
|
|
71
|
+
|
|
72
|
+
tmpStep.TimeStart = false;
|
|
73
|
+
tmpStep.TimeEnd = false;
|
|
74
|
+
|
|
75
|
+
// There is an array of steps, in the Operation State itself ... push a step there
|
|
76
|
+
this.state.Steps.push(tmpStep);
|
|
77
|
+
|
|
78
|
+
this.stepMap[tmpStep.GUIDStep]
|
|
79
|
+
this.stepFunctions[tmpStep.GUIDStep] = fStepFunction;
|
|
80
|
+
|
|
81
|
+
this.state.Status.StepCount++;
|
|
82
|
+
return tmpStep;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getStep(pGUIDStep)
|
|
86
|
+
{
|
|
87
|
+
if (this.stepMap.hasOwnProperty(pGUIDStep))
|
|
88
|
+
{
|
|
89
|
+
return this.stepMap[pGUIDStep];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
startStep(pGUIDStep)
|
|
96
|
+
{
|
|
97
|
+
let tmpStep = this.getStep(pGUIDStep);
|
|
98
|
+
|
|
99
|
+
if (tmpStep === false)
|
|
100
|
+
{
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
tmpStep.TimeStart = +new Date();
|
|
105
|
+
|
|
106
|
+
return tmpStep;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
stopStep(pGUIDStep)
|
|
110
|
+
{
|
|
111
|
+
let tmpStep = this.getStep(pGUIDStep);
|
|
112
|
+
|
|
113
|
+
if (tmpStep === false)
|
|
114
|
+
{
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
tmpStep.TimeEnd = +new Date();
|
|
119
|
+
|
|
120
|
+
return tmpStep;
|
|
121
|
+
}
|
|
122
|
+
|
|
30
123
|
writeOperationLog(pLogLevel, pLogText, pLogObject)
|
|
31
124
|
{
|
|
32
125
|
this.state.Log.push(`${new Date().toUTCString()} [${pLogLevel}]: ${pLogText}`);
|
|
@@ -47,6 +140,7 @@ class FableOperation extends libFableServiceBase
|
|
|
47
140
|
}
|
|
48
141
|
}
|
|
49
142
|
|
|
143
|
+
|
|
50
144
|
trace(pLogText, pLogObject)
|
|
51
145
|
{
|
|
52
146
|
this.writeOperationLog('TRACE', pLogText, pLogObject);
|
|
@@ -85,6 +179,7 @@ class FableOperation extends libFableServiceBase
|
|
|
85
179
|
this.fable.log.fatal(pLogText, pLogObject);
|
|
86
180
|
}
|
|
87
181
|
|
|
182
|
+
|
|
88
183
|
/************************************************************************
|
|
89
184
|
* BEGINNING OF --> Telemetry Helpers
|
|
90
185
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const libFableServiceBase = require('
|
|
1
|
+
const libFableServiceBase = require('fable-serviceproviderbase');
|
|
2
2
|
|
|
3
3
|
// TODO: These are still pretty big -- consider the smaller polyfills
|
|
4
4
|
const libAsyncWaterfall = require('async.waterfall');
|
|
@@ -56,7 +56,7 @@ class FableServiceUtility extends libFableServiceBase
|
|
|
56
56
|
// with the added twist of returning a precompiled function ready to go.
|
|
57
57
|
template(pTemplateText, pData)
|
|
58
58
|
{
|
|
59
|
-
let tmpTemplate = this.fable.
|
|
59
|
+
let tmpTemplate = this.fable.instantiateServiceProviderWithoutRegistration('Template');
|
|
60
60
|
|
|
61
61
|
return tmpTemplate.buildTemplateFunction(pTemplateText, pData);
|
|
62
62
|
}
|
|
@@ -64,7 +64,7 @@ class FableServiceUtility extends libFableServiceBase
|
|
|
64
64
|
// Build a template function from a template hash, and, register it with the service provider
|
|
65
65
|
buildHashedTemplate(pTemplateHash, pTemplateText, pData)
|
|
66
66
|
{
|
|
67
|
-
let tmpTemplate = this.fable.
|
|
67
|
+
let tmpTemplate = this.fable.instantiateServiceProvider('Template', {}, pTemplateHash);
|
|
68
68
|
|
|
69
69
|
this.templates[pTemplateHash] = tmpTemplate.buildTemplateFunction(pTemplateText, pData);
|
|
70
70
|
|