retold 1.0.6 → 4.0.1

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 (71) hide show
  1. package/.claude/settings.local.json +58 -0
  2. package/CLAUDE.md +52 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/README.md +161 -0
  5. package/docs/_sidebar.md +65 -0
  6. package/docs/_topbar.md +6 -0
  7. package/docs/architecture.md +312 -0
  8. package/docs/cover.md +15 -0
  9. package/docs/css/docuserve.css +73 -0
  10. package/docs/fable.md +198 -0
  11. package/docs/getting-started.md +272 -0
  12. package/docs/index.html +39 -0
  13. package/docs/js/pict.min.js +12 -0
  14. package/docs/js/pict.min.js.map +1 -0
  15. package/docs/meadow.md +211 -0
  16. package/docs/modules.md +96 -0
  17. package/docs/orator.md +164 -0
  18. package/docs/pict-docuserve.min.js +58 -0
  19. package/docs/pict-docuserve.min.js.map +1 -0
  20. package/docs/pict.md +213 -0
  21. package/docs/retold-building-documentation.md +33 -0
  22. package/docs/retold-catalog.json +2826 -0
  23. package/docs/retold-keyword-index.json +161289 -0
  24. package/docs/utility.md +63 -0
  25. package/examples/quickstart/README.md +47 -0
  26. package/examples/quickstart/layer1/README.md +21 -0
  27. package/examples/quickstart/layer1/index.js +49 -0
  28. package/examples/quickstart/layer1/package-lock.json +344 -0
  29. package/examples/quickstart/layer1/package.json +12 -0
  30. package/examples/quickstart/layer2/README.md +34 -0
  31. package/examples/quickstart/layer2/index.js +251 -0
  32. package/examples/quickstart/layer2/package-lock.json +4468 -0
  33. package/examples/quickstart/layer2/package.json +17 -0
  34. package/examples/quickstart/layer2/setup-database.js +61 -0
  35. package/examples/quickstart/layer3/README.md +39 -0
  36. package/examples/quickstart/layer3/index.js +91 -0
  37. package/examples/quickstart/layer3/package-lock.json +1936 -0
  38. package/examples/quickstart/layer3/package.json +14 -0
  39. package/examples/quickstart/layer4/README.md +47 -0
  40. package/examples/quickstart/layer4/generate-build-config.js +18 -0
  41. package/examples/quickstart/layer4/html/index.html +17 -0
  42. package/examples/quickstart/layer4/package-lock.json +13206 -0
  43. package/examples/quickstart/layer4/package.json +38 -0
  44. package/examples/quickstart/layer4/server.js +28 -0
  45. package/examples/quickstart/layer4/source/BookStore-Application-Config.json +15 -0
  46. package/examples/quickstart/layer4/source/BookStore-Application.js +54 -0
  47. package/examples/quickstart/layer4/source/providers/Router-Config.json +18 -0
  48. package/examples/quickstart/layer4/source/views/View-About.js +38 -0
  49. package/examples/quickstart/layer4/source/views/View-Home.js +50 -0
  50. package/examples/quickstart/layer4/source/views/View-Layout.js +60 -0
  51. package/examples/quickstart/layer5/README.md +26 -0
  52. package/examples/quickstart/layer5/index.js +121 -0
  53. package/examples/quickstart/layer5/package-lock.json +345 -0
  54. package/examples/quickstart/layer5/package.json +13 -0
  55. package/modules/.claude/settings.local.json +52 -0
  56. package/modules/CLAUDE.md +60 -0
  57. package/modules/Checkout.sh +42 -0
  58. package/modules/Include-Retold-Module-List.sh +15 -0
  59. package/modules/Retold-Modules.md +24 -0
  60. package/modules/Status.sh +59 -0
  61. package/modules/Update.sh +45 -0
  62. package/modules/fable/Fable.md +2 -0
  63. package/modules/meadow/Meadow.md +1 -0
  64. package/modules/orator/Orator.md +1 -0
  65. package/modules/pict/Pict.md +1 -0
  66. package/package.json +30 -35
  67. package/source/Retold.cjs +2 -0
  68. package/test/Retold_tests.js +23 -41
  69. package/.travis.yml +0 -13
  70. package/source/Retold-Meadow-Macros.js +0 -269
  71. package/source/Retold.js +0 -48
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "retold-quickstart-layer4-pict",
3
+ "version": "1.0.0",
4
+ "description": "Retold Quickstart: Layer 4 - Pict (Browser MVC with Views and Router)",
5
+ "main": "source/BookStore-Application.js",
6
+ "scripts": {
7
+ "postinstall": "node generate-build-config.js",
8
+ "build": "npx quack build && npx quack copy",
9
+ "start": "node server.js",
10
+ "demo": "npm run build && npm start"
11
+ },
12
+ "dependencies": {
13
+ "pict": "^1.0.343",
14
+ "pict-application": "^1.0.28",
15
+ "pict-router": "^1.0.4",
16
+ "pict-view": "^1.0.64",
17
+ "pict-provider": "^1.0.3",
18
+ "orator": "^5.0.2",
19
+ "orator-serviceserver-restify": "^2.0.5",
20
+ "fable": "^3.1.51"
21
+ },
22
+ "devDependencies": {
23
+ "quackage": "^1.0.41"
24
+ },
25
+ "copyFilesSettings": {
26
+ "whenFileExists": "overwrite"
27
+ },
28
+ "copyFiles": [
29
+ {
30
+ "from": "./html/*",
31
+ "to": "./dist/"
32
+ },
33
+ {
34
+ "from": "./node_modules/pict/dist/*",
35
+ "to": "./dist/js/"
36
+ }
37
+ ]
38
+ }
@@ -0,0 +1,28 @@
1
+ // Simple static file server using Orator to serve the built Pict application
2
+ const libFable = require('fable');
3
+ const libOrator = require('orator');
4
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
5
+
6
+ let _Fable = new libFable(
7
+ {
8
+ Product: 'BookStore-Server',
9
+ ProductVersion: '1.0.0',
10
+ APIServerPort: 8086
11
+ });
12
+
13
+ _Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
14
+ _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
15
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
16
+ let _Orator = _Fable.serviceManager.instantiateServiceProvider('Orator');
17
+
18
+ _Orator.initialize(
19
+ function ()
20
+ {
21
+ _Orator.addStaticRoute(`${__dirname}/dist/`, 'index.html');
22
+
23
+ _Orator.startService(
24
+ function ()
25
+ {
26
+ _Fable.log.info('Open http://localhost:8086 in your browser');
27
+ });
28
+ });
@@ -0,0 +1,15 @@
1
+ {
2
+ "Name": "BookStore Pict Application",
3
+ "Hash": "BookStore",
4
+
5
+ "MainViewportViewIdentifier": "BookStore-Layout",
6
+
7
+ "AutoSolveAfterInitialize": true,
8
+ "AutoRenderMainViewportViewAfterInitialize": false,
9
+ "AutoRenderViewsAfterInitialize": false,
10
+
11
+ "pict_configuration":
12
+ {
13
+ "Product": "BookStore-Pict"
14
+ }
15
+ }
@@ -0,0 +1,54 @@
1
+ const libPictApplication = require('pict-application');
2
+ const libPictRouter = require('pict-router');
3
+
4
+ const libViewLayout = require('./views/View-Layout.js');
5
+ const libViewHome = require('./views/View-Home.js');
6
+ const libViewAbout = require('./views/View-About.js');
7
+
8
+ class BookStoreApplication extends libPictApplication
9
+ {
10
+ constructor(pFable, pOptions, pServiceHash)
11
+ {
12
+ super(pFable, pOptions, pServiceHash);
13
+
14
+ this.pict.addProvider('PictRouter', require('./providers/Router-Config.json'), libPictRouter);
15
+
16
+ this.pict.addView('BookStore-Layout', libViewLayout.default_configuration, libViewLayout);
17
+ this.pict.addView('BookStore-Home', libViewHome.default_configuration, libViewHome);
18
+ this.pict.addView('BookStore-About', libViewAbout.default_configuration, libViewAbout);
19
+ }
20
+
21
+ onAfterInitializeAsync(fCallback)
22
+ {
23
+ this.pict.AppData.BookStore =
24
+ {
25
+ Title: 'Retold BookStore',
26
+ Books:
27
+ [
28
+ { Title: 'The Hobbit', Author: 'J.R.R. Tolkien', Year: 1937 },
29
+ { Title: 'Dune', Author: 'Frank Herbert', Year: 1965 },
30
+ { Title: 'Neuromancer', Author: 'William Gibson', Year: 1984 }
31
+ ]
32
+ };
33
+
34
+ this.pict.views['BookStore-Layout'].render();
35
+
36
+ return super.onAfterInitializeAsync(fCallback);
37
+ }
38
+
39
+ navigateTo(pRoute)
40
+ {
41
+ this.pict.providers.PictRouter.navigate(pRoute);
42
+ }
43
+
44
+ showView(pViewIdentifier)
45
+ {
46
+ if (pViewIdentifier in this.pict.views)
47
+ {
48
+ this.pict.views[pViewIdentifier].render();
49
+ }
50
+ }
51
+ }
52
+
53
+ module.exports = BookStoreApplication;
54
+ module.exports.default_configuration = require('./BookStore-Application-Config.json');
@@ -0,0 +1,18 @@
1
+ {
2
+ "ProviderIdentifier": "Pict-Router",
3
+
4
+ "AutoInitialize": true,
5
+ "AutoInitializeOrdinal": 0,
6
+
7
+ "Routes":
8
+ [
9
+ {
10
+ "path": "/Home",
11
+ "template": "{~LV:Pict.PictApplication.showView(`BookStore-Home`)~}"
12
+ },
13
+ {
14
+ "path": "/About",
15
+ "template": "{~LV:Pict.PictApplication.showView(`BookStore-About`)~}"
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,38 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: 'BookStore-About',
6
+ DefaultRenderable: 'BookStore-About-Content',
7
+ DefaultDestinationAddress: '#BookStore-Content',
8
+ AutoRender: false,
9
+
10
+ Templates:
11
+ [
12
+ {
13
+ Hash: 'BookStore-About-Template',
14
+ Template: `<h1>About</h1><p>This is a quickstart example for Retold Layer 4: Pict.</p><p>Pict provides browser-side MVC with views, templates, providers, and an application lifecycle. It uses Fable for dependency injection and service management.</p><p><a style="color:#3498db;cursor:pointer" onclick="{~P~}.PictApplication.navigateTo('/Home')">Back to Home</a></p>`
15
+ }
16
+ ],
17
+
18
+ Renderables:
19
+ [
20
+ {
21
+ RenderableHash: 'BookStore-About-Content',
22
+ TemplateHash: 'BookStore-About-Template',
23
+ DestinationAddress: '#BookStore-Content',
24
+ RenderMethod: 'replace'
25
+ }
26
+ ]
27
+ };
28
+
29
+ class BookStoreAboutView extends libPictView
30
+ {
31
+ constructor(pFable, pOptions, pServiceHash)
32
+ {
33
+ super(pFable, pOptions, pServiceHash);
34
+ }
35
+ }
36
+
37
+ module.exports = BookStoreAboutView;
38
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,50 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: 'BookStore-Home',
6
+ DefaultRenderable: 'BookStore-Home-Content',
7
+ DefaultDestinationAddress: '#BookStore-Content',
8
+ AutoRender: false,
9
+
10
+ CSS: `
11
+ .bs-book-list { list-style: none; padding: 0; }
12
+ .bs-book-item { padding: 0.75em 1em; margin: 0.5em 0; background: #f8f9fa; border-radius: 6px; border-left: 4px solid #3498db; }
13
+ .bs-book-title { font-weight: 600; }
14
+ .bs-book-author { color: #666; }
15
+ .bs-book-year { color: #999; font-size: 0.9em; }
16
+ `,
17
+
18
+ Templates:
19
+ [
20
+ {
21
+ Hash: 'BookStore-Home-Template',
22
+ Template: `<h1>{~D:AppData.BookStore.Title~}</h1><p>A simple Pict application demonstrating views, templates, and routing.</p><h2>Book Catalog</h2><ul class="bs-book-list">{~TemplateSet:BookStore-Home-BookRow:AppData.BookStore.Books~}</ul>`
23
+ },
24
+ {
25
+ Hash: 'BookStore-Home-BookRow',
26
+ Template: `<li class="bs-book-item"><span class="bs-book-title">{~D:Record.Title~}</span> <span class="bs-book-author">by {~D:Record.Author~}</span> <span class="bs-book-year">({~D:Record.Year~})</span></li>`
27
+ }
28
+ ],
29
+
30
+ Renderables:
31
+ [
32
+ {
33
+ RenderableHash: 'BookStore-Home-Content',
34
+ TemplateHash: 'BookStore-Home-Template',
35
+ DestinationAddress: '#BookStore-Content',
36
+ RenderMethod: 'replace'
37
+ }
38
+ ]
39
+ };
40
+
41
+ class BookStoreHomeView extends libPictView
42
+ {
43
+ constructor(pFable, pOptions, pServiceHash)
44
+ {
45
+ super(pFable, pOptions, pServiceHash);
46
+ }
47
+ }
48
+
49
+ module.exports = BookStoreHomeView;
50
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,60 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ const _ViewConfiguration =
4
+ {
5
+ ViewIdentifier: 'BookStore-Layout',
6
+ DefaultRenderable: 'BookStore-Layout-Shell',
7
+ DefaultDestinationAddress: '#BookStore-Container',
8
+ AutoRender: false,
9
+
10
+ CSS: `
11
+ body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
12
+ .bs-nav { display: flex; align-items: center; justify-content: space-between; background: #2c3e50; color: #ecf0f1; padding: 0 1.5em; height: 50px; }
13
+ .bs-nav a { color: #bdc3c7; text-decoration: none; padding: 0.5em 0.75em; cursor: pointer; }
14
+ .bs-nav a:hover { color: #fff; }
15
+ .bs-nav-brand { font-size: 1.2em; font-weight: 600; color: #ecf0f1; cursor: pointer; text-decoration: none; }
16
+ #BookStore-Content { max-width: 800px; margin: 2em auto; padding: 0 1em; }
17
+ `,
18
+
19
+ Templates:
20
+ [
21
+ {
22
+ Hash: 'BookStore-Layout-Template',
23
+ Template: `<div class="bs-nav"><a class="bs-nav-brand" onclick="{~P~}.PictApplication.navigateTo('/Home')">Retold BookStore</a><div><a onclick="{~P~}.PictApplication.navigateTo('/Home')">Home</a><a onclick="{~P~}.PictApplication.navigateTo('/About')">About</a></div></div><div id="BookStore-Content"></div>`
24
+ }
25
+ ],
26
+
27
+ Renderables:
28
+ [
29
+ {
30
+ RenderableHash: 'BookStore-Layout-Shell',
31
+ TemplateHash: 'BookStore-Layout-Template',
32
+ DestinationAddress: '#BookStore-Container',
33
+ RenderMethod: 'replace'
34
+ }
35
+ ]
36
+ };
37
+
38
+ class BookStoreLayoutView extends libPictView
39
+ {
40
+ constructor(pFable, pOptions, pServiceHash)
41
+ {
42
+ super(pFable, pOptions, pServiceHash);
43
+ }
44
+
45
+ onAfterRender()
46
+ {
47
+ this.pict.views['BookStore-Home'].render();
48
+ this.pict.CSSMap.injectCSS();
49
+
50
+ if (this.pict.providers.PictRouter)
51
+ {
52
+ this.pict.providers.PictRouter.resolve();
53
+ }
54
+
55
+ return super.onAfterRender();
56
+ }
57
+ }
58
+
59
+ module.exports = BookStoreLayoutView;
60
+ module.exports.default_configuration = _ViewConfiguration;
@@ -0,0 +1,26 @@
1
+ # Utility: Manyfest - Object Navigation
2
+
3
+ > Retold Utility Layer — Supporting tools: Manyfest (manifest management),
4
+ > Quackage (build), Indoctrinate (documentation), Ultravisor (process
5
+ > supervision), CacheTrax (caching), Precedent (meta-templating), and more
6
+
7
+ Manyfest provides schema-driven JSON object description, navigation, and
8
+ validation. It is used throughout Retold for consistent data access across
9
+ layers. Fable bundles Manyfest as a built-in service.
10
+
11
+ ## Run
12
+
13
+ ```bash
14
+ npm install
15
+ npm start
16
+ ```
17
+
18
+ ## What This Demonstrates
19
+
20
+ - Defining a manifest schema with descriptors, data types, and defaults
21
+ - Reading and writing values by dot-notation address (`Author.Name`)
22
+ - Hash-based lookups for aliased field access (e.g. `AuthorName` -> `Author.Name`)
23
+ - Setting values on nested paths that don't exist yet
24
+ - Populating objects with default values from the schema
25
+ - Validating objects against schema type constraints
26
+ - Using Manyfest as a Fable service via `_Fable.newManyfest()`
@@ -0,0 +1,121 @@
1
+ const libFable = require('fable');
2
+ const libManyfest = require('manyfest');
3
+
4
+ let _Fable = new libFable(
5
+ {
6
+ Product: 'ManyfestDemo',
7
+ ProductVersion: '1.0.0'
8
+ });
9
+
10
+ // 1. Define a schema with descriptors
11
+ let _BookManifest = new libManyfest(
12
+ {
13
+ Scope: 'Book',
14
+ Descriptors:
15
+ {
16
+ 'IDBook':
17
+ {
18
+ Name: 'Book ID',
19
+ Hash: 'ID',
20
+ DataType: 'Integer',
21
+ Default: 0
22
+ },
23
+ 'Title':
24
+ {
25
+ Name: 'Title',
26
+ Hash: 'Title',
27
+ DataType: 'String',
28
+ Default: 'Untitled'
29
+ },
30
+ 'Author.Name':
31
+ {
32
+ Name: 'Author Name',
33
+ Hash: 'AuthorName',
34
+ DataType: 'String',
35
+ Default: 'Unknown'
36
+ },
37
+ 'Author.BirthYear':
38
+ {
39
+ Name: 'Author Birth Year',
40
+ Hash: 'AuthorBirthYear',
41
+ DataType: 'Integer',
42
+ Default: 0
43
+ },
44
+ 'Genre':
45
+ {
46
+ Name: 'Genre',
47
+ Hash: 'Genre',
48
+ DataType: 'String',
49
+ Default: 'Fiction'
50
+ }
51
+ }
52
+ });
53
+
54
+ // 2. Create a book object
55
+ let tmpBook =
56
+ {
57
+ IDBook: 1,
58
+ Title: 'The Hobbit',
59
+ Author:
60
+ {
61
+ Name: 'J.R.R. Tolkien',
62
+ BirthYear: 1892
63
+ },
64
+ Genre: 'Fantasy'
65
+ };
66
+
67
+ _Fable.log.info('--- Manyfest Object Navigation Demo ---');
68
+
69
+ // 3. Read values by address (dot notation)
70
+ _Fable.log.info(`Title: ${_BookManifest.getValueAtAddress(tmpBook, 'Title')}`);
71
+ _Fable.log.info(`Author: ${_BookManifest.getValueAtAddress(tmpBook, 'Author.Name')}`);
72
+ _Fable.log.info(`Birth Year: ${_BookManifest.getValueAtAddress(tmpBook, 'Author.BirthYear')}`);
73
+
74
+ // 4. Read values by hash (aliases)
75
+ _Fable.log.info(`By hash 'AuthorName': ${_BookManifest.getValueByHash(tmpBook, 'AuthorName')}`);
76
+ _Fable.log.info(`By hash 'ID': ${_BookManifest.getValueByHash(tmpBook, 'ID')}`);
77
+
78
+ // 5. Write values by address
79
+ _BookManifest.setValueAtAddress(tmpBook, 'Title', 'The Hobbit (Revised Edition)');
80
+ _Fable.log.info(`Updated title: ${_BookManifest.getValueAtAddress(tmpBook, 'Title')}`);
81
+
82
+ // 6. Write nested values that don't exist yet
83
+ _BookManifest.setValueAtAddress(tmpBook, 'Publisher.Name', 'Allen & Unwin');
84
+ _Fable.log.info(`Publisher: ${_BookManifest.getValueAtAddress(tmpBook, 'Publisher.Name')}`);
85
+
86
+ // 7. Populate defaults for missing fields
87
+ let tmpEmptyBook = { IDBook: 42 };
88
+ _Fable.log.info('\nBefore populate defaults:');
89
+ _Fable.log.info(` Has Title property: ${'Title' in tmpEmptyBook}`);
90
+ _Fable.log.info(` Has Author.Name property: ${tmpEmptyBook.Author !== undefined}`);
91
+
92
+ _BookManifest.populateDefaults(tmpEmptyBook);
93
+ _Fable.log.info('After populate defaults:');
94
+ _Fable.log.info(` Title: ${tmpEmptyBook.Title}`);
95
+ _Fable.log.info(` Author.Name: ${tmpEmptyBook.Author ? tmpEmptyBook.Author.Name : 'N/A'}`);
96
+ _Fable.log.info(` Genre: ${tmpEmptyBook.Genre}`);
97
+
98
+ // 8. Validate an object
99
+ let tmpValidation = _BookManifest.validate(tmpBook);
100
+ _Fable.log.info(`\nValidation of full book: ${tmpValidation.Error ? 'INVALID' : 'VALID'}`);
101
+ if (tmpValidation.Errors.length > 0)
102
+ {
103
+ _Fable.log.info(` Errors: ${tmpValidation.Errors.join(', ')}`);
104
+ }
105
+
106
+ // 9. Manyfest is also available as a Fable service
107
+ let tmpManifest = _Fable.newManyfest(
108
+ {
109
+ Scope: 'Config',
110
+ Descriptors:
111
+ {
112
+ 'Database.Host': { Name: 'DB Host', DataType: 'String', Default: 'localhost' },
113
+ 'Database.Port': { Name: 'DB Port', DataType: 'Integer', Default: 3306 }
114
+ }
115
+ });
116
+ let tmpConfig = {};
117
+ tmpManifest.populateDefaults(tmpConfig);
118
+ _Fable.log.info(`\nFable Manyfest service - DB Host: ${tmpManifest.getValueAtAddress(tmpConfig, 'Database.Host')}`);
119
+ _Fable.log.info(`Fable Manyfest service - DB Port: ${tmpManifest.getValueAtAddress(tmpConfig, 'Database.Port')}`);
120
+
121
+ _Fable.log.info('\n--- Manyfest Demo Complete ---');