qtools-library-dot-d 1.0.5 → 1.0.7

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 (2) hide show
  1. package/README.md +184 -151
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,208 +1,241 @@
1
- # qtools-library-dot-d
1
+ ## NAME
2
2
 
3
- # NOT READY. STILL WORKING IT OUT.
3
+     **qtools-library-dot-d** is system for creating dynamic, modular libraries in Node.js. The dotD (dot-D) pattern provides a powerful way to build extensible applications through automatic module discovery and loading.
4
4
 
5
- NAME
5
+ ## What is qtools-library-dot-d?
6
6
 
7
-     qtools-library-dot-d
7
+ **qtools-library-dot-d** is a Node.js library that enables dynamic module loading from directories. It automatically discovers JavaScript files in specified directories and makes them available as methods on a library object, creating a plugin-like architecture without the complexity of traditional plugin systems.
8
8
 
9
- DESCRIPTION
9
+ ## The dotD Pattern
10
10
 
11
- Utility provides tools to scan a directory for NodeJS modules, require() them into existance with tools to connect them to a system.
11
+ The "dotD" naming convention (short for "dot-D") refers to directories that contain dynamically loadable modules:
12
12
 
13
+ - `modules.d/` - Directory containing module files
14
+ - `endpoints.d/` - Directory containing API endpoint modules
15
+ - `accessPoints.d/` - Directory containing data access modules
16
+ - `mappers.d/` - Directory containing data mapping modules
13
17
 
18
+ Each `.js` file in a dotD directory becomes a method on the library object, with the filename determining the method name.
14
19
 
15
- First use case is adding endpoints to an expressJS system. When instantiated, qtDotD
20
+ ## Why Use Dynamic dotD Libraries?
16
21
 
17
- scans a directory containing modules, dotLib.d. It requires it with two parameters,
22
+ ### 1. **Automatic Module Discovery**
18
23
 
19
- dotD and passThroughArgs. For this case, passThrough args has two properties,
24
+ No need to manually import or register modules. Simply add a `.js` file to the dotD directory and it's automatically available.
20
25
 
21
- expressApp and routingPrefix. The module uses these to construct one or more
26
+ ```javascript
27
+ // Traditional approach - manual imports
28
+ const module1 = require('./modules/module1');
29
+ const module2 = require('./modules/module2');
30
+ const module3 = require('./modules/module3');
22
31
 
23
- expressJS endpoitns.
32
+ // dotD approach - automatic discovery
33
+ const library = qtLibDotD({ libraryName: 'myLibrary' });
34
+ library.setLibraryPath('./modules.d');
35
+ library.loadModules();
36
+ // All modules in modules.d/ are now available as library.moduleName()
37
+ ```
24
38
 
39
+ ### 2. **Plugin Architecture**
25
40
 
41
+ Create extensible applications where new functionality can be added by simply dropping files into directories.
26
42
 
27
- the dotD object contains three parameters, add....
43
+ ```javascript
44
+ // Add new functionality by creating a new file
45
+ // modules.d/newFeature.js -> library.newFeature()
46
+ ```
28
47
 
29
- ASYNCHRONOUS CODE SAMPLE
48
+ ### 3. **Shared Resources**
30
49
 
31
- const promptObjects = require('qtools-library-dot-d')({
32
- libraryName: 'promptObjects',
33
- }, callback);
34
- promptObjects.setLibraryPath(path.join(__dirname, 'prompts.d'), callback);
50
+ Pass common resources (configuration, database connections, utilities) to all modules through `passThroughParameters`.
35
51
 
36
- const passThroughParameters = {};
37
- promptObjects.loadModules({ passThroughParameters }, callback);
38
- promptObjects.seal(); //make the library immutable
52
+ ```javascript
53
+ const passThroughParameters = {
54
+ config: getConfig(),
55
+ database: dbConnection,
56
+ logger: xLog,
57
+ utilities: commonUtils
58
+ };
59
+ library.loadModules({ passThroughParameters });
60
+ ```
61
+
62
+ ### 4. **Clean Separation of Concerns**
63
+
64
+ Each module is self-contained and focused on a single responsibility, making code easier to maintain and test.
39
65
 
