fable 3.1.72 → 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.
Files changed (37) hide show
  1. package/docs/README.md +30 -6
  2. package/docs/_brand.json +18 -0
  3. package/docs/_playground.json +10 -0
  4. package/docs/_sidebar.md +2 -0
  5. package/docs/_version.json +3 -3
  6. package/docs/architecture.md +201 -39
  7. package/docs/index.html +6 -7
  8. package/docs/pict-docuserve.min.js +91 -0
  9. package/docs/pict-docuserve.min.js.map +1 -0
  10. package/docs/playground.md +38 -0
  11. package/docs/retold-catalog.json +1 -1
  12. package/docs/retold-keyword-index.json +8721 -8105
  13. package/docs/services/README.md +26 -9
  14. package/docs/services/anticipate.md +104 -40
  15. package/docs/services/csv-parser.md +63 -35
  16. package/docs/services/data-format.md +154 -49
  17. package/docs/services/data-generation.md +77 -16
  18. package/docs/services/dates.md +103 -36
  19. package/docs/services/environment-data.md +13 -2
  20. package/docs/services/expression-parser.md +280 -68
  21. package/docs/services/file-persistence.md +142 -150
  22. package/docs/services/logging.md +93 -37
  23. package/docs/services/logic.md +70 -22
  24. package/docs/services/manifest.md +114 -26
  25. package/docs/services/math.md +168 -63
  26. package/docs/services/meta-template.md +312 -158
  27. package/docs/services/object-cache.md +94 -11
  28. package/docs/services/operation.md +68 -6
  29. package/docs/services/progress-time.md +74 -13
  30. package/docs/services/progress-tracker-set.md +101 -3
  31. package/docs/services/rest-client.md +136 -104
  32. package/docs/services/settings-manager.md +133 -40
  33. package/docs/services/template.md +71 -22
  34. package/docs/services/utility.md +121 -29
  35. package/docs/services/uuid.md +58 -10
  36. package/package.json +2 -2
  37. package/.claude/settings.local.json +0 -8
@@ -5,9 +5,12 @@ The Logging service provides a pluggable logging system that supports multiple o
5
5
  ## Access
6
6
 
7
7
  ```javascript
8
+ const libFable = require('fable');
9
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
10
+
8
11
  // Pre-initialized, available directly
9
- fable.log
10
- fable.Logging
12
+ console.log('fable.log:', typeof fable.log);
13
+ console.log('fable.Logging:', typeof fable.Logging);
11
14
  ```
12
15
 
13
16
  ## Log Levels
@@ -24,6 +27,9 @@ From most to least verbose:
24
27
  ## Basic Logging
25
28
 
26
29
  ```javascript
30
+ const libFable = require('fable');
31
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
32
+
27
33
  fable.log.trace('Detailed trace information');
28
34
  fable.log.debug('Debug message');
29
35
  fable.log.info('Application started');
@@ -37,6 +43,9 @@ fable.log.fatal('Critical system failure');
37
43
  Pass additional context as a second parameter:
38
44
 
39
45
  ```javascript
46
+ const libFable = require('fable');
47
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
48
+
40
49
  fable.log.info('User logged in', { userId: 123, username: 'john' });
41
50
  fable.log.error('Database connection failed', { host: 'db.example.com', port: 5432 });
42
51
  ```
@@ -46,28 +55,23 @@ fable.log.error('Database connection failed', { host: 'db.example.com', port: 54
46
55
  Configure logging when creating a Fable instance:
47
56
 
48
57
  ```javascript
