divhunt 2.0.0 → 2.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 (110) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/CLAUDE.md +132 -0
  3. package/addons/core/clients/back/grpc/addon.js +0 -2
  4. package/addons/core/clients/back/grpc/item/catch/add.js +0 -2
  5. package/addons/core/clients/back/grpc/item/functions/connect.js +0 -2
  6. package/addons/core/clients/back/grpc/item/functions/resolve.js +0 -2
  7. package/addons/core/clients/back/grpc/item/functions/stream.js +0 -2
  8. package/addons/core/clients/back/grpc/load.js +0 -2
  9. package/addons/core/clients/back/http/addon.js +0 -2
  10. package/addons/core/clients/back/http/item/catch/add.js +0 -2
  11. package/addons/core/clients/back/http/item/functions/gRPC/create.js +0 -2
  12. package/addons/core/clients/back/http/item/functions/gRPC/execute.js +0 -2
  13. package/addons/core/clients/back/http/item/functions/http/create.js +0 -2
  14. package/addons/core/clients/back/http/item/functions/http/delete.js +0 -2
  15. package/addons/core/clients/back/http/item/functions/http/get.js +0 -2
  16. package/addons/core/clients/back/http/item/functions/http/post.js +0 -2
  17. package/addons/core/clients/back/http/item/functions/http/put.js +0 -2
  18. package/addons/core/clients/back/http/item/functions/http/request.js +0 -2
  19. package/addons/core/clients/back/http/load.js +0 -2
  20. package/addons/core/commands/back/addon.js +0 -2
  21. package/addons/core/commands/back/functions/find.js +0 -2
  22. package/addons/core/commands/back/functions/grpc/server.js +0 -2
  23. package/addons/core/commands/back/functions/http/server.js +0 -2
  24. package/addons/core/commands/back/item/functions/run.js +0 -2
  25. package/addons/core/commands/back/items/many.js +0 -2
  26. package/addons/core/commands/back/items/one.js +0 -2
  27. package/addons/core/commands/back/items/run.js +1 -3
  28. package/addons/core/commands/back/load.js +0 -2
  29. package/addons/core/commands/front/#register/addon.js +0 -2
  30. package/addons/core/commands/front/functions/find.js +0 -2
  31. package/addons/core/commands/front/item/functions/run.js +0 -2
  32. package/addons/core/servers/back/grpc/addon.js +0 -2
  33. package/addons/core/servers/back/grpc/item/functions/resolve.js +0 -2
  34. package/addons/core/servers/back/grpc/item/functions/start.js +0 -2
  35. package/addons/core/servers/back/grpc/item/functions/stream.js +0 -2
  36. package/addons/core/servers/back/http/item/functions/start.js +10 -4
  37. package/addons/render/assets/back/addon.js +0 -2
  38. package/addons/render/assets/back/functions/css.js +0 -2
  39. package/addons/render/assets/back/functions/js.js +0 -2
  40. package/addons/render/assets/back/functions/scan/directories.js +0 -2
  41. package/addons/render/assets/back/functions/scan/files.js +0 -2
  42. package/addons/render/assets/back/functions/utils/read.js +0 -2
  43. package/addons/render/assets/back/functions/utils/transform.js +0 -2
  44. package/addons/render/assets/back/items/commands/css.js +0 -2
  45. package/addons/render/assets/back/items/commands/js.js +0 -2
  46. package/addons/render/assets/back/items/html/css.js +0 -2
  47. package/addons/render/assets/back/items/html/js.js +0 -2
  48. package/addons/render/assets/back/load.js +0 -2
  49. package/architecture.md +138 -0
  50. package/brief.md +62 -0
  51. package/decisions.md +58 -0
  52. package/examples/basic-api/README.md +34 -0
  53. package/examples/basic-api/addons/tasks/addon.js +10 -0
  54. package/examples/basic-api/addons/tasks/items/commands/create.js +22 -0
  55. package/examples/basic-api/addons/tasks/items/commands/delete.js +26 -0
  56. package/examples/basic-api/addons/tasks/items/commands/list.js +17 -0
  57. package/examples/basic-api/addons/tasks/items/commands/toggle.js +26 -0
  58. package/examples/basic-api/addons/tasks/load.js +8 -0
  59. package/examples/basic-api/index.js +15 -0
  60. package/examples/basic-api/package.json +7 -0
  61. package/lib/browser.js +0 -2
  62. package/lib/events.js +0 -2
  63. package/lib/load.js +0 -2
  64. package/lib/src/classes/addon/class.js +0 -2
  65. package/lib/src/classes/addon/classes/item/class.js +0 -2
  66. package/lib/src/classes/addon/classes/item/mixins/crud.js +0 -2
  67. package/lib/src/classes/addon/classes/item/mixins/functions.js +0 -2
  68. package/lib/src/classes/addon/classes/item/mixins/get.js +0 -2
  69. package/lib/src/classes/addon/classes/item/mixins/remove.js +0 -2
  70. package/lib/src/classes/addon/classes/item/mixins/set.js +0 -2
  71. package/lib/src/classes/addon/classes/item/mixins/store.js +0 -2
  72. package/lib/src/classes/addon/classes/render/class.js +0 -2
  73. package/lib/src/classes/addon/classes/render/mixins/compile.js +0 -2
  74. package/lib/src/classes/addon/classes/render/mixins/dom.js +0 -2
  75. package/lib/src/classes/addon/classes/render/mixins/events.js +0 -2
  76. package/lib/src/classes/addon/classes/render/mixins/get.js +0 -2
  77. package/lib/src/classes/addon/classes/render/mixins/methods.js +0 -2
  78. package/lib/src/classes/addon/classes/render/mixins/process.js +0 -2
  79. package/lib/src/classes/addon/classes/render/mixins/set.js +0 -2
  80. package/lib/src/classes/addon/mixins/fields.js +0 -2
  81. package/lib/src/classes/addon/mixins/find.js +0 -2
  82. package/lib/src/classes/addon/mixins/functions.js +0 -2
  83. package/lib/src/classes/addon/mixins/get.js +0 -2
  84. package/lib/src/classes/addon/mixins/items.js +0 -2
  85. package/lib/src/classes/addon/mixins/remove.js +0 -2
  86. package/lib/src/classes/addon/mixins/render.js +0 -2
  87. package/lib/src/classes/addon/mixins/store.js +0 -2
  88. package/lib/src/classes/addon/mixins/table.js +0 -2
  89. package/lib/src/classes/error/class.js +13 -0
  90. package/lib/src/divhunt.js +2 -2
  91. package/lib/src/mixins/addons.js +0 -2
  92. package/lib/src/mixins/binaries.js +0 -2
  93. package/lib/src/mixins/data.js +0 -2
  94. package/lib/src/mixins/dependencies.js +0 -2
  95. package/lib/src/mixins/dom.js +0 -2
  96. package/lib/src/mixins/emitter.js +0 -2
  97. package/lib/src/mixins/error.js +15 -0
  98. package/lib/src/mixins/function.js +0 -2
  99. package/lib/src/mixins/generate.js +0 -2
  100. package/lib/src/mixins/helper.js +0 -2
  101. package/lib/src/mixins/logger.js +10 -2
  102. package/lib/src/mixins/middleware.js +0 -2
  103. package/lib/src/mixins/overrides.js +0 -2
  104. package/lib/src/mixins/request.js +0 -2
  105. package/lib/src/mixins/route.js +0 -2
  106. package/lib/src/mixins/string.js +0 -2
  107. package/lib/src/mixins/validate.js +0 -2
  108. package/package.json +1 -1
  109. package/progress.md +35 -0
  110. package/tasks.md +23 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git add:*)",
