retold 1.0.6 → 4.0.2

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 (119) hide show
  1. package/.claude/settings.local.json +84 -0
  2. package/CLAUDE.md +52 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/README.md +162 -0
  5. package/docs/_sidebar.md +78 -0
  6. package/docs/_topbar.md +6 -0
  7. package/docs/architecture/architecture.md +312 -0
  8. package/docs/architecture/module-architecture.md +234 -0
  9. package/docs/architecture/modules.md +99 -0
  10. package/docs/cover.md +15 -0
  11. package/docs/css/docuserve.css +73 -0
  12. package/docs/examples/examples.md +71 -0
  13. package/docs/examples/todolist/todo-list-cli-client.md +178 -0
  14. package/docs/examples/todolist/todo-list-console-client.md +152 -0
  15. package/docs/examples/todolist/todo-list-model.md +114 -0
  16. package/docs/examples/todolist/todo-list-server.md +128 -0
  17. package/docs/examples/todolist/todo-list-web-client.md +177 -0
  18. package/docs/examples/todolist/todo-list.md +162 -0
  19. package/docs/getting-started.md +273 -0
  20. package/docs/index.html +39 -0
  21. package/docs/modules/fable.md +198 -0
  22. package/docs/modules/meadow.md +209 -0
  23. package/docs/modules/orator.md +165 -0
  24. package/docs/modules/pict.md +235 -0
  25. package/docs/modules/utility.md +54 -0
  26. package/docs/retold-building-documentation.md +33 -0
  27. package/docs/retold-catalog.json +1405 -0
  28. package/docs/retold-keyword-index.json +203389 -0
  29. package/examples/quickstart/README.md +47 -0
  30. package/examples/quickstart/layer1/README.md +21 -0
  31. package/examples/quickstart/layer1/index.js +49 -0
  32. package/examples/quickstart/layer1/package-lock.json +344 -0
  33. package/examples/quickstart/layer1/package.json +12 -0
  34. package/examples/quickstart/layer2/README.md +34 -0
  35. package/examples/quickstart/layer2/index.js +251 -0
  36. package/examples/quickstart/layer2/package-lock.json +4468 -0
  37. package/examples/quickstart/layer2/package.json +17 -0
  38. package/examples/quickstart/layer2/setup-database.js +61 -0
  39. package/examples/quickstart/layer3/README.md +39 -0
  40. package/examples/quickstart/layer3/index.js +91 -0
  41. package/examples/quickstart/layer3/package-lock.json +1936 -0
  42. package/examples/quickstart/layer3/package.json +14 -0
  43. package/examples/quickstart/layer4/README.md +47 -0
  44. package/examples/quickstart/layer4/generate-build-config.js +18 -0
  45. package/examples/quickstart/layer4/html/index.html +17 -0
  46. package/examples/quickstart/layer4/package-lock.json +13206 -0
  47. package/examples/quickstart/layer4/package.json +38 -0
  48. package/examples/quickstart/layer4/server.js +28 -0
  49. package/examples/quickstart/layer4/source/BookStore-Application-Config.json +15 -0
  50. package/examples/quickstart/layer4/source/BookStore-Application.js +54 -0
  51. package/examples/quickstart/layer4/source/providers/Router-Config.json +18 -0
  52. package/examples/quickstart/layer4/source/views/View-About.js +38 -0
  53. package/examples/quickstart/layer4/source/views/View-Home.js +50 -0
  54. package/examples/quickstart/layer4/source/views/View-Layout.js +60 -0
  55. package/examples/quickstart/layer5/README.md +26 -0
  56. package/examples/quickstart/layer5/index.js +121 -0
  57. package/examples/quickstart/layer5/package-lock.json +345 -0
  58. package/examples/quickstart/layer5/package.json +13 -0
  59. package/examples/todo-list/Dockerfile +45 -0
  60. package/examples/todo-list/README.md +394 -0
  61. package/examples/todo-list/cli-client/package-lock.json +418 -0
  62. package/examples/todo-list/cli-client/package.json +19 -0
  63. package/examples/todo-list/cli-client/source/TodoCLI-CLIProgram.js +30 -0
  64. package/examples/todo-list/cli-client/source/TodoCLI-Run.js +3 -0
  65. package/examples/todo-list/cli-client/source/commands/add/TodoCLI-Command-Add.js +74 -0
  66. package/examples/todo-list/cli-client/source/commands/complete/TodoCLI-Command-Complete.js +84 -0
  67. package/examples/todo-list/cli-client/source/commands/list/TodoCLI-Command-List.js +110 -0
  68. package/examples/todo-list/cli-client/source/commands/remove/TodoCLI-Command-Remove.js +49 -0
  69. package/examples/todo-list/cli-client/source/services/TodoCLI-Service-API.js +92 -0
  70. package/examples/todo-list/console-client/console-client.cjs +913 -0
  71. package/examples/todo-list/console-client/package-lock.json +426 -0
  72. package/examples/todo-list/console-client/package.json +19 -0
  73. package/examples/todo-list/console-client/views/PictView-TUI-Header.cjs +43 -0
  74. package/examples/todo-list/console-client/views/PictView-TUI-Layout.cjs +58 -0
  75. package/examples/todo-list/console-client/views/PictView-TUI-StatusBar.cjs +41 -0
  76. package/examples/todo-list/console-client/views/PictView-TUI-TaskList.cjs +104 -0
  77. package/examples/todo-list/docker-motd.sh +36 -0
  78. package/examples/todo-list/docker-run.sh +2 -0
  79. package/examples/todo-list/docker-shell.sh +2 -0
  80. package/examples/todo-list/model/MeadowSchema-Task.json +152 -0
  81. package/examples/todo-list/model/Task-Compiled.json +25 -0
  82. package/examples/todo-list/model/Task.mddl +15 -0
  83. package/examples/todo-list/model/data/seeded_todo_events.csv +1001 -0
  84. package/examples/todo-list/server/database-initialization-service.cjs +273 -0
  85. package/examples/todo-list/server/package-lock.json +6113 -0
  86. package/examples/todo-list/server/package.json +19 -0
  87. package/examples/todo-list/server/server.cjs +138 -0
  88. package/examples/todo-list/web-client/css/todolist-theme.css +235 -0
  89. package/examples/todo-list/web-client/generate-build-config.cjs +18 -0
  90. package/examples/todo-list/web-client/html/index.html +18 -0
  91. package/examples/todo-list/web-client/package-lock.json +12030 -0
  92. package/examples/todo-list/web-client/package.json +43 -0
  93. package/examples/todo-list/web-client/source/TodoList-Application-Config.json +12 -0
  94. package/examples/todo-list/web-client/source/TodoList-Application.cjs +383 -0
  95. package/examples/todo-list/web-client/source/providers/Provider-TaskData.cjs +243 -0
  96. package/examples/todo-list/web-client/source/providers/Router-Config.json +32 -0
  97. package/examples/todo-list/web-client/source/views/View-Layout.cjs +75 -0
  98. package/examples/todo-list/web-client/source/views/View-TaskForm.cjs +87 -0
  99. package/examples/todo-list/web-client/source/views/View-TaskList.cjs +127 -0
  100. package/examples/todo-list/web-client/source/views/calendar/View-MonthView.cjs +293 -0
  101. package/examples/todo-list/web-client/source/views/calendar/View-WeekView.cjs +149 -0
  102. package/examples/todo-list/web-client/source/views/calendar/View-YearView.cjs +226 -0
  103. package/modules/.claude/settings.local.json +52 -0
  104. package/modules/CLAUDE.md +60 -0
  105. package/modules/Checkout.sh +42 -0
  106. package/modules/Include-Retold-Module-List.sh +15 -0
  107. package/modules/Retold-Modules.md +24 -0
  108. package/modules/Status.sh +59 -0
  109. package/modules/Update.sh +45 -0
  110. package/modules/fable/Fable.md +2 -0
  111. package/modules/meadow/Meadow.md +1 -0
  112. package/modules/orator/Orator.md +1 -0
  113. package/modules/pict/Pict.md +1 -0
  114. package/package.json +30 -35
  115. package/source/Retold.cjs +2 -0
  116. package/test/Retold_tests.js +23 -41
  117. package/.travis.yml +0 -13
  118. package/source/Retold-Meadow-Macros.js +0 -269
  119. package/source/Retold.js +0 -48