66
+ ### 5. **Runtime Flexibility**
40
67
 
68
+ Modules can be loaded synchronously or asynchronously, and the library can be sealed to prevent modifications after loading.
41
69
 
42
- SYNCHROMOUS CODE SAMPLE:
70
+ ## Real-World Use Cases
43
71
 
44
- const promptObjects = require('qtools-library-dot-d')({
45
- libraryName: 'promptObjects',
46
- });
47
- promptObjects.setLibraryPath(path.join(__dirname, 'prompts.d'));
72
+ ### API Endpoint Management
48
73
 
49
- const passThroughParameters = {};
50
- promptObjects.loadModules({ passThroughParameters });
51
- promptObjects.seal(); //make the library immutable
74
+ ```javascript
75
+ // endpoints.d/userEndpoints.js
76
+ // endpoints.d/productEndpoints.js
77
+ // endpoints.d/orderEndpoints.js
78
+ // Each file defines related API endpoints
79
+ ```
52
80
 
81
+ ### Data Access Layer
53
82
 
54
- COMPLETE WORKING CODE SAMPLE
83
+ ```javascript
84
+ // accessPoints.d/getUserData.js
85
+ // accessPoints.d/saveUserData.js
86
+ // accessPoints.d/deleteUserData.js
87
+ // Each file handles specific data operations
88
+ ```
55
89
 
56
- // ================================================================================
57
- // index.js for demonstration
90
+ ### Business Logic Modules
58
91
 
59
- #!/usr/bin/env node
60
- 'use strict';
61
- // Suppress punycode deprecation warning
62
- process.noDeprecation = true;
92
+ ```javascript
93
+ // processors.d/validateOrder.js
94
+ // processors.d/calculateTax.js
95
+ // processors.d/sendNotification.js
96
+ // Each file contains specific business logic
97
+ ```
63
98
 
64
- const moduleName = __filename.replace(__dirname + '/', '').replace(/.js$/, ''); //this just seems to come in handy a lot
99
+ ### CLI Command Tools
65
100
 
66
- // const qt = require('qtools-functional-library'); //also exposes qtLog(); qt.help({printOutput:true, queryString:'.*', sendJson:false});
101
+ ```javascript
102
+ // commands.d/deploy.js
103
+ // commands.d/backup.js
104
+ // commands.d/migrate.js
105
+ // Each file implements a CLI command
106
+ ```
67
107
 
68
- const os = require('os');
69
- const path = require('path');
70
- const fs = require('fs');
108
+ ## How It Works
71
109
 
110
+ ### 1. **Library Creation**
111
+
112
+ ```javascript
72
113
  const qtLibDotD = require('qtools-library-dot-d');
114
+ const library = qtLibDotD({ libraryName: 'myLibrary' });
115
+ ```
73
116
 
