@cldmv/slothlet 1.0.3 → 2.1.0

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 (48) hide show
  1. package/README.md +913 -73
  2. package/dist/lib/engine/README.md +21 -0
  3. package/dist/lib/engine/slothlet_child.mjs +58 -0
  4. package/dist/lib/engine/slothlet_engine.mjs +371 -0
  5. package/dist/lib/engine/slothlet_esm.mjs +229 -0
  6. package/dist/lib/engine/slothlet_helpers.mjs +454 -0
  7. package/dist/lib/engine/slothlet_worker.mjs +148 -0
  8. package/dist/lib/helpers/resolve-from-caller.mjs +141 -0
  9. package/dist/lib/helpers/sanitize.mjs +265 -0
  10. package/dist/lib/modes/slothlet_eager.mjs +80 -0
  11. package/dist/lib/modes/slothlet_lazy.mjs +342 -0
  12. package/dist/lib/runtime/runtime.mjs +249 -0
  13. package/dist/slothlet.mjs +1097 -0
  14. package/index.cjs +81 -0
  15. package/index.mjs +76 -0
  16. package/package.json +132 -20
  17. package/types/dist/lib/engine/slothlet_child.d.mts +2 -0
  18. package/types/dist/lib/engine/slothlet_child.d.mts.map +1 -0
  19. package/types/dist/lib/engine/slothlet_engine.d.mts +31 -0
  20. package/types/dist/lib/engine/slothlet_engine.d.mts.map +1 -0
  21. package/types/{src/lib → dist/lib/engine}/slothlet_esm.d.mts +1 -0
  22. package/types/dist/lib/engine/slothlet_esm.d.mts.map +1 -0
  23. package/types/{src/lib → dist/lib/engine}/slothlet_helpers.d.mts +2 -2
  24. package/types/dist/lib/engine/slothlet_helpers.d.mts.map +1 -0
  25. package/types/dist/lib/engine/slothlet_worker.d.mts +2 -0
  26. package/types/dist/lib/engine/slothlet_worker.d.mts.map +1 -0
  27. package/types/dist/lib/helpers/resolve-from-caller.d.mts +149 -0
  28. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -0
  29. package/types/dist/lib/helpers/sanitize.d.mts +79 -0
  30. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -0
  31. package/types/dist/lib/modes/slothlet_eager.d.mts +66 -0
  32. package/types/dist/lib/modes/slothlet_eager.d.mts.map +1 -0
  33. package/types/dist/lib/modes/slothlet_lazy.d.mts +32 -0
  34. package/types/dist/lib/modes/slothlet_lazy.d.mts.map +1 -0
  35. package/types/dist/lib/runtime/runtime.d.mts +49 -0
  36. package/types/dist/lib/runtime/runtime.d.mts.map +1 -0
  37. package/types/dist/slothlet.d.mts +124 -0
  38. package/types/dist/slothlet.d.mts.map +1 -0
  39. package/types/index.d.mts +23 -0
  40. package/slothlet.mjs +0 -1248
  41. package/types/debug-slothlet.d.mts +0 -1
  42. package/types/eslint.config.d.mts +0 -2
  43. package/types/jest.config.d.mts +0 -6
  44. package/types/slothlet.d.mts +0 -189
  45. package/types/src/lib/slothlet_child.d.mts +0 -1
  46. package/types/src/lib/slothlet_engine.d.mts +0 -6
  47. package/types/src/lib/slothlet_worker.d.mts +0 -1
  48. package/types/vitest.config.d.ts +0 -2
