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.
Files changed (39) 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 +4 -4
  37. package/source/services/Fable-Service-RestClient.js +204 -7
  38. package/test/RestClient_test.js +342 -0
  39. package/.claude/settings.local.json +0 -8
package/docs/README.md CHANGED
@@ -16,10 +16,10 @@ Fable is a comprehensive framework that provides a service-oriented architecture
16
16
  ## Quick Start
17
17
 
18
18
  ```javascript
19
- const Fable = require('fable');
19
+ const libFable = require('fable');
20
20
 
21
21
  // Create a new Fable instance with optional configuration
22
- const fable = new Fable({
22
+ const fable = new libFable({
23
23
  Product: 'MyApplication',
24
24
  ProductVersion: '1.0.0',
25
25
  LogStreams: [
@@ -54,14 +54,32 @@ Fable services fall into three categories:
54
54
  ### Service Registration
55
55
 
56
56
  ```javascript
57
+ const libFable = require('fable');
58
+ const libFableServiceBase = require('fable-serviceproviderbase');
59
+ const fable = new libFable({ Product: 'ServiceRegistrationDemo', ProductVersion: '1.0.0' });
60
+
61
+ // A trivial service class for demonstration purposes
62
+ class MyServiceClass extends libFableServiceBase
63
+ {
64
+ constructor(pFable, pOptions, pServiceHash)
65
+ {
66
+ super(pFable, pOptions, pServiceHash);
67
+ this.serviceType = 'MyService';
68
+ }
69
+ }
70
+ const options = { greeting: 'hello' };
71
+
57
72
  // Add a service type without instantiating
58
73
  fable.addServiceType('MyService', MyServiceClass);
74
+ console.log('Registered service types include MyService:', 'MyService' in fable.serviceTypes);
59
75
 
60
76
  // Add and immediately instantiate a service
61
- fable.addAndInstantiateServiceType('MyService', MyServiceClass);
77
+ fable.addAndInstantiateServiceType('AnotherService', MyServiceClass);
78
+ console.log('AnotherService instantiated:', typeof fable.AnotherService);
62
79
 
63
80
  // Instantiate a service on-demand
64
81
  const myService = fable.instantiateServiceProvider('MyService', options, 'custom-hash');
82
+ console.log('myService.serviceType:', myService.serviceType);
65
83
  ```
66
84
 
67
85
  ## Configuration
@@ -69,16 +87,22 @@ const myService = fable.instantiateServiceProvider('MyService', options, 'custom
69
87
  Fable accepts a configuration object that controls various aspects of behavior:
70
88
 
71
89
  ```javascript
