@githolon/dsl 0.65.0 → 0.65.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.
- package/dart/CHANGELOG.md +8 -0
- package/dart/pubspec.yaml +2 -2
- package/dart_types/CHANGELOG.md +8 -0
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/src/compile_package_main.ts +63 -5
package/dart/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.43.0
|
|
2
|
+
|
|
3
|
+
- `NomosBridge.foreignReader({cloud})` — a `NomosForeignReader` backed by the device's multi-workspace bridge
|
|
4
|
+
plane, so a generated `ForeignRef` (`t.foreignRef`) resolves against real data: it mounts the foreign
|
|
5
|
+
workspace on demand (`connect(session: ws, allowUnborn: true)`, idempotent) and reads it
|
|
6
|
+
(`session(ws).queryById(id)`); `watch` re-reads on each sync tick. A locator resolver, not a foreign key —
|
|
7
|
+
the foreign holon is mounted only when you resolve. Requires `nomos_types >= 0.1.1` (the `ForeignRef` types).
|
|
8
|
+
|
|
1
9
|
## 0.41.0
|
|
2
10
|
- `NomosTestHarness` emits named phase-progress diagnostics (install → spawn runner → await ready → connect, plus per-session progress in `cluster`) and each `connect()` carries a `connectTimeout` (default 120s) that throws a NAMED remedy instead of hanging — so a multi-test AppSim run can tell install vs runner-wait vs session-block vs deadlock (co2 feedback).
|
|
3
11
|
|
package/dart/pubspec.yaml
CHANGED
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
Nomos 2 Dart frontend types — the hand-written kernel wire types plus the
|
|
12
12
|
code-generated per-domain aggregate + directive-payload types. (De)serializes
|
|
13
13
|
the EXACT serde JSON the Rust kernel + projection produce/consume.
|
|
14
|
-
version: 0.
|
|
14
|
+
version: 0.43.0
|
|
15
15
|
|
|
16
16
|
environment:
|
|
17
17
|
sdk: ^3.5.0
|
|
@@ -20,7 +20,7 @@ dependencies:
|
|
|
20
20
|
# The pure-data core (wire types, offer codec, NomosReads, schema validation, error
|
|
21
21
|
# info). nomos_client depends on and re-exports it, so existing imports are unchanged.
|
|
22
22
|
# For local monorepo dev, pubspec_overrides.yaml points this at ../dart_types.
|
|
23
|
-
nomos_types: ^0.1.
|
|
23
|
+
nomos_types: ^0.1.1
|
|
24
24
|
json_schema: ^5.2.2
|
|
25
25
|
crypto: ^3.0.0
|
|
26
26
|
|
package/dart_types/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.1.1
|
|
2
|
+
|
|
3
|
+
- Add `t.foreignRef` runtime types: `ForeignRef<T>` (a typed cross-workspace locator), `NomosForeignReader` /
|
|
4
|
+
`NomosForeignWorkspaceReader`, the sealed `ForeignResolveResult<T>` (`ForeignFound`/`ForeignNotFound`/
|
|
5
|
+
`ForeignDenied`/`ForeignUnreachable`), and `ForeignAttestation`. Generated read models type a `foreignRef`
|
|
6
|
+
field as `ForeignRef<Target>`; `.resolve/.resolveResult/.watch/.exists` are the informational lookup,
|
|
7
|
+
`.attest` is gated on the attested-read lane. Purely additive.
|
|
8
|
+
|
|
1
9
|
## 0.1.0
|
|
2
10
|
- Initial release. The pure-data core split out of `nomos_client`: kernel wire types,
|
|
3
11
|
the offer codec, `NomosReads`, the tri-state `NomosSlot`, aggregate metadata, schema
|
package/dart_types/pubspec.yaml
CHANGED
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
|
|
12
12
|
no runtime. The hand-written serde-JSON-compatible types plus the offer codec,
|
|
13
13
|
reactive read engine, schema validation, and data-only error/trace types.
|
|
14
|
-
version: 0.1.
|
|
14
|
+
version: 0.1.1
|
|
15
15
|
|
|
16
16
|
environment:
|
|
17
17
|
sdk: ^3.5.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@githolon/dsl",
|
|
3
|
-
"version": "0.65.
|
|
3
|
+
"version": "0.65.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -674,6 +674,15 @@ function emitDart(
|
|
|
674
674
|
writeGenerated(FRAMEWORK_FILE, generateDartDomain(shared.frameworkMod));
|
|
675
675
|
}
|
|
676
676
|
|
|
677
|
+
// CROSS-DOMAIN `t.foreignRef` (auto import). A foreignRef field typed `ForeignRef<CatalogueListing>` +
|
|
678
|
+
// `CatalogueListing.fromJson` needs the TARGET aggregate's Dart class — which lives in the target DOMAIN's
|
|
679
|
+
// generated file. Within ONE package the compiler knows which domain owns each aggregate, so we auto-emit
|
|
680
|
+
// the import (no manual `dartImports` config). Map every aggregate id → its domain's generated file base.
|
|
681
|
+
const aggIdToDartFile = new Map<string, string>();
|
|
682
|
+
for (const m of modules) {
|
|
683
|
+
for (const agg of (m.aggregates as { id: string }[])) aggIdToDartFile.set(agg.id, m.name);
|
|
684
|
+
}
|
|
685
|
+
|
|
677
686
|
// 2b. one generated file per composed domain — the TYPES (`<name>.dart`) + the async bridge
|
|
678
687
|
// CLIENT (`<name>.client.dart`, the Flutter sibling of `<name>.client.ts`).
|
|
679
688
|
for (const mod of modules) {
|
|
@@ -684,7 +693,28 @@ function emitDart(
|
|
|
684
693
|
// framework import. Only pass the import when this domain actually folds a framework symbol.
|
|
685
694
|
const { modForDart, skips, foldsFramework } = domainDedupOpts(mod, shared);
|
|
686
695
|
const domainFrameworkImport = foldsFramework ? frameworkImportUri : undefined;
|
|
687
|
-
|
|
696
|
+
// AUTO cross-domain foreignRef imports: for each foreignRef whose target aggregate lives in ANOTHER
|
|
697
|
+
// tenant domain, import that domain's generated file so `ForeignRef<Target>` + `Target.fromJson` resolve.
|
|
698
|
+
// A target that is framework-shared resolves via the frameworkImportUri (not in the tenant map), so it is
|
|
699
|
+
// skipped here. Merged with any manual `dartImports`; deduped by uri.
|
|
700
|
+
const foreignRefImportUris = new Set<string>();
|
|
701
|
+
for (const agg of (modForDart.aggregates as { fields: Record<string, { foreignRef?: { targetAggregateId: string } }> }[])) {
|
|
702
|
+
for (const f of Object.values(agg.fields)) {
|
|
703
|
+
const tid = f.foreignRef?.targetAggregateId;
|
|
704
|
+
if (tid === undefined) continue;
|
|
705
|
+
const targetFile = aggIdToDartFile.get(tid);
|
|
706
|
+
if (targetFile !== undefined && targetFile !== modForDart.name) foreignRefImportUris.add(`${targetFile}.dart`);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
const mergedDartImports = [
|
|
710
|
+
...(modForDart.dartImports ?? []),
|
|
711
|
+
...[...foreignRefImportUris]
|
|
712
|
+
.filter((uri) => !(modForDart.dartImports ?? []).some((i) => i.uri === uri))
|
|
713
|
+
.sort()
|
|
714
|
+
.map((uri) => ({ uri })),
|
|
715
|
+
];
|
|
716
|
+
const modForDartWithImports = mergedDartImports.length > 0 ? { ...modForDart, dartImports: mergedDartImports } : modForDart;
|
|
717
|
+
const src = generateDartDomain(modForDartWithImports, {
|
|
688
718
|
...skips,
|
|
689
719
|
...(domainFrameworkImport !== undefined ? { frameworkImportUri: domainFrameworkImport } : {}),
|
|
690
720
|
});
|
|
@@ -857,18 +887,29 @@ function emitDartPackages(
|
|
|
857
887
|
// ── the TYPES package — pure data, `nomos_types` only ──
|
|
858
888
|
const typesGen = freshGenDir(packages.types);
|
|
859
889
|
const typesSources = new Map<string, string>(); // fileBase → src (for alias validation + purity)
|
|
890
|
+
// The SIBLING generated type files a types-package file MAY import (a cross-domain `t.foreignRef` types its
|
|
891
|
+
// field as the target aggregate's class, which lives in the target domain's file). A sibling types file is
|
|
892
|
+
// still PURE (no runtime/bridge surface — the purity gate exists to keep nomos_client out, not to isolate
|
|
893
|
+
// domain files from each other; Dart allows type-import cycles for mutual refs).
|
|
894
|
+
const siblingTypeFiles = new Set<string>([...modules.map((m) => `${m.name}.dart`), `${FRAMEWORK_FILE}.dart`]);
|
|
860
895
|
const writeTypes = (fileBase: string, src: string): void => {
|
|
861
896
|
if (!src.includes(DART_PACKAGE_IMPORT)) {
|
|
862
897
|
fail(`generated Dart for '${fileBase}' does not carry the expected support import — codegen_dart header drifted`);
|
|
863
898
|
}
|
|
864
899
|
const pure = src.replace(DART_PACKAGE_IMPORT, DART_TYPES_IMPORT);
|
|
865
|
-
// PURITY, fail-closed: only the nomos_types barrel
|
|
900
|
+
// PURITY, fail-closed: only the nomos_types barrel, the framework file, and SIBLING generated type files
|
|
901
|
+
// (cross-domain foreignRef targets) may be imported. Runtime/bridge surfaces (nomos_client) stay out.
|
|
866
902
|
for (const line of pure.split("\n")) {
|
|
867
903
|
const m = /^import\s+'([^']+)'/.exec(line.trim());
|
|
868
|
-
if (
|
|
904
|
+
if (
|
|
905
|
+
m !== null &&
|
|
906
|
+
m[1] !== "package:nomos_types/nomos_types.dart" &&
|
|
907
|
+
m[1] !== `${FRAMEWORK_FILE}.dart` &&
|
|
908
|
+
!siblingTypeFiles.has(m[1]!)
|
|
909
|
+
) {
|
|
869
910
|
fail(
|
|
870
911
|
`types-package purity: generated '${fileBase}.dart' imports '${m[1]}' — a types file may only ` +
|
|
871
|
-
`import the nomos_types core
|
|
912
|
+
`import the nomos_types core, the framework file, or a sibling generated domain file`,
|
|
872
913
|
);
|
|
873
914
|
}
|
|
874
915
|
}
|
|
@@ -879,11 +920,28 @@ function emitDartPackages(
|
|
|
879
920
|
};
|
|
880
921
|
|
|
881
922
|
if (shared.frameworkMod !== undefined) writeTypes(FRAMEWORK_FILE, generateDartDomain(shared.frameworkMod));
|
|
923
|
+
// CROSS-DOMAIN foreignRef (layered): map aggregate id → its domain's type file, so a foreignRef field's
|
|
924
|
+
// target class resolves via a sibling import (the purity gate now permits sibling type files).
|
|
925
|
+
const aggIdToTypeFile = new Map<string, string>();
|
|
926
|
+
for (const m of modules) for (const agg of (m.aggregates as { id: string }[])) aggIdToTypeFile.set(agg.id, m.name);
|
|
882
927
|
const perDomain = modules.map((mod) => ({ mod, dd: domainDedupOpts(mod, shared) }));
|
|
883
928
|
for (const { mod, dd } of perDomain) {
|
|
929
|
+
const frImports = new Set<string>();
|
|
930
|
+
for (const agg of (dd.modForDart.aggregates as { fields: Record<string, { foreignRef?: { targetAggregateId: string } }> }[])) {
|
|
931
|
+
for (const f of Object.values(agg.fields)) {
|
|
932
|
+
const tid = f.foreignRef?.targetAggregateId;
|
|
933
|
+
const tf = tid !== undefined ? aggIdToTypeFile.get(tid) : undefined;
|
|
934
|
+
if (tf !== undefined && tf !== dd.modForDart.name) frImports.add(`${tf}.dart`);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
const merged = [
|
|
938
|
+
...(dd.modForDart.dartImports ?? []),
|
|
939
|
+
...[...frImports].filter((uri) => !(dd.modForDart.dartImports ?? []).some((i) => i.uri === uri)).sort().map((uri) => ({ uri })),
|
|
940
|
+
];
|
|
941
|
+
const modForTypes = merged.length > 0 ? { ...dd.modForDart, dartImports: merged } : dd.modForDart;
|
|
884
942
|
writeTypes(
|
|
885
943
|
mod.name,
|
|
886
|
-
generateDartDomain(
|
|
944
|
+
generateDartDomain(modForTypes, {
|
|
887
945
|
...dd.skips,
|
|
888
946
|
...(dd.foldsFramework ? { frameworkImportUri: `${FRAMEWORK_FILE}.dart` } : {}),
|
|
889
947
|
}),
|