fable-serviceproviderbase 3.0.16 → 3.0.18

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.
@@ -0,0 +1,50 @@
1
+ # Contributing to Retold
2
+
3
+ We welcome contributions to Retold and its modules. This guide covers the expectations and process for contributing.
4
+
5
+ ## Code of Conduct
6
+
7
+ The Retold community values **empathy**, **equity**, **kindness**, and **thoughtfulness**. We expect all participants to treat each other with respect, assume good intent, and engage constructively. These values apply to all interactions: pull requests, issues, discussions, and code review.
8
+
9
+ ## How to Contribute
10
+
11
+ ### Pull Requests
12
+
13
+ Pull requests are the preferred method for contributing changes. To submit one:
14
+
15
+ 1. Fork the module repository you want to change
16
+ 2. Create a branch for your work
17
+ 3. Make your changes, following the code style of the module you are editing
18
+ 4. Ensure your changes have test coverage (see below)
19
+ 5. Open a pull request against the module's main branch
20
+
21
+ **Submitting a pull request does not guarantee it will be accepted.** Maintainers review contributions for fit, quality, and alignment with the project's direction. A PR may be declined, or you may be asked to revise it. This is normal and not a reflection on the quality of your effort.
22
+
23
+ ### Reporting Issues
24
+
25
+ If you find a bug or have a feature suggestion, open an issue on the relevant module's repository. Include enough detail to reproduce the problem or understand the proposal.
26
+
27
+ ## Test Coverage
28
+
29
+ Every commit must include test coverage for the changes it introduces. Retold modules use Mocha in TDD style. Before submitting:
30
+
31
+ - **Write tests** for any new functionality or bug fixes
32
+ - **Run the existing test suite** with `npm test` and confirm all tests pass
33
+ - **Check coverage** with `npm run coverage` if the module supports it
34
+
35
+ Pull requests that break existing tests or lack coverage for new code will not be merged.
36
+
37
+ ## Code Style
38
+
39
+ Follow the conventions of the module you are working in. The general Retold style is:
40
+
41
+ - **Tabs** for indentation, never spaces
42
+ - **Plain JavaScript** only (no TypeScript)
43
+ - **Allman-style braces** (opening brace on its own line)
44
+ - **Variable naming:** `pVariable` for parameters, `tmpVariable` for temporaries, `libSomething` for imports
45
+
46
+ When in doubt, match what the surrounding code does.
47
+
48
+ ## Repository Structure
49
+
50
+ Each module is its own git repository. The [retold](https://github.com/stevenvelozo/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
package/README.md CHANGED
@@ -1,71 +1,223 @@
1
- # Fable Service Provider
1
+ # Fable Service Provider Base
2
2
 
3
- A very basic set of base classes to provide the interface for Fable services.
4
- This is used for instantiating connections to databases, extending core
5
- services and whatever other services.
3
+ The base class for all services in the Fable ecosystem. Provides a standard interface for dependency injection, options handling, unique identification, and lifecycle management — used to build database connectors, API servers, template engines, view controllers, and any other service that plugs into a Fable application.
6
4
 
7
- Some service types Fable provides out of the box:
5
+ [![Build Status](https://github.com/stevenvelozo/fable-serviceproviderbase/workflows/Fable-ServiceProviderBase/badge.svg)](https://github.com/stevenvelozo/fable-serviceproviderbase/actions)
6
+ [![npm version](https://badge.fury.io/js/fable-serviceproviderbase.svg)](https://badge.fury.io/js/fable-serviceproviderbase)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
 
9
- * settings
10
- * logging
11
- * uuid
12
- * templating
9
+ ---
13
10
 
11
+ ## Features
14
12
 
15
- ## Basic Services
13
+ - **Service Base Class** - Standard constructor accepting a Fable instance, options object, and service hash
14
+ - **Dependency Injection** - Automatic access to `this.fable`, `this.log`, `this.services`, and `this.servicesMap` when connected to a Fable instance
15
+ - **Unique Identification** - Every service instance receives a UUID from Fable (or a random fallback) and a configurable Hash for service map lookups
16
+ - **Pre-Initialization Support** - Core services can be constructed before Fable is initialized and connected later via `connectFable()`
17
+ - **Standalone Mode** - Services can be instantiated without a Fable instance at all, receiving options and a random UUID
18
+ - **TypeScript Definitions** - Ships with `.d.ts` type declarations for editor support
16
19
 
17
- There are two types of services -- just requiring the class provides a base
18
- class for most services. The constructor for this type takes in a fully
19
- initialized fable object.
20
+ ## Installation
20
21
 
22
+ ```bash
23
+ npm install fable-serviceproviderbase
21
24
  ```
25
+
26
+ ## Quick Start
27
+
28
+ ```javascript
29
+ const libFable = require('fable');
22
30
  const libFableServiceProviderBase = require('fable-serviceproviderbase');
23
31
 
24
- class SimpleService extends libFableServiceProviderBase
32
+ class GreeterService extends libFableServiceProviderBase
25
33
  {
26
- constructor(pFable, pOptions, pServiceHash)
27
- {
28
- super(pFable, pOptions, pServiceHash);
34
+ constructor(pFable, pOptions, pServiceHash)
35
+ {
36
+ super(pFable, pOptions, pServiceHash);
29
37
 
30
- this.serviceType = 'SimpleService';
31
- }
38
+ this.serviceType = 'GreeterService';
39
+ }
32
40
 
33
- doSomething()
34
- {
35
- this.fable.log.info(`SimpleService ${this.UUID}::${this.Hash} is doing something.`);
36
- }
41
+ greet(pName)
42
+ {
43
+ this.log.info(`Hello, ${pName}! I am service ${this.Hash}.`);
44
+ }
37
45
  }
38
- ```
39
46
 
40
- ## Core Pre-initialization Services
47
+ let fable = new libFable();
41
48
 
42
- For some service types, we want to instantiate behaviors before the fable
43
- class has been initialized. These use a special service base that defers
44
- the connection of an initialized fable object until after it's created.
49
+ fable.serviceManager.addServiceType('GreeterService', GreeterService);
50
+ fable.serviceManager.instantiateServiceProvider('GreeterService',
51
+ { greeting: 'Hello' }, 'PrimaryGreeter');
45
52
 
46
- The one caveat here is the fable service doesn't provide consistent settings,
47
- log or uuid functionality until they have been initialized and mapped in.
53
+ fable.services.GreeterService.greet('World');
54
+ ```
48
55
 
49
- If you want to use this base class, please refer to the fable service
50
- manager code as well to get a good understanding of how initialization
51
- differs from the basic services.
56
+ ## Usage
52
57
 
58
+ ### Basic Services
53
59
 
54
- ```
60
+ Most services extend the base class directly and receive a fully initialized Fable instance:
61
+
62
+ ```javascript
55
63
  const libFableServiceProviderBase = require('fable-serviceproviderbase');
56
64
 
57
65
  class SimpleService extends libFableServiceProviderBase
58
66
  {
59
- constructor(pFable, pOptions, pServiceHash)
60
- {
61
- super(pFable, pOptions, pServiceHash);
67
+ constructor(pFable, pOptions, pServiceHash)
68
+ {
69
+ super(pFable, pOptions, pServiceHash);
62
70
 
63
- this.serviceType = 'SimpleService';
64
- }
71
+ this.serviceType = 'SimpleService';
72
+ }
65
73
 
66
- doSomething()
67
- {
68
- this.fable.log.info(`SimpleService ${this.UUID}::${this.Hash} is doing something.`);
69
- }
74
+ doSomething()
75
+ {
76
+ this.fable.log.info(`SimpleService ${this.UUID}::${this.Hash} is doing something.`);
77
+ }
70
78
  }
71
79
  ```
80
+
81
+ Register and use through the Fable service manager:
82
+
83
+ ```javascript
84
+ let fable = new libFable();
85
+
86
+ fable.serviceManager.addServiceType('SimpleService', SimpleService);
87
+ fable.serviceManager.instantiateServiceProvider('SimpleService',
88
+ { SomeOption: true }, 'SimpleService-123');
89
+
90
+ // Access via the services map
91
+ fable.services.SimpleService.doSomething();
92
+
93
+ // Or look up a specific instance by hash
94
+ fable.servicesMap.SimpleService['SimpleService-123'].doSomething();
95
+ ```
96
+
97
+ ### Core Pre-Initialization Services
98
+
99
+ Some services need to exist before Fable is fully initialized (e.g., logging, settings, UUID generation). These use the `CoreServiceProviderBase` export and connect to Fable later:
100
+
101
+ ```javascript
102
+ const libCoreServiceBase = require('fable-serviceproviderbase').CoreServiceProviderBase;
103
+
104
+ class EarlyService extends libCoreServiceBase
105
+ {
106
+ constructor(pOptions, pServiceHash)
107
+ {
108
+ super(pOptions, pServiceHash);
109
+
110
+ this.serviceType = 'EarlyService';
111
+ }
112
+
113
+ earlyWork()
114
+ {
115
+ console.log(`EarlyService ${this.UUID}::${this.Hash} is working.`);
116
+ }
117
+ }
118
+
119
+ // Create before Fable exists
120
+ let earlyService = new EarlyService({ SomeOption: true }, 'EarlyService-1');
121
+ earlyService.earlyWork();
122
+
123
+ // Later, connect to Fable
124
+ let fable = new libFable();
125
+ fable.serviceManager.connectPreinitServiceProviderInstance(earlyService);
126
+
127
+ // Now it has full fable access
128
+ earlyService.fable.log.info('Connected to Fable!');
129
+ ```
130
+
131
+ ### Standalone Mode
132
+
133
+ Services can be instantiated without any Fable instance. They receive a random UUID and the first parameter is treated as the options object:
134
+
135
+ ```javascript
136
+ let standalone = new SimpleService({ Setting: 'Something' });
137
+ // standalone.options.Setting === 'Something'
138
+ // standalone.UUID is a random string like 'CORE-SVC-12345'
139
+ // standalone.fable === false
140
+ ```
141
+
142
+ ## API
143
+
144
+ ### Constructor
145
+
146
+ ```javascript
147
+ new FableServiceProviderBase(pFable, pOptions, pServiceHash)
148
+ ```
149
+
150
+ | Parameter | Type | Description |
151
+ |-----------|------|-------------|
152
+ | `pFable` | `Fable \| Object` | A Fable instance, or an options object if no Fable is available |
153
+ | `pOptions` | `Object \| String` | Options object, or service hash string if no Fable is available |
154
+ | `pServiceHash` | `String` | Identifier for this service instance in the services map |
155
+
156
+ ### Methods
157
+
158
+ | Method | Description |
159
+ |--------|-------------|
160
+ | `connectFable(pFable)` | Attach a Fable instance after construction. Sets `this.fable`, `this.log`, `this.services`, and `this.servicesMap`. Returns `true` on success or an `Error` on failure. |
161
+
162
+ ### Properties
163
+
164
+ | Property | Type | Description |
165
+ |----------|------|-------------|
166
+ | `fable` | `Fable \| false` | The connected Fable instance, or `false` if standalone |
167
+ | `UUID` | `String` | Unique identifier assigned by Fable or generated randomly |
168
+ | `Hash` | `String` | Service hash for lookups in the services map (defaults to UUID) |
169
+ | `serviceType` | `String` | Service type identifier (set by the deriving class) |
170
+ | `options` | `Object` | Options object passed at construction |
171
+ | `log` | `Object` | Reference to `fable.Logging` (available after Fable connection) |
172
+ | `services` | `Object` | Reference to `fable.services` (available after Fable connection) |
173
+ | `servicesMap` | `Object` | Reference to `fable.servicesMap` (available after Fable connection) |
174
+
175
+ ### Static Properties
176
+
177
+ | Property | Type | Description |
178
+ |----------|------|-------------|
179
+ | `isFableService` | `Boolean` | Always `true` — used to identify Fable service classes |
180
+
181
+ ### Exports
182
+
183
+ | Export | Description |
184
+ |--------|-------------|
185
+ | `require('fable-serviceproviderbase')` | The `FableServiceProviderBase` class |
186
+ | `require('fable-serviceproviderbase').CoreServiceProviderBase` | Same class (alias for pre-init service pattern) |
187
+
188
+ ## Part of the Retold Framework
189
+
190
+ Fable Service Provider Base is the foundation class for all services in the ecosystem:
191
+
192
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework and service manager
193
+ - [fable-log](https://github.com/stevenvelozo/fable-log) - Logging framework (core service)
194
+ - [fable-uuid](https://github.com/stevenvelozo/fable-uuid) - UUID generation (core service)
195
+ - [meadow](https://github.com/stevenvelozo/meadow) - ORM built as Fable services
196
+ - [orator](https://github.com/stevenvelozo/orator) - API server built as Fable services
197
+ - [pict](https://github.com/stevenvelozo/pict) - MVC framework built as Fable services
198
+
199
+ ## Testing
200
+
201
+ Run the test suite:
202
+
203
+ ```bash
204
+ npm test
205
+ ```
206
+
207
+ Run with coverage:
208
+
209
+ ```bash
210
+ npm run coverage
211
+ ```
212
+
213
+ ## Related Packages
214
+
215
+ - [fable](https://github.com/stevenvelozo/fable) - Application services framework
216
+
217
+ ## License
218
+
219
+ MIT
220
+
221
+ ## Contributing
222
+
223
+ Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Fable Service Provider Base
2
+
3
+ The base class that every Retold service extends. It provides the contract for registration, dependency injection, and lifecycle management within a Fable instance.
4
+
5
+ ## What It Does
6
+
7
+ When you extend `FableServiceProviderBase`, your class gains:
8
+
9
+ - `this.fable` -- Reference to the Fable instance (or `false` if standalone)
10
+ - `this.log` -- Shortcut to Fable's logging service
11
+ - `this.services` -- Access to all registered services
12
+ - `this.servicesMap` -- The full service registry map
13
+ - `this.options` -- Service-specific configuration
14
+ - `this.serviceType` -- The registered type name (set this in your constructor)
15
+ - `this.Hash` -- Unique identifier for this specific instance
16
+ - `this.UUID` -- Auto-generated unique ID
17
+
18
+ ## Quick Start
19
+
20
+ ```javascript
21
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
22
+
23
+ class MyService extends libFableServiceProviderBase
24
+ {
25
+ constructor(pFable, pOptions, pServiceHash)
26
+ {
27
+ super(pFable, pOptions, pServiceHash);
28
+ this.serviceType = 'MyService';
29
+ }
30
+
31
+ doSomething()
32
+ {
33
+ this.log.info('MyService is doing something');
34
+ return this.fable.getUUID();
35
+ }
36
+ }
37
+ ```
38
+
39
+ Register with a Fable instance:
40
+
41
+ ```javascript
42
+ const libFable = require('fable');
43
+ let _Fable = new libFable();
44
+
45
+ // Register the type and create an instance
46
+ _Fable.serviceManager.addServiceType('MyService', MyService);
47
+ _Fable.serviceManager.instantiateServiceProvider('MyService', { SomeOption: true }, 'MyService-1');
48
+
49
+ // Access via the services shortcut
50
+ _Fable.services.MyService.doSomething();
51
+ ```
52
+
53
+ Or use the shorthand:
54
+
55
+ ```javascript
56
+ _Fable.addAndInstantiateServiceType('MyService', MyService);
57
+ _Fable.services.MyService.doSomething();
58
+ ```
59
+
60
+ ## Three Initialization Patterns
61
+
62
+ The constructor is flexible and supports three modes. See [Initialization Patterns](initialization-patterns.md) for details.
63
+
64
+ **With Fable** -- The standard pattern for application services:
65
+
66
+ ```javascript
67
+ let tmpService = new MyService(fableInstance, optionsObject, serviceHash);
68
+ ```
69
+
70
+ **Pre-initialization** -- For core services needed before Fable is ready:
71
+
72
+ ```javascript
73
+ let tmpCore = new MyCoreService(optionsObject, serviceHash);
74
+ // Later, after Fable is ready:
75
+ fableInstance.serviceManager.connectPreinitServiceProviderInstance(tmpCore);
76
+ ```
77
+
78
+ **Standalone** -- For testing or non-Fable contexts:
79
+
80
+ ```javascript
81
+ let tmpService = new MyService({ Setting: 'value' });
82
+ // tmpService.fable === false
83
+ ```
84
+
85
+ ## Multiple Instances
86
+
87
+ You can create multiple instances of the same service type, each with a different hash:
88
+
89
+ ```javascript
90
+ _Fable.serviceManager.instantiateServiceProvider('DatabaseService', { Host: 'primary-db' }, 'Primary');
91
+ _Fable.serviceManager.instantiateServiceProvider('DatabaseService', { Host: 'replica-db' }, 'Replica');
92
+
93
+ // Access the default (first registered)
94
+ _Fable.services.DatabaseService.connect();
95
+
96
+ // Access a specific instance
97
+ _Fable.servicesMap.DatabaseService['Replica'].connect();
98
+
99
+ // Change the default
100
+ _Fable.serviceManager.setDefaultServiceInstantiation('DatabaseService', 'Replica');
101
+ ```
102
+
103
+ ## API Reference
104
+
105
+ See the [API Reference](api.md) for complete method and property documentation.
106
+
107
+ ## Learn More
108
+
109
+ - [Initialization Patterns](initialization-patterns.md) -- The three ways to construct a service
110
+ - [API Reference](api.md) -- Properties, methods, and static members
111
+ - [Fable Service Provider Pattern](/fable/fable/) -- How services compose in the Fable ecosystem
@@ -0,0 +1,15 @@
1
+ - Getting Started
2
+
3
+ - [Overview](README.md)
4
+ - [Initialization Patterns](initialization-patterns.md)
5
+
6
+ - Reference
7
+
8
+ - [API Reference](api.md)
9
+
10
+ - Retold Ecosystem
11
+
12
+ - [Fable](/fable/fable/)
13
+ - [Fable-Settings](/fable/fable-settings/)
14
+ - [Fable-Log](/fable/fable-log/)
15
+ - [Fable-UUID](/fable/fable-uuid/)
@@ -0,0 +1,5 @@
1
+ # Fable Service Provider Base
2
+
3
+ - [Overview](README.md)
4
+ - [API Reference](api.md)
5
+ - [GitHub](https://github.com/stevenvelozo/fable-serviceproviderbase)
package/docs/api.md ADDED
@@ -0,0 +1,132 @@
1
+ # API Reference
2
+
3
+ ## Class: FableServiceProviderBase
4
+
5
+ The base class for all Fable services. Import it and extend it to create your own services.
6
+
7
+ ```javascript
8
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
9
+
10
+ class MyService extends libFableServiceProviderBase
11
+ {
12
+ constructor(pFable, pOptions, pServiceHash)
13
+ {
14
+ super(pFable, pOptions, pServiceHash);
15
+ this.serviceType = 'MyService';
16
+ }
17
+ }
18
+ ```
19
+
20
+ ## Constructor
21
+
22
+ ```javascript
23
+ new FableServiceProviderBase(pFable, pOptions, pServiceHash)
24
+ ```
25
+
26
+ | Parameter | Type | Required | Description |
27
+ |-----------|------|----------|-------------|
28
+ | `pFable` | Fable instance or object | No | A Fable instance, or an options object if no Fable is available |
29
+ | `pOptions` | object or string | No | Options for the service, or the service hash if no Fable |
30
+ | `pServiceHash` | string | No | Unique identifier for this service instance |
31
+
32
+ See [Initialization Patterns](initialization-patterns.md) for detailed usage of each parameter combination.
33
+
34
+ ## Instance Properties
35
+
36
+ ### fable
37
+
38
+ - **Type:** Fable instance or `false`
39
+ - **Description:** Reference to the connected Fable instance. Set to `false` when no Fable is connected.
40
+
41
+ ### log
42
+
43
+ - **Type:** object or `undefined`
44
+ - **Description:** Shortcut to `fable.Logging`. Provides `trace()`, `debug()`, `info()`, `warn()`, `error()`, and `fatal()` methods.
45
+
46
+ ### UUID
47
+
48
+ - **Type:** string
49
+ - **Description:** Unique identifier for this service instance. Generated by Fable's UUID service when connected, or a random `CORE-SVC-XXXXX` string when standalone.
50
+
51
+ ### Hash
52
+
53
+ - **Type:** string
54
+ - **Description:** The service instance hash, used to look up this specific instance in the service registry. Defaults to the UUID if not provided.
55
+
56
+ ### serviceType
57
+
58
+ - **Type:** string
59
+ - **Description:** The registered type name for this service. Defaults to `'Unknown-{UUID}'`. Subclasses should set this in their constructor.
60
+
61
+ ### options
62
+
63
+ - **Type:** object
64
+ - **Description:** Service-specific configuration passed during construction.
65
+
66
+ ### services
67
+
68
+ - **Type:** object or `undefined`
69
+ - **Description:** Reference to `fable.services`. Provides shortcut access to the default instance of each registered service type.
70
+
71
+ ### servicesMap
72
+
73
+ - **Type:** object or `undefined`
74
+ - **Description:** Reference to `fable.servicesMap`. A two-level map: `servicesMap[serviceType][hash]` returns a specific service instance.
75
+
76
+ ### _PackageFableServiceProvider
77
+
78
+ - **Type:** object
79
+ - **Description:** The `package.json` contents of fable-serviceproviderbase. Useful for version checking.
80
+
81
+ ## Instance Methods
82
+
83
+ ### connectFable(pFable)
84
+
85
+ Connects a Fable instance to this service. Used for core services that were constructed before Fable was initialized.
86
+
87
+ ```javascript
88
+ let tmpResult = myService.connectFable(fableInstance);
89
+ ```
90
+
91
+ | Parameter | Type | Required | Description |
92
+ |-----------|------|----------|-------------|
93
+ | `pFable` | Fable instance | Yes | Must have `isFable` property set to `true` |
94
+
95
+ **Returns:** `true` on success, or an `Error` if the parameter is not a valid Fable instance.
96
+
97
+ **Behavior:**
98
+ - Sets `this.fable` if not already set
99
+ - Sets `this.log` to `fable.Logging` if not already set
100
+ - Sets `this.services` to `fable.services` if not already set
101
+ - Sets `this.servicesMap` to `fable.servicesMap` if not already set
102
+ - Idempotent: calling multiple times will not overwrite existing references
103
+
104
+ ## Static Properties
105
+
106
+ ### isFableService
107
+
108
+ - **Type:** boolean
109
+ - **Value:** `true`
110
+ - **Description:** Class-level flag that identifies a class as a Fable service. Used by the service manager to validate service types.
111
+
112
+ ## Exports
113
+
114
+ ### Default Export
115
+
116
+ The `FableServiceProviderBase` class itself.
117
+
118
+ ```javascript
119
+ const libBase = require('fable-serviceproviderbase');
120
+ class MyService extends libBase { ... }
121
+ ```
122
+
123
+ ### CoreServiceProviderBase
124
+
125
+ An alias for `FableServiceProviderBase`. They are the same class.
126
+
127
+ ```javascript
128
+ const libBase = require('fable-serviceproviderbase');
129
+ class MyCoreService extends libBase.CoreServiceProviderBase { ... }
130
+ ```
131
+
132
+ The alias exists for readability when building services that are designed to be constructed before Fable is initialized.
package/docs/cover.md ADDED
@@ -0,0 +1,14 @@
1
+ # Fable Service Provider Base
2
+
3
+ > The foundation class for every Retold service
4
+
5
+ A lightweight base class that provides registration, dependency injection, and lifecycle management. Every service in the Fable ecosystem -- from logging to data access to views -- extends this class.
6
+
7
+ - **Dependency Injection** -- Access logging, configuration, and other services through `this.fable`
8
+ - **Service Registry** -- Register by type, instantiate with unique hashes, discover via `this.services`
9
+ - **Flexible Initialization** -- Construct with Fable, before Fable, or without Fable at all
10
+ - **Multiple Instances** -- Run several instances of the same service type with different configurations
11
+
12
+ [Get Started](README.md)
13
+ [API Reference](api.md)
14
+ [GitHub](https://github.com/stevenvelozo/fable-serviceproviderbase)
@@ -0,0 +1,73 @@
1
+ /* ============================================================================
2
+ Pict Docuserve - Base Styles
3
+ ============================================================================ */
4
+
5
+ /* Reset and base */
6
+ *, *::before, *::after {
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ html, body {
11
+ margin: 0;
12
+ padding: 0;
13
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
14
+ font-size: 16px;
15
+ line-height: 1.5;
16
+ color: #423D37;
17
+ background-color: #fff;
18
+ -webkit-font-smoothing: antialiased;
19
+ -moz-osx-font-smoothing: grayscale;
20
+ }
21
+
22
+ /* Typography */
23
+ h1, h2, h3, h4, h5, h6 {
24
+ margin-top: 0;
25
+ line-height: 1.3;
26
+ }
27
+
28
+ a {
29
+ color: #2E7D74;
30
+ text-decoration: none;
31
+ }
32
+
33
+ a:hover {
34
+ color: #256861;
35
+ }
36
+
37
+ /* Application container */
38
+ #Docuserve-Application-Container {
39
+ min-height: 100vh;
40
+ }
41
+
42
+ /* Utility: scrollbar styling */
43
+ ::-webkit-scrollbar {
44
+ width: 8px;
45
+ }
46
+
47
+ ::-webkit-scrollbar-track {
48
+ background: #F5F0E8;
49
+ }
50
+
51
+ ::-webkit-scrollbar-thumb {
52
+ background: #D4CCBE;
53
+ border-radius: 4px;
54
+ }
55
+
56
+ ::-webkit-scrollbar-thumb:hover {
57
+ background: #B5AA9A;
58
+ }
59
+
60
+ /* Responsive adjustments */
61
+ @media (max-width: 768px) {
62
+ html {
63
+ font-size: 14px;
64
+ }
65
+
66
+ #Docuserve-Sidebar-Container {
67
+ display: none;
68
+ }
69
+
70
+ .docuserve-body {
71
+ flex-direction: column;
72
+ }
73
+ }
@@ -0,0 +1,39 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
+ <meta name="description" content="Documentation powered by pict-docuserve">
8
+
9
+ <title>Documentation</title>
10
+
11
+ <!-- Application Stylesheet -->
12
+ <link href="css/docuserve.css" rel="stylesheet">
13
+ <!-- KaTeX stylesheet for LaTeX equation rendering -->
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css">
15
+ <!-- PICT Dynamic View CSS Container -->
16
+ <style id="PICT-CSS"></style>
17
+
18
+ <!-- Load the PICT library from jsDelivr CDN -->
19
+ <script src="https://cdn.jsdelivr.net/npm/pict@1/dist/pict.min.js" type="text/javascript"></script>
20
+ <!-- Bootstrap the Application -->
21
+ <script type="text/javascript">
22
+ //<![CDATA[
23
+ Pict.safeOnDocumentReady(() => { Pict.safeLoadPictApplication(PictDocuserve, 2)});
24
+ //]]>
25
+ </script>
26
+ </head>
27
+ <body>
28
+ <!-- The root container for the Pict application -->
29
+ <div id="Docuserve-Application-Container"></div>
30
+
31
+ <!-- Mermaid diagram rendering -->
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
+ <!-- KaTeX for LaTeX equation rendering -->
35
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script>
36
+ <!-- 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>
38
+ </body>
39
+ </html>
@@ -0,0 +1,123 @@
1
+ # Initialization Patterns
2
+
3
+ The `FableServiceProviderBase` constructor supports three initialization modes. The same base class handles all three -- it detects whether a Fable instance was passed in and adjusts behavior accordingly.
4
+
5
+ ## Pattern 1: With Fable
6
+
7
+ The standard pattern for application services. Pass a Fable instance as the first argument.
8
+
9
+ ```javascript
10
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
11
+
12
+ class MyService extends libFableServiceProviderBase
13
+ {
14
+ constructor(pFable, pOptions, pServiceHash)
15
+ {
16
+ super(pFable, pOptions, pServiceHash);
17
+ this.serviceType = 'MyService';
18
+ }
19
+ }
20
+
21
+ const libFable = require('fable');
22
+ let _Fable = new libFable();
23
+
24
+ let tmpService = new MyService(_Fable, { ConnectionTimeout: 5000 }, 'Primary');
25
+ ```
26
+
27
+ After construction:
28
+
29
+ | Property | Value |
30
+ |----------|-------|
31
+ | `this.fable` | The Fable instance |
32
+ | `this.log` | `fable.Logging` |
33
+ | `this.services` | `fable.services` |
34
+ | `this.servicesMap` | `fable.servicesMap` |
35
+ | `this.UUID` | Generated by Fable's UUID service |
36
+ | `this.options` | `{ ConnectionTimeout: 5000 }` |
37
+ | `this.Hash` | `'Primary'` |
38
+
39
+ ## Pattern 2: Pre-initialization (Core Services)
40
+
41
+ Some services need to exist before Fable is fully initialized -- for example, logging or settings services that Fable itself depends on. These are constructed without a Fable instance and connected later.
42
+
43
+ ```javascript
44
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
45
+
46
+ class MyCoreService extends libFableServiceProviderBase.CoreServiceProviderBase
47
+ {
48
+ constructor(pOptions, pServiceHash)
49
+ {
50
+ super(pOptions, pServiceHash);
51
+ this.serviceType = 'MyCoreService';
52
+ }
53
+
54
+ earlyBehavior()
55
+ {
56
+ // This works even before Fable is initialized
57
+ console.log(`Core service ${this.Hash} is ready`);
58
+ }
59
+ }
60
+
61
+ // Create the service early
62
+ let tmpCore = new MyCoreService({ SomeOption: true }, 'CoreInstance-1');
63
+ tmpCore.earlyBehavior();
64
+
65
+ // Later, when Fable is ready, connect it
66
+ let _Fable = new libFable();
67
+ _Fable.serviceManager.connectPreinitServiceProviderInstance(tmpCore);
68
+
69
+ // Now tmpCore.fable, tmpCore.log, tmpCore.services are all available
70
+ ```
71
+
72
+ After construction (before `connectFable`):
73
+
74
+ | Property | Value |
75
+ |----------|-------|
76
+ | `this.fable` | `false` |
77
+ | `this.log` | `undefined` |
78
+ | `this.services` | `undefined` |
79
+ | `this.UUID` | `'CORE-SVC-XXXXX'` (random 5-digit number) |
80
+ | `this.options` | `{ SomeOption: true }` |
81
+ | `this.Hash` | `'CoreInstance-1'` |
82
+
83
+ After `connectFable` or `connectPreinitServiceProviderInstance`:
84
+
85
+ | Property | Value |
86
+ |----------|-------|
87
+ | `this.fable` | The Fable instance |
88
+ | `this.log` | `fable.Logging` |
89
+ | `this.services` | `fable.services` |
90
+
91
+ Note: `CoreServiceProviderBase` is an alias for `FableServiceProviderBase`. They are the same class. The alias exists for readability -- it signals that the service is designed for pre-initialization use.
92
+
93
+ ## Pattern 3: Standalone (No Fable)
94
+
95
+ For testing or non-Fable contexts, services can be constructed with just an options object:
96
+
97
+ ```javascript
98
+ let tmpService = new MyService({ Setting: 'value' });
99
+ ```
100
+
101
+ After construction:
102
+
103
+ | Property | Value |
104
+ |----------|-------|
105
+ | `this.fable` | `false` |
106
+ | `this.log` | `undefined` |
107
+ | `this.UUID` | `'CORE-SVC-XXXXX'` (random) |
108
+ | `this.options` | `{ Setting: 'value' }` |
109
+ | `this.Hash` | Same as UUID |
110
+
111
+ The service works but has no access to Fable's logging, configuration, or other services. You can call `connectFable(fableInstance)` later to wire everything up.
112
+
113
+ ## Constructor Parameter Detection
114
+
115
+ The constructor uses a simple heuristic: if the first parameter is an object with an `isFable` property set to `true`, it treats it as a Fable instance. Otherwise, the first parameter is treated as the options object.
116
+
117
+ ```
118
+ new Service(fable, options, hash) → fable.isFable is true → Pattern 1
119
+ new Service(options, hash) → options.isFable is falsy → Pattern 2/3
120
+ new Service() → no arguments → Pattern 3
121
+ ```
122
+
123
+ The `pServiceHash` parameter sets `this.Hash`. If omitted, the hash defaults to the UUID. When no Fable is present, if the second parameter is a string, it is used as the hash.
@@ -0,0 +1,41 @@
1
+ {
2
+ "Generated": "2026-02-18T03:21:49.210Z",
3
+ "GitHubOrg": "stevenvelozo",
4
+ "DefaultBranch": "master",
5
+ "Groups": [
6
+ {
7
+ "Name": "Dist",
8
+ "Key": "dist",
9
+ "Description": "",
10
+ "Modules": [
11
+ {
12
+ "Name": "indoctrinate_content_staging",
13
+ "Repo": "indoctrinate_content_staging",
14
+ "Group": "dist",
15
+ "Branch": "master",
16
+ "HasDocs": false,
17
+ "HasCover": false,
18
+ "Sidebar": [],
19
+ "DocFiles": []
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "Name": "Types",
25
+ "Key": "types",
26
+ "Description": "",
27
+ "Modules": [
28
+ {
29
+ "Name": "source",
30
+ "Repo": "source",
31
+ "Group": "types",
32
+ "Branch": "master",
33
+ "HasDocs": false,
34
+ "HasCover": false,
35
+ "Sidebar": [],
36
+ "DocFiles": []
37
+ }
38
+ ]
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "Generated": "2026-02-18T03:21:49.288Z",
3
+ "DocumentCount": 0,
4
+ "LunrIndex": {
5
+ "version": "2.3.9",
6
+ "fields": [
7
+ "title",
8
+ "module",
9
+ "group",
10
+ "body"
11
+ ],
12
+ "fieldVectors": [],
13
+ "invertedIndex": [],
14
+ "pipeline": [
15
+ "stemmer"
16
+ ]
17
+ },
18
+ "Documents": {}
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fable-serviceproviderbase",
3
- "version": "3.0.16",
3
+ "version": "3.0.18",
4
4
  "description": "Simple base classes for fable services.",
5
5
  "main": "source/Fable-ServiceProviderBase.js",
6
6
  "scripts": {
@@ -47,8 +47,8 @@
47
47
  "homepage": "https://github.com/stevenvelozo/fable-serviceproviderbase",
48
48
  "devDependencies": {
49
49
  "@types/mocha": "^10.0.10",
50
- "fable": "^3.1.51",
51
- "quackage": "^1.0.45",
50
+ "fable": "^3.1.55",
51
+ "quackage": "^1.0.51",
52
52
  "typescript": "^5.9.3"
53
53
  }
54
54
  }