fable 3.1.71 → 3.1.73
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/docs/README.md +30 -6
- package/docs/_brand.json +18 -0
- package/docs/_playground.json +10 -0
- package/docs/_sidebar.md +2 -0
- package/docs/_version.json +3 -3
- package/docs/architecture.md +201 -39
- package/docs/index.html +6 -7
- package/docs/pict-docuserve.min.js +91 -0
- package/docs/pict-docuserve.min.js.map +1 -0
- package/docs/playground.md +38 -0
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +8721 -8105
- package/docs/services/README.md +26 -9
- package/docs/services/anticipate.md +104 -40
- package/docs/services/csv-parser.md +63 -35
- package/docs/services/data-format.md +154 -49
- package/docs/services/data-generation.md +77 -16
- package/docs/services/dates.md +103 -36
- package/docs/services/environment-data.md +13 -2
- package/docs/services/expression-parser.md +280 -68
- package/docs/services/file-persistence.md +142 -150
- package/docs/services/logging.md +93 -37
- package/docs/services/logic.md +70 -22
- package/docs/services/manifest.md +114 -26
- package/docs/services/math.md +168 -63
- package/docs/services/meta-template.md +312 -158
- package/docs/services/object-cache.md +94 -11
- package/docs/services/operation.md +68 -6
- package/docs/services/progress-time.md +74 -13
- package/docs/services/progress-tracker-set.md +101 -3
- package/docs/services/rest-client.md +136 -104
- package/docs/services/settings-manager.md +133 -40
- package/docs/services/template.md +71 -22
- package/docs/services/utility.md +121 -29
- package/docs/services/uuid.md +58 -10
- package/package.json +4 -4
- package/source/services/Fable-Service-RestClient.js +204 -7
- package/test/RestClient_test.js +342 -0
- package/.claude/settings.local.json +0 -8
|
@@ -5,12 +5,17 @@ The ObjectCache service (powered by [cachetrax](https://github.com/stevenvelozo/
|
|
|
5
5
|
## Access
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
10
|
+
|
|
8
11
|
// On-demand service - instantiate when needed
|
|
9
12
|
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
13
|
+
console.log('cache:', typeof cache);
|
|
10
14
|
|
|
11
15
|
// Create named caches for different purposes
|
|
12
|
-
const userCache
|
|
16
|
+
const userCache = fable.instantiateServiceProvider('ObjectCache', {}, 'user-cache');
|
|
13
17
|
const sessionCache = fable.instantiateServiceProvider('ObjectCache', {}, 'session-cache');
|
|
18
|
+
console.log('userCache and sessionCache instantiated:', typeof userCache, typeof sessionCache);
|
|
14
19
|
```
|
|
15
20
|
|
|
16
21
|
## Basic Operations
|
|
@@ -18,35 +23,60 @@ const sessionCache = fable.instantiateServiceProvider('ObjectCache', {}, 'sessio
|
|
|
18
23
|
### Put (Add or Update)
|
|
19
24
|
|
|
20
25
|
```javascript
|
|
26
|
+
const libFable = require('fable');
|
|
27
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
28
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
29
|
+
|
|
21
30
|
cache.put('some-data', 'my-key');
|
|
22
31
|
// Stores 'some-data' with hash 'my-key'
|
|
23
32
|
// If 'my-key' already exists, updates the stored datum
|
|
24
33
|
|
|
25
34
|
cache.put({ name: 'John', age: 30 }, 'user-123');
|
|
26
35
|
// Stores an object with hash 'user-123'
|
|
36
|
+
|
|
37
|
+
console.log('my-key:', cache.read('my-key'));
|
|
38
|
+
console.log('user-123:', cache.read('user-123'));
|
|
27
39
|
```
|
|
28
40
|
|
|
29
41
|
### Read
|
|
30
42
|
|
|
31
43
|
```javascript
|
|
44
|
+
const libFable = require('fable');
|
|
45
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
46
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
47
|
+
|
|
48
|
+
cache.put('some-data', 'my-key');
|
|
32
49
|
const data = cache.read('my-key');
|
|
50
|
+
console.log('data:', data);
|
|
33
51
|
// Returns the stored datum, or false if not found
|
|
34
52
|
```
|
|
35
53
|
|
|
36
54
|
### Expire (Remove)
|
|
37
55
|
|
|
38
56
|
```javascript
|
|
39
|
-
|
|
57
|
+
const libFable = require('fable');
|
|
58
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
59
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
60
|
+
|
|
61
|
+
cache.put('some-data', 'my-key');
|
|
62
|
+
console.log(cache.expire('my-key'));
|
|
40
63
|
// Removes the entry from the cache and returns the removed node
|
|
41
64
|
// Returns false if the key doesn't exist
|
|
65
|
+
console.log('After expire — read:', cache.read('my-key'));
|
|
42
66
|
```
|
|
43
67
|
|
|
44
68
|
### Touch (Refresh)
|
|
45
69
|
|
|
46
70
|
```javascript
|
|
71
|
+
const libFable = require('fable');
|
|
72
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
73
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
74
|
+
|
|
75
|
+
cache.put('some-data', 'my-key');
|
|
47
76
|
cache.touch('my-key');
|
|
48
77
|
// Moves the entry to the tail of the list and resets its timestamp
|
|
49
78
|
// Useful for keeping frequently accessed items fresh
|
|
79
|
+
console.log('after touch — my-key still present:', cache.read('my-key'));
|
|
50
80
|
```
|
|
51
81
|
|
|
52
82
|
## Size-Based Expiration
|
|
@@ -56,15 +86,19 @@ cache.touch('my-key');
|
|
|
56
86
|
Set `maxLength` to automatically evict the oldest entry when the cache exceeds the limit:
|
|
57
87
|
|
|
58
88
|
```javascript
|
|
89
|
+
const libFable = require('fable');
|
|
90
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
91
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
92
|
+
|
|
59
93
|
cache.maxLength = 2;
|
|
60
94
|
|
|
61
95
|
cache.put('A', 'ABC');
|
|
62
96
|
cache.put('D', 'DEF');
|
|
63
|
-
|
|
97
|
+
console.log('After two puts:', Object.keys(cache.RecordMap));
|
|
64
98
|
|
|
65
99
|
cache.put('G', 'GHI');
|
|
66
100
|
// ABC is automatically evicted
|
|
67
|
-
|
|
101
|
+
console.log('After third put (evicts oldest):', Object.keys(cache.RecordMap));
|
|
68
102
|
```
|
|
69
103
|
|
|
70
104
|
Setting `maxLength` to `0` (the default) disables automatic size-based eviction on insert. To enforce a new smaller `maxLength` on existing entries, call `prune()`.
|
|
@@ -76,7 +110,12 @@ Setting `maxLength` to `0` (the default) disables automatic size-based eviction
|
|
|
76
110
|
Set `maxAge` (in milliseconds) to expire entries older than the specified age when `prune()` is called:
|
|
77
111
|
|
|
78
112
|
```javascript
|
|
113
|
+
const libFable = require('fable');
|
|
114
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
115
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
116
|
+
|
|
79
117
|
cache.maxAge = 60000; // 1 minute
|
|
118
|
+
console.log('cache.maxAge:', cache.maxAge);
|
|
80
119
|
```
|
|
81
120
|
|
|
82
121
|
## Pruning
|
|
@@ -86,9 +125,15 @@ cache.maxAge = 60000; // 1 minute
|
|
|
86
125
|
Prune the cache based on both `maxAge` and `maxLength` rules. Expired entries are removed first, then size limits are enforced:
|
|
87
126
|
|
|
88
127
|
```javascript
|
|
128
|
+
const libFable = require('fable');
|
|
129
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
130
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
131
|
+
|
|
89
132
|
cache.maxLength = 2;
|
|
90
133
|
|
|
91
134
|
// After adding many entries...
|
|
135
|
+
for (let i = 0; i < 5; i++) cache.put('value-' + i, 'key-' + i);
|
|
136
|
+
|
|
92
137
|
cache.prune((removedRecords) => {
|
|
93
138
|
console.log(`Pruned ${removedRecords.length} entries`);
|
|
94
139
|
// Cache is now within maxLength
|
|
@@ -100,6 +145,11 @@ cache.prune((removedRecords) => {
|
|
|
100
145
|
Prune only entries older than `maxAge`:
|
|
101
146
|
|
|
102
147
|
```javascript
|
|
148
|
+
const libFable = require('fable');
|
|
149
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
150
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
151
|
+
|
|
152
|
+
cache.put('fresh', 'recent-key');
|
|
103
153
|
cache.maxAge = 30000; // 30 seconds
|
|
104
154
|
cache.pruneBasedOnExpiration((removed) => {
|
|
105
155
|
console.log(`Expired ${removed.length} old entries`);
|
|
@@ -111,6 +161,12 @@ cache.pruneBasedOnExpiration((removed) => {
|
|
|
111
161
|
Prune only based on `maxLength`, popping entries from the head (oldest) of the list:
|
|
112
162
|
|
|
113
163
|
```javascript
|
|
164
|
+
const libFable = require('fable');
|
|
165
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
166
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
167
|
+
|
|
168
|
+
cache.maxLength = 2;
|
|
169
|
+
for (let i = 0; i < 5; i++) cache.put('v-' + i, 'k-' + i);
|
|
114
170
|
cache.pruneBasedOnLength((removed) => {
|
|
115
171
|
console.log(`Evicted ${removed.length} entries for length`);
|
|
116
172
|
});
|
|
@@ -121,6 +177,14 @@ cache.pruneBasedOnLength((removed) => {
|
|
|
121
177
|
Prune entries using a custom function. The function receives `(datum, hash, node)` and should return `true` to expire the entry:
|
|
122
178
|
|
|
123
179
|
```javascript
|
|
180
|
+
const libFable = require('fable');
|
|
181
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
182
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
183
|
+
|
|
184
|
+
cache.put('temp-A', 'key-1');
|
|
185
|
+
cache.put('keep-me', 'key-2');
|
|
186
|
+
cache.put('temp-B', 'key-3');
|
|
187
|
+
|
|
124
188
|
cache.pruneCustom(
|
|
125
189
|
(removed) => { console.log(`Custom pruned ${removed.length}`); },
|
|
126
190
|
(datum, hash, node) => {
|
|
@@ -128,6 +192,7 @@ cache.pruneCustom(
|
|
|
128
192
|
return typeof datum === 'string' && datum.startsWith('temp');
|
|
129
193
|
}
|
|
130
194
|
);
|
|
195
|
+
console.log('Remaining keys:', Object.keys(cache.RecordMap));
|
|
131
196
|
```
|
|
132
197
|
|
|
133
198
|
## Low-Level Access
|
|
@@ -137,10 +202,15 @@ cache.pruneCustom(
|
|
|
137
202
|
Get the full linked list node (including metadata) for a hash:
|
|
138
203
|
|
|
139
204
|
```javascript
|
|
205
|
+
const libFable = require('fable');
|
|
206
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
207
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
208
|
+
|
|
209
|
+
cache.put('some-data', 'my-key');
|
|
140
210
|
const node = cache.getNode('my-key');
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
211
|
+
console.log('node.Datum:', node.Datum);
|
|
212
|
+
console.log('node.Hash:', node.Hash);
|
|
213
|
+
console.log('node.Metadata.Created:', node.Metadata.Created);
|
|
144
214
|
```
|
|
145
215
|
|
|
146
216
|
### RecordMap
|
|
@@ -148,8 +218,14 @@ const node = cache.getNode('my-key');
|
|
|
148
218
|
Access the record map directly (a plain object mapping hashes to data):
|
|
149
219
|
|
|
150
220
|
```javascript
|
|
221
|
+
const libFable = require('fable');
|
|
222
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
223
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
224
|
+
|
|
225
|
+
cache.put('some-data', 'my-key');
|
|
226
|
+
cache.put({ name: 'John', age: 30 }, 'user-123');
|
|
151
227
|
const allRecords = cache.RecordMap;
|
|
152
|
-
|
|
228
|
+
console.log('allRecords:', allRecords);
|
|
153
229
|
```
|
|
154
230
|
|
|
155
231
|
### Internal List
|
|
@@ -157,9 +233,16 @@ const allRecords = cache.RecordMap;
|
|
|
157
233
|
The cache is backed by a linked list accessible via `cache._List`:
|
|
158
234
|
|
|
159
235
|
```javascript
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
cache
|
|
236
|
+
const libFable = require('fable');
|
|
237
|
+
const fable = new libFable({ Product: 'ObjectCacheDemo', ProductVersion: '1.0.0' });
|
|
238
|
+
const cache = fable.instantiateServiceProvider('ObjectCache');
|
|
239
|
+
|
|
240
|
+
cache.put('A', 'a-key');
|
|
241
|
+
cache.put('B', 'b-key');
|
|
242
|
+
|
|
243
|
+
console.log('length:', cache._List.length); // Number of entries in the cache
|
|
244
|
+
console.log('head.Datum:', cache._List.head ? cache._List.head.Datum : null);
|
|
245
|
+
console.log('tail.Datum:', cache._List.tail ? cache._List.tail.Datum : null);
|
|
163
246
|
```
|
|
164
247
|
|
|
165
248
|
## Notes
|
|
@@ -5,8 +5,12 @@ The Operation service provides phased step execution with built-in progress trac
|
|
|
5
5
|
## Access
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
10
|
+
|
|
8
11
|
// On-demand service - instantiate when needed
|
|
9
12
|
const operation = fable.instantiateServiceProvider('Operation', { Name: 'My Operation' }, 'MY-OP-1');
|
|
13
|
+
console.log('operation:', typeof operation, 'name:', operation.state.Metadata.Name);
|
|
10
14
|
```
|
|
11
15
|
|
|
12
16
|
## Basic Usage
|
|
@@ -14,9 +18,13 @@ const operation = fable.instantiateServiceProvider('Operation', { Name: 'My Oper
|
|
|
14
18
|
### Create an Operation
|
|
15
19
|
|
|
16
20
|
```javascript
|
|
21
|
+
const libFable = require('fable');
|
|
22
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
23
|
+
|
|
17
24
|
const operation = fable.instantiateServiceProvider('Operation', {
|
|
18
25
|
Name: 'Data Import'
|
|
19
26
|
}, 'IMPORT-123');
|
|
27
|
+
console.log('Operation created:', operation.state.Metadata.Name);
|
|
20
28
|
```
|
|
21
29
|
|
|
22
30
|
### Add Steps
|
|
@@ -24,6 +32,10 @@ const operation = fable.instantiateServiceProvider('Operation', {
|
|
|
24
32
|
Use `addStep()` to register sequential steps. Each step function receives a completion callback and runs with a bound context:
|
|
25
33
|
|
|
26
34
|
```javascript
|
|
35
|
+
const libFable = require('fable');
|
|
36
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
37
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Data Import' }, 'IMPORT-123');
|
|
38
|
+
|
|
27
39
|
operation.addStep(
|
|
28
40
|
function (fStepComplete) {
|
|
29
41
|
this.log.info('Validating input...');
|
|
@@ -47,6 +59,8 @@ operation.addStep(
|
|
|
47
59
|
'Process all records',
|
|
48
60
|
'PROCESS-STEP'
|
|
49
61
|
);
|
|
62
|
+
|
|
63
|
+
console.log('Registered steps:', operation.state.Status.StepCount);
|
|
50
64
|
```
|
|
51
65
|
|
|
52
66
|
### Execute the Operation
|
|
@@ -54,6 +68,15 @@ operation.addStep(
|
|
|
54
68
|
Steps execute sequentially in the order they were added:
|
|
55
69
|
|
|
56
70
|
```javascript
|
|
71
|
+
const libFable = require('fable');
|
|
72
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
73
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Demo' }, 'DEMO-1');
|
|
74
|
+
|
|
75
|
+
operation.addStep(function (fStepComplete) {
|
|
76
|
+
this.log.info('Step 1 running');
|
|
77
|
+
fStepComplete();
|
|
78
|
+
}, {}, 'Step1', 'first step', 'S1');
|
|
79
|
+
|
|
57
80
|
operation.execute((pError) => {
|
|
58
81
|
if (pError) {
|
|
59
82
|
fable.log.error('Operation failed', { error: pError.message });
|
|
@@ -83,6 +106,10 @@ Inside a step function, `this` is bound to a context object with these propertie
|
|
|
83
106
|
### Set Total Operations for a Step
|
|
84
107
|
|
|
85
108
|
```javascript
|
|
109
|
+
const libFable = require('fable');
|
|
110
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
111
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Demo' }, 'TOTALS-1');
|
|
112
|
+
|
|
86
113
|
operation.addStep(
|
|
87
114
|
function (fStepComplete) {
|
|
88
115
|
// ... step work ...
|
|
@@ -93,11 +120,20 @@ operation.addStep(
|
|
|
93
120
|
|
|
94
121
|
// Set expected total operations for the step
|
|
95
122
|
operation.setStepTotalOperations('PROCESS-STEP', 100);
|
|
123
|
+
console.log('Step PROCESS-STEP total ops registered.');
|
|
96
124
|
```
|
|
97
125
|
|
|
98
126
|
### Increment Progress Within a Step
|
|
99
127
|
|
|
100
128
|
```javascript
|
|
129
|
+
const libFable = require('fable');
|
|
130
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
131
|
+
|
|
132
|
+
const items = ['a', 'b', 'c'];
|
|
133
|
+
function processItem(item) { console.log('processed:', item); }
|
|
134
|
+
|
|
135
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Item Processor' }, 'ITEMS-1');
|
|
136
|
+
|
|
101
137
|
operation.addStep(
|
|
102
138
|
function (fStepComplete) {
|
|
103
139
|
this.ProgressTracker.setProgressTrackerTotalOperations(items.length);
|
|
@@ -117,6 +153,8 @@ operation.addStep(
|
|
|
117
153
|
},
|
|
118
154
|
{}, 'Process Items', 'Process each item with tracking', 'ITEMS-STEP'
|
|
119
155
|
);
|
|
156
|
+
|
|
157
|
+
operation.execute((pError) => console.log('Done — pError:', pError));
|
|
120
158
|
```
|
|
121
159
|
|
|
122
160
|
## Operation State and Logging
|
|
@@ -124,12 +162,16 @@ operation.addStep(
|
|
|
124
162
|
The operation maintains a structured state object:
|
|
125
163
|
|
|
126
164
|
```javascript
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
operation.
|
|
130
|
-
|
|
131
|
-
operation.state.
|
|
132
|
-
operation.state.
|
|
165
|
+
const libFable = require('fable');
|
|
166
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
167
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'State Demo' }, 'STATE-1');
|
|
168
|
+
|
|
169
|
+
console.log('Metadata.UUID:', operation.state.Metadata.UUID); // Unique identifier
|
|
170
|
+
console.log('Metadata.Name:', operation.state.Metadata.Name); // Operation name
|
|
171
|
+
console.log('Status.StepCount:', operation.state.Status.StepCount); // Number of registered steps
|
|
172
|
+
console.log('Steps:', operation.state.Steps); // Array of step state entries
|
|
173
|
+
console.log('Log:', operation.state.Log); // Array of log strings
|
|
174
|
+
console.log('Errors:', operation.state.Errors); // Array of error strings
|
|
133
175
|
```
|
|
134
176
|
|
|
135
177
|
### Built-in Log Methods
|
|
@@ -137,19 +179,29 @@ operation.state.Errors // Array of error strings
|
|
|
137
179
|
The operation provides logging methods that write to both fable.log and the operation's internal log:
|
|
138
180
|
|
|
139
181
|
```javascript
|
|
182
|
+
const libFable = require('fable');
|
|
183
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
184
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Log Demo' }, 'LOG-1');
|
|
185
|
+
|
|
140
186
|
operation.log.trace('Trace message');
|
|
141
187
|
operation.log.debug('Debug message');
|
|
142
188
|
operation.log.info('Info message');
|
|
143
189
|
operation.log.warn('Warning message');
|
|
144
190
|
operation.log.error('Error message'); // Also writes to state.Errors
|
|
145
191
|
operation.log.fatal('Fatal message'); // Also writes to state.Errors
|
|
192
|
+
console.log('state.Errors count:', operation.state.Errors.length);
|
|
146
193
|
```
|
|
147
194
|
|
|
148
195
|
### Logging with Data
|
|
149
196
|
|
|
150
197
|
```javascript
|
|
198
|
+
const libFable = require('fable');
|
|
199
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
200
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Log With Data' }, 'LOGDATA-1');
|
|
201
|
+
|
|
151
202
|
operation.log.debug('Processing', { TestData: 'Ignition Complete' });
|
|
152
203
|
// Appends JSON stringified data to the log
|
|
204
|
+
console.log('Last log entry:', operation.state.Log[operation.state.Log.length - 1]);
|
|
153
205
|
```
|
|
154
206
|
|
|
155
207
|
## Use Cases
|
|
@@ -157,6 +209,13 @@ operation.log.debug('Processing', { TestData: 'Ignition Complete' });
|
|
|
157
209
|
### Multi-Step Async Workflow
|
|
158
210
|
|
|
159
211
|
```javascript
|
|
212
|
+
const libFable = require('fable');
|
|
213
|
+
const fable = new libFable({ Product: 'OperationDemo', ProductVersion: '1.0.0' });
|
|
214
|
+
|
|
215
|
+
// Stubs for the playground demo
|
|
216
|
+
function importRecord(rec, cb) { console.log('imported:', rec); cb(); }
|
|
217
|
+
function finalizeImport(cb) { console.log('finalized'); cb(); }
|
|
218
|
+
|
|
160
219
|
function createImportOperation(fable, records) {
|
|
161
220
|
const operation = fable.instantiateServiceProvider('Operation', {
|
|
162
221
|
Name: 'Record Import'
|
|
@@ -195,6 +254,9 @@ function createImportOperation(fable, records) {
|
|
|
195
254
|
|
|
196
255
|
return operation;
|
|
197
256
|
}
|
|
257
|
+
|
|
258
|
+
const op = createImportOperation(fable, [{ id: 1 }, { id: 2 }, { id: 3 }]);
|
|
259
|
+
op.execute((pError) => console.log('Import done — pError:', pError));
|
|
198
260
|
```
|
|
199
261
|
|
|
200
262
|
## Notes
|
|
@@ -5,8 +5,11 @@ The ProgressTime service provides named timestamp creation and delta measurement
|
|
|
5
5
|
## Access
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
10
|
+
|
|
8
11
|
// Auto-instantiated, available directly
|
|
9
|
-
fable.ProgressTime
|
|
12
|
+
console.log('fable.ProgressTime:', typeof fable.ProgressTime);
|
|
10
13
|
```
|
|
11
14
|
|
|
12
15
|
## Basic Timing
|
|
@@ -14,11 +17,16 @@ fable.ProgressTime
|
|
|
14
17
|
### Create a Timestamp
|
|
15
18
|
|
|
16
19
|
```javascript
|
|
20
|
+
const libFable = require('fable');
|
|
21
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
22
|
+
|
|
17
23
|
// Create a 'Default' timestamp (no hash specified)
|
|
18
24
|
fable.ProgressTime.createTimeStamp();
|
|
19
25
|
|
|
20
26
|
// Create a named timestamp
|
|
21
27
|
fable.ProgressTime.createTimeStamp('MyOperation');
|
|
28
|
+
|
|
29
|
+
console.log('Timestamps:', Object.keys(fable.ProgressTime.timeStamps));
|
|
22
30
|
```
|
|
23
31
|
|
|
24
32
|
### Get Elapsed Time (Delta)
|
|
@@ -26,18 +34,23 @@ fable.ProgressTime.createTimeStamp('MyOperation');
|
|
|
26
34
|
Measure milliseconds elapsed since a timestamp was created:
|
|
27
35
|
|
|
28
36
|
```javascript
|
|
37
|
+
const libFable = require('fable');
|
|
38
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
39
|
+
|
|
29
40
|
fable.ProgressTime.createTimeStamp();
|
|
30
41
|
|
|
31
42
|
// ... do some work ...
|
|
43
|
+
await new Promise(r => setTimeout(r, 10));
|
|
32
44
|
|
|
33
45
|
const elapsed = fable.ProgressTime.getTimeStampDelta();
|
|
34
|
-
|
|
46
|
+
console.log('elapsed since Default:', elapsed, 'ms');
|
|
35
47
|
|
|
36
48
|
// With a named timestamp
|
|
37
49
|
fable.ProgressTime.createTimeStamp('DatabaseQuery');
|
|
38
50
|
// ... query ...
|
|
51
|
+
await new Promise(r => setTimeout(r, 5));
|
|
39
52
|
const queryTime = fable.ProgressTime.getTimeStampDelta('DatabaseQuery');
|
|
40
|
-
|
|
53
|
+
console.log('queryTime:', queryTime, 'ms');
|
|
41
54
|
```
|
|
42
55
|
|
|
43
56
|
Returns `-1` if the timestamp doesn't exist.
|
|
@@ -45,14 +58,18 @@ Returns `-1` if the timestamp doesn't exist.
|
|
|
45
58
|
### Get Duration Between Two Timestamps
|
|
46
59
|
|
|
47
60
|
```javascript
|
|
61
|
+
const libFable = require('fable');
|
|
62
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
63
|
+
|
|
48
64
|
fable.ProgressTime.createTimeStamp('Start');
|
|
49
65
|
|
|
50
66
|
// ... some time passes ...
|
|
67
|
+
await new Promise(r => setTimeout(r, 25));
|
|
51
68
|
|
|
52
69
|
fable.ProgressTime.createTimeStamp('End');
|
|
53
70
|
|
|
54
71
|
const duration = fable.ProgressTime.getDurationBetweenTimestamps('Start', 'End');
|
|
55
|
-
|
|
72
|
+
console.log('Duration Start..End:', duration, 'ms');
|
|
56
73
|
```
|
|
57
74
|
|
|
58
75
|
## Timestamp Management
|
|
@@ -60,31 +77,49 @@ const duration = fable.ProgressTime.getDurationBetweenTimestamps('Start', 'End')
|
|
|
60
77
|
### Get Timestamp Value
|
|
61
78
|
|
|
62
79
|
```javascript
|
|
80
|
+
const libFable = require('fable');
|
|
81
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
82
|
+
|
|
83
|
+
fable.ProgressTime.createTimeStamp('MyOperation');
|
|
63
84
|
const value = fable.ProgressTime.getTimeStampValue('MyOperation');
|
|
85
|
+
console.log('value:', value);
|
|
64
86
|
// Returns the raw millisecond timestamp, or -1 if not found
|
|
65
87
|
```
|
|
66
88
|
|
|
67
89
|
### Remove a Timestamp
|
|
68
90
|
|
|
69
91
|
```javascript
|
|
70
|
-
|
|
92
|
+
const libFable = require('fable');
|
|
93
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
94
|
+
|
|
95
|
+
fable.ProgressTime.createTimeStamp('MyOperation');
|
|
96
|
+
console.log(fable.ProgressTime.removeTimeStamp('MyOperation'));
|
|
71
97
|
// Returns true if removed, false if it didn't exist
|
|
72
98
|
```
|
|
73
99
|
|
|
74
100
|
### Update a Timestamp
|
|
75
101
|
|
|
76
102
|
```javascript
|
|
103
|
+
const libFable = require('fable');
|
|
104
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
105
|
+
|
|
106
|
+
fable.ProgressTime.createTimeStamp('MyOperation');
|
|
77
107
|
fable.ProgressTime.updateTimeStampValue('MyOperation');
|
|
78
|
-
|
|
108
|
+
console.log('After current-time update:', fable.ProgressTime.getTimeStampValue('MyOperation'));
|
|
79
109
|
|
|
80
110
|
fable.ProgressTime.updateTimeStampValue('MyOperation', 1700000000000);
|
|
81
|
-
|
|
111
|
+
console.log('After explicit update:', fable.ProgressTime.getTimeStampValue('MyOperation'));
|
|
82
112
|
```
|
|
83
113
|
|
|
84
114
|
### Access All Timestamps
|
|
85
115
|
|
|
86
116
|
```javascript
|
|
87
|
-
fable
|
|
117
|
+
const libFable = require('fable');
|
|
118
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
119
|
+
|
|
120
|
+
fable.ProgressTime.createTimeStamp();
|
|
121
|
+
fable.ProgressTime.createTimeStamp('MyOperation');
|
|
122
|
+
console.log(fable.ProgressTime.timeStamps);
|
|
88
123
|
// { Default: 1700000000000, MyOperation: 1700000001000, ... }
|
|
89
124
|
```
|
|
90
125
|
|
|
@@ -93,16 +128,30 @@ fable.ProgressTime.timeStamps
|
|
|
93
128
|
### Get Delta Message
|
|
94
129
|
|
|
95
130
|
```javascript
|
|
131
|
+
const libFable = require('fable');
|
|
132
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
133
|
+
|
|
134
|
+
fable.ProgressTime.createTimeStamp();
|
|
135
|
+
fable.ProgressTime.createTimeStamp('DatabaseQuery');
|
|
136
|
+
await new Promise(r => setTimeout(r, 10));
|
|
137
|
+
|
|
96
138
|
const message = fable.ProgressTime.getTimeStampDeltaMessage();
|
|
97
|
-
|
|
139
|
+
console.log(message);
|
|
98
140
|
|
|
99
141
|
const customMessage = fable.ProgressTime.getTimeStampDeltaMessage('DatabaseQuery', 'DB query took');
|
|
100
|
-
|
|
142
|
+
console.log(customMessage);
|
|
101
143
|
```
|
|
102
144
|
|
|
103
145
|
### Log Delta
|
|
104
146
|
|
|
105
147
|
```javascript
|
|
148
|
+
const libFable = require('fable');
|
|
149
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
150
|
+
|
|
151
|
+
fable.ProgressTime.createTimeStamp();
|
|
152
|
+
fable.ProgressTime.createTimeStamp('DatabaseQuery');
|
|
153
|
+
await new Promise(r => setTimeout(r, 5));
|
|
154
|
+
|
|
106
155
|
fable.ProgressTime.logTimeStampDelta();
|
|
107
156
|
// Logs via fable.log.info: 'Elapsed for Default: 2s 150ms'
|
|
108
157
|
|
|
@@ -113,13 +162,16 @@ fable.ProgressTime.logTimeStampDelta('DatabaseQuery', 'DB query completed in');
|
|
|
113
162
|
### Format Duration
|
|
114
163
|
|
|
115
164
|
```javascript
|
|
116
|
-
fable
|
|
165
|
+
const libFable = require('fable');
|
|
166
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
167
|
+
|
|
168
|
+
console.log(fable.ProgressTime.formatTimeDuration(3661150));
|
|
117
169
|
// Returns '1h 1m 1s 150ms'
|
|
118
170
|
|
|
119
|
-
fable.ProgressTime.formatTimeDuration(523);
|
|
171
|
+
console.log(fable.ProgressTime.formatTimeDuration(523));
|
|
120
172
|
// Returns '523ms'
|
|
121
173
|
|
|
122
|
-
fable.ProgressTime.formatTimeDuration(65000);
|
|
174
|
+
console.log(fable.ProgressTime.formatTimeDuration(65000));
|
|
123
175
|
// Returns '1m 5s 0ms'
|
|
124
176
|
```
|
|
125
177
|
|
|
@@ -128,15 +180,20 @@ fable.ProgressTime.formatTimeDuration(65000);
|
|
|
128
180
|
### Multi-Phase Operations
|
|
129
181
|
|
|
130
182
|
```javascript
|
|
183
|
+
const libFable = require('fable');
|
|
184
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
185
|
+
|
|
131
186
|
fable.ProgressTime.createTimeStamp('Total');
|
|
132
187
|
fable.ProgressTime.createTimeStamp('Phase1');
|
|
133
188
|
|
|
134
189
|
// ... Phase 1 work ...
|
|
190
|
+
await new Promise(r => setTimeout(r, 5));
|
|
135
191
|
|
|
136
192
|
fable.ProgressTime.logTimeStampDelta('Phase1', 'Phase 1');
|
|
137
193
|
fable.ProgressTime.createTimeStamp('Phase2');
|
|
138
194
|
|
|
139
195
|
// ... Phase 2 work ...
|
|
196
|
+
await new Promise(r => setTimeout(r, 5));
|
|
140
197
|
|
|
141
198
|
fable.ProgressTime.logTimeStampDelta('Phase2', 'Phase 2');
|
|
142
199
|
fable.ProgressTime.logTimeStampDelta('Total', 'Total time');
|
|
@@ -145,6 +202,9 @@ fable.ProgressTime.logTimeStampDelta('Total', 'Total time');
|
|
|
145
202
|
### Request Timing
|
|
146
203
|
|
|
147
204
|
```javascript
|
|
205
|
+
const libFable = require('fable');
|
|
206
|
+
const fable = new libFable({ Product: 'ProgressTimeDemo', ProductVersion: '1.0.0' });
|
|
207
|
+
|
|
148
208
|
function timeRequest(name) {
|
|
149
209
|
fable.ProgressTime.createTimeStamp(name);
|
|
150
210
|
return () => {
|
|
@@ -155,6 +215,7 @@ function timeRequest(name) {
|
|
|
155
215
|
|
|
156
216
|
const done = timeRequest('api-call');
|
|
157
217
|
// ... do request ...
|
|
218
|
+
await new Promise(r => setTimeout(r, 10));
|
|
158
219
|
done();
|
|
159
220
|
// Logs: 'Request api-call 245ms'
|
|
160
221
|
```
|