72
- const fable = new Fable({
90
+ const libFable = require('fable');
91
+
92
+ const fable = new libFable({
73
93
  Product: 'MyApp',
74
94
  ProductVersion: '1.0.0',
75
95
  UUID: { DataCenter: 0, Worker: 0 },
76
96
  LogStreams: [
77
- { level: 'info' },
78
- { level: 'error', path: '/var/log/myapp/error.log' }
97
+ { level: 'info' }
98
+ // In Node.js you can also write a file-based stream, e.g.:
99
+ // { level: 'error', path: '/var/log/myapp/error.log' }
79
100
  ],
80
101
  RestClientURLPrefix: 'https://api.example.com'
81
102
  });
103
+
104
+ console.log('Configured fable:', fable.settings.Product, 'v' + fable.settings.ProductVersion);
105
+ console.log('RestClientURLPrefix setting:', fable.settings.RestClientURLPrefix);
82
106
  ```
83
107
 
84
108
  ## Documentation
@@ -0,0 +1,18 @@
1
+ {
2
+ "Hash": "fable",
3
+ "Name": "Fable",
4
+ "Tagline": "Service dependency injection, configuration, and logging library — the foundation of every Retold application",
5
+ "Palette": "mix",
6
+ "Icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-fable-filled-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#af2aef\"/>\n\t\t<g clip-path=\"url(#frame-fable-filled-light)\"><circle cx=\"48\" cy=\"48\" r=\"36\" fill=\"none\" stroke=\"#4ed5e8\" stroke-width=\"2\" opacity=\"0.45\"/>\n\t\t\t\t\t<circle cx=\"48\" cy=\"48\" r=\"22\" fill=\"rgba(255,255,255,0.18)\"/>\n\t\t\t\t\t<circle cx=\"13.69\" cy=\"58.91\" r=\"9\" fill=\"#4ed5e8\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"56\" font-weight=\"700\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">F</text>\n\t</svg>",
7
+ "IconType": "svg",
8
+ "Favicon": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-fable-light\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#af2aef\"/>\n\t\t<g clip-path=\"url(#fav-fable-light)\"><circle cx=\"48\" cy=\"48\" r=\"28\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">F</text>\n\t</svg>",
9
+ "FaviconDark": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-fable-dark\">\n\t\t\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 24 2\n\t\tH 72\n\t\tQ 94 2 94 24\n\t\tV 72\n\t\tQ 94 94 72 94\n\t\tH 24\n\t\tQ 2 94 2 72\n\t\tV 24\n\t\tQ 2 2 24 2 Z\" fill=\"#ce84f2\"/>\n\t\t<g clip-path=\"url(#fav-fable-dark)\"><circle cx=\"48\" cy=\"48\" r=\"28\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">F</text>\n\t</svg>",
10
+ "Colors": {
11
+ "Primary": "#af2aef",
12
+ "Secondary": "#4ed5e8",
13
+ "PrimaryLight": "#af2aef",
14
+ "PrimaryDark": "#ce84f2",
15
+ "SecondaryLight": "#4ed5e8",
16
+ "SecondaryDark": "#a2e6ef"
17
+ }
18
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "Imports":
3
+ [
4
+ { "Name": "fable", "Source": "bundled" },
5
+ { "Name": "fable-uuid", "Source": "bundled" },
6
+ { "Name": "fable-settings", "Source": "bundled" },
7
+ { "Name": "fable-log", "Source": "bundled" },
8
+ { "Name": "fable-serviceproviderbase","Source": "bundled" }
9
+ ]
10
+ }
package/docs/_sidebar.md CHANGED
@@ -40,3 +40,5 @@
40
40
  - [Environment Data](services/environment-data.md)
41
41
  - [Progress Time](services/progress-time.md)
42
42
  - [Progress Tracker Set](services/progress-tracker-set.md)
43
+
44
+ - [Code Playground](playground.md)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "Name": "fable",
3
- "Version": "3.1.68",
3
+ "Version": "3.1.72",
4
4
  "Description": "A service dependency injection, configuration and logging library.",
5
- "GeneratedAt": "2026-04-10T17:19:38.218Z",
6
- "GitCommit": "70452b7"
5
+ "GeneratedAt": "2026-05-15T13:50:08.507Z",
6
+ "GitCommit": "3564579"
7
7
  }
@@ -24,15 +24,24 @@ Fable (Core ServiceManager)
24
24
  Services depend on Fable rather than creating their own dependencies. Each service receives a reference to the Fable instance during construction, providing access to all other services and shared configuration.
25
25
 
26
26
  ```javascript
27
+ const libFable = require('fable');
28
+ const libFableServiceBase = require('fable-serviceproviderbase');
29
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
30
+
27
31
  class MyService extends libFableServiceBase {
28
32
  constructor(pFable, pOptions, pServiceHash) {
29
33
  super(pFable, pOptions, pServiceHash);
34
+ this.serviceType = 'MyService';
30
35
 
31
36
  // Access other services through fable
32
- this.log = this.fable.log;
37
+ this.log = this.fable.log;
33
38
  this.settings = this.fable.settings;
34
39
  }
35
40
  }
41
+
42
+ fable.addAndInstantiateServiceType('MyService', MyService);
43
+ console.log('MyService wired up; log + settings accessible:',
44
+ typeof fable.MyService.log, typeof fable.MyService.settings);
36
45
  ```
37
46
 
38
47
  ### Lazy Instantiation
@@ -40,11 +49,25 @@ class MyService extends libFableServiceBase {
40
49
  Services can be registered without being instantiated, allowing for on-demand creation when first needed:
41
50
 
42
51
  ```javascript
52
+ const libFable = require('fable');
53
+ const libFableServiceBase = require('fable-serviceproviderbase');
54
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
55
+
56
+ class ExpensiveServiceClass extends libFableServiceBase {
57
+ constructor(pFable, pOptions, pServiceHash) {
58
+ super(pFable, pOptions, pServiceHash);
59
+ this.serviceType = 'ExpensiveService';
60
+ console.log('ExpensiveServiceClass instantiated — work happens here.');
61
+ }
62
+ }
63
+
43
64
  // Register without instantiating
44
65
  fable.addServiceType('ExpensiveService', ExpensiveServiceClass);
66
+ console.log('Registered; no instance yet.');
45
67
 
46
68
  // Later, when needed
47
69
  const service = fable.instantiateServiceProvider('ExpensiveService');
70
+ console.log('Instantiated:', service.serviceType);
48
71
  ```
49
72
 
50
73
  ### Service Containers
@@ -52,13 +75,16 @@ const service = fable.instantiateServiceProvider('ExpensiveService');
52
75
  Each service type maintains a map of instances, supporting multiple named instances of the same service type:
53
76
 
54
77
  ```javascript
78
+ const libFable = require('fable');
79
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
80
+
55
81
  // Create multiple instances of the same service type
56
82
  const clientA = fable.instantiateServiceProvider('RestClient', {}, 'api-client');
57
83
  const clientB = fable.instantiateServiceProvider('RestClient', {}, 'auth-client');
58
84
 
59
85
  // Access via services map
60
- fable.servicesMap.RestClient['api-client'];
61
- fable.servicesMap.RestClient['auth-client'];
86
+ console.log('api-client:', typeof fable.servicesMap.RestClient['api-client']);
87
+ console.log('auth-client:', typeof fable.servicesMap.RestClient['auth-client']);
62
88
  ```
63
89
 
64
90
  ### Default Service Pattern
@@ -66,12 +92,15 @@ fable.servicesMap.RestClient['auth-client'];
66
92
  The first instance of each service type becomes the default accessor on the Fable object:
67
93
 
68
94
  ```javascript
95
+ const libFable = require('fable');
96
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
97
+
69
98
  // First instantiation becomes default
70
99
  fable.instantiateServiceProvider('RestClient', {}, 'primary');
71
100
 
72
101
  // Now accessible directly
73
- fable.RestClient; // The 'primary' instance
74
- fable.services.RestClient; // Same as above
102
+ console.log('fable.RestClient:', typeof fable.RestClient); // The 'primary' instance
103
+ console.log('fable.services.RestClient:', typeof fable.services.RestClient); // Same as above
75
104
  ```
76
105
 
77
106
  ## Initialization Phases
@@ -83,11 +112,21 @@ Fable initializes in distinct phases to ensure proper dependency ordering:
83
112
  The lowest level state and service infrastructure is established:
84
113
 
85
114
  ```javascript
86
- this.serviceType = 'ServiceManager';
87
- this.serviceTypes = []; // Array of registered service types
88
- this.servicesMap = {}; // Map of instantiated services by type and hash
89
- this.services = {}; // Map of default service instances
90
- this.serviceClasses = {}; // Map of service class constructors
115
+ const libFable = require('fable');
116
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
117
+
118
+ // Inside Fable's constructor, Phase 0 sets up its own service-manager state:
119
+ // this.serviceType = 'ServiceManager';
120
+ // this.serviceTypes = []; // Array of registered service types
121
+ // this.servicesMap = {}; // Map of instantiated services by type and hash
122
+ // this.services = {}; // Map of default service instances
123
+ // this.serviceClasses = {}; // Map of service class constructors
124
+ //
125
+ // You can observe these on a constructed instance:
126
+ console.log('serviceType:', fable.serviceType);
127
+ console.log('serviceTypes count:', fable.serviceTypes.length);
128
+ console.log('servicesMap keys:', Object.keys(fable.servicesMap).slice(0, 5), '...');
129
+ console.log('services keys:', Object.keys(fable.services).slice(0, 5), '...');
91
130
  ```
92
131
 
93
132
  ### Phase 1: Core Utility Services
@@ -95,10 +134,19 @@ this.serviceClasses = {}; // Map of service class constructors
95
134
  Fundamental services required for Fable to operate:
96
135
 
97
136
  ```javascript
98
- this.SettingsManager = new libFableSettings(pSettings);
99
- this.UUID = new libFableUUID(this.SettingsManager.settings);
100
- this.Logging = new libFableLog(this.SettingsManager.settings);
101
- this.Logging.initialize();
137
+ const libFable = require('fable');
138
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
139
+
140
+ // Inside Fable's constructor, Phase 1 wires up the core utility services:
141
+ // this.SettingsManager = new libFableSettings(pSettings);
142
+ // this.UUID = new libFableUUID(this.SettingsManager.settings);
143
+ // this.Logging = new libFableLog(this.SettingsManager.settings);
144
+ // this.Logging.initialize();
145
+ //
146
+ // On the constructed instance these are all live:
147
+ console.log('SettingsManager:', typeof fable.SettingsManager);
148
+ console.log('UUID:', typeof fable.UUID);
149
+ console.log('Logging:', typeof fable.Logging);
102
150
  ```
103
151
 
104
152
  ### Phase 1.5: Self-Registration
@@ -106,8 +154,15 @@ this.Logging.initialize();
106
154
  Fable registers itself as a service, enabling consistent service access patterns:
107
155
 
108
156
  ```javascript
109
- this.ServiceManager = this;
110
- this.connectFable(this);
157
+ const libFable = require('fable');
158
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
159
+
160
+ // Inside Fable's constructor, Phase 1.5 self-registers:
161
+ // this.ServiceManager = this;
162
+ // this.connectFable(this);
163
+ //
164
+ // On the constructed instance, fable.ServiceManager === fable:
165
+ console.log('fable.ServiceManager === fable:', fable.ServiceManager === fable);
111
166
  ```
112
167
 
113
168
  ### Phase 2: Default Built-in Services
@@ -115,16 +170,24 @@ this.connectFable(this);
115
170
  All default services are registered and optionally instantiated:
116
171
 
117
172
  ```javascript
118
- // Auto-instantiated (available immediately)
119
- this.addAndInstantiateServiceType('EnvironmentData', ...);
120
- this.addAndInstantiateServiceType('Dates', ...);
121
- this.addAndInstantiateServiceType('DataFormat', ...);
122
- // ... etc
123
-
124
- // On-demand (registered but not instantiated)
125
- this.addServiceType('Template', ...);
126
- this.addServiceType('RestClient', ...);
127
- // ... etc
173
+ const libFable = require('fable');
174
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
175
+
176
+ // Inside Fable's constructor, Phase 2 registers all built-in services:
177
+ // // Auto-instantiated (available immediately)
178
+ // this.addAndInstantiateServiceType('EnvironmentData', ...);
179
+ // this.addAndInstantiateServiceType('Dates', ...);
180
+ // this.addAndInstantiateServiceType('DataFormat', ...);
181
+ // ...
182
+ // // On-demand (registered but not instantiated)
183
+ // this.addServiceType('Template', ...);
184
+ // this.addServiceType('RestClient', ...);
185
+ // ...
186
+ //
187
+ // On the constructed instance, you can see both:
188
+ const autoInstantiated = Object.keys(fable.services).filter(k => fable[k]);
189
+ console.log('Auto-instantiated services:', autoInstantiated.join(', '));
190
+ console.log('Registered service types:', fable.serviceTypes.join(', '));
128
191
  ```
129
192
 
130
193
  ## Service Base Class
@@ -132,6 +195,10 @@ this.addServiceType('RestClient', ...);
132
195
  All Fable services extend `CoreServiceProviderBase` from `fable-serviceproviderbase`:
133
196
 
134
197
  ```javascript
198
+ const libFable = require('fable');
199
+ const libFableServiceBase = require('fable-serviceproviderbase');
200
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
201
+
135
202
  class MyService extends libFableServiceBase {
136
203
  constructor(pFable, pOptions, pServiceHash) {
137
204
  super(pFable, pOptions, pServiceHash);
@@ -145,6 +212,14 @@ class MyService extends libFableServiceBase {
145
212
  // - this.options (passed options)
146
213
  // - this.Hash (unique service instance identifier)
147
214
  }
215
+
216
+ fable.addAndInstantiateServiceType('MyService', MyService);
217
+ const svc = fable.MyService;
218
+ console.log('serviceType:', svc.serviceType);
219
+ console.log('fable ref:', typeof svc.fable);
220
+ console.log('log:', typeof svc.log);
221
+ console.log('options:', typeof svc.options);
222
+ console.log('Hash:', svc.Hash);
148
223
  ```
149
224
 
150
225
  ## Service Registration Methods
@@ -154,7 +229,16 @@ class MyService extends libFableServiceBase {
154
229
  Registers a service class without instantiation:
155
230
 
156
231
  ```javascript
232
+ const libFable = require('fable');
233
+ const libFableServiceBase = require('fable-serviceproviderbase');
234
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
235
+
236
+ class MyServiceClass extends libFableServiceBase {
237
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.serviceType = 'MyService'; }
238
+ }
239
+
157
240
  fable.addServiceType('MyService', MyServiceClass);
241
+ console.log('Registered:', fable.serviceTypes.includes('MyService'));
158
242
  ```
159
243
 
160
244
  ### `addAndInstantiateServiceType(pServiceType, pServiceClass)`
@@ -162,8 +246,17 @@ fable.addServiceType('MyService', MyServiceClass);
162
246
  Registers and immediately creates a default instance:
163
247
 
164
248
  ```javascript
249
+ const libFable = require('fable');
250
+ const libFableServiceBase = require('fable-serviceproviderbase');
251
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
252
+
253
+ class MyServiceClass extends libFableServiceBase {
254
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.serviceType = 'MyService'; }
255
+ }
256
+
165
257
  fable.addAndInstantiateServiceType('MyService', MyServiceClass);
166
258
  // Creates instance with hash 'MyService-Default'
259
+ console.log('Default instance Hash:', fable.MyService.Hash);
167
260
  ```
168
261
 
169
262
  ### `instantiateServiceProvider(pServiceType, pOptions, pCustomServiceHash)`
@@ -171,10 +264,22 @@ fable.addAndInstantiateServiceType('MyService', MyServiceClass);
171
264
  Creates a new instance of a registered service:
172
265
 
173
266
  ```javascript
267
+ const libFable = require('fable');
268
+ const libFableServiceBase = require('fable-serviceproviderbase');
269
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
270
+
271
+ class MyServiceClass extends libFableServiceBase {
272
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.serviceType = 'MyService'; }
273
+ }
274
+
275
+ fable.addServiceType('MyService', MyServiceClass);
276
+
174
277
  const service = fable.instantiateServiceProvider('MyService',
175
278
  { option: 'value' },
176
279
  'my-custom-hash'
177
280
  );
281
+ console.log('Service Hash:', service.Hash);
282
+ console.log('Service options:', service.options);
178
283
  ```
179
284
 
180
285
  ### `instantiateServiceProviderFromPrototype(pServiceType, pOptions, pCustomServiceHash, pServicePrototype)`
@@ -182,14 +287,28 @@ const service = fable.instantiateServiceProvider('MyService',
182
287
  Creates an instance using a custom class that may differ from the registered class:
183
288
 
184
289
  ```javascript
185
- class CustomizedService extends MyServiceClass { /* ... */ }
290
+ const libFable = require('fable');
291
+ const libFableServiceBase = require('fable-serviceproviderbase');
292
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
293
+
294
+ class MyServiceClass extends libFableServiceBase {
295
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.serviceType = 'MyService'; }
296
+ }
297
+ fable.addServiceType('MyService', MyServiceClass);
298
+
299
+ class CustomizedService extends MyServiceClass {
300
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.flavor = 'custom'; }
301
+ }
186
302
 
