create-githolon 0.58.0 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.59.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Scaffold a Nomos domain package: the starter domain + compile config + live e2e. `npm create githolon my-app`.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# 10 — Flutter clients: layered packages + humane names
|
|
2
|
+
|
|
3
|
+
`nomos-compile` can emit your generated Dart as **three sibling pub packages** instead of one
|
|
4
|
+
flat tree, so a Flutter app can enforce a layered architecture with the package graph itself:
|
|
5
|
+
|
|
6
|
+
```js
|
|
7
|
+
// nomos.package.mjs
|
|
8
|
+
export default {
|
|
9
|
+
name: "acme",
|
|
10
|
+
domains: [ /* … */ ],
|
|
11
|
+
dart: {
|
|
12
|
+
out: "build/dart",
|
|
13
|
+
packages: {
|
|
14
|
+
types: "acme_nomos_types", // pure data — frontend-safe
|
|
15
|
+
client: "acme_nomos_client", // effectful runtime clients
|
|
16
|
+
test: "acme_nomos_test", // headless harness — dev_dependencies only
|
|
17
|
+
},
|
|
18
|
+
names: {
|
|
19
|
+
// public aliases over the stable generated identities (typedefs in the types barrel)
|
|
20
|
+
AcmeEstateCustomFieldDefinitionFieldType: "FieldType",
|
|
21
|
+
AcmeEstateDrawingTransform2d: "DrawingTransform2d",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## The layering line
|
|
28
|
+
|
|
29
|
+
**Don't ban generated types from UI; ban generated clients/runtime from UI.**
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
your_frontend -> acme_nomos_types (payloads, read models, VOs/enums,
|
|
33
|
+
typed watch/read accessors, aggregate meta)
|
|
34
|
+
your_composition -> acme_nomos_client + types (offer methods over NomosBridge,
|
|
35
|
+
sessions, sync, workspace lifecycle)
|
|
36
|
+
apps/your_app -> your_frontend + your_composition
|
|
37
|
+
widget/e2e tests -> acme_nomos_test (dev_dependencies only)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- `types` depends ONLY on the pure `nomos_types` core — no bridge, no sessions, no lifecycle.
|
|
41
|
+
A type-only law change reaches the UI; a client/runtime change does not.
|
|
42
|
+
- `client` depends on the types package + `nomos_client`. It re-exports the types barrel, so
|
|
43
|
+
composition code needs one import.
|
|
44
|
+
- `test` re-exports the headless harness (`package:nomos_client/testing.dart`) plus the full
|
|
45
|
+
client layer.
|
|
46
|
+
|
|
47
|
+
The generated `watch*/read*` accessors live in **types** on purpose: they are pure typed
|
|
48
|
+
wrappers over an injected `NomosReads` seam (plain function fields) — the UI can render live
|
|
49
|
+
data without ever seeing the runtime. Your composition layer constructs the one `NomosReads`
|
|
50
|
+
from its bridge and hands it down.
|
|
51
|
+
|
|
52
|
+
## What is generated-owned vs yours
|
|
53
|
+
|
|
54
|
+
- `lib/src/generated/**` and each package barrel (`lib/<pkg>.dart`) are **generated-owned** —
|
|
55
|
+
wiped and rewritten on every compile. Never hand-edit them.
|
|
56
|
+
- Each `pubspec.yaml` is scaffolded **only if missing** — you own versions, publishing
|
|
57
|
+
(`publish_to`), and any extra dependencies. Version the three packages independently: that
|
|
58
|
+
independence IS the blast-radius win; releasing them in lockstep rebuilds the god artifact
|
|
59
|
+
with more pubspecs.
|
|
60
|
+
|
|
61
|
+
## Aliases (`dart.names`)
|
|
62
|
+
|
|
63
|
+
Generated names are fully qualified (`<Domain><Aggregate><Field>…`) because identity must be
|
|
64
|
+
collision-free across your whole law. The `names` map layers humane public names on top as
|
|
65
|
+
`typedef` aliases in the types barrel. Validation is fail-closed at compile: the generated
|
|
66
|
+
name must exist, and an alias may not collide with any generated public name or another alias.
|
|
67
|
+
The compile summary prints long generated names that still lack an alias.
|
|
68
|
+
|
|
69
|
+
Renaming an alias is free (it's a label over a stable identity — the law and the wire never
|
|
70
|
+
see it). `names` works in the single-package emit too.
|
|
71
|
+
|
|
72
|
+
## Notes
|
|
73
|
+
|
|
74
|
+
- `dart.packages` implies `support: "package"` (pub dependencies on `nomos_types` /
|
|
75
|
+
`nomos_client`); combining it with `support: "vendored"` is a named compile refusal.
|
|
76
|
+
- The scaffolded client/test pubspecs wire the sibling dependency as a `path:` (they are
|
|
77
|
+
co-emitted); replace with hosted constraints when you publish.
|
|
78
|
+
- Types-file purity is enforced by the compiler, not convention: a generated types file that
|
|
79
|
+
imported anything beyond the `nomos_types` core would refuse the compile.
|