5
+ "Bash(git commit:*)",
6
+ "Bash(git push:*)",
7
+ "Bash(git diff --staged)",
8
+ "Bash(git status)",
9
+ "Bash(git push git@github-iamdejan:tomic-d/framework.git main)",
10
+ "Bash(node:*)"
11
+ ]
12
+ }
13
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,132 @@
1
+ # CLAUDE.md — Divhunt Framework
2
+
3
+ ## PURPOSE
4
+
5
+ AI project guardian. Maintains full context, protects scope, tracks every decision, and keeps all project files synchronized. This file is the operating system of this project.
6
+
7
+ ---
8
+
9
+ ## STATUS
10
+
11
+ Phase: 3 — Maintenance
12
+ Focus: Stability, bugfixes, optimization
13
+ Blocker: None
14
+ Last session: 2026-02-19 — Added DivhuntError (divhunt.Error(code, message, context)), emit on error, removed copyright headers
15
+
16
+ ---
17
+
18
+ ## PHASES
19
+
20
+ ### Phase 1: V2 Build (completed)
21
+ - Core rebuilt from scratch — Proxy reactivity, mixin composition, addon abstraction
22
+ - PostgreSQL ORM, HTTP/gRPC servers, command system, render engine
23
+ - 40+ UI components, SPA router, directive system, asset bundler
24
+ - **Gate:** Framework powers a real application end-to-end.
25
+
26
+ ### Phase 2: Open Source Launch (completed)
27
+ - Published on npm as `divhunt`
28
+ - MIT license
29
+ - Full documentation (6 docs covering all subsystems)
30
+ - Working example (basic-api)
31
+ - Public GitHub repo
32
+ - **Gate:** Published, documented, usable by external developers.
33
+
34
+ ### Phase 3: Maintenance (current)
35
+ - Bugfixes, stability improvements, performance optimization
36
+ - No new major features without explicit approval
37
+ - Documentation kept up to date
38
+ - **Gate:** Stable, battle-tested, zero critical bugs.
39
+
40
+ ### Phase 4: Growth
41
+ - Community adoption, contributions
42
+ - New addons, integrations
43
+ - Plugin system, ecosystem
44
+
45
+ ---
46
+
47
+ ## MODES
48
+
49
+ ### Work Mode (default)
50
+ Normal development. Follow tasks, fix bugs, optimize code.
51
+
52
+ ### Vision Mode
53
+ **Trigger:** "let's talk about the vision", "let's change the vision", "let's discuss strategy", "let's talk about the framework direction"
54
+
55
+ Behavior:
56
+ 1. Read brief.md and current STATUS
57
+ 2. Discuss with user — ask questions, challenge assumptions, propose alternatives
58
+ 3. After alignment, update ALL affected files:
59
+ - brief.md — product definition changes
60
+ - architecture.md — if technical direction changes
61
+ - decisions.md — log what changed and why
62
+ - tasks.md — add/remove/reprioritize
63
+ - progress.md — adjust milestones if needed
64
+ 4. Update STATUS in CLAUDE.md
65
+ 5. Print a summary of all changes made
66
+
67
+ ### Review Mode
68
+ **Trigger:** "where are we?", "status?", "overview", "what's done?"
69
+
70
+ Behavior:
71
+ 1. Read all files
72
+ 2. Give a concise report: phase, focus, blockers, recent progress, next steps
73
+
74
+ ### Decision Mode
75
+ **Trigger:** "I need to decide", "what do you think I should choose", "I have a dilemma"
76
+
77
+ Behavior:
78
+ 1. Listen to the options
79
+ 2. Analyze pros and cons of each
80
+ 3. Give a recommendation with reasoning
81
+ 4. After the decision — log in decisions.md with full context
82
+
83
+ ---
84
+
85
+ ## RULES
86
+
87
+ ### Scope Protection
88
+ - Phase 3 = maintenance. No new features without explicit approval.
89
+ - If user proposes a new feature → "Is this maintenance or Phase 4? Logging in tasks.md as future."
90
+ - Bugfix and optimization PRs are always welcome
91
+ - Breaking changes require a decision logged in decisions.md
92
+
93
+ ### Decision Tracking
94
+ - Every non-trivial decision MUST be logged in decisions.md BEFORE implementation
95
+ - Format: decision + reason + rejected alternatives + context
96
+
97
+ ### Session Management
98
+ - Start of session: read STATUS and tasks.md to know where you are
99
+ - End of session: update STATUS (phase, focus, blocker, last session summary)
100
+ - If session was a vision/strategy discussion — update all affected files
101
+
102
+ ### Auto-Update Rules
103
+ - **brief.md** — Changes ONLY in Vision Mode with explicit approval.
104
+ - **architecture.md** — Updated when code or technical direction changes.
105
+ - **decisions.md** — Every decision, immediately, no exceptions.
106
+ - **tasks.md** — Updated when a task is completed, added, or reprioritized.
107
+ - **progress.md** — Updated when a milestone is reached.
108
+
109
+ ### Git
110
+ - Never add Co-Authored-By or any co-author lines to commit messages
111
+ - All commits are authored solely by Dejan Tomic
112
+ - Use SSH remote: git@github-iamdejan:tomic-d/framework.git
113
+ - Commit style: short, lowercase, imperative, no period
114
+
115
+ ### Communication
116
+ - Serbian or English, match the user
117
+ - Direct, no fluff
118
+ - When user is wrong — say it
119
+ - When user is right — confirm it
120
+ - Code style: follow existing conventions with maximum precision
121
+
122
+ ---
123
+
124
+ ## FILES
125
+
126
+ | File | Purpose | When it changes |
127
+ |---|---|---|
128
+ | brief.md | What, for whom, why, vision, competition | Vision Mode, with approval |
129
+ | architecture.md | Living technical overview of the system | When code/tech stack changes |
130
+ | decisions.md | Decision + why + rejected alternatives | Every decision, immediately |
131
+ | tasks.md | Active tasks, granular | When task is added/completed/changed |
132
+ | progress.md | Milestones, what's done | When a milestone is reached |
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
 