303
+ const options = { mode: 'demo' };
187
304
  const service = fable.instantiateServiceProviderFromPrototype(
188
305
  'MyService',
189
306
  options,
190
307
  'customized',
191
308
  CustomizedService
192
309
  );
310
+ console.log('Custom flavor:', service.flavor);
311
+ console.log('Hash:', service.Hash);
193
312
  ```
194
313
 
195
314
  ## Service Access Patterns
@@ -199,9 +318,12 @@ const service = fable.instantiateServiceProviderFromPrototype(
199
318
  Auto-instantiated services are available directly on the Fable instance:
200
319
 
201
320
  ```javascript
202
- fable.Dates.dayJS().format('YYYY-MM-DD');
203
- fable.Math.addPrecise('1.5', '2.5');
204
- fable.DataFormat.formatterDollars(1234.56);
321
+ const libFable = require('fable');
322
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
323
+
324
+ console.log(fable.Dates.dayJS().format('YYYY-MM-DD'));
325
+ console.log(fable.Math.addPrecise('1.5', '2.5'));
326
+ console.log(fable.DataFormat.formatterDollars(1234.56));
205
327
  ```
206
328
 
207
329
  ### Services Map Access
@@ -209,8 +331,11 @@ fable.DataFormat.formatterDollars(1234.56);
209
331
  All instantiated services are accessible through the services map:
210
332
 
211
333
  ```javascript