@@ -0,0 +1,312 @@
1
+ # Architecture
2
+
3
+ Retold modules are designed to compose into layered application stacks. Each layer builds on the one below it through the Fable service provider pattern.
4
+
5
+ ## The Layer Model
6
+
7
+ A fully-realized Retold application assembles five layers, from infrastructure at the bottom to your application logic at the top.
8
+
9
+ ```mermaid
10
+ graph TB
11
+ L5["<b>Layer 5</b> — Your Application / Mid-Tier Service<br/><i>Authentication, business logic, custom endpoints</i>"]
12
+ L4["<b>Layer 4</b> — Orator (API Server)<br/><i>HTTP lifecycle, middleware, static files, proxy</i>"]
13
+ L3["<b>Layer 3</b> — Meadow-Endpoints<br/><i>Auto-generated CRUD routes, behavior hooks</i>"]
14
+ L2["<b>Layer 2</b> — Meadow + FoxHound + Stricture<br/><i>Data broker, SQL generation, schema definitions</i>"]
15
+ L1["<b>Layer 1</b> — Fable (Core Ecosystem)<br/><i>DI, configuration, logging, UUID, expressions</i>"]
16
+ Infra["<b>Infrastructure</b><br/><i>Config files, log streams, databases, filesystem</i>"]
17
+
18
+ L5 --> L4
19
+ L4 --> L3
20
+ L3 --> L2
21
+ L2 --> L1
22
+ L1 --> Infra
23
+
24
+ style L5 fill:#e8f5e9,stroke:#43a047,color:#333
25
+ style L4 fill:#e3f2fd,stroke:#42a5f5,color:#333
26
+ style L3 fill:#e3f2fd,stroke:#64b5f6,color:#333
27
+ style L2 fill:#fff3e0,stroke:#ffa726,color:#333
28
+ style L1 fill:#fce4ec,stroke:#ef5350,color:#333
29
+ style Infra fill:#f5f5f5,stroke:#bdbdbd,color:#333
30
+ ```
31
+
32
+ Not every application uses every layer. A browser app might use Fable + Pict. A CLI tool might use Fable + Meadow. A full API service uses the complete stack.
33
+
34
+ ## The Service Provider Pattern
35
+
36
+ Every Retold module extends `fable-serviceproviderbase`. This base class provides:
37
+
38
+ - **Registration** — Services register with a Fable instance by type and hash
39
+ - **Dependency access** — Any service can reach any other through `this.fable`
40
+ - **Logging** — Built-in `this.log` from Fable-Log
41
+ - **Configuration** — Shared settings through `this.fable.settings`
42
+ - **Identity** — UUID generation through `this.fable.getUUID()`
43
+
44
+ ```javascript
45
+ const libFable = require('fable');
46
+ const libMeadow = require('meadow');
47
+ const libOrator = require('orator');
48
+
49
+ let _Fable = new libFable({ Product: 'MyApp', LogLevel: 3 });
50
+
51
+ // Services register themselves with the Fable instance
52
+ let _Meadow = _Fable.instantiateServiceProvider('Meadow');
53
+ let _Orator = _Fable.instantiateServiceProvider('Orator');
54
+
55
+ // Now every service can reach every other service
56
+ // _Meadow.fable.Orator, _Orator.fable.Meadow, etc.
57
+ ```
58
+
59
+ This pattern means modules are loosely coupled. You can swap database providers, change API server implementations, or add custom services without modifying existing code.
60
+
61
+ ## Layer 1: Fable — The Foundation
62
+
63
+ Fable is the only module that every other module depends on. It provides the core services that all other modules consume.
64
+
65
+ ```mermaid
66
+ graph TB
67
+ subgraph Fable["Fable (Core Ecosystem)"]
68
+ direction TB
69
+ settings["Fable-Settings<br/><code>.settings</code>"]
70
+ flog["Fable-Log<br/><code>.log</code>"]
71
+ uuid["Fable-UUID<br/><code>.getUUID()</code>"]
72
+ spb["Service<br/>Provider Base"]
73
+ end
74
+
75
+ settings --> configfiles["Config Files<br/>(.json, env)"]
76
+ flog --> logstreams["Log Streams<br/>(console, file, bunyan)"]
77
+
78
+ style Fable fill:#fce4ec,stroke:#ef5350,color:#333
79
+ style settings fill:#fff,stroke:#ef9a9a,color:#333
80
+ style flog fill:#fff,stroke:#ef9a9a,color:#333
81
+ style uuid fill:#fff,stroke:#ef9a9a,color:#333
82
+ style spb fill:#fff,stroke:#ef9a9a,color:#333
83
+ style configfiles fill:#f5f5f5,stroke:#bdbdbd,color:#666
84
+ style logstreams fill:#f5f5f5,stroke:#bdbdbd,color:#666
85
+ ```
86
+
87
+ **Fable-Settings** loads and merges configuration from files, defaults, and runtime overrides into a single settings object.
88
+
89
+ **Fable-Log** provides six log levels (trace, debug, info, warn, error, fatal) with extensible output streams. Logs go to console by default; add bunyan or custom loggers as needed.
90
+
91
+ **Fable-UUID** generates RFC 4122 v4 UUIDs or configurable random strings for identity and uniqueness.
92
+
93
+ **Fable-ServiceProviderBase** is the base class all Retold services extend. It provides the registration and dependency injection mechanics.
94
+
95
+ Fable also bundles an expression parser, a REST client (Fable-RestClient), a template engine, date utilities, and data format helpers — all accessible as services.
96
+
97
+ ## Layer 2: Meadow — Data Access
98
+
99
+ Meadow sits on top of Fable and provides a provider-agnostic data broker. You define entities once and access them through any supported database.
100
+
101
+ ```mermaid
102
+ graph TB
103
+ subgraph Meadow["Meadow (Data Broker / ORM)"]
104
+ direction TB
105
+ foxhound["FoxHound<br/>(Query DSL)<br/><code>.addFilter() .setSort() .buildRead()</code>"]
106
+ stricture["Stricture<br/>(Schema DDL)<br/>JSON schema, CREATE TABLE, docs"]
107
+ conn["Connections<br/>meadow-connection-mysql<br/>meadow-connection-mssql<br/>meadow-connection-sqlite"]
108
+ end
109
+
110
+ foxhound --> sql["SQL Queries<br/>(MySQL, MSSQL, SQLite, ALASQL)"]
111
+ stricture --> ddl["DDL Scripts<br/>(CREATE TABLE, indexes)"]
112
+ conn --> db[("Database<br/>(pooled connections)")]
113
+
114
+ style Meadow fill:#fff3e0,stroke:#ffa726,color:#333
115
+ style foxhound fill:#fff,stroke:#ffcc80,color:#333
116
+ style stricture fill:#fff,stroke:#ffcc80,color:#333
117
+ style conn fill:#fff,stroke:#ffcc80,color:#333
118
+ style sql fill:#f5f5f5,stroke:#bdbdbd,color:#666
119
+ style ddl fill:#f5f5f5,stroke:#bdbdbd,color:#666
120
+ style db fill:#ffebee,stroke:#ef5350,color:#333
121
+ ```
122
+
123
+ **Meadow** handles CRUD operations (Create, Read, Reads, Update, Delete, Count, Undelete), automatic audit columns (CreatingIDUser, UpdatingIDUser, timestamps), soft deletes, GUID uniqueness, and data marshalling.
124
+
125
+ **FoxHound** generates dialect-specific SQL from a single chainable API. One query definition produces correct SQL for MySQL, MSSQL, SQLite, or ALASQL (for in-browser use).
126
+
127
+ **Stricture** is an opinionated MicroDDL — define your data model in a simple text format and generate JSON schemas, MySQL CREATE statements, Meadow schema files, and documentation from a single source.
128
+
129
+ **Connection modules** (meadow-connection-mysql, meadow-connection-mssql, meadow-connection-sqlite) provide pooled database connections as Fable services.
130
+
131
+ ## Layer 3: Meadow-Endpoints — Auto-Generated API
132
+
133
+ Meadow-Endpoints takes a Meadow entity definition and automatically generates a full suite of RESTful routes.
134
+
135
+ ```mermaid
136
+ graph LR
137
+ entity["Meadow Entity<br/><b>Book</b>"] --> endpoints["<b>Meadow-Endpoints</b>"]
138
+
139
+ endpoints --> r1["GET /Books → Reads"]
140
+ endpoints --> r2["GET /Books/Count → Count"]
141
+ endpoints --> r3["GET /Book/:id → Read"]
142
+ endpoints --> r4["GET /Book/Schema → Schema"]
143
+ endpoints --> r5["POST /Book → Create"]
144
+ endpoints --> r6["PUT /Book → Update"]
145
+ endpoints --> r7["DEL /Book/:id → Delete"]
146
+ endpoints --> r8["DEL /Book/:id/Undelete"]
147
+
148
+ entity --> hooks["+ Behavior injection hooks<br/>+ Dynamic filtering & pagination<br/>+ Bulk operations"]
149
+
150
+ style entity fill:#fff3e0,stroke:#ffa726,color:#333
151
+ style endpoints fill:#e3f2fd,stroke:#42a5f5,color:#333
152
+ style hooks fill:#f3e5f5,stroke:#ab47bc,color:#333
153
+ style r1 fill:#fff,stroke:#90caf9,color:#333
154
+ style r2 fill:#fff,stroke:#90caf9,color:#333
155
+ style r3 fill:#fff,stroke:#90caf9,color:#333
156
+ style r4 fill:#fff,stroke:#90caf9,color:#333
157
+ style r5 fill:#fff,stroke:#90caf9,color:#333
158
+ style r6 fill:#fff,stroke:#90caf9,color:#333
159
+ style r7 fill:#fff,stroke:#90caf9,color:#333
160
+ style r8 fill:#fff,stroke:#90caf9,color:#333
161
+ ```
162
+
163
+ Behavior hooks let you inject authentication, authorization, validation, and transformation logic at any point in the request lifecycle — before or after each CRUD operation.
164
+
165
+ ## Layer 4: Orator — API Server
166
+
167
+ Orator provides the HTTP server that hosts the endpoints from Layer 3 (and any custom routes).
168
+
169
+ ```mermaid
170
+ graph TB
171
+ subgraph Orator["Orator (HTTP Server Abstraction)"]
172
+ direction TB
173
+ restify["orator-serviceserver-restify<br/>(Production HTTP)"]
174
+ static["orator-static-server<br/>(File Serving)"]
175
+ restify --> core["Orator Core<br/>Lifecycle hooks, middleware,<br/>content negotiation, IPC mode"]
176
+ static --> core
177
+ proxy["orator-http-proxy<br/>(Reverse Proxy)"]
178
+ tidings["Tidings<br/>(Reporting)"]
179
+ end
180
+
181
+ style Orator fill:#e3f2fd,stroke:#42a5f5,color:#333
182
+ style restify fill:#fff,stroke:#90caf9,color:#333
183
+ style static fill:#fff,stroke:#90caf9,color:#333
184
+ style core fill:#bbdefb,stroke:#42a5f5,color:#333
185
+ style proxy fill:#fff,stroke:#90caf9,color:#333
186
+ style tidings fill:#fff,stroke:#90caf9,color:#333
187
+ ```
188
+
189
+ Orator is deliberately thin. It provides a consistent interface regardless of the underlying server, so you can swap Restify for another implementation or use IPC mode for testing — without changing your application code.
190
+
191
+ ## Pict — MVC Tools
192
+
193
+ Pict sits alongside the server stack, providing Model-View-Controller tools for any text-based UI: browser DOM, terminal, or rendered strings.
194
+
195
+ ```mermaid
196
+ graph TB
197
+ subgraph Pict["Pict (Non-Opinionated MVC)"]
198
+ direction TB
199
+ subgraph Core["Core"]
200
+ views["Views<br/><i>pict-view</i>"]
201
+ templates["Templates<br/><i>pict-template</i>"]
202
+ providers["Providers<br/><i>pict-provider</i>"]
203
+ appfw["Application<br/><i>pict-application</i>"]
204
+ end
205
+ subgraph Sections["Sections & Components"]
206
+ forms["Forms<br/><i>pict-section-form</i>"]
207
+ recordset["Recordset<br/><i>pict-section-recordset</i>"]
208
+ tuigrid["TUI Grid<br/><i>pict-section-tuigrid</i>"]
209
+ content["Content<br/><i>pict-section-content</i>"]
210
+ end
211
+ Core --> Sections
212
+ end
213
+
214
+ style Pict fill:#f3e5f5,stroke:#ab47bc,color:#333
215
+ style Core fill:#f3e5f5,stroke:#ce93d8,color:#333
216
+ style Sections fill:#f3e5f5,stroke:#ce93d8,color:#333
217
+ style views fill:#fff,stroke:#ce93d8,color:#333
218
+ style templates fill:#fff,stroke:#ce93d8,color:#333
219
+ style providers fill:#fff,stroke:#ce93d8,color:#333
220
+ style appfw fill:#fff,stroke:#ce93d8,color:#333
221
+ style forms fill:#fff,stroke:#ce93d8,color:#333
222
+ style recordset fill:#fff,stroke:#ce93d8,color:#333
223
+ style tuigrid fill:#fff,stroke:#ce93d8,color:#333
224
+ style content fill:#fff,stroke:#ce93d8,color:#333
225
+ ```
226
+
227
+ Pict's core philosophy: UI is text. Views render templates into strings. Providers fetch data. The Application class coordinates lifecycle. Sections provide pre-built patterns for common UI needs (forms, record lists, grids).
228
+
229
+ Pict connects to Fable for services and can use Meadow-Endpoints as its data source, but it has no hard dependency on the server stack.
230
+
231
+ ## Putting It All Together
232
+
233
+ A full Retold application combines these layers. Here is the typical assembly order from the whiteboard architecture diagram:
234
+
235
+ ```mermaid
236
+ graph LR
237
+ S1["<b>Step 1</b><br/>Fable<br/><i>Config, logging, DI</i>"]
238
+ S2["<b>Step 2</b><br/>Meadow<br/><i>Entities, DB connection</i>"]
239
+ S3["<b>Step 3</b><br/>Meadow-Endpoints<br/><i>Auto-generate REST</i>"]
240
+ S4["<b>Step 4</b><br/>Orator<br/><i>HTTP server</i>"]
241
+ S5["<b>Step 5</b><br/>Your Application<br/><i>Mid-tier service</i>"]
242
+
243
+ S1 --> S2 --> S3 --> S4 --> S5
244
+
245
+ style S1 fill:#fce4ec,stroke:#ef5350,color:#333
246
+ style S2 fill:#fff3e0,stroke:#ffa726,color:#333
247
+ style S3 fill:#fff3e0,stroke:#ffcc80,color:#333
248
+ style S4 fill:#e3f2fd,stroke:#42a5f5,color:#333
249
+ style S5 fill:#e8f5e9,stroke:#43a047,color:#333
250
+ ```
251
+
252
+ ```javascript
253
+ const libFable = require('fable');
254
+ const libOrator = require('orator');
255
+ const libMeadowEndpoints = require('meadow-endpoints');
256
+
257
+ let _Fable = new libFable({
258
+ Product: 'BookService',
259
+ LogLevel: 3,
260
+ "MySQL": { "Server": "localhost", "User": "root", "Database": "bookstore" }
261
+ });
262
+
263
+ // Layer 2: Data access
264
+ let _MeadowEntity = _Fable.instantiateServiceProvider('Meadow',
265
+ { Scope: 'Book', DefaultSchema: BookSchema });
266
+
267
+ // Layer 3: Auto-generate REST endpoints
268
+ let _Endpoints = _Fable.instantiateServiceProvider('MeadowEndpoints',
269
+ { Entity: _MeadowEntity });
270
+
271
+ // Layer 4: HTTP server
272
+ let _Orator = _Fable.instantiateServiceProvider('Orator');
273
+
274
+ // Wire endpoints to the server
275
+ _Endpoints.connectRoutes(_Orator);
276
+
277
+ // Start listening
278
+ _Orator.startService((pError) =>
279
+ {
280
+ _Fable.log.info('BookService is running on port 8086');
281
+ });
282
+ ```
283
+
284
+ ## Utility Modules
285
+
286
+ Supporting the application stack are utility modules:
287
+
288
+ | Module | Purpose |
289
+ |--------|---------|
290
+ | **[Manyfest](/utility/manyfest/)** | JSON manifest for consistent data description across layers |
291
+ | **[Quackage](/utility/quackage/)** | Standardized build tool for browser bundles, testing, and packaging |
292
+ | **[Indoctrinate](/utility/indoctrinate/)** | Documentation scaffolding, catalog generation, and cross-module search |
293
+ | **[Ultravisor](/utility/ultravisor/)** | Process supervision with scheduled tasks and LLM integration |
294
+ | **[Choreographic](/utility/choreographic/)** | Scaffolding for single-run data processing scripts |
295
+
296
+ ## Design Principles
297
+
298
+ ### Convention Over Configuration
299
+
300
+ Modules generate rich metadata automatically. A Meadow entity with a well-named schema and standard columns needs zero additional configuration to get a full REST API.
301
+
302
+ ### Provider Agnostic
303
+
304
+ Data access, server implementations, and log destinations are all pluggable. Swap MySQL for SQLite, Restify for IPC, or console logging for Bunyan — without changing application code.
305
+
306
+ ### Composable, Not Monolithic
307
+
308
+ Each module does one thing. Combine the modules you need; skip the rest. A CLI tool does not need Orator. A browser widget does not need Meadow.
309
+
310
+ ### Everything is a Service
311
+
312
+ The service provider pattern means modules discover and use each other through dependency injection. No global state, no singletons, no import ordering problems.
@@ -0,0 +1,234 @@
1
+ # Ecosystem Architecture - Module Philosophy
2
+
3
+ Retold modules each embody a specific design philosophy. Together they form a coherent system for building applications — from the stateless service core, through data access and API generation, up to state-driven UI rendering. At the same time, each module is designed to be used (*and useful*) independently. You can adopt Fable's configuration and logging without using Pict. You can use Meadow for data access without Orator. These modules are decoupled by design, but also fit together in a complementary way.
4
+
5
+ ```mermaid
6
+ graph TB
7
+ subgraph Clients["Client Applications"]
8
+ direction LR
9
+ browser["Browser App<br/><i>Pict + Pict-Application<br/>+ Pict-Views</i>"]
10
+ console["Console App<br/><i>Pict + Terminal UI</i>"]
11
+ cli["CLI Tool<br/><i>CommandLineUtility</i>"]
12
+ end
13
+
14
+ internet(("The Internet<br/>☁"))
15
+
16
+ subgraph Server["Server / Mid-Tier"]
17
+ direction TB
18
+ orator["Orator<br/><i>HTTP Server Abstraction</i>"]
19
+ endpoints["Meadow-Endpoints<br/><i>Auto-generated REST API</i>"]
20
+ meadow["Meadow<br/><i>Data Access Abstraction</i>"]
21
+
22
+ subgraph DataTools["Schema & Query Tools"]
23
+ direction LR
24
+ foxhound["FoxHound<br/><i>Query Generation</i>"]
25
+ stricture["Stricture<br/><i>MicroDDL → Schema</i>"]
26
+ end
27
+
28
+ orator --> endpoints
29
+ endpoints --> meadow
30
+ meadow --> DataTools
31
+ end
32
+
33
+ subgraph Foundation["Foundation (Stateless)"]
34
+ direction LR
35
+ fable["Fable<br/><i>DI, Config, Logging</i>"]
36
+ manyfest["Manyfest<br/><i>Address-Based<br/>Object Access</i>"]
37
+ end
38
+
39
+ Clients -- "HTTP requests" --> internet
40
+ internet -- "HTTP requests" --> orator
41
+
42
+ browser -. "Fable services" .-> Foundation
43
+ Server --> Foundation
44
+
45
+ style Clients fill:#e8f5e9,stroke:#43a047,color:#333
46
+ style browser fill:#fff,stroke:#66bb6a,color:#333
47
+ style console fill:#fff,stroke:#66bb6a,color:#333
48
+ style cli fill:#fff,stroke:#66bb6a,color:#333
49
+ style internet fill:#e1f5fe,stroke:#03a9f4,color:#333,stroke-width:2px
50
+ style Server fill:#e3f2fd,stroke:#42a5f5,color:#333
51
+ style orator fill:#fff,stroke:#64b5f6,color:#333
52
+ style endpoints fill:#fff,stroke:#64b5f6,color:#333
53
+ style meadow fill:#fff3e0,stroke:#ffa726,color:#333
54
+ style DataTools fill:#fff8e1,stroke:#ffcc80,color:#333
55
+ style foxhound fill:#fff,stroke:#ffcc80,color:#333
56
+ style stricture fill:#fff,stroke:#ffcc80,color:#333
57
+ style Foundation fill:#fce4ec,stroke:#ef5350,color:#333
58
+ style fable fill:#fff,stroke:#ef9a9a,color:#333
59
+ style manyfest fill:#fff,stroke:#ef9a9a,color:#333
60
+ ```
61
+
62
+ Clients — browsers, terminals, CLI tools — communicate with the server over HTTP. Orator receives those requests, Meadow-Endpoints maps them to data operations, and Meadow executes them against the database. Fable provides the stateless service container that every module on both sides of the network depends on. Manyfest provides the consistent data-addressing language used everywhere.
63
+
64
+ ---
65
+
66
+ ## Fable Is Stateless
67
+
68
+ Fable draws a hard line between **configuration** and **state**.
69
+
70
+ In Retold's vocabulary, *state* is **application data** — the records in a database, the items in a shopping cart, the text a user has typed into a form. State changes as users interact with the system. It is the core subject matter of the application.
71
+
72
+ Configuration is everything else: the address of the database server, the port the API listens on, the log level, the product name. Configuration describes how the application runs in its environment, not what the application is doing. Fable manages configuration. It does not manage state.
73
+
74
+ This distinction matters because the "Out of the Tar Pit" problem — the paper Fable's design references — identifies uncontrolled state as the primary source of software complexity. By keeping the service container stateless, Fable ensures that the foundation layer has no opinion about your data. Services register with Fable, receive configuration and logging, and operate on whatever data flows through them without Fable holding onto it.
75
+
76
+ Every Retold module extends `fable-serviceproviderbase` and registers with a Fable instance. That instance provides dependency injection, logging, UUID generation, and shared settings. But the Fable instance itself stores no application data. It is the wiring, not the warehouse.
77
+
78
+ ## Pict Is for State and Transformation
79
+
80
+ If Fable is deliberately stateless, Pict is deliberately stateful. Pict's job is to hold application state and transform it consistently into output using a templating language.
81
+
82
+ Pict provides three dedicated state containers:
83
+
84
+ | Container | Purpose | Example Contents |
85
+ |-----------|---------|------------------|
86
+ | **AppData** | Primary application state | User records, form values, loaded entities |
87
+ | **Bundle** | Supporting reference data | Lookup tables, dropdown options, translations |
88
+ | **TempData** | Ephemeral intermediate data | Chart caches, calculated summaries, UI flags |
89
+
90
+ All state lives in known locations. Templates reference state through address expressions like `AppData.Tasks[0].Name`. Code accesses the same state through the same addresses. There is one source of truth and one notation for reaching it.
91
+
92
+ The key insight is that **state and lifecycle are coupled**. Pict's lifecycle phases — Solve, Render, Marshal — all operate on these state containers:
93
+
94
+ 1. **Solve** reads state and writes derived values back into state
95
+ 2. **Render** reads state and produces output through templates
96
+ 3. **Marshal** collects input and writes it back into state
97
+
98
+ This cycle is predictable and debuggable. At any point in the lifecycle you can inspect the state containers and know exactly what data the application is working with.
99
+
100
+ Pict intentionally separates logic from templates. Templates describe *what* to render; code (in views and providers) describes *when* and *how* data moves. You can override templates without altering behavior, and you can alter behavior without touching templates.
101
+
102
+ ## Pict-Application Manages the Lifecycle
103
+
104
+ Pict-Application is the orchestration layer. It coordinates the startup, data loading, solving, rendering, and marshaling of an entire application composed of multiple views and providers.
105
+
106
+ The lifecycle follows a defined sequence:
107
+
108
+ ```mermaid
109
+ graph LR
110
+ init["Initialize<br/><i>Register views,<br/>providers, templates</i>"]
111
+ data["Load Data<br/><i>Fetch from APIs,<br/>populate AppData</i>"]
112
+ solve["Solve<br/><i>Calculate derived<br/>values</i>"]
113
+ render["Render<br/><i>Transform state<br/>into output</i>"]
114
+ marshal["Marshal<br/><i>Collect input<br/>back into state</i>"]
115
+
116
+ init --> data --> solve --> render --> marshal
117
+ marshal -. "user interaction" .-> solve
118
+
119
+ style init fill:#fce4ec,stroke:#ef5350,color:#333
120
+ style data fill:#fff3e0,stroke:#ffa726,color:#333
121
+ style solve fill:#e8f5e9,stroke:#43a047,color:#333
122
+ style render fill:#e3f2fd,stroke:#42a5f5,color:#333
123
+ style marshal fill:#f3e5f5,stroke:#ab47bc,color:#333
124
+ ```
125
+
126
+ Each view and provider within the application participates in these phases. Pict-Application ensures they execute in the correct order (controlled by configurable ordinals) and provides auto-behaviors to reduce boilerplate — for example, automatically solving and rendering after initialization completes.
127
+
128
+ The application also manages authentication flows, data loading sequences, and the coordination between views that need to share state. It is the conductor; views and providers are the musicians.
129
+
130
+ ## Pict-View Is Not Just a Screen
131
+
132
+ A Pict view is any representation of information. It is not a page. It is not a screen. It is not a route.
133
+
134
+ A single screen might contain dozens of views: a header view, a navigation view, a list view, a detail panel view, a status bar view. Or a single view might render to a log file, a terminal widget, or a test harness instead of a browser DOM. The view is the unit of *rendering*, not the unit of *navigation*.
135
+
136
+ Each view contains **renderables** — individual render instructions that specify:
137
+
138
+ - Which **template** to use
139
+ - Which **data address** to read from state
140
+ - Which **destination** to render into
141
+ - Which **method** to use (replace, append, prepend)
142
+
143
+ This makes views composable. Small views handle small concerns. Larger patterns emerge from combining them. A form section view renders input fields. A recordset view renders a list of records. A content view renders static markup. You assemble an application from these building blocks.
144
+
145
+ Because views render through a content assignment abstraction, they are not bound to the browser DOM. The same view code can render to a blessed terminal widget, a log stream, or a mock environment for testing — by swapping the content assignment functions. The view does not know or care where its output ends up.
146
+
147
+ ## Orator Abstracts Web Servers
148
+
149
+ Orator provides a thin abstraction over HTTP servers. Your application code interacts with Orator's interface — defining routes, middleware, and lifecycle hooks — without coupling to a specific server implementation.
150
+
151
+ The default implementation uses Restify (`orator-serviceserver-restify`), but the abstraction means you could swap in a different HTTP library or use IPC mode for testing without changing application routes or middleware. Orator handles the HTTP lifecycle: receiving requests, running middleware, dispatching to handlers, and sending responses.
152
+
153
+ Orator also provides static file serving (`orator-static-server`) and reverse proxy capabilities (`orator-http-proxy`), making it a complete server-side HTTP toolkit without being a heavyweight framework.
154
+
155
+ The philosophy is deliberate thinness. Orator does not dictate application structure. It provides the plumbing for getting HTTP requests to your code and responses back to the client.
156
+
157
+ ## Meadow Abstracts Data Access
158
+
159
+ Meadow is a provider-agnostic data broker. You define entities once — their fields, types, and relationships — and Meadow handles CRUD operations against whatever database is connected.
160
+
161
+ The abstraction has real teeth: the same Meadow entity definition works with MySQL, MSSQL, SQLite, and ALASQL (for in-browser use). Switch databases by swapping a connection module. Your application code, entity definitions, and endpoint configurations do not change.
162
+
163
+ Meadow automatically manages audit columns (who created a record, who last updated it, and when), soft deletes (marking records as deleted without removing them), GUID-based uniqueness, and data marshalling between JavaScript objects and database rows.
164
+
165
+ The data access pattern is deliberately simple: Create, Read, Reads (list), Update, Delete, Count, and Undelete. These seven operations cover the vast majority of data access needs. When they do not, behavior hooks let you inject custom logic at any point in the operation lifecycle.
166
+
167
+ ## Meadow-Endpoints Connects Data Access to a Consistent API
168
+
169
+ Meadow-Endpoints takes a Meadow entity and automatically generates a full REST API for it. Define an entity called `Book` and you immediately get `GET /Books`, `GET /Book/:id`, `POST /Book`, `PUT /Book`, `DEL /Book/:id`, and more — with filtering, pagination, sorting, and schema introspection built in.
170
+
171
+ This is not code generation that produces files you maintain. The endpoints are generated at runtime from the entity definition. Change the schema, restart the server, and the API updates. Add a new entity, wire it to Meadow-Endpoints, and the routes appear.
172
+
173
+ Behavior hooks provide the extension points. Need authentication? Add a `before` hook. Need to transform data before it reaches the client? Add an `after` hook. Need custom validation? Hook into the create and update paths. The auto-generated API is the foundation; hooks let you customize without replacing it.
174
+
175
+ ## FoxHound Generates Queries
176
+
177
+ FoxHound is the query generation engine inside Meadow. It provides a chainable API for building queries — adding filters, setting sort order, configuring pagination — and then generates the correct SQL dialect for whichever database you are using.
178
+
179
+ ```javascript
180
+ _Query.addFilter('Status', 'Complete')
181
+ .setSort('CreatedDate')
182
+ .setBegin(0).setCap(50)
183
+ .buildReadQuery();
184
+ ```
185
+
186
+ This same code produces valid MySQL, MSSQL, SQLite, or ALASQL depending on the dialect. Application code never writes raw SQL. FoxHound's job is to be the single translation layer between a database-agnostic query description and dialect-specific SQL.
187
+
188
+ FoxHound also powers the **FilteredTo** URL syntax used by Meadow-Endpoints, which encodes filters, sorts, and pagination into URL paths for GET requests. This means clients can express complex queries through standard HTTP URLs without POST bodies.
189
+
190
+ ## Stricture Transforms MicroDDL into Schemas
191
+
192
+ Stricture provides a compact notation — MicroDDL — for defining data models. A MicroDDL file is a human-readable text format where each line defines a column using single-character sigils:
193
+
194
+ ```
195
+ !ID
196
+ @GUIDTask
197
+ #Name
198
+ #Description
199
+ #Status
200
+ &Hours
201
+ %Due
202
+ ```
203
+
204
+ From this terse input, Stricture generates:
205
+
206
+ - **JSON schemas** for Meadow entity definitions
207
+ - **CREATE TABLE statements** for MySQL, MSSQL, or SQLite
208
+ - **Documentation** describing the data model
209
+ - **Seed data templates** for testing
210
+
211
+ The philosophy is *define once, generate everywhere*. The MicroDDL is the single source of truth for a data model. Every downstream artifact — database tables, API schemas, documentation — derives from it. Change the MicroDDL, regenerate, and all representations stay in sync.
212
+
213
+ ## Manyfest Provides Address-Based Object Access
214
+
215
+ Manyfest solves a recurring problem: the same data structure is described and accessed differently at every layer of an application. The database has column names. The API has JSON keys. The frontend has display labels. Business logic has domain terms.
216
+
217
+ Manyfest unifies this through **address-based access**. An address is a string like `Record.Contact.Email` that describes a location in a nested JavaScript object. Manyfest provides safe accessors that navigate the address without throwing exceptions on missing intermediate objects:
218
+
219
+ ```javascript
220
+ // Safe read — returns undefined if any part of the path is missing
221
+ let email = _Manyfest.getValueAtAddress(pRecord, 'Contact.Email');
222
+
223
+ // Safe write — creates intermediate objects as needed
224
+ _Manyfest.setValueAtAddress(pRecord, 'Contact.Email', 'new@example.com');
225
+ ```
226
+
227
+ Beyond safe access, Manyfest provides **descriptors** — metadata that maps addresses to human-readable names, short names, descriptions, data types, and hashes. This means a single Manyfest definition can drive:
228
+
229
+ - API field documentation
230
+ - Form field labels and validation
231
+ - Report column headers
232
+ - Data transformation between layers
233
+
234
+ The address notation is the same notation Pict uses for template expressions and state access. This consistency means a Manyfest schema defined for the data layer can flow all the way through to form labels in the browser without translation.
@@ -0,0 +1,99 @@
1
+ # All Modules
2
+
3
+ An exhaustive list of every repository in the Retold suite, organized by group. Each module is its own git repository hosted at `github.com/stevenvelozo/<module-name>`.
4
+
5
+ ## Fable — Core Ecosystem (6 modules)
6
+
7
+ | Module | npm | Description |
8
+ |--------|-----|-------------|
9
+ | [fable](/fable/fable/) | `fable` | Service dependency injection, configuration, and logging library — the foundation of every Retold application |
10
+ | [fable-serviceproviderbase](/fable/fable-serviceproviderbase/) | `fable-serviceproviderbase` | Base classes for Fable services providing registration, DI, and lifecycle |
11
+ | [fable-settings](/fable/fable-settings/) | `fable-settings` | Tolerant configuration chain for loading and merging application settings |
12
+ | [fable-log](/fable/fable-log/) | `fable-log` | Flexible logging wrapper with six levels and extensible output streams |
13
+ | [fable-uuid](/fable/fable-uuid/) | `fable-uuid` | UUID generator supporting RFC 4122 v4 and configurable random strings |
14
+ | [fable-log-logger-bunyan](/fable/fable-log-logger-bunyan/) | `fable-log-logger-bunyan` | Bunyan structured logging provider for Fable-Log |
15
+
16
+ ## Meadow — Data Access Layer (12 modules)
17
+
18
+ | Module | npm | Description |
19
+ |--------|-----|-------------|
20
+ | [stricture](/meadow/stricture/) | `stricture` | MicroDDL schema definition language generating JSON, SQL DDL, and documentation |
21
+ | [foxhound](/meadow/foxhound/) | `foxhound` | Fluent query DSL generating dialect-specific SQL for MySQL, MSSQL, SQLite, and ALASQL |
22
+ | [bibliograph](/meadow/bibliograph/) | `bibliograph` | Key-value record comprehension for change tracking in data ingestion pipelines |
23
+ | [meadow](/meadow/meadow/) | `meadow` | Provider-agnostic data broker with CRUD operations, audit tracking, and soft deletes |
24
+ | [parime](/meadow/parime/) | `parime` | Generic data lake behaviors and services |
25
+ | [meadow-endpoints](/meadow/meadow-endpoints/) | `meadow-endpoints` | Automatic RESTful CRUD endpoint generation from Meadow entities with behavior injection |
26
+ | [meadow-connection-mysql](/meadow/meadow-connection-mysql/) | `meadow-connection-mysql` | MySQL/MariaDB pooled connection provider for Meadow |
27
+ | [meadow-connection-mssql](/meadow/meadow-connection-mssql/) | `meadow-connection-mssql` | Microsoft SQL Server connection provider for Meadow |
28
+ | [meadow-connection-sqlite](/meadow/meadow-connection-sqlite/) | `meadow-connection-sqlite` | SQLite connection provider for Meadow via better-sqlite3 |
29
+ | [retold-data-service](/meadow/retold-data-service/) | `retold-data-service` | All-in-one Fable service assembling schema → entity → endpoints → REST API |
30
+ | [retold-harness](/meadow/retold-harness/) | `retold-harness` | Pre-built API harness with a bookstore demo (8 entities, 10,000+ records) |
31
+ | [meadow-integration](/meadow/meadow-integration/) | `meadow-integration` | Data integration tools for CSV import, schema mapping, and centralized formats |
32
+
33
+ ## Orator — API Server (7 modules)
34
+
35
+ | Module | npm | Description |
36
+ |--------|-----|-------------|
37
+ | [orator](/orator/orator/) | `orator` | Unopinionated HTTP server abstraction with lifecycle hooks and route management |
38
+ | [orator-serviceserver-restify](/orator/orator-serviceserver-restify/) | `orator-serviceserver-restify` | Production HTTP server implementation powered by Restify |
39
+ | [orator-static-server](/orator/orator-static-server/) | `orator-static-server` | Static file serving with MIME detection, default files, and subdomain routing |
40
+ | [orator-http-proxy](/orator/orator-http-proxy/) | `orator-http-proxy` | HTTP reverse proxy for forwarding requests to backend services |
41
+ | [tidings](/orator/tidings/) | `tidings` | Extensible reporting system for generating HTML, PDF, and other format reports |
42
+ | [orator-endpoint](/orator/orator-endpoint/) | `orator-endpoint` | Pluggable API endpoint base class for reusable route handlers |
43
+ | [orator-conversion](/orator/orator-conversion/) | `orator-conversion` | File format conversion endpoints for Orator service servers |
44
+
45
+ ## Pict — MVC Tools (19 modules)
46
+
47
+ | Module | npm | Description |
48
+ |--------|-----|-------------|
49
+ | [pict](/pict/pict/) | `pict` | Non-opinionated MVC module with template expression engine for text-based UIs |
50
+ | [pict-template](/pict/pict-template/) | `pict-template` | Template handler base class for custom expression types |
51
+ | [pict-view](/pict/pict-view/) | `pict-view` | View base class with full lifecycle (init, render, solve, marshal), renderables, and CSS |
52
+ | [pict-provider](/pict/pict-provider/) | `pict-provider` | Data provider base class for delivering data to views |
53
+ | [pict-application](/pict/pict-application/) | `pict-application` | Application base class coordinating views, state, and lifecycle |
54
+ | [pict-panel](/pict/pict-panel/) | `pict-panel` | Hot-loadable control panel component for browser applications |
55
+ | [pict-nonlinearconfig](/pict/pict-nonlinearconfig/) | `pict-nonlinearconfig` | Pict nonlinear configuration manager |
56
+ | [pict-section-flow](/pict/pict-section-flow/) | `pict-section-flow` | Pict section flow diagram |
57
+ | [pict-docuserve](/pict/pict-docuserve/) | `pict-docuserve` | Single-page documentation viewer built on Pict |
58
+ | [cryptbrau](/pict/cryptbrau/) | `cryptbrau` | Simple in-browser symmetric encryption |
59
+ | [informary](/pict/informary/) | `informary` | Dependency-free browser form marshaling with undo/redo and field-level deltas |
60
+ | [pict-service-commandlineutility](/pict/pict-service-commandlineutility/) | `pict-service-commandlineutility` | CLI utility module built on Commander for Pict-based command-line tools |
61
+ | [pict-section-recordset](/pict/pict-section-recordset/) | `pict-section-recordset` | CRUD record management views from Meadow endpoint schemas |
62
+ | [pict-section-content](/pict/pict-section-content/) | `pict-section-content` | Markdown parsing and content rendering with Mermaid diagrams and KaTeX math |
63
+ | [pict-section-form](/pict/pict-section-form/) | `pict-section-form` | Configuration-driven dynamic forms with 13+ input types and data marshaling |
64
+ | [pict-section-tuigrid](/pict/pict-section-tuigrid/) | `pict-section-tuigrid` | Toast UI Grid integration for tabular data display and editing |
65
+ | [pict-router](/pict/pict-router/) | `pict-router` | Hash-based URL routing via Navigo with template string route functions |
66
+ | [pict-serviceproviderbase](/pict/pict-serviceproviderbase/) | `pict-serviceproviderbase` | Base classes for Pict services with pre-initialization support |
67
+ | [pict-terminalui](/pict/pict-terminalui/) | `pict-terminalui` | Blessed-based terminal interface for Pict views |
68
+
69
+ ## Utility — Build & Documentation Tools (4 modules)
70
+
71
+ | Module | npm | Description |
72
+ |--------|-----|-------------|
73
+ | [indoctrinate](/utility/indoctrinate/) | `indoctrinate` | Documentation scaffolding with content cataloging, label-based filtering, and multi-format output |
74
+ | [manyfest](/utility/manyfest/) | `manyfest` | JSON manifest for consistent data description, validation, and address-based access across layers |
75
+ | [quackage](/utility/quackage/) | `quackage` | Standardized build tool for browser bundles, transpilation, testing, and packaging |
76
+ | [ultravisor](/utility/ultravisor/) | `ultravisor` | Process supervision with scheduled tasks, distributed nodes, and LLM integration |
77
+
78
+ ## Summary
79
+
80
+ | Group | Count | Focus |
81
+ |-------|-------|-------|
82
+ | Fable | 6 | Core ecosystem, DI, configuration, logging |
83
+ | Meadow | 12 | Data access, ORM, query DSL, schema, connectors |
84
+ | Orator | 7 | API server, HTTP, static files, proxy, reporting, conversion |
85
+ | Pict | 19 | MVC, views, templates, forms, grids, routing, docs, TUI |
86
+ | Utility | 4 | Build tools, manifests, docs, process supervision |
87
+ | **Total** | **48** | |
88
+
89
+ ## GitHub Repositories
90
+
91
+ All modules are hosted at `github.com/stevenvelozo/<module-name>`:
92
+
93
+ - [github.com/stevenvelozo/retold](https://github.com/stevenvelozo/retold) — This meta-repository
94
+ - [github.com/stevenvelozo/fable](https://github.com/stevenvelozo/fable) — Core ecosystem
95
+ - [github.com/stevenvelozo/meadow](https://github.com/stevenvelozo/meadow) — Data access
96
+ - [github.com/stevenvelozo/orator](https://github.com/stevenvelozo/orator) — API server
97
+ - [github.com/stevenvelozo/pict](https://github.com/stevenvelozo/pict) — MVC tools
98
+
99
+ Each module follows the same structure: `package.json`, `source/`, `test/` (Mocha TDD), and optionally `docs/` (Docsify).