5
3
  const clientsGRPC = divhunt.Addon('clients.grpc', (addon) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clientsGRPC from '#clients/grpc/addon.js';
4
2
 
5
3
  clientsGRPC.ItemOn('add', function(item)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import { fileURLToPath } from 'url'
4
2
  import { dirname, join } from 'path'
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clientsGRPC from '#clients/grpc/addon.js';
4
2
 
5
3
  const promises = {};
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clientsGRPC from '#clients/grpc/addon.js';
4
2
  import divhunt from '#framework/load.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clientsGRPC from '#clients/grpc/addon.js';
4
2
 
5
3
  import '#clients/grpc/item/catch/add.js';
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
 
5
3
  const clients = divhunt.Addon('clients', (addon) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.ItemOn('add', function(item)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import * as grpc from '@grpc/grpc-js'
4
2
  import * as protoLoader from '@grpc/proto-loader'
5
3
  import { fileURLToPath } from 'url'
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.grpc.execute', function(item, name, data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import clients from '#clients/addon.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.http.delete', function(item, path, data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.http.get', function(item, path, data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.http.post', function(item, path, data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.http.put', function(item, path, data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  clients.Fn('item.http.request', function(item, path, method = 'GET', data = {}, requestTimeout)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import clients from '#clients/addon.js';
4
2
 
5
3
  import '#clients/item/catch/add.js';
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
 
5
3
  const commands = divhunt.Addon('commands', (addon) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import commands from '../addon.js';
4
2
 
5
3
  commands.Fn('find', function(method, pathname)
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import commands from '../../addon.js';
4
2
 
5
3
  commands.Fn('grpc.server', async function(port = 50000, callbacks = {})
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import commands from '../../addon.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import commands from '../../addon.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import commands from '../addon.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import commands from '../addon.js';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import commands from '../addon.js';
4
2
 
5
3
  commands.Item({
@@ -45,7 +43,7 @@ commands.Item({
45
43
  }
46
44
  catch(error)
47
45
  {
48
- resolve(null, error.message, 500);
46
+ resolve(null, error.message, typeof error.code === 'number' ? error.code : 500);
49
47
  }
50
48
  }
51
49
  });
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import commands from './addon.js';
4
2
 
5
3
  import './functions/find.js';
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  const commands = divhunt.Addon('commands', (addon) =>
4
2
  {
5
3
  addon.Field('id', ['string']);
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  commands.Fn('find', function(method, pathname)
4
2
  {
5
3
  const items = Object.values(this.Items());
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  commands.Fn('item.run', function(item, properties = {}, context = {})
4
2
  {
5
3
  this.methods.resolve = null;
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
 
5
3
  const serversGRPC = divhunt.Addon('servers.grpc', (addon) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import serversGRPC from '#servers/grpc/addon.js';
4
2
 
5
3
  const promises = {};
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import { fileURLToPath } from 'url'
4
2
  import { dirname, join } from 'path'
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
  import serversGRPC from '#servers/grpc/addon.js';
5
3
 
@@ -70,14 +70,16 @@ serversHTTP.Fn('item.start', function(item)
70
70
 
71
71
  if(http.error)
72
72
  {
73
- response.writeHead(500, { 'Content-Type': 'application/json' });
73
+ const code = http.errorCode || 500;
74
+
75
+ response.writeHead(code, { 'Content-Type': 'application/json' });
74
76
  response.end(JSON.stringify({
75
- data: {},
77
+ data: http.errorContext || {},
76
78
  message: http.error,
77
- code: 500,
79
+ code: code,
78
80
  time: http.time
79
81
  }));
80
-
82
+
81
83
  return;
82
84
  }
83
85
 
@@ -111,7 +113,11 @@ serversHTTP.Fn('item.start', function(item)
111
113
  }
112
114
  catch(error)
113
115
  {
116
+ const code = typeof error.code === 'number' ? error.code : 500;
117
+
114
118
  http.error = error.message || 'Internal server error';
119
+ http.errorCode = code;
120
+ http.errorContext = error.context || {};
115
121
 
116
122
  item.Get('onError') && item.Get('onError')(http.error);
117
123
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from '#framework/load.js';
4
2
 
5
3
  const assets = divhunt.Addon('assets', (addon) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../addon.js';
4
2
 
5
3
  assets.Fn('css', function()
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../addon.js';
4
2
 
5
3
  assets.Fn('js', function(context = {})
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../../addon.js';
4
2
  import fs from 'fs';
5
3
  import path from 'path';
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../../addon.js';
4
2
  import fs from 'fs';
5
3
  import path from 'path';
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../../addon.js';
4
2
  import fs from 'fs';
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from '../../addon.js';
4
2
 
5
3
  assets.Fn('utils.transform', function(contents, type = 'js')
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from "#framework/load.js";
4
2
  import assets from "#assets/load.js";
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from "#framework/load.js";
4
2
  import assets from "#assets/addon.js";
5
3
 
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from "#framework/load.js";
4
2
 
5
3
  divhunt.AddonReady('html', (html) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import divhunt from "#framework/load.js";
4
2
 
5
3
  divhunt.AddonReady('html', (html) =>
@@ -1,5 +1,3 @@
1
- // © 2025 Divhunt GmbH — Licensed under the Divhunt Framework License. See LICENSE for terms.
2
-
3
1
  import assets from './addon.js';
4
2
 
5
3
  /* Functions */
@@ -0,0 +1,138 @@
1
+ # ARCHITECTURE — Divhunt Framework
2
+
3
+ *Living technical overview. Updated alongside the code.*
4
+
5
+ ---
6
+
7
+ ## Status: Stable — V2 complete, in maintenance
8
+
9
+ ## Stack
10
+
11
+ - **Language:** JavaScript (ES Modules, `"type": "module"`)
12
+ - **Runtime:** Node.js >= 18 (backend), Browser (frontend bundle)
13
+ - **Database:** PostgreSQL via Knex
14
+ - **Transport:** HTTP + gRPC
15
+ - **Bundling:** Convention-based (terser for minification)
16
+ - **SSR:** linkedom for server-side DOM
17
+ - **No TypeScript, no test framework, no linter, no build step**
18
+
19
+ ## Project Structure
20
+
21
+ ```
22
+ lib/ Core Divhunt class + 17 mixins
23
+ load.js Node.js entry point (creates instance, handles signals)
24
+ browser.js Browser entry point (attaches to window, mounts body)
25
+ src/
26
+ divhunt.js Main class (mixin-composed)
27
+ mixins/ addons, emitter, middleware, data, dom, route,
28
+ function, generate, binaries, helper, validate,
29
+ string, request, logger, dependencies, overrides, error
30
+ classes/
31
+ addon/ DivhuntAddon + mixins (fields, items, functions, find, render, store)
32
+ classes/
33
+ item/ DivhuntAddonItem + mixins (get, set, crud, functions, store)
34
+ render/ DivhuntAddonRender + mixins (compile, dom, process, events)
35
+ error/ DivhuntError class (extends Error — code, message, context)
36
+
37
+ addons/ Built-in addon library
38
+ core/
39
+ database/ PostgreSQL ORM (Knex, fluent query builder, 17+ operators)
40
+ servers/ HTTP + gRPC servers
41
+ clients/ HTTP + gRPC clients
42
+ commands/ Typed API command system
43
+ queue/ Concurrency task queue
44
+ render/
45
+ directives/ dh-if, dh-for, dh-click, dh-fetch, dh-show, dh-html, dh-text
46
+ pages/ SPA page router with CSS Grid layouts + async data loading
47
+ elements/ 40+ pre-built UI components
48
+ assets/ Convention-based asset bundler (terser)
49
+ html/ HTML document builder
50
+ tags/ HTML tag system
51
+ transforms/ Data transforms
52
+ modules/
53
+ variables/ Named variable registry
54
+ actions/ Action triggers
55
+ events/ Event bindings
56
+ schedules/ Cron-like scheduling
57
+ shortcuts/ Keyboard shortcut bindings
58
+ sources/ Data source registry
59
+ float/
60
+ modals/ Modal dialogs
61
+ toasts/ Toast notifications
62
+ tooltips/ Tooltip system
63
+ popups/ Popup menus
64
+ overlays/ Overlay backdrops
65
+
66
+ docs/ Full documentation (6 files)
67
+ examples/basic-api/ Minimal working example
68
+ ```
69
+
70
+ ## Key Classes
71
+
72
+ | Class | Mixins | Purpose |
73
+ |---|---|---|
74
+ | Divhunt | 17 | Core engine — addon registry, emitter, middleware, routing, DOM, error |
75
+ | DivhuntAddon | 9 | Addon abstraction — fields, items, functions, find, render, store |
76
+ | DivhuntAddonItem | 6 | Single record — get, set, CRUD, functions, store |
77
+ | DivhuntAddonRender | 7 | Frontend component — compile, DOM diffing, events, lifecycle |
78
+ | DivhuntError | — | Structured error (extends Error) — code, message, context |
79
+
80
+ ## Import Aliases
81
+
82
+ Defined in `package.json` under `imports`:
83
+
84
+ | Alias | Maps to |
85
+ |---|---|
86
+ | `#framework/*` | `./lib/*` |
87
+ | `#database/*` | `./addons/core/database/back/*` |
88
+ | `#servers/*` | `./addons/core/servers/back/*` |
89
+ | `#clients/*` | `./addons/core/clients/back/*` |
90
+ | `#commands/*` | `./addons/core/commands/back/*` |
91
+ | `#queue/*` | `./addons/core/queue/back/*` |
92
+ | `#assets/*` | `./addons/render/assets/back/*` |
93
+ | `#html/*` | `./addons/render/html/*` |
94
+ | `#directives/*` | `./addons/render/directives/*` |
95
+ | `#elements/*` | `./addons/render/elements/*` |
96
+ | `#tags/*` | `./addons/render/tags/*` |
97
+ | `#sources/*` | `./addons/modules/sources/*` |
98
+ | `#variables/*` | `./addons/modules/variables/*` |
99
+
100
+ ## Design Decisions
101
+
102
+ ### Mixin composition over inheritance
103
+ `Object.assign(Class.prototype, mixin)`. No class hierarchies. Each mixin is a plain object of methods merged onto the prototype.
104
+
105
+ ### Middleware as the extension point
106
+ CRUD operations are async middleware chains. Database addon intercepts for SQL. Without database — everything works in-memory. Storage is swappable.
107
+
108
+ ### Self-registering imports
109
+ Importing `load.js` registers the addon. No manual wiring, no DI container. `AddonReady` handles async dependency resolution regardless of import order.
110
+
111
+ ### Field transforms
112
+ Every field has `get[]` and `set[]` transform arrays plus a `define` schema. Type coercion, validation, and computed fields are declared at the field level.
113
+
114
+ ### Proxy-driven reactivity (frontend)
115
+ Property assignment triggers Proxy trap → schedules 16ms debounced `Update()` → re-compile → DOM diff → patch. No virtual DOM.
116
+
117
+ ### Binary transport over gRPC
118
+ Buffer instances extracted to separate `map<string, bytes>` before sending. Re-injected on receive. Transparent binary transport over JSON-based gRPC.
119
+
120
+ ### Structured error handling
121
+ `divhunt.Error(code, message, context)` returns a `DivhuntError` (extends `Error`). HTTP-compatible codes (400, 404, 500). Emits `'error'` event on creation. HTTP server and command system read `error.code` instead of hardcoding 500. `LogError` includes code and context in meta.
122
+
123
+ ### Convention-based bundling
124
+ No webpack. Scans directories, prioritizes `addon.js`, strips ES module syntax, concatenates by order, minifies via terser.
125
+
126
+ ## Dependencies
127
+
128
+ | Package | Purpose |
129
+ |---|---|
130
+ | knex | SQL query builder |
131
+ | pg | PostgreSQL driver |
132
+ | @grpc/grpc-js | gRPC server/client |
133
+ | @grpc/proto-loader | gRPC proto loading |
134
+ | bcrypt | Password hashing |
135
+ | busboy | Multipart/file upload parsing |
136
+ | dotenv | Environment config |
137
+ | linkedom | Server-side DOM |
138
+ | terser | JS minification |