212
- fable.services.Dates;
213
- fable.servicesMap.Dates['Dates-Default'];
334
+ const libFable = require('fable');
335
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
336
+
337
+ console.log('fable.services.Dates:', typeof fable.services.Dates);
338
+ console.log("fable.servicesMap.Dates['Dates-Default']:", typeof fable.servicesMap.Dates['Dates-Default']);
214
339
  ```
215
340
 
216
341
  ### Factory Methods
@@ -218,11 +343,17 @@ fable.servicesMap.Dates['Dates-Default'];
218
343
  Some services provide convenient factory methods:
219
344
 
220
345
  ```javascript
346
+ const libFable = require('fable');
347
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
348
+
221
349
  // Create a new Anticipate instance without registration
222
350
  const anticipate = fable.newAnticipate();
351
+ console.log('anticipate:', typeof anticipate);
223
352
 
224
353
  // Create a new Manifest instance without registration
354
+ const definition = { Scope: 'Demo', Descriptors: { Foo: { Hash: 'foo', Type: 'String' } } };
225
355
  const manifest = fable.newManyfest(definition);
356
+ console.log('manifest scope:', manifest.scope);
226
357
  ```
227
358
 
228
359
  ## Configuration Flow
@@ -240,8 +371,16 @@ User Config -> SettingsManager -> Fable.settings -> All Services
240
371
  Services access configuration through:
241
372
 
242
373
  ```javascript