package/README.md CHANGED
@@ -1,115 +1,955 @@
1
1
  # @cldmv/slothlet
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@cldmv/slothlet.svg)](https://www.npmjs.com/package/@cldmv/slothlet)
4
- [![license](https://img.shields.io/github/license/CLDMV/slothlet.svg)](LICENSE)
5
- ![size](https://img.shields.io/npm/unpacked-size/@cldmv/slothlet.svg)
6
- ![npm-downloads](https://img.shields.io/npm/dm/@cldmv/slothlet.svg)
7
- ![github-downloads](https://img.shields.io/github/downloads/CLDMV/slothlet/total)
3
+ <div align="center">
4
+ <img src="https://github.com/CLDMV/slothlet/raw/HEAD/images/slothlet-logo-v1-horizontal-transparent.png" alt="Slothlet Logo" width="600">
5
+ </div>
8
6
 
9
- > **⚠️ WARNING: This module is under active development!**
7
+ **@cldmv/slothlet** is a sophisticated module loading framework that revolutionizes how you work with massive APIs in Node.js. Built for developers who demand smart, efficient module loading without compromising performance or developer experience.
8
+
9
+ Choose your loading strategy based on your needs: **lazy mode** loads modules on-demand for faster startup and lower memory usage, while **eager mode** loads everything upfront for maximum runtime performance and predictable behavior.
10
+
11
+ With our **copy-left materialization** in lazy mode, you get the best of both worlds: the memory efficiency of on-demand loading with near-eager performance on repeated calls. Once a module is materialized, it stays materialized—no re-processing overhead.
12
+
13
+ The name might suggest we're taking it easy, but don't be fooled. **Slothlet delivers speed where it counts**, with smart optimizations that make your APIs fly.
14
+
15
+ > _"slothlet is anything but slow."_
16
+
17
+ [![npm version]][npm_version_url] [![npm downloads]][npm_downloads_url] <!-- [![GitHub release]][github_release_url] -->[![GitHub downloads]][github_downloads_url] [![Last commit]][last_commit_url] <!-- [![Release date]][release_date_url] -->[![npm last update]][npm_last_update_url]
18
+
19
+ > [!NOTE]
20
+ > **🚀 Production Ready Modes:**
21
+ >
22
+ > - **Eager Mode**: Fully stable and production-ready for immediate module loading
23
+ > - **Lazy Mode**: Production-ready with advanced copy-left materialization and 4.3x faster startup (1.1x slower function calls)
24
+
25
+ > [!CAUTION]
26
+ > **⚙️ Experimental Modes:**
27
+ >
28
+ > - **Worker, Fork, Child, VM modes**: In active development, not recommended for production use
10
29
  >
11
- > - The standard **eager mode** works well and is stable for production use.
12
- > - **Lazy mode** has been tested and works for most use cases.
13
- > - **Experimental modes** (such as worker, child process, and advanced context binding) are in development and may not be fully functional or stable.
30
+ > Please report issues and contribute feedback to help improve the experimental features.
31
+
32
+ [![Contributors]][contributors_url] [![Sponsor shinrai]][sponsor_url]
33
+
34
+ ---
35
+
36
+ ## ✨ What's New in v2.0
37
+
38
+ ### 🎯 **Complete Architectural Rewrite**
39
+
40
+ v2.0 represents a ground-up rewrite with enterprise-grade features:
41
+
42
+ - **Universal Module Support**: Load both ESM (`.mjs`) and CommonJS (`.cjs`) files seamlessly
43
+ - **AsyncLocalStorage Integration**: Advanced context isolation and live-binding system
44
+ - **4.3x Faster Startup**: Lazy mode achieves 564.17μs vs 2.45ms in eager mode
45
+ - **Copy-Left Materialization**: Once loaded, modules stay materialized for optimal performance
46
+ - **Zero Dependencies**: Pure Node.js implementation with no external dependencies
47
+
48
+ ### 🏗️ **Enhanced Architecture**
49
+
50
+ - **Modular Design**: Organized into `engine/`, `modes/`, `runtime/`, and `helpers/`
51
+ - **Live-Binding System**: Dynamic context and reference binding with runtime coordination
52
+ - **Smart Function Naming**: Preserves original capitalization (`autoIP`, `parseJSON`, `getHTTPStatus`)
53
+ - **Multi-Execution Environments**: Singleton, VM, worker, fork isolation modes (experimental)
54
+
55
+ ### 🔧 **Advanced Sanitization Control** ⭐ NEW
56
+
57
+ - **Custom API Naming**: Control how filenames become API property names through sanitize options
58
+ - **Boundary Pattern Matching**: Use `**string**` patterns for precise transformations (`**url**` → `buildURLWithParams`)
59
+ - **Glob Pattern Support**: Apply rules with wildcards (`*json*`, `auto*`, `http*`) for flexible naming control
60
+ - **Case-Sensitive Rules**: Preserve important naming patterns (acronyms, technical terms, branding)
61
+ - **Mixed Rule Types**: Combine exact matches, globs, and boundary patterns for sophisticated naming strategies
62
+
63
+ ### 📊 **Performance Optimizations**
64
+
65
+ - **Startup**: Lazy mode 4.3x faster (564.17μs vs 2.45ms)
66
+ - **Function Calls**: Eager mode 1.1x faster (0.65μs vs 0.72μs) after materialization
67
+ - **Memory**: On-demand loading scales with actual usage
68
+ - **Predictability**: Consistent performance characteristics per mode
69
+
70
+ ---
71
+
72
+ ## 🚀 Key Features
73
+
74
+ ### 🎯 **Dual Loading Strategies**
75
+
76
+ - **Eager Loading**: Immediate loading for maximum performance in production environments
77
+ - **Lazy Loading**: Copy-left materialization with look-ahead proxies (4.3x faster startup, 1.1x slower calls after materialization)
78
+
79
+ > [!IMPORTANT]
80
+ > **Function Call Patterns:**
14
81
  >
15
- > Please report issues, contribute, and use experimental features with caution.
82
+ > - **Lazy Mode**: ALL function calls must be awaited (`await api.math.add(2, 3)`) due to materialization process
83
+ > - **Eager Mode**: Functions behave as originally defined - sync functions are sync (`api.math.add(2, 3)`), async functions are async (`await api.async.process()`)
84
+
85
+ ### ⚡ Performance Excellence
86
+
87
+ - **📊 For comprehensive performance analysis, benchmarks, and recommendations, see [PERFORMANCE.md](https://github.com/CLDMV/slothlet/blob/HEAD/PERFORMANCE.md)**
16
88
 
17
- **@cldmv/slothlet** is a modern, lazy modular API loader for Node.js projects. Designed for developers who want fast, flexible, and memory-efficient access to large modular APIs, it dynamically loads API modules and submodules only when accessed. Slothlet supports both lazy and eager loading, automatic flattening of single-file modules, and descriptive error handling—all with a fun branding twist: "slothlet is anything but slow."
89
+ ### 🔧 **Smart API Management**
18
90
 
19
- ## Features
91
+ - **Callable Interface**: Use `slothlet(options)` for direct API creation
92
+ - **Automatic Flattening**: Single-file modules become direct API properties (`math/math.mjs` → `api.math`)
93
+ - **Intelligent Naming**: Dash-separated names convert automatically (`root-math.mjs` → `api.rootMath`)
94
+ - **Function Name Preservation**: Maintains original capitalization (`auto-ip.mjs` with `autoIP` → `api.autoIP`)
95
+ - **Hybrid Exports**: Support for callable APIs with methods, default + named exports, and mixed patterns
20
96
 
21
- - **Lazy loading:** API endpoints are loaded on demand using ES6 Proxy, minimizing initial load time and memory usage.
22
- - **Eager loading:** Optionally load all modules up front for maximum performance.
23
- - **Automatic flattening:** Single-file modules (e.g., `math/math.mjs`) become `api.math`.
24
- - **CamelCase mapping:** Filenames and folders with dashes are mapped to camelCase API properties (e.g., `root-math.mjs` → `api.rootMath`).
25
- - **Descriptive errors:** Throws clear errors for missing API paths or methods.
26
- - **Configurable:** Set root directory and lazy loading depth.
27
- - **ESM-first:** Clean, standards-based API.
28
- - **TypeScript-friendly:** JSDoc-annotated API for editor support.
29
- - **Lightweight:** No dependencies, minimal footprint.
97
+ > [!TIP]
98
+ > **📁 For comprehensive examples of API flattening, naming conventions, and function preservation patterns, see the test modules in [api_tests/](https://github.com/CLDMV/slothlet/blob/HEAD/api_tests) and their documentation in [docs/api_tests/](https://github.com/CLDMV/slothlet/blob/HEAD/docs/api_tests)**
30
99
 
31
- ## Installation
100
+ ### 🔗 **Advanced Binding System**
32
101
 
33
- ```sh
102
+ - **Live Bindings**: Dynamic context and reference binding for runtime API mutation
103
+ - **AsyncLocalStorage**: Per-instance context isolation with seamless integration
104
+ - **Copy-Left Preservation**: Materialized functions stay materialized, preserving performance gains
105
+ - **Bubble-Up Updates**: Parent API synchronization ensures consistency across the API tree
106
+ - **Mixed Module Support**: Seamlessly blend ESM and CommonJS modules in the same API
107
+
108
+ ### 🛠 **Developer Experience**
109
+
110
+ - **Standard Error Handling**: Clear JavaScript errors with plans for enhanced descriptive errors in v2.1.0
111
+ - **TypeScript-Friendly**: Comprehensive JSDoc annotations for excellent editor support with auto-generated declarations
112
+ - **Configurable Debug**: Detailed logging for development and troubleshooting via CLI flags or environment variables
113
+ - **Multiple Instances**: Parameter-based isolation for complex applications with instance ID management
114
+ - **Development Checks**: Built-in environment detection with silent production behavior
115
+
116
+ ### 🏗 **Architecture & Compatibility**
117
+
118
+ - **ESM-First**: Built for modern JavaScript with full ES module support
119
+ - **Universal Loading**: CommonJS and ESM files work together seamlessly
120
+ - **Zero Dependencies**: Lightweight footprint with no external dependencies
121
+ - **Cross-Platform**: Works seamlessly across all Node.js environments
122
+ - **Extensible**: Modular architecture designed for future plugin system (in development)
123
+
124
+ ---
125
+
126
+ ## 📦 Installation
127
+
128
+ ### Requirements
129
+
130
+ - **Node.js v16.4.0 or higher** (for stable AsyncLocalStorage support)
131
+ - **ESM support** (ES modules with `import`/`export`)
132
+
133
+ > [!IMPORTANT]
134
+ > **v2.x Breaking Change**: Slothlet v2.x requires AsyncLocalStorage for its comprehensive live-binding system, which was stabilized in Node.js v16.4.0+ (June 2021). If you need older Node.js versions, please use slothlet v1.x (which requires Node.js v12.20.0+ (November 2020) for ESM support, dynamic imports, and query string imports). Note that v1.x live-binding worked in ESM (including multiple APIs via query strings) but was not available for multiple API instances in CommonJS.
135
+
136
+ ### Install
137
+
138
+ ```bash
34
139
  npm install @cldmv/slothlet
35
140
  ```
36
141
 
37
- ## Usage
142
+ ---
38
143
 
39
- > **Note:**
40
- >
41
- > - When using **lazy mode**, all API calls must be `await`ed, as modules are loaded asynchronously on access.
42
- > - If you need to create more than one slothlet instance, you must import the slothlet module using a param string (e.g., `import slothlet from "./slothlet.mjs?instance=1"`).
43
- > - **Caveat:** Live bindings (`self`, `context`, `reference`) will only work correctly if you use the same param string for both the loader and any submodules that import those bindings. Mismatched param strings will result in separate module instances and broken live bindings.
144
+ ## 🚀 Quick Start
44
145
 
45
- ### Node.js API
146
+ ### ESM (ES Modules)
46
147
 
47
- ```js
148
+ ```javascript
48
149
  import slothlet from "@cldmv/slothlet";
49
150
 
50
- // Lazy load from default directory
51
- const api = await slothlet.create({ lazy: true, context });
151
+ // Direct usage - eager mode by default (auto-detects callable interface)
152
+ const api = await slothlet({
153
+ dir: "./api",
154
+ context: { user: "alice" }
155
+ });
156
+
157
+ // Eager mode: Functions behave as originally defined
158
+ const result = api.math.add(2, 3); // Sync function - no await needed
159
+ const greeting = api("World"); // Instant if callable
160
+
161
+ // Original async functions still need await in eager mode
162
+ const asyncResult = await api.async.processData({ data: "async" });
52
163
 
53
- // Access API endpoints
54
- const sum = await api.math.add(2, 3); // 5
55
- const upper = await api.string.upper("abc"); // 'ABC'
56
- const today = await api.nested.date.today(); // '2025-08-15'
164
+ // Access both ESM and CJS modules seamlessly
165
+ const esmResult = api.mathEsm.multiply(4, 5); // 20 (sync)
166
+ const cjsResult = await api.mathCjs.divide(10, 2); // 5 (if originally async)
167
+ ```
168
+
169
+ ### CommonJS (CJS)
170
+
171
+ ```javascript
172
+ const slothlet = require("@cldmv/slothlet");
173
+
174
+ // Same usage pattern works with CommonJS
175
+ const api = await slothlet({
176
+ dir: "./api",
177
+ context: { env: "production" }
178
+ });
179
+
180
+ const result = api.math.multiply(4, 5); // 20
181
+ const mixedResult = await api.interop.processData({ data: "test" }); // CJS+ESM interop
182
+ ```
183
+
184
+ ### Lazy Loading Mode
57
185
 
186
+ ```javascript
187
+ import slothlet from "@cldmv/slothlet";
58
188
 
189
+ // Lazy mode with copy-left materialization (opt-in)
190
+ const api = await slothlet({
191
+ lazy: true,
192
+ dir: "./api",
193
+ apiDepth: 3
194
+ });
59
195
 
60
- // Eager load from a custom directory
61
- const api = await slothlet.create({ lazy: false, dir: "./api_test" context });
196
+ // First access: ~310μs (materialization overhead)
197
+ const result1 = await api.math.add(2, 3);
62
198
 
63
- // Access API endpoints
64
- const sum = api.math.add(2, 3); // 5
65
- const upper = api.string.upper("abc"); // 'ABC'
66
- const today = api.nested.date.today(); // '2025-08-15'
199
+ // Subsequent access: ~0.5μs (materialized function)
200
+ const result2 = await api.math.add(5, 7); // 700x faster than first call!
67
201
  ```
68
202
 
69
- ## API Reference
203
+ ### Advanced Configuration
70
204
 
71
- ### Main Methods
205
+ ```javascript
206
+ import slothlet from "@cldmv/slothlet";
72
207
 
73
- - `slothlet.create(options)` Loads API modules and returns a bound API object. Options include lazy/eager mode, context, reference, and directory.
74
- - `slothlet.load(config, ctxRef)` — Loads API modules (lazy or eager) and binds context/reference. Returns the API object.
75
- - `slothlet.createBoundApi(context, reference)` Returns an API object bound to the provided context and reference.
76
- - `slothlet.getApi()` Returns the loaded API object (Proxy or plain object).
77
- - `slothlet.getBoundApi()` Returns the bound API object (with context/reference).
78
- - `slothlet.isLoaded()` Returns true if the API is loaded.
79
- - `slothlet.shutdown()` — Gracefully shuts down the API and internal resources.
208
+ const api = await slothlet({
209
+ dir: "./api",
210
+ lazy: false, // Loading strategy
211
+ api_mode: "auto", // API structure behavior
212
+ apiDepth: Infinity, // Directory traversal depth
213
+ debug: false, // Enable verbose logging
214
+ context: {
215
+ // Injected into live-binding
216
+ user: "alice",
217
+ env: "production",
218
+ config: { timeout: 5000 }
219
+ },
220
+ reference: {
221
+ // Merged into API root
222
+ version: "2.0.0",
223
+ helpers: {
224
+ /* ... */
225
+ }
226
+ },
227
+ sanitize: {
228
+ // 🔧 NEW: Control API property naming
229
+ lowerFirst: false, // Keep first character casing
230
+ rules: {
231
+ leave: ["parseJSON", "autoIP"], // Preserve exact names
232
+ leaveInsensitive: ["*xml*"], // Case-insensitive preservation
233
+ upper: ["**url**", "api", "http*"], // Force uppercase (including boundary patterns)
234
+ lower: ["id", "uuid", "*id"] // Force lowercase
235
+ }
236
+ }
237
+ });
238
+ ```
80
239
 
81
- ### Config Options
240
+ ### Sanitize Options Examples
241
+
242
+ Transform module filenames into clean, professional API property names:
243
+
244
+ ```javascript
245
+ // Without sanitize options (default behavior)
246
+ const api = await slothlet({ dir: "./api" });
247
+ // Files: build-url-with-params.mjs, parse-json-data.mjs, auto-ip.mjs
248
+ // Result: api.buildUrlWithParams, api.parseJsonData, api.autoIp
249
+
250
+ // With sanitize options (custom naming control)
251
+ const api = await slothlet({
252
+ dir: "./api",
253
+ sanitize: {
254
+ lowerFirst: false,
255
+ rules: {
256
+ leave: ["parseJSON"], // Exact match preservation
257
+ upper: ["**url**", "ip", "http*"], // Boundary + glob patterns
258
+ leaveInsensitive: ["*xml*"] // Case-insensitive globs
259
+ }
260
+ }
261
+ });
262
+ // Result: api.buildURLWithParams, api.parseJSON, api.autoIP
263
+ ```
82
264
 
83
- - `lazy` (boolean): Enable lazy loading (default: true)
84
- - `lazyDepth` (number): How deep to lazy load subdirectories (default: Infinity)
85
- - `dir` (string): Directory to load API modules from (default: loader's directory)
86
- - `debug` (boolean): Enable debug logging (default: false)
265
+ **Sanitize Pattern Types:**
87
266
 
88
- ### Context & Reference
267
+ - **Exact Match**: `"parseJSON"` - Matches exact string only
268
+ - **Glob Patterns**: `"*json*"`, `"auto*"`, `"http*"` - Wildcard matching
269
+ - **Boundary Patterns**: `"**url**"` - Only matches when surrounded by word boundaries
270
+ - **Case Control**: `leaveInsensitive` for case-insensitive matching
89
271
 
90
- - `context`: Object passed to API modules for contextual data (e.g., user/session info)
91
- - `reference`: Object passed to API modules for additional references or configuration
272
+ ### Multiple Instances
92
273
 
93
- ### Error Handling
274
+ In v2.x, each call to `slothlet(options)` automatically creates a new isolated instance with its own context and configuration:
94
275
 
95
- - Throws descriptive errors for missing API paths or methods
96
- - All errors include the requested path and directory for easier debugging
276
+ #### ESM (ES Modules)
97
277
 
98
- ### JSDoc
278
+ ```javascript
279
+ import slothlet from "@cldmv/slothlet";
99
280
 
100
- See JSDoc comments in the source code for detailed type annotations and usage examples.
281
+ // Each call creates a new isolated instance automatically
282
+ const api1 = await slothlet({ dir: "./api1", context: { tenant: "alice" } });
283
+ const api2 = await slothlet({ dir: "./api2", context: { tenant: "bob" } });
101
284
 
102
- ## Module Structure
285
+ // Instances are completely isolated
286
+ console.log(api1.context.tenant); // "alice"
287
+ console.log(api2.context.tenant); // "bob"
288
+ ```
103
289
 
104
- - Single-file modules: `api_test/math/math.mjs` → `api.math`
105
- - Multi-file modules: `api_test/multi/alpha.mjs` → `api.multi.alpha`, `api_test/multi/beta.mjs` → `api.multi.beta`
106
- - Dashes in names: `api_test/root-math.mjs` → `api.rootMath`
290
+ #### CommonJS (CJS)
107
291
 
108
- ## Safety & Errors
292
+ ```javascript
293
+ const slothlet = require("@cldmv/slothlet");
109
294
 
110
- - Throws descriptive errors for missing API paths or methods
111
- - Only loads modules when accessed (lazy) or all at once (eager)
295
+ // Each call creates a new isolated instance automatically
296
+ const api1 = await slothlet({ dir: "./api1", context: { tenant: "alice" } });
297
+ const api2 = await slothlet({ dir: "./api2", context: { tenant: "bob" } });
112
298
 
113
- ## License
299
+ // Instances are completely isolated with their own AsyncLocalStorage contexts
300
+ console.log(api1.context.tenant); // "alice"
301
+ console.log(api2.context.tenant); // "bob"
302
+ ```
303
+
304
+ > [!NOTE]
305
+ > **v2.x Simplification**: Unlike v1.x which required query string parameters or `withInstanceId()` methods, v2.x automatically creates isolated instances with each `slothlet()` call, leveraging AsyncLocalStorage for complete context separation.
306
+
307
+ ---
308
+
309
+ ## 📚 API Reference
310
+
311
+ ### Core Methods
312
+
313
+ #### `slothlet(options)` ⇒ `Promise<object>`
314
+
315
+ Creates and loads an API instance with the specified configuration.
316
+
317
+ **Parameters:**
318
+
319
+ | Param | Type | Description |
320
+ | ------- | -------- | --------------------- |
321
+ | options | `object` | Configuration options |
322
+
323
+ **Returns:** `Promise<object>` - The bound API object
324
+
325
+ **Options:**
326
+
327
+ | Option | Type | Default | Description |
328
+ | ----------- | --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
329
+ | `dir` | `string` | `"api"` | Directory to load API modules from. Can be absolute or relative path. If relative, resolved from process.cwd(). |
330
+ | `lazy` | `boolean` | `false` | Loading strategy - `true` for lazy loading (on-demand), `false` for eager loading (immediate) |
331
+ | `apiDepth` | `number` | `Infinity` | Directory traversal depth control - `0` for root only, `Infinity` for all levels |
332
+ | `debug` | `boolean` | `false` | Enable verbose logging. Can also be set via `--slothletdebug` command line flag or `SLOTHLET_DEBUG=true` environment variable |
333
+ | `mode` | `string` | `"singleton"` | Execution environment mode - `"singleton"`, `"vm"`, `"worker"`, or `"fork"` |
334
+ | `api_mode` | `string` | `"auto"` | API structure behavior when root-level default functions exist:<br/>• `"auto"`: Automatically detects if root has default function export and creates callable API<br/>• `"function"`: Forces API to be callable (use when you have root-level default function exports)<br/>• `"object"`: Forces API to be object-only (use when you want object interface regardless of exports) |
335
+ | `context` | `object` | `{}` | Context data object injected into live-binding `context` reference. Available to all loaded modules via `import { context } from '@cldmv/slothlet/runtime'` |
336
+ | `reference` | `object` | `{}` | Reference object merged into the API root level. Properties not conflicting with loaded modules are added directly to the API |
337
+ | `sanitize` | `object` | `{}` | **🔧 NEW**: Control how filenames become API property names. Supports exact matches, glob patterns (`*json*`), and boundary patterns (`**url**`). Configure `lowerFirst` and `rules` for `leave`, `leaveInsensitive`, `upper`, and `lower` transformations |
338
+
339
+ #### `slothlet.getApi()` ⇒ `object`
340
+
341
+ Returns the raw API object (Proxy or plain object).
342
+
343
+ **Returns:** `function | object` - The raw API object or function
344
+
345
+ #### `slothlet.getBoundApi()` ⇒ `object`
346
+
347
+ Returns the bound API object with context and reference.
348
+
349
+ **Returns:** `function | object` - The bound API object or function with live bindings and context
350
+
351
+ #### `slothlet.isLoaded()` ⇒ `boolean`
352
+
353
+ Returns true if the API is loaded.
354
+
355
+ **Returns:** `boolean` - Whether the API has been loaded
356
+
357
+ #### `slothlet.shutdown()` ⇒ `Promise<void>`
358
+
359
+ Gracefully shuts down the API and cleans up resources.
360
+
361
+ **Returns:** `Promise<void>` - Resolves when shutdown is complete
362
+
363
+ > [!NOTE]
364
+ > **📚 For detailed API documentation with comprehensive parameter descriptions, method signatures, and examples, see [docs/API.md](https://github.com/CLDMV/slothlet/blob/HEAD/docs/API.md)**
365
+
366
+ ### Live Bindings
367
+
368
+ Access live-bound references in your API modules:
369
+
370
+ ```javascript
371
+ // Create API with reference functions
372
+ const api = await slothlet({
373
+ dir: "./api",
374
+ reference: {
375
+ md5: (str) => crypto.createHash("md5").update(str).digest("hex"),
376
+ version: "2.0.0",
377
+ utils: { format: (msg) => `[LOG] ${msg}` }
378
+ }
379
+ });
380
+ ```
381
+
382
+ ```javascript
383
+ // In your API modules (ESM)
384
+ import { self, context, reference } from "@cldmv/slothlet/runtime";
385
+
386
+ export function myFunction() {
387
+ console.log(context.user); // Access live context
388
+ return self.otherModule.helper(); // Access other API modules
389
+
390
+ // Reference functions are available directly on self
391
+ const hash = self.md5("hello world"); // Access reference function
392
+ console.log(self.version); // Access reference data
393
+ }
394
+
395
+ // Mixed module example (ESM accessing CJS)
396
+ export function processData(data) {
397
+ // Call a CJS module from ESM
398
+ const processed = self.cjsModule.process(data);
399
+
400
+ // Use reference utilities directly
401
+ const logged = self.utils.format(`Processed: ${processed}`);
402
+ return self.md5(logged); // Hash the result
403
+ }
404
+ ```
405
+
406
+ ```javascript
407
+ // In your CJS modules
408
+ const { self, context, reference } = require("@cldmv/slothlet/runtime");
409
+
410
+ function cjsFunction(data) {
411
+ console.log(context.env); // Access live context
412
+
413
+ // Reference functions available directly on self
414
+ const hash = self.md5(data); // Direct access to reference function
415
+
416
+ return self.esmModule.transform(hash); // Access ESM modules from CJS
417
+ }
418
+
419
+ module.exports = { cjsFunction };
420
+ ```
421
+
422
+ ### API Mode Configuration
423
+
424
+ The `api_mode` option controls how slothlet handles root-level default function exports:
425
+
426
+ #### Auto-Detection (Recommended)
427
+
428
+ ```javascript
429
+ const api = await slothlet({
430
+ api_mode: "auto" // Default - automatically detects structure
431
+ });
432
+
433
+ // If you have a root-level function export:
434
+ // root-function.mjs: export default function(name) { return `Hello, ${name}!` }
435
+ // Result: api("World") works AND api.otherModule.method() works
436
+
437
+ // If you only have object exports:
438
+ // Result: api.math.add() works, api("World") doesn't exist
439
+ ```
440
+
441
+ #### Explicit Function Mode
442
+
443
+ ```javascript
444
+ const api = await slothlet({
445
+ api_mode: "function" // Force callable interface
446
+ });
447
+
448
+ // Always creates callable API even without root default export
449
+ // Useful when you know you have root functions
450
+ const result = api("World"); // Calls root default function
451
+ const math = api.math.add(2, 3); // Also access other modules
452
+ ```
453
+
454
+ #### Explicit Object Mode
455
+
456
+ ```javascript
457
+ const api = await slothlet({
458
+ api_mode: "object" // Force object-only interface
459
+ });
460
+
461
+ // Always creates object interface even with root default export
462
+ // api("World") won't work, but api.rootFunction("World") will
463
+ const result = api.rootFunction("World"); // Access via property
464
+ const math = api.math.add(2, 3); // Normal module access
465
+ ```
466
+
467
+ ---
468
+
469
+ ## 🏗 Module Structure & Examples
470
+
471
+ Slothlet supports sophisticated module organization patterns with seamless ESM/CJS interoperability:
472
+
473
+ ### Root-Level Modules
474
+
475
+ ```text
476
+ root-math.mjs → api.rootMath (dash-to-camelCase)
477
+ rootstring.mjs → api.rootstring
478
+ config.mjs → api.config
479
+ ```
480
+
481
+ ### Single-File Modules
482
+
483
+ ```text
484
+ math/math.mjs → api.math (automatic flattening)
485
+ string/string.mjs → api.string
486
+ util/util.cjs → api.util (CJS support)
487
+ ```
488
+
489
+ ### Multi-File Modules
490
+
491
+ ```text
492
+ multi/
493
+ ├── alpha.mjs → api.multi.alpha
494
+ ├── beta.mjs → api.multi.beta
495
+ └── gamma.cjs → api.multi.gamma (mixed ESM/CJS)
496
+ ```
497
+
498
+ ### Function-Based Modules
499
+
500
+ ```text
501
+ funcmod/funcmod.mjs → api.funcmod() (callable function)
502
+ multi_func/
503
+ ├── alpha.mjs → api.multi_func.alpha()
504
+ └── beta.cjs → api.multi_func.beta() (CJS callable)
505
+ ```
506
+
507
+ ### Mixed ESM/CJS Modules
508
+
509
+ ```text
510
+ interop/
511
+ ├── esm-module.mjs → api.interop.esmModule
512
+ ├── cjs-module.cjs → api.interop.cjsModule
513
+ └── mixed.mjs → api.interop.mixed (calls both ESM and CJS)
514
+ ```
515
+
516
+ ### Hybrid Export Patterns
517
+
518
+ ```text
519
+ exportDefault/exportDefault.mjs → api.exportDefault() (callable with methods)
520
+ objectDefaultMethod/ → api.objectDefaultMethod() (object with default)
521
+ ```
522
+
523
+ ### Nested Structure
524
+
525
+ ```text
526
+ nested/
527
+ └── date/
528
+ ├── date.mjs → api.nested.date
529
+ └── util.cjs → api.nested.dateUtil
530
+ advanced/
531
+ ├── selfObject/ → api.advanced.selfObject
532
+ └── nest*/ → Various nesting examples
533
+ ```
534
+
535
+ ### Utility Modules
536
+
537
+ ```text
538
+ util/
539
+ ├── controller.mjs → api.util.controller
540
+ ├── extract.cjs → api.util.extract (CJS utility)
541
+ └── url/
542
+ ├── parser.mjs → api.util.url.parser
543
+ └── builder.cjs → api.util.url.builder (mixed)
544
+ ```
545
+
546
+ ### Smart Function Naming Examples
547
+
548
+ ```text
549
+ task/auto-ip.mjs (exports autoIP) → api.task.autoIP (preserves function name)
550
+ util/parseJSON.mjs → api.util.parseJSON (preserves JSON casing)
551
+ api/getHTTPStatus.mjs → api.api.getHTTPStatus (preserves HTTP casing)
552
+ ```
553
+
554
+ ## 🔀 How Slothlet Works: Loading Modes Explained
555
+
556
+ ```mermaid
557
+ flowchart TD
558
+ MODULEFOLDERS --> SLOTHLET
559
+ SLOTHLET --> CHOOSEMODE
560
+
561
+ CHOOSEMODE --> LAZY
562
+ CHOOSEMODE --> EAGER
563
+
564
+ subgraph EAGER ["⚡ Eager Mode"]
565
+ direction TB
566
+ EAGER0 ~~~ EAGER1
567
+ EAGER2 ~~~ EAGER3
568
+
569
+ EAGER0@{ shape: braces, label: "📥 All modules loaded immediately" }
570
+ EAGER1@{ shape: braces, label: "✅ API methods available right away" }
571
+ EAGER2@{ shape: braces, label: "🔄 Function calls behave as originally defined" }
572
+ EAGER3@{ shape: braces, label: "📞 Sync stays sync: api.math.add(2,3)<br/>🔄 Async stays async: await api.async.process()" }
573
+ end
574
+
575
+ subgraph LAZY ["💤 Lazy Mode"]
576
+ direction TB
577
+ LAZY0 ~~~ LAZY1
578
+ LAZY2 ~~~ LAZY3
579
+ LAZY4 ~~~ LAZY5
580
+
581
+ LAZY0@{ shape: braces, label: "📦 Modules not loaded yet" }
582
+ LAZY1@{ shape: braces, label: "🎭 API methods are placeholders/proxies" }
583
+ LAZY2@{ shape: braces, label: "📞 First call triggers materialization" }
584
+ LAZY3@{ shape: braces, label: "⏳ All calls must be awaited<br/>await api.math.add(2,3)" }
585
+ LAZY4@{ shape: braces, label: "💾 Module stays loaded after materialization<br/>Copy-left materialization" }
586
+ LAZY5@{ shape: braces, label: "🚀 Subsequent calls nearly as fast as eager mode" }
587
+ end
588
+
589
+ subgraph EAGERCALL ["⚡ Eager Mode Calls"]
590
+ direction TB
591
+ end
592
+
593
+ subgraph LAZYCALL ["💤 Lazy Mode Calls"]
594
+ direction TB
595
+ LAZYCALL0 --> LAZYCALL2
596
+
597
+ LAZYCALL0@{ shape: rounded, label: "📞 First call" }
598
+ LAZYCALL1@{ shape: rounded, label: "🔁 Sequential calls" }
599
+ LAZYCALL2@{ shape: rounded, label: "🧩 Materialize" }
600
+ end
601
+
602
+ EAGER --> READYTOUSE
603
+ LAZY --> READYTOUSE
604
+
605
+ READYTOUSE --> CALL
606
+ CALL -.-> EAGERCALL
607
+ CALL -.-> LAZYCALL
608
+
609
+ EAGERCALL --> MATERIALIZEDFUNCTION
610
+ LAZYCALL1 --> MATERIALIZEDFUNCTION
611
+ LAZYCALL2 --> MATERIALIZEDFUNCTION
612
+
613
+ READYTOUSE@{ shape: rounded, label: "🎯 Ready to Use" }
614
+ MATERIALIZEDFUNCTION@{ shape: rounded, label: "✅ Materialized method/property" }
615
+ CALL@{ shape: trap-b, label: "📞 Call" }
616
+
617
+ %% Notes as unattached nodes with braces shape
618
+ subgraph ALWAYS ["✨ Extras Always On"]
619
+ direction TB
620
+ ALWAYS0 ~~~ ALWAYS1
621
+ ALWAYS1 ~~~ ALWAYS2
622
+
623
+ ALWAYS0@{ shape: rounded, label: "🔗 Live Bindings ALS<br/>Per-instance context isolation" }
624
+ ALWAYS1@{ shape: rounded, label: "🏷️ Smart Naming & Flattening<br/>math/math.mjs → api.math" }
625
+ ALWAYS2@{ shape: rounded, label: "🔄 Mixed Module Support<br/>Seamlessly mix .mjs and .cjs" }
626
+ end
627
+
628
+ MODULEFOLDERS@{ shape: st-rect, label: "📁 Modules Folder<br/>.mjs and/or .cjs files<br/>math.mjs, string.cjs, async.mjs" }
629
+ SLOTHLET@{ shape: rounded, label: "🔧 Call slothlet(options)" }
630
+ CHOOSEMODE@{ shape: diamond, label: "Choose Mode<br/>in options" }
631
+
632
+ style EAGER0 stroke:#9BC66B,color:#9BC66B,opacity:0.5
633
+ style EAGER1 stroke:#9BC66B,color:#9BC66B,opacity:0.5
634
+ style EAGER2 stroke:#9BC66B,color:#9BC66B,opacity:0.5
635
+ style EAGER3 stroke:#9BC66B,color:#9BC66B,opacity:0.5
636
+
637
+ style LAZY0 stroke:#9BC66B,color:#9BC66B,opacity:0.5
638
+ style LAZY1 stroke:#9BC66B,color:#9BC66B,opacity:0.5
639
+ style LAZY2 stroke:#9BC66B,color:#9BC66B,opacity:0.5
640
+ style LAZY3 stroke:#9BC66B,color:#9BC66B,opacity:0.5
641
+ style LAZY4 stroke:#9BC66B,color:#9BC66B,opacity:0.5
642
+ style LAZY5 stroke:#9BC66B,color:#9BC66B,opacity:0.5
643
+
644
+ %% Slothlet brand colors - #9BC66B primary on dark theme
645
+ style MODULEFOLDERS fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
646
+ style SLOTHLET fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
647
+ style CHOOSEMODE fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
648
+ style READYTOUSE fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
649
+ style CALL fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
650
+ style MATERIALIZEDFUNCTION fill:#1a1a1a,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
651
+
652
+ %% Eager mode - primary green
653
+ style EAGER fill:#0d1a0d,stroke:#9BC66B,stroke-width:3px,color:#9BC66B,opacity:0.5
654
+ style EAGERCALL fill:#0d1a0d,stroke:#9BC66B,stroke-width:2px,color:#9BC66B,opacity:0.5
655
+
656
+ %% Lazy mode - lighter green tint
657
+ style LAZY fill:#0d1a0d,stroke:#B8D982,stroke-width:3px,color:#B8D982,opacity:0.5
658
+ style LAZYCALL fill:#0d1a0d,stroke:#B8D982,stroke-width:2px,color:#B8D982,opacity:0.5
659
+ style LAZYCALL0 fill:#1a1a1a,stroke:#B8D982,stroke-width:2px,color:#B8D982,opacity:0.5
660
+ style LAZYCALL1 fill:#1a1a1a,stroke:#B8D982,stroke-width:2px,color:#B8D982,opacity:0.5
661
+ style LAZYCALL2 fill:#1a1a1a,stroke:#B8D982,stroke-width:2px,color:#B8D982,opacity:0.5
662
+
663
+ %% Always available - accent green
664
+ style ALWAYS fill:#0d1a0d,stroke:#7FA94F,stroke-width:3px,color:#7FA94F,opacity:0.5
665
+ style ALWAYS0 fill:#1a1a1a,stroke:#7FA94F,stroke-width:1px,color:#7FA94F,opacity:0.5
666
+ style ALWAYS1 fill:#1a1a1a,stroke:#7FA94F,stroke-width:1px,color:#7FA94F,opacity:0.5
667
+ style ALWAYS2 fill:#1a1a1a,stroke:#7FA94F,stroke-width:1px,color:#7FA94F,opacity:0.5
668
+
669
+ %% Arrow styling
670
+ linkStyle default stroke:#9BC66B,stroke-width:3px,opacity:0.5
671
+ linkStyle 4,5,6,7,8,18,19 stroke-width:0px
672
+ ```
673
+
674
+ ---
675
+
676
+ ## 🚀 Performance Modes
677
+
678
+ ### Eager Mode (Default - Production Ready)
679
+
680
+ ```javascript
681
+ const api = await slothlet({ dir: "./api" }); // lazy: false by default
682
+
683
+ // Functions behave as originally defined - no await needed for sync functions
684
+ const result = api.math.add(2, 3); // Sync function - direct call
685
+ const greeting = api("World"); // Instant if callable
686
+
687
+ // Async functions still need await (as originally defined)
688
+ const asyncResult = await api.async.processData({ data: "test" }); // Original async function
689
+
690
+ // ESM+CJS works seamlessly with native behavior
691
+ const mixed = api.interop.process({ data: "test" }); // Sync or async as defined
692
+ ```
693
+
694
+ **Benefits:**
695
+
696
+ - ✅ Fastest function calls (0.36μs average)
697
+ - ✅ Predictable performance
698
+ - ✅ No materialization delays
699
+ - ✅ Functions behave exactly as originally defined (sync stays sync, async stays async)
700
+ - ✅ Optimal for production environments
701
+
702
+ ### Lazy Mode with Copy-Left Materialization (Production Ready)
703
+
704
+ ```javascript
705
+ const api = await slothlet({ lazy: true, dir: "./api" });
706
+
707
+ // ALL function calls must be awaited in lazy mode (due to materialization)
708
+ const result1 = await api.math.add(2, 3); // First access: ~310μs (materialization)
709
+ const result2 = await api.math.add(5, 7); // Subsequent: ~0.5μs (materialized)
710
+
711
+ // Even originally sync functions need await in lazy mode
712
+ const greeting = await api("World"); // Callable interface also needs await
713
+ const syncResult = await api.string.format("Hello"); // Originally sync, but needs await
714
+ ```
715
+
716
+ **Benefits:**
717
+
718
+ - ✅ 4.3x faster startup (564.17μs vs 2.45ms)
719
+ - ✅ Memory efficient (loads only what you use)
720
+ - ✅ Copy-left optimization (once loaded, stays loaded)
721
+ - ✅ Optimal for startup-sensitive applications
722
+ - ⚠️ All function calls require await (regardless of original sync/async nature)
723
+
724
+ **Performance Summary:**
725
+
726
+ > [!TIP]
727
+ > **Choose your loading strategy based on your needs:**
728
+ >
729
+ > - **Startup**: Lazy wins (4.3x faster - 564.17μs vs 2.45ms)
730
+ > - **Function calls**: Eager wins (1.1x faster - 0.65μs vs 0.72μs)
731
+ > - **Memory**: Lazy wins (loads only what you use)
732
+ > - **Predictability**: Eager wins (no materialization delays)
733
+
734
+ ---
735
+
736
+ ## 🛡 Error Handling
737
+
738
+ > [!NOTE]
739
+ > **Current Error Behavior**: Slothlet currently uses standard JavaScript error handling. Enhanced error handling with module suggestions is planned for v2.1.0 but not yet implemented.
740
+
741
+ **Current behavior:**
742
+
743
+ ```javascript
744
+ try {
745
+ console.log(api.nonexistent); // Returns: undefined
746
+ await api.nonexistent.method(); // Throws: "Cannot read properties of undefined (reading 'method')"
747
+ } catch (error) {
748
+ console.error(error.message); // Standard JavaScript error message
749
+ }
750
+ ```
751
+
752
+ **Planned Enhanced Error Features (v2.1.0):**
753
+
754
+ > [!TIP]
755
+ > **Coming Soon**: Enhanced error handling with descriptive messages and module suggestions:
756
+ >
757
+ > ```javascript
758
+ > try {
759
+ > await api.nonexistent.method();
760
+ > } catch (error) {
761
+ > console.error(error.message);
762
+ > // Planned: "Module 'nonexistent' not found in './api'. Available modules: math, string, util. Did you mean 'util'?"
763
+ > }
764
+ > ```
765
+ >
766
+ > **Planned Features:**
767
+ >
768
+ > - 🔍 **Module discovery**: Show available modules and suggest alternatives
769
+ > - 📍 **Context information**: Include directory path and configuration details
770
+ > - 🎯 **Actionable suggestions**: Provide specific guidance for resolution
771
+ > - 🚀 **Development mode**: Additional debugging information when debug flag is enabled
772
+
773
+ ---
774
+
775
+ ## 🔧 Production vs Development Modes
776
+
777
+ ### Production Ready ✅
778
+
779
+ - **Eager Mode**: Stable, battle-tested, maximum performance
780
+ - **Lazy Mode**: Production-ready with copy-left optimization
781
+ - **Singleton Mode**: Default mode for standard applications
782
+ - **Mixed Module Loading**: ESM/CJS interoperability fully supported
783
+
784
+ ### Development Features 🛠️
785
+
786
+ - **Development Check**: `devcheck.mjs` for environment validation
787
+ - **Debug Mode**: Comprehensive logging via `--slothletdebug` flag or `SLOTHLET_DEBUG=true`
788
+ - **Performance Monitoring**: Built-in timing and performance analysis
789
+ - **Source Detection**: Automatic `src/` vs `dist/` mode detection
790
+
791
+ ### Experimental ⚠️
792
+
793
+ > [!WARNING]
794
+ > The following modes are in active development and not recommended for production use:
795
+ >
796
+ > - **Worker Mode**: Thread isolation (in development)
797
+ > - **Fork Mode**: Process isolation (in development)
798
+ > - **Child Mode**: Child process execution (in development)
799
+ > - **VM Mode**: Virtual machine context (in development)
800
+ >
801
+ > The experimental modes are located in `src/lib/engine/` and should not be used in production environments.
802
+
803
+ ---
804
+
805
+ ## 🌟 Migration from v1.x
806
+
807
+ ### Key Changes
808
+
809
+ 1. **Import paths**: `@cldmv/slothlet` instead of specific file paths
810
+ 2. **Configuration**: New options (`api_mode`, `context`, `reference`)
811
+ 3. **Function names**: Enhanced preservation of original capitalization
812
+ 4. **Module structure**: Mixed ESM/CJS support
813
+ 5. **Live bindings**: New runtime system with AsyncLocalStorage
814
+
815
+ ### Migration Steps
816
+
817
+ ```javascript
818
+ // v1.3.x - API creation (same pattern as v2.x)
819
+ import slothlet from "@cldmv/slothlet";
820
+ const api = await slothlet({
821
+ dir: "./api",
822
+ lazy: true
823
+ });
824
+
825
+ // v1.3.x - Multiple instances required query strings or withInstanceId()
826
+ const api1 = await slothlet({ dir: "./api?instanceId=alice" });
827
+ const api2 = slothlet.withInstanceId("bob");
828
+ const bobApi = await api2({ dir: "./api" });
829
+
830
+ // v2.0 - Same API creation, but automatic instance isolation
831
+ import slothlet from "@cldmv/slothlet";
832
+ const api = await slothlet({
833
+ dir: "./api",
834
+ lazy: true,
835
+ context: { user: "alice" }, // New: context injection
836
+ api_mode: "auto" // New: API mode control
837
+ });
838
+
839
+ // v2.0 - Multiple instances automatically isolated (no query strings needed)
840
+ const api1 = await slothlet({ dir: "./api", context: { tenant: "alice" } });
841
+ const api2 = await slothlet({ dir: "./api", context: { tenant: "bob" } });
842
+ ```
843
+
844
+ ### Performance Improvements
845
+
846
+ - **Architectural optimizations** with copy-left materialization and AsyncLocalStorage integration
847
+ - **Zero dependencies** - pure Node.js implementation reduces overhead
848
+ - **Enhanced materialization** with copy-left optimization in lazy mode
849
+ - **Modular design** improves maintainability and potential optimization opportunities
850
+
851
+ ---
852
+
853
+ ## 🤝 Contributing
854
+
855
+ We welcome contributions! The experimental modes in particular need development and testing. Please:
856
+
857
+ 1. **Review the code** in `src/lib/engine/` for experimental features
858
+ 2. **Report issues** with detailed reproduction steps
859
+ 3. **Submit pull requests** with comprehensive tests
860
+ 4. **Provide feedback** on API design and performance
861
+ 5. **Documentation improvements** are always appreciated
862
+
863
+ See [CONTRIBUTING.md](https://github.com/CLDMV/slothlet/blob/HEAD/CONTRIBUTING.md) for detailed contribution guidelines.
864
+
865
+ [![Contributors]][contributors_url] [![Sponsor shinrai]][sponsor_url]
866
+
867
+ ---
868
+
869
+ ## 📊 Performance Analysis
870
+
871
+ For comprehensive performance benchmarks, analysis, and recommendations:
872
+
873
+ **📈 [See PERFORMANCE.md](https://github.com/CLDMV/slothlet/blob/HEAD/PERFORMANCE.md)**
874
+
875
+ Key highlights:
876
+
877
+ - Detailed startup vs runtime performance comparison
878
+ - Memory usage analysis by loading mode
879
+ - Materialization cost breakdown by module type
880
+ - Real-world performance recommendations
881
+
882
+ [![CodeFactor]][codefactor_url] [![npms.io score]][npms_url]
883
+
884
+ [![npm unpacked size]][npm_size_url] [![Repo size]][repo_size_url]
885
+
886
+ ---
887
+
888
+ ## 📚 Documentation
889
+
890
+ - **[API Documentation](https://github.com/CLDMV/slothlet/blob/HEAD/docs/API.md)** - Complete API reference with examples
891
+ - **[Performance Analysis](https://github.com/CLDMV/slothlet/blob/HEAD/PERFORMANCE.md)** - Detailed benchmarks and recommendations
892
+ - **[Contributing Guide](https://github.com/CLDMV/slothlet/blob/HEAD/CONTRIBUTING.md)** - How to contribute to the project
893
+ - **[Security Policy](https://github.com/CLDMV/slothlet/blob/HEAD/SECURITY.md)** - Security guidelines and reporting
894
+ - **[Test Documentation](https://github.com/CLDMV/slothlet/blob/HEAD/api_tests)** - Comprehensive test module examples
895
+
896
+ ---
897
+
898
+ ## 🔗 Links
899
+
900
+ - **npm**: [@cldmv/slothlet](https://www.npmjs.com/package/@cldmv/slothlet)
901
+ - **GitHub**: [CLDMV/slothlet](https://github.com/CLDMV/slothlet)
902
+ - **Issues**: [GitHub Issues](https://github.com/CLDMV/slothlet/issues)
903
+ - **Releases**: [GitHub Releases](https://github.com/CLDMV/slothlet/releases)
904
+
905
+ ---
906
+
907
+ ## 📄 License
908
+
909
+ [![GitHub license]][github_license_url] [![npm license]][npm_license_url]
114
910
 
115
911
  Apache-2.0 © Shinrai / CLDMV
912
+
913
+ ---
914
+
915
+ ## 🙏 Acknowledgments
916
+
917
+ Slothlet v2.0 represents a complete architectural rewrite with enterprise-grade features and performance. Special thanks to all contributors who made this comprehensive enhancement possible.
918
+
919
+ **🎉 Welcome to the future of module loading with Slothlet v2.0!**
920
+
921
+ > _Where sophisticated architecture meets blazing performance - slothlet is anything but slow._
922
+
923
+ <!-- [github release]: https://img.shields.io/github/v/release/CLDMV/slothlet?style=for-the-badge&logo=github&logoColor=white&labelColor=181717 -->
924
+ <!-- [github_release_url]: https://github.com/CLDMV/slothlet/releases -->
925
+
926
+ [npm version]: https://img.shields.io/npm/v/%40cldmv%2Fslothlet.svg?style=for-the-badge&logo=npm&logoColor=white&labelColor=CB3837
927
+ [npm_version_url]: https://www.npmjs.com/package/@cldmv/slothlet
928
+ [last commit]: https://img.shields.io/github/last-commit/CLDMV/slothlet?style=for-the-badge&logo=github&logoColor=white&labelColor=181717
929
+ [last_commit_url]: https://github.com/CLDMV/slothlet/commits
930
+
931
+ <!-- [release date]: https://img.shields.io/github/release-date/CLDMV/slothlet?style=for-the-badge&logo=github&logoColor=white&labelColor=181717 -->
932
+ <!-- [release_date_url]: https://github.com/CLDMV/slothlet/releases -->
933
+
934
+ [npm last update]: https://img.shields.io/npm/last-update/%40cldmv%2Fslothlet?style=for-the-badge&logo=npm&logoColor=white&labelColor=CB3837
935
+ [npm_last_update_url]: https://www.npmjs.com/package/@cldmv/slothlet
936
+ [codefactor]: https://img.shields.io/codefactor/grade/github/CLDMV/slothlet?style=for-the-badge&logo=codefactor&logoColor=white&labelColor=F44A6A
937
+ [codefactor_url]: https://www.codefactor.io/repository/github/cldmv/slothlet
938
+ [npms.io score]: https://img.shields.io/npms-io/final-score/%40cldmv%2Fslothlet?style=for-the-badge&logo=npms&logoColor=white&labelColor=0B5D57
939
+ [npms_url]: https://npms.io/search?q=%40cldmv%2Fslothlet
940
+ [npm downloads]: https://img.shields.io/npm/dm/%40cldmv%2Fslothlet.svg?style=for-the-badge&logo=npm&logoColor=white&labelColor=CB3837
941
+ [npm_downloads_url]: https://www.npmjs.com/package/@cldmv/slothlet
942
+ [github downloads]: https://img.shields.io/github/downloads/CLDMV/slothlet/total?style=for-the-badge&logo=github&logoColor=white&labelColor=181717
943
+ [github_downloads_url]: https://github.com/CLDMV/slothlet/releases
944
+ [npm unpacked size]: https://img.shields.io/npm/unpacked-size/%40cldmv%2Fslothlet.svg?style=for-the-badge&logo=npm&logoColor=white&labelColor=CB3837
945
+ [npm_size_url]: https://www.npmjs.com/package/@cldmv/slothlet
946
+ [repo size]: https://img.shields.io/github/repo-size/CLDMV/slothlet?style=for-the-badge&logo=github&logoColor=white&labelColor=181717
947
+ [repo_size_url]: https://github.com/CLDMV/slothlet
948
+ [github license]: https://img.shields.io/github/license/CLDMV/slothlet.svg?style=for-the-badge&logo=github&logoColor=white&labelColor=181717
949
+ [github_license_url]: https://github.com/CLDMV/slothlet/blob/HEAD/LICENSE
950
+ [npm license]: https://img.shields.io/npm/l/%40cldmv%2Fslothlet.svg?style=for-the-badge&logo=npm&logoColor=white&labelColor=CB3837
951
+ [npm_license_url]: https://www.npmjs.com/package/@cldmv/slothlet
952
+ [contributors]: https://img.shields.io/github/contributors/CLDMV/slothlet.svg?style=for-the-badge&logo=github&logoColor=white&labelColor=181717
953
+ [contributors_url]: https://github.com/CLDMV/slothlet/graphs/contributors
954
+ [sponsor shinrai]: https://img.shields.io/github/sponsors/shinrai?style=for-the-badge&logo=githubsponsors&logoColor=white&labelColor=EA4AAA&label=Sponsor
955
+ [sponsor_url]: https://github.com/sponsors/shinrai