74
- //START OF moduleFunction() ============================================================
75
- const moduleFunction =
76
- ({ moduleName } = {}) =>
77
- ({ unused } = {}) => {
78
-
79
- // ========================================================================
80
- // SYNCHRONOUS DEMO
81
-
82
- const synchronousDemo = () => {
83
- const demoDotD = qtLibDotD({
84
- libraryName: 'demoDotD',
85
- });
86
-
87
- const libraryModulesPath = path.join(__dirname, 'demoModules_DotD');
88
-
89
- const passThroughParameters = {
90
- message: 'Hello from a dotDlib module',
91
- add: (a, b) => a + b,
92
- };
93
-
94
- demoDotD.setLibraryPath(libraryModulesPath);
95
- demoDotD.loadModules({ passThroughParameters });
96
- demoDotD.seal();
97
-
98
- // console.log(demoDotD.qtdProcessLog());
99
- console.log(demoDotD.toString());
100
-
101
- demoDotD.demo1();
102
- demoDotD.demo2(10, 7);
103
- };
104
- console.log(`SYNCHRONOUS DEMO =====================================`);
105
- synchronousDemo();
106
-
107
- // ========================================================================
108
- // ASYNCHRONOUS DEMO
109
-
110
- const asynchronousDemo = (callback) => {
111
- const localCallback = (err) => {
112
- demoDotD.seal();
113
- callback(err, demoDotD);
114
- };
115
-
116
- const demoDotD = qtLibDotD({
117
- libraryName: 'demoDotD',
118
- });
119
-
120
- const libraryModulesPath = path.join(__dirname, 'demoModules_DotD');
121
-
122
- const passThroughParameters = {
123
- message: 'Hello from a dotDlib module',
124
- add: (a, b) => a + b,
125
- };
126
-
127
- demoDotD.setLibraryPath(libraryModulesPath);
128
- demoDotD.loadModules({ passThroughParameters }, localCallback);
129
- };
130
-
131
- console.log(`\n\nASYNCHRONOUS DEMO =====================================`);
132
-
133
- const callback = (err, demoDotD) => {
134
- console.log(demoDotD.toString());
135
- demoDotD.demo1();
136
- demoDotD.demo2(10, 7);
137
- };
138
-
139
- asynchronousDemo(callback);
140
- };
141
-
142
-
143
- // ================================================================================
144
- // demo1.js
145
-
146
- #!/usr/bin/env node
147
- 'use strict';
148
- // Suppress punycode deprecation warning
149
- process.noDeprecation = true;
150
-
151
- const moduleName = __filename.replace(__dirname + '/', '').replace(/.js$/, ''); //this just seems to come in handy a lot
152
-
153
- //START OF moduleFunction() ============================================================
154
- const moduleFunction = ({ moduleName } = {}) => ({ dotD, passThroughParameters } = {}) => {
117
+ ### 2. **Module Directory Setup**
118
+
119
+ ```javascript
120
+ library.setLibraryPath('./modules.d');
121
+ ```
155
122
 
156
- const workingFunction = () => {
157
- console.log(`${passThroughParameters.message} [${moduleName}]`);
158
- return 'hello';
159
- };
160
-
123
+ ### 3. **Shared Resource Definition**
161
124
 
162
- dotD.library.add(moduleName, workingFunction);
125
+ ```javascript
126
+ const passThroughParameters = {
127
+ config: appConfig,
128
+ database: dbConnection,
129
+ logger: logger
163
130
  };
131
+ ```
164
132
 
165
- //END OF moduleFunction() ============================================================
133
+ ### 4. **Module Loading**
166
134
 
167
- module.exports = moduleFunction({ moduleName }); //runs it right now
168
- //END OF moduleFunction() ============================================================
135
+ ```javascript
136
+ // Synchronous
137
+ library.loadModules({ passThroughParameters });
169
138
 
170
- module.exports = moduleFunction({ moduleName })({});
139
+ // Asynchronous
140
+ library.loadModules({ passThroughParameters }, callback);
141
+ ```
171
142
 
143
+ ### 5. **Library Sealing**
172
144
 
173
- // ================================================================================
174
- //demo2.js
145
+ ```javascript
146
+ library.seal(); // Prevents further modifications
147
+ ```
175
148
 
176
- #!/usr/bin/env node
177
- 'use strict';
178
- // Suppress punycode deprecation warning
179
- process.noDeprecation = true;
149
+ ### 6. **Module Usage**
180
150
 
181
- const moduleName = __filename.replace(__dirname + '/', '').replace(/.js$/, ''); //this just seems to come in handy a lot
151
+ ```javascript
152
+ // If you have modules.d/processOrder.js
153
+ library.processOrder(orderData);
154
+
155
+ // If you have modules.d/sendEmail.js
156
+ library.sendEmail(recipient, message);
157
+ ```
158
+
159
+ ## Module Structure
160
+
161
+ Every dotD module follows this pattern:
162
+
163
+ ```javascript
164
+ const moduleName = __filename.replace(__dirname + '/', '').replace(/.js$/, '');
182
165
 
183
- //START OF moduleFunction() ============================================================
184
166
  const moduleFunction = ({ moduleName } = {}) => ({ dotD, passThroughParameters } = {}) => {
185
167
 
186
- const workingFunction = (arg1, arg2) => {
187
- console.log(`Pass Through Function: ${arg1}+${arg2}=${passThroughParameters.add(arg1, arg2)} [${moduleName}]`);
188
- return 'hello';
189
- };
190
-
168
+ const workingFunction = (/* your parameters */) => {
169
+ // Access shared resources
170
+ const config = passThroughParameters.config;
171
+ const logger = passThroughParameters.logger;
172
+
173
+ // Your module logic here
174
+
175
+ return result;
176
+ };
191
177
 
192
- dotD.library.add(moduleName, workingFunction);
178
+ // Register the function
179
+ dotD.library.add(moduleName, workingFunction);
193
180
  };
194
181
 
195
- //END OF moduleFunction() ============================================================
182
+ module.exports = moduleFunction({ moduleName });
183
+ ```
196
184
 
197
- module.exports = moduleFunction({ moduleName }); //runs it right now
185
+ ## Benefits Over Traditional Approaches
198
186
 
187
+ | Traditional | dotD Libraries |
188
+ | --------------------- | --------------------------- |
189
+ | Manual imports | Automatic discovery |
190
+ | Tight coupling | Loose coupling |
191
+ | Hard to extend | Easy to extend |
192
+ | Configuration in code | Configuration through files |
193
+ | Monolithic | Modular |
194
+ | Static structure | Dynamic structure |
199
195
 
200
- HISTORY
196
+ ## Getting Started
201
197
 
202
- v1.05 - cleaned up toString() report, returns exception list (or err if callback) if needed, added qtools-functional-library
203
- v1.04 - Now tolerates (and reports) directories and files that are not modules.
198
+ 1. **Install the dependency:**
199
+
200
+ ```bash
201
+ npm install qtools-library-dot-d
202
+ ```
203
+
204
+ 2. **Run the example:**
205
+
206
+ ```bash
207
+ npm start
208
+ ```
209
+
210
+ 3. **Create your own modules:**
211
+
212
+ - Add `.js` files to `demoModules_DotD/`
213
+ - Follow the module pattern shown in the examples
214
+ - Access shared resources via `passThroughParameters`
215
+
216
+ ## Advanced Features
217
+
218
+ - **Async module loading** for modules that need initialization
219
+ - **Error handling** during module loading
220
+ - **Library introspection** with `toString()` and `qtdProcessLog()`
221
+ - **Multiple libraries** in the same application
222
+ - **Nested module structures** for complex applications
204
223
 
224
+ ## Integration with Larger Systems
205
225
 
206
- HISTORY
226
+ The dotD pattern works particularly well in:
207
227
 
228
+ - **Web frameworks** (Express, Koa) for route organization
229
+ - **API systems** for endpoint management
230
+ - **CLI tools** for command organization
231
+ - **Microservices** for feature modularity
232
+ - **Plugin systems** for extensible applications
233
+
234
+ This pattern is used extensively in the qtools ecosystem for building scalable, maintainable Node.js applications.
235
+
236
+ ## HISTORY
237
+
238
+ v1.07 - updated README
239
+ v1.05 - cleaned up toString() report, returns exception list (or err if callback) if needed, added qtools-functional-library
208
240
  v1.04 - Now tolerates (and reports) directories and files that are not modules.
241
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qtools-library-dot-d",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Scan a directory for JS modules that can execute and addMe() that attaches it to some form of name/value list, eg, a Map() with functions as values or an xPressJS route/endpoint list.",
5
5
  "main": "qtools-library-dot-d.js",
6
6
  "scripts": {