243
- this.fable.settings.SomeSetting;
244
- this.fable.SettingsManager.settings;
374
+ const libFable = require('fable');
375
+ const fable = new libFable({ Product: 'ArchitectureDemo', SomeSetting: 'demo-value' });
376
+
377
+ // Inside a service, you access config via:
378
+ // this.fable.settings.SomeSetting
379
+ // this.fable.SettingsManager.settings
380
+ //
381
+ // At the top level, drop "this.":
382
+ console.log('settings.SomeSetting:', fable.settings.SomeSetting);
383
+ console.log('SettingsManager.settings type:', typeof fable.SettingsManager.settings);
245
384
  ```
246
385
 
247
386
  ## Logging Architecture
@@ -260,13 +399,22 @@ Log levels: `trace`, `debug`, `info`, `warn`, `error`, `fatal`
260
399
  Custom log providers can be created by extending `LogProviderBase`:
261
400
 
262
401
  ```javascript
263
- const LogProviderBase = require('fable').LogProviderBase;
402
+ const libFable = require('fable');
403
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
404
+
405
+ const LogProviderBase = require('fable-log').LogProviderBase;
264
406
 
265
407
  class CustomLogProvider extends LogProviderBase {
266
408
  write(pLogEntry) {
267
409
  // Custom logging implementation
410
+ console.log('CustomLogProvider received:', pLogEntry.msg);
268
411
  }
269
412
  }