49
- const fable = new Fable({
58
+ const libFable = require('fable');
59
+
60
+ const fable = new libFable({
50
61
  Product: 'MyApp',
51
62
  ProductVersion: '1.0.0',
52
63
 
53
64
  LogStreams: [
54
65
  // Console output at info level
55
- { level: 'info' },
56
-
57
- // File output for errors
58
- {
59
- level: 'error',
60
- path: '/var/log/myapp/error.log'
61
- },
62
-
63
- // MongoDB stream
64
- {
65
- level: 'warn',
66
- streamtype: 'mongodb',
67
- // MongoDB-specific configuration
68
- }
66
+ { level: 'info' }
67
+
68
+ // In Node.js you can add file and external streams:
69
+ // { level: 'error', path: '/var/log/myapp/error.log' },
70
+ // { level: 'warn', streamtype: 'mongodb' /* MongoDB-specific config */ }
69
71
  ]
70
72
  });
73
+
74
+ fable.log.info('Logging configured with', fable.settings.LogStreams.length, 'stream(s)');
71
75
  ```
72
76
 
73
77
  ### Stream Configuration
@@ -85,7 +89,11 @@ Each log stream can have:
85
89
  Get the current timestamp:
86
90
 
87
91
  ```javascript
92
+ const libFable = require('fable');
93
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
94
+
88
95
  const timestamp = fable.log.getTimeStamp();
96
+ console.log('timestamp:', timestamp);
89
97
  // Returns milliseconds since epoch
90
98
  ```
91
99
 
@@ -94,12 +102,21 @@ const timestamp = fable.log.getTimeStamp();
94
102
  Create custom log providers by extending `LogProviderBase`:
95
103
 
96
104
  ```javascript
97
- const LogProviderBase = require('fable').LogProviderBase;
105
+ const libFable = require('fable');
106
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
107
+
108
+ // A stub connection for the playground demo
109
+ function createConnection() {
110
+ return { send: (entry) => console.log('CustomLogProvider received entry:', entry) };
111
+ }
112
+
113
+ const LogProviderBase = require('fable-log').LogProviderBase;
98
114
 
99
115
  class CustomLogProvider extends LogProviderBase {
100
116
  initialize() {
101
117
  // Setup code
102
118
  this.myConnection = createConnection();
119
+ console.log('CustomLogProvider initialized');
103
120
  }
104
121
 
105
122
  write(pLogEntry) {
@@ -114,20 +131,24 @@ class CustomLogProvider extends LogProviderBase {
114
131
  }
115
132
  }
116
133
 
117
- // Register the custom provider
118
- fable.Logging.addStream(new CustomLogProvider(fable.Logging));
134
+ // Register the custom provider with fable.Logging
135
+ const customProvider = new CustomLogProvider(fable.Logging, { level: 'trace' });
136
+ customProvider.initialize();
137
+ fable.Logging.addLogger(customProvider);
138
+ fable.log.info('CustomLogProvider registered — fable.log calls now also hit it');
119
139
  ```
120
140
 
121
141
  ### Log Entry Structure
122
142
 
123
143
  ```javascript
124
- {
144
+ const sampleLogEntry = {
125
145
  dt: 1704067200000, // Timestamp (milliseconds)
126
146
  lvl: 'info', // Log level
127
147
  src: 'MyApp v1.0.0', // Product/version
128
148
  msg: 'User logged in', // Message
129
149
  dat: { userId: 123 } // Additional data (optional)
130
- }
150
+ };
151
+ console.log('sampleLogEntry:', sampleLogEntry);
131
152
  ```
132
153
 
133
154
  ## Log Streams
@@ -137,20 +158,22 @@ fable.Logging.addStream(new CustomLogProvider(fable.Logging));
137
158
  Outputs to standard console:
138
159
 
139
160
  ```javascript
140
- {
161
+ const consoleStreamConfig = {
141
162
  level: 'info' // Shows info and above
142
- }
163
+ };
164
+ console.log('consoleStreamConfig:', consoleStreamConfig);
143
165
  ```
144
166
 
145
167
  ### File Stream
146
168
 
147
- Writes to a file:
169
+ Writes to a file (Node.js only):
148
170
 
149
171
  ```javascript
150
- {
172
+ const fileStreamConfig = {
151
173
  level: 'error',
152
174
  path: '/var/log/myapp/error.log'
153
- }
175
+ };
176
+ console.log('fileStreamConfig:', fileStreamConfig);
154
177
  ```
155
178
 
156
179
  ### Multiple Streams
@@ -158,18 +181,21 @@ Writes to a file:
158
181
  Configure multiple outputs:
159
182
 
160
183
  ```javascript
161
- const fable = new Fable({
184
+ const libFable = require('fable');
185
+
186
+ const fable = new libFable({
162
187
  LogStreams: [
163
188
  // Development console (all levels)
164
- { level: 'trace' },
165
-
166
- // Production file (warnings and above)
167
- { level: 'warn', path: '/var/log/app.log' },
189
+ { level: 'trace' }
168
190
 
169
- // Error alerting service
170
- { level: 'error', streamtype: 'alerting' }
191
+ // In Node.js you can add file and external streams:
192
+ // { level: 'warn', path: '/var/log/app.log' },
193
+ // { level: 'error', streamtype: 'alerting' }
171
194
  ]
172
195
  });
196
+
197
+ console.log('Configured streams:', fable.settings.LogStreams.length);
198
+ fable.log.trace('Trace-level message (visible because lowest stream level is trace)');
173
199
  ```
174
200
 
175
201
  ## Noisiness Control
@@ -177,9 +203,17 @@ const fable = new Fable({
177
203
  Control the verbosity of internal Fable logging:
178
204
 
179
205
  ```javascript
206
+ const libFable = require('fable');
207
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
208
+
180
209
  fable.LogNoisiness = 0; // Quiet (default)
210
+ console.log('LogNoisiness =', fable.LogNoisiness);
211
+
181
212
  fable.LogNoisiness = 1; // Normal
213
+ console.log('LogNoisiness =', fable.LogNoisiness);
214
+
182
215
  fable.LogNoisiness = 2; // Verbose
216
+ console.log('LogNoisiness =', fable.LogNoisiness);
183
217
  ```
184
218
 
185
219
  ## Integration with Services
@@ -187,20 +221,29 @@ fable.LogNoisiness = 2; // Verbose
187
221
  All Fable services have access to logging via `this.log`:
188
222
 
189
223
  ```javascript
224
+ const libFable = require('fable');
225
+ const libFableServiceBase = require('fable-serviceproviderbase');
226
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
227
+
190
228
  class MyService extends libFableServiceBase {
191
229
  constructor(pFable, pOptions, pServiceHash) {
192
230
  super(pFable, pOptions, pServiceHash);
231
+ this.serviceType = 'MyService';
193
232
  }
194
233
 
195
234
  doSomething() {
196
235
  this.log.info('Doing something');
197
236
  try {
198
237
  // operation
238
+ throw new Error('demo failure');
199
239
  } catch (error) {
200
240
  this.log.error('Operation failed', { error: error.message });
201
241
  }
202
242
  }
203
243
  }
244
+
245
+ fable.addAndInstantiateServiceType('MyService', MyService);
246
+ fable.MyService.doSomething();
204
247
  ```
205
248
 
206
249
  ## Best Practices
@@ -212,6 +255,11 @@ class MyService extends libFableServiceBase {
212
255
  5. **Use trace for detailed debugging**: Enable only when needed
213
256
 
214
257
  ```javascript
258
+ const libFable = require('fable');
259
+ const fable = new libFable({ Product: 'LoggingDemo', ProductVersion: '1.0.0' });
260
+
261
+ const order = { id: 'order-001', total: 49.99 };
262
+
215
263
  // Good
216
264
  fable.log.info('Order processed', { orderId: order.id, total: order.total });
217
265
 
@@ -224,14 +272,22 @@ fable.log.info('Order processed: ' + JSON.stringify(order));
224
272
  Set up different logging based on environment:
225
273
 
226
274
  ```javascript
227
- const logStreams = process.env.NODE_ENV === 'production'
275
+ const libFable = require('fable');
276
+
277
+ const nodeEnv = (typeof process !== 'undefined' && process.env)
278
+ ? process.env.NODE_ENV
279
+ : 'browser';
280
+
281
+ const logStreams = nodeEnv === 'production'
228
282
  ? [
229
- { level: 'warn', path: '/var/log/app.log' },
283
+ { level: 'warn', path: '/var/log/app.log' },
230
284
  { level: 'error', streamtype: 'alerting' }
231
285
  ]
232
286
  : [
233
287
  { level: 'trace' } // Console only in development
234
288
  ];
235
289
 
236
- const fable = new Fable({ LogStreams: logStreams });
290
+ const fable = new libFable({ LogStreams: logStreams });
291
+ console.log('nodeEnv:', nodeEnv);
292
+ console.log('LogStreams configured:', fable.settings.LogStreams);
237
293
  ```
@@ -5,8 +5,11 @@ The Logic service provides comparison and conditional operations, supporting bot
5
5
  ## Access
6
6
 
7
7
  ```javascript
8
+ const libFable = require('fable');
9
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
10
+
8
11
  // Auto-instantiated, available directly
9
- fable.Logic
12
+ console.log('fable.Logic:', typeof fable.Logic);
10
13
  ```
11
14
 
12
15
  ## Conditional Check (checkIf)
@@ -14,7 +17,11 @@ fable.Logic
14
17
  Perform comparisons and return different values based on the result:
15
18
 
16
19
  ```javascript
17
- fable.Logic.checkIf(left, operator, right, onTrue, onFalse);
20
+ const libFable = require('fable');
21
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
22
+
23
+ // Signature shape — see the examples below for runnable invocations.
24
+ console.log('checkIf signature: (left, operator, right, onTrue, onFalse) =>', typeof fable.Logic.checkIf);
18
25
  ```
19
26
 
20
27
  ### Parameters
@@ -43,13 +50,16 @@ fable.Logic.checkIf(left, operator, right, onTrue, onFalse);
43
50
  When both values can be parsed as numbers, arbitrary precision comparison is used:
44
51
 
45
52
  ```javascript
46
- fable.Logic.checkIf(10, '>', 5, 'greater', 'not greater');
53
+ const libFable = require('fable');
54
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
55
+
56
+ console.log(fable.Logic.checkIf(10, '>', 5, 'greater', 'not greater'));
47
57
  // Returns 'greater'
48
58
 
49
- fable.Logic.checkIf('3.14159', '==', '3.14159', 'equal', 'not equal');
59
+ console.log(fable.Logic.checkIf('3.14159', '==', '3.14159', 'equal', 'not equal'));
50
60
  // Returns 'equal' (with small tolerance for ==)
51
61
 
52
- fable.Logic.checkIf('100', 'LTE', '50', 'yes', 'no');
62
+ console.log(fable.Logic.checkIf('100', 'LTE', '50', 'yes', 'no'));
53
63
  // Returns 'no'
54
64
  ```
55
65
 
@@ -58,25 +68,31 @@ fable.Logic.checkIf('100', 'LTE', '50', 'yes', 'no');
58
68
  When either value is not a number, standard string comparison is used:
59
69
 
60
70
  ```javascript
61
- fable.Logic.checkIf('apple', '<', 'banana', 'first', 'second');
71
+ const libFable = require('fable');
72
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
73
+
74
+ console.log(fable.Logic.checkIf('apple', '<', 'banana', 'first', 'second'));
62
75
  // Returns 'first' (alphabetical order)
63
76
 
64
- fable.Logic.checkIf('Hello', '===', 'Hello', 'match', 'no match');
77
+ console.log(fable.Logic.checkIf('Hello', '===', 'Hello', 'match', 'no match'));
65
78
  // Returns 'match'
66
79
 
67
- fable.Logic.checkIf('hello', '===', 'Hello', 'match', 'no match');
80
+ console.log(fable.Logic.checkIf('hello', '===', 'Hello', 'match', 'no match'));
68
81
  // Returns 'no match' (case sensitive)
69
82
  ```
70
83
 
71
84
  #### Default False Values
72
85
 
73
86
  ```javascript
87
+ const libFable = require('fable');
88
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
89
+
74
90
  // String comparison defaults to empty string
75
- fable.Logic.checkIf('a', '>', 'b', 'yes');
91
+ console.log(JSON.stringify(fable.Logic.checkIf('a', '>', 'b', 'yes')));
76
92
  // Returns '' (empty string) when false
77
93
 
78
94
  // Numeric comparison defaults to '0'
79
- fable.Logic.checkIf(5, '>', 10, 'yes');
95
+ console.log(fable.Logic.checkIf(5, '>', 10, 'yes'));
80
96
  // Returns '0' when false
81
97
  ```
82
98
 
@@ -85,7 +101,11 @@ fable.Logic.checkIf(5, '>', 10, 'yes');
85
101
  Return different values based on whether a value is truthy:
86
102
 
87
103
  ```javascript
88
- fable.Logic.when(checkValue, onTrue, onFalse);
104
+ const libFable = require('fable');
105
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
106
+
107
+ // Signature shape — see the examples below for runnable invocations.
108
+ console.log('when signature: (checkValue, onTrue, onFalse) =>', typeof fable.Logic.when);
89
109
  ```
90
110
 
91
111
  ### Parameters
@@ -104,23 +124,26 @@ The `when` method considers the following as falsy:
104
124
  ### Examples
105
125
 
106
126
  ```javascript
127
+ const libFable = require('fable');
128
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
129
+
107
130
  // Basic truthy check
108
- fable.Logic.when(true, 'yes', 'no'); // Returns 'yes'
109
- fable.Logic.when(false, 'yes', 'no'); // Returns 'no'
110
- fable.Logic.when('hello', 'yes', 'no'); // Returns 'yes'
111
- fable.Logic.when('', 'yes', 'no'); // Returns 'no'
131
+ console.log(fable.Logic.when(true, 'yes', 'no')); // Returns 'yes'
132
+ console.log(fable.Logic.when(false, 'yes', 'no')); // Returns 'no'
133
+ console.log(fable.Logic.when('hello', 'yes', 'no')); // Returns 'yes'
134
+ console.log(fable.Logic.when('', 'yes', 'no')); // Returns 'no'
112
135
 
113
136
  // With numbers
114
- fable.Logic.when(42, 'has value', 'empty'); // Returns 'has value'
115
- fable.Logic.when(0, 'has value', 'empty'); // Returns 'empty'
137
+ console.log(fable.Logic.when(42, 'has value', 'empty')); // Returns 'has value'
138
+ console.log(fable.Logic.when(0, 'has value', 'empty')); // Returns 'empty'
116
139
 
117
140
  // With arrays
118
- fable.Logic.when([1, 2, 3], 'has items', 'empty'); // Returns 'has items'
119
- fable.Logic.when([], 'has items', 'empty'); // Returns 'empty'
141
+ console.log(fable.Logic.when([1, 2, 3], 'has items', 'empty')); // Returns 'has items'
142
+ console.log(fable.Logic.when([], 'has items', 'empty')); // Returns 'empty'
120
143
 
121
144
  // With objects
122
- fable.Logic.when({ a: 1 }, 'has props', 'empty'); // Returns 'has props'
123
- fable.Logic.when({}, 'has props', 'empty'); // Returns 'empty'
145
+ console.log(fable.Logic.when({ a: 1 }, 'has props', 'empty')); // Returns 'has props'
146
+ console.log(fable.Logic.when({}, 'has props', 'empty')); // Returns 'empty'
124
147
  ```
125
148
 
126
149
  ## Use Cases
@@ -128,24 +151,41 @@ fable.Logic.when({}, 'has props', 'empty'); // Returns 'empty'
128
151
  ### Form Validation
129
152
 
130
153
  ```javascript
154
+ const libFable = require('fable');
155
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
156
+
157
+ const formData = { age: 21 };
131
158
  const age = formData.age;
132
159
  const message = fable.Logic.checkIf(age, '>=', 18, 'Welcome!', 'Must be 18 or older');
160
+ console.log(message);
133
161
  ```
134
162
 
135
163
  ### Conditional Display
136
164
 
137
165
  ```javascript
166
+ const libFable = require('fable');
167
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
168
+
169
+ function getItems() { return ['apple', 'banana']; }
170
+
138
171
  const items = getItems();
139
172
  const display = fable.Logic.when(items, `Found ${items.length} items`, 'No items found');
173
+ console.log(display);
140
174
  ```
141
175
 
142
176
  ### Numeric Thresholds
143
177
 
144
178
  ```javascript
179
+ const libFable = require('fable');
180
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
181
+
182
+ function calculateScore() { return 85; }
183
+
145
184
  const score = calculateScore();
146
185
  const grade = fable.Logic.checkIf(score, '>=', 90, 'A',
147
186
  fable.Logic.checkIf(score, '>=', 80, 'B',
148
187
  fable.Logic.checkIf(score, '>=', 70, 'C', 'F')));
188
+ console.log('score:', score, '-> grade:', grade);
149
189
  ```
150
190
 
151
191
  ### Template Conditionals
@@ -153,9 +193,17 @@ const grade = fable.Logic.checkIf(score, '>=', 90, 'A',
153
193
  Combined with the Template service:
154
194
 
155
195
  ```javascript
196
+ const libFable = require('fable');
197
+ const fable = new libFable({ Product: 'LogicDemo', ProductVersion: '1.0.0' });
198
+
199
+ const user = { premium: true };
200
+ // Use double-quoted strings inside <%= ... %> so underscore's template compiler
201
+ // doesn't collide with the single-quoted wrapper it generates internally.
156
202
  const template = fable.Utility.template(`
157
- <%= fable.Logic.when(user.premium, 'Premium Member', 'Free User') %>
203
+ <%= fable.Logic.when(user.premium, "Premium Member", "Free User") %>
158
204
  `);
205
+ // The template references `fable` and `user`; pass them explicitly when rendering.
206
+ console.log(template({ fable: fable, user: user }));
159
207
  ```
160
208
 
161
209
  ## Notes