413
+
414
+ const provider = new CustomLogProvider(fable.Logging, { level: 'trace' });
415
+ provider.initialize();
416
+ fable.Logging.addLogger(provider);
417
+ fable.log.info('Hello from custom provider demo');
270
418
  ```
271
419
 
272
420
  ## Browser Compatibility
@@ -274,15 +422,16 @@ class CustomLogProvider extends LogProviderBase {
274
422
  Fable supports browser environments through service remapping:
275
423
 
276
424
  ```javascript
277
- // package.json browser field
278
- {
425
+ // Shape of the browser remap declared in package.json:
426
+ const packageJSONBrowserField = {
279
427
  "browser": {
280
428
  "./source/service/Fable-Service-EnvironmentData.js":
281
429
  "./source/service/Fable-Service-EnvironmentData-Web.js",
282
430
  "./source/service/Fable-Service-FilePersistence.js":
283
431
  "./source/service/Fable-Service-FilePersistence-Web.js"
284
432
  }
285
- }
433
+ };
434
+ console.log('Browser remap entries:', Object.keys(packageJSONBrowserField.browser).length);
286
435
  ```
287
436
 
288
437
  The `dist/` folder contains browserified bundles for direct browser use.
@@ -292,7 +441,9 @@ The `dist/` folder contains browserified bundles for direct browser use.
292
441
  ### Creating Custom Services
293
442
 
294
443
  ```javascript
444
+ const libFable = require('fable');
295
445
  const libFableServiceBase = require('fable-serviceproviderbase');
446
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
296
447
 
297
448
  class MyCustomService extends libFableServiceBase {
298
449
  constructor(pFable, pOptions, pServiceHash) {
@@ -310,7 +461,7 @@ class MyCustomService extends libFableServiceBase {
310
461
  fable.addAndInstantiateServiceType('MyCustomService', MyCustomService);
311
462
 
312
463
  // Use it
313
- fable.MyCustomService.myMethod();
464
+ console.log('myMethod() returns:', fable.MyCustomService.myMethod());
314
465
  ```
315
466
 
316
467
  ### Service Initialization Hook
@@ -318,9 +469,20 @@ fable.MyCustomService.myMethod();
318
469
  For advanced scenarios, Fable supports an extra initialization callback:
319
470
 
320
471
  ```javascript
472
+ const libFable = require('fable');
473
+ const libFableServiceBase = require('fable-serviceproviderbase');
474
+ const fable = new libFable({ Product: 'ArchitectureDemo', ProductVersion: '1.0.0' });
475
+
321
476
  fable.extraServiceInitialization = (pService) => {
322
477
  // Perform additional setup on every service
323
478
  pService.customProperty = 'value';
324
479
  return pService;
325
480
  };
481
+
482
+ // Subsequent service instantiations now pass through the hook:
483
+ class DemoService extends libFableServiceBase {
484
+ constructor(pFable, pOptions, pServiceHash) { super(pFable, pOptions, pServiceHash); this.serviceType = 'DemoService'; }
485
+ }
486
+ fable.addAndInstantiateServiceType('DemoService', DemoService);
487
+ console.log('DemoService.customProperty:', fable.DemoService.customProperty);
326
488
  ```
package/docs/index.html CHANGED
@@ -4,12 +4,10 @@
4
4
  <meta charset="utf-8">
5
5
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
- <meta name="description" content="Fable &lt;small&gt;3&lt;/small&gt; v3.1.68 Documentation — A service dependency injection, configuration and logging library.">
7
+ <meta name="description" content="Fable &lt;small&gt;3&lt;/small&gt; v3.1.72 Documentation — A service dependency injection, configuration and logging library.">
8
8
 
9
- <title>Fable &lt;small&gt;3&lt;/small&gt; v3.1.68 Documentation</title>
9
+ <title>Fable &lt;small&gt;3&lt;/small&gt; v3.1.72 Documentation</title>
10
10
 
11
- <!-- Application Stylesheet -->
12
- <link href="css/docuserve.css" rel="stylesheet">
13
11
  <!-- KaTeX stylesheet for LaTeX equation rendering -->
14
12
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css">
15
13
  <!-- PICT Dynamic View CSS Container -->
@@ -28,12 +26,13 @@
28
26
  <!-- The root container for the Pict application -->
29
27
  <div id="Docuserve-Application-Container"></div>
30
28
 
31
- <!-- Mermaid diagram rendering -->
29
+ <!-- Mermaid diagram rendering. pict-section-content (v0.1.8+) drives
30
+ initialization with theme: 'base' + themeVariables sourced
31
+ from --theme-color-* so diagrams follow the active theme. -->
32
32
  <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
33
- <script>mermaid.initialize({ startOnLoad: false, theme: 'default' });</script>
34
33
  <!-- KaTeX for LaTeX equation rendering -->
35
34
  <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script>
36
35
  <!-- Load the Docuserve PICT Application Bundle from jsDelivr CDN -->
37
- <script src="https://cdn.jsdelivr.net/npm/pict-docuserve@0/dist/pict-docuserve.min.js" type="text/javascript"></script>
36
+ <script src="https://cdn.jsdelivr.net/npm/pict-docuserve@1/dist/pict-docuserve.min.js" type="text/javascript"></script>
38
37
  </body>
39
38
  </html>