@githolon/dsl 0.102.4 → 0.103.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/compile_package.mjs +43 -2
- package/compile_proof.d.mts +47 -0
- package/compile_proof.mjs +343 -0
- package/dart/CHANGELOG.md +7 -0
- package/dart/lib/src/dev_cloud.dart +8 -8
- package/dart/lib/src/nms_generated_runtime.dart +2 -0
- package/dart/lib/src/runner/node-entry.mjs +5504 -1236
- package/dart/lib/src/runner/offline-install.mjs +4578 -528
- package/dart/lib/src/test_harness.dart +206 -152
- package/dart/lib/src/webview_bridge.dart +196 -89
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/acquire_session_credentials_test.dart +4 -3
- package/dart/test/adv_realm_interference_test.dart +7 -6
- package/dart/test/cloud_bound_topology_test.dart +3 -3
- package/dart/test/cluster_births_test.dart +4 -3
- package/dart/test/cluster_device_keyed_acceptance_test.dart +10 -16
- package/dart/test/cluster_local_autosync_test.dart +3 -2
- package/dart/test/cluster_scale_test.dart +3 -2
- package/dart/test/dlq_session_surface_test.dart +7 -6
- package/dart/test/first_app_gauntlet_test.dart +14 -21
- package/dart/test/fixtures/wedge/fake-install.mjs +1 -1
- package/dart/test/four_layer_nested_topology_test.dart +4 -4
- package/dart/test/harness_phase_timeout_test.dart +2 -2
- package/dart/test/local_sync_inert_test.dart +1 -1
- package/dart/test/parent_signer_recovery_test.dart +2 -2
- package/dart/test/sealing_client_test.dart +4 -3
- package/dart/test/session_bound_test.dart +8 -7
- package/dart/test/test_harness_test.dart +13 -12
- package/dart/test/vo_read_typing_test.dart +4 -3
- package/dart/test/watch_after_offer_stall_test.dart +4 -3
- package/dart/test/webview_bridge_test.dart +102 -5
- package/dart_types/CHANGELOG.md +5 -0
- package/dart_types/lib/nomos_types.dart +9 -0
- package/dart_types/lib/src/nomos_ref.dart +20 -0
- package/dart_types/lib/src/optional_ref.dart +85 -0
- package/dart_types/lib/src/sha256_digest.dart +41 -0
- package/dart_types/lib/src/versioned_nomos_ref.dart +81 -0
- package/dart_types/pubspec.yaml +1 -1
- package/dart_types/test/optional_ref_test.dart +44 -0
- package/dart_types/test/sha256_digest_test.dart +18 -0
- package/package.json +9 -5
- package/runtime/generated-application-host.js +5365 -1105
- package/src/aggregate.ts +18 -0
- package/src/application_composition.ts +6 -32
- package/src/attested_core.ts +6 -3
- package/src/birth_meter.ts +1 -0
- package/src/birth_meter_ensure.ts +28 -2
- package/src/births.ts +1 -1
- package/src/build_package.ts +162 -538
- package/src/business_birth.ts +19 -3
- package/src/canonical_json.ts +21 -0
- package/src/check_package_main.ts +76 -35
- package/src/clear_directive.ts +19 -8
- package/src/codegen_dart.ts +305 -22
- package/src/codegen_dart_application.ts +844 -292
- package/src/codegen_dart_client.ts +1084 -407
- package/src/codegen_dart_scenario.ts +12 -12
- package/src/codegen_proof.ts +169 -39
- package/src/codegen_provider_dart.ts +17 -1
- package/src/codegen_ts.ts +298 -106
- package/src/compat_manifest.ts +2 -2
- package/src/compat_package_main.ts +8 -12
- package/src/compile_package_main.ts +1866 -597
- package/src/compose.ts +1 -1
- package/src/directive.ts +208 -15
- package/src/engine_entry.ts +165 -111
- package/src/evolve_preview.ts +43 -81
- package/src/extremum.ts +1 -1
- package/src/fields.ts +183 -4
- package/src/flow_gate.ts +75 -2
- package/src/framework/application_home.ts +2 -0
- package/src/framework/auth_provider_law.ts +2 -2
- package/src/framework/birth_meter.ts +7 -19
- package/src/framework/bootstrap.ts +0 -2
- package/src/framework/business_corrections.ts +9 -5
- package/src/framework/domain_lifecycle.ts +15 -29
- package/src/framework/encryption_scope.ts +2 -1
- package/src/framework/framework_aggregates.ts +2 -0
- package/src/framework/genesis.ts +16 -14
- package/src/framework/home.ts +20 -14
- package/src/framework/owned_custody.ts +9 -3
- package/src/framework/platform_admin.ts +3 -3
- package/src/framework/relations.ts +21 -13
- package/src/framework/signing_identity.ts +45 -40
- package/src/framework/workspace_invariant.ts +245 -0
- package/src/framework/workspaces.ts +23 -29
- package/src/index.ts +36 -16
- package/src/intent.ts +178 -6
- package/src/law_check.ts +32 -11
- package/src/law_graph.ts +2902 -0
- package/src/law_graph_usda.ts +1799 -0
- package/src/law_identity.ts +435 -0
- package/src/law_value_type.ts +230 -0
- package/src/lsp_server.ts +61 -31
- package/src/ops.ts +7 -0
- package/src/package_config.ts +141 -0
- package/src/package_dependencies.ts +108 -0
- package/src/package_dependency_usage.ts +150 -0
- package/src/package_source_imports.ts +71 -0
- package/src/plan_source_slice.ts +335 -0
- package/src/point_guard.ts +192 -0
- package/src/precondition.ts +44 -9
- package/src/read_projection_namespace.ts +1 -1
- package/src/runtime_zod.ts +44 -0
- package/src/secondary_ensure.ts +67 -14
- package/src/shape_compat.ts +1 -1
- package/src/stable_id_identity_bridge.ts +149 -0
- package/src/stable_id_lockfile.ts +278 -0
- package/src/stable_ids.ts +7 -2
- package/src/stable_ids_for_module.ts +348 -0
- package/src/stable_ids_types.ts +1 -1
- package/src/sum.ts +1 -1
- package/src/usd_state.ts +1 -1
- package/src/usda_relationship_integrity.ts +66 -0
- package/src/usda_text.ts +18 -0
- package/src/usdz.ts +78 -0
- package/src/value_object.ts +95 -0
- package/src/wire.ts +19 -0
- package/src/wire_encode.ts +22 -0
- package/src/workspace_sharding.ts +52 -36
- package/src/workspace_sharing.ts +28 -4
- package/src/zod_introspection.ts +1 -1
- package/dart/test/cluster_attested_test.dart +0 -201
- package/src/compile_engine.ts +0 -595
- package/src/manifest.ts +0 -1476
- package/src/read_projection_composition.ts +0 -117
- package/src/read_projection_manifest.ts +0 -115
- package/src/relation_composition.ts +0 -286
- package/src/usd.ts +0 -1967
- package/src/usd_layers.ts +0 -1776
|
@@ -16,6 +16,7 @@ class FakeRunner implements BridgeTransport {
|
|
|
16
16
|
final _incoming = StreamController<Map<String, Object?>>.broadcast();
|
|
17
17
|
final List<Map<String, Object?>> sent = [];
|
|
18
18
|
String? lastWatchSubId;
|
|
19
|
+
bool acknowledgeWatch = true;
|
|
19
20
|
bool acknowledgeUnwatch = true;
|
|
20
21
|
|
|
21
22
|
FakeRunner() {
|
|
@@ -109,6 +110,18 @@ class FakeRunner implements BridgeTransport {
|
|
|
109
110
|
]
|
|
110
111
|
}));
|
|
111
112
|
break;
|
|
113
|
+
case 'queryPage':
|
|
114
|
+
_incoming.add(reply({
|
|
115
|
+
'rows': [
|
|
116
|
+
{
|
|
117
|
+
'id': 'page-a',
|
|
118
|
+
'data': {'q': args['queryId']}
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
'cursor': 'opaque-next',
|
|
122
|
+
'done': false,
|
|
123
|
+
}));
|
|
124
|
+
break;
|
|
112
125
|
case 'queryById':
|
|
113
126
|
_incoming.add(reply({
|
|
114
127
|
'rows': [
|
|
@@ -119,6 +132,24 @@ class FakeRunner implements BridgeTransport {
|
|
|
119
132
|
]
|
|
120
133
|
}));
|
|
121
134
|
break;
|
|
135
|
+
case 'checkRefFreshness':
|
|
136
|
+
_incoming.add(reply({
|
|
137
|
+
'unique': [
|
|
138
|
+
{
|
|
139
|
+
'ref': (args['refs'] as List).single,
|
|
140
|
+
'outcome': {
|
|
141
|
+
'status': 'stale',
|
|
142
|
+
'latest': {
|
|
143
|
+
'workspace': 'catalogue',
|
|
144
|
+
'type': 'catalogue.Publication',
|
|
145
|
+
'id': 'publication:2',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
'order': [0],
|
|
151
|
+
}));
|
|
152
|
+
break;
|
|
122
153
|
case 'count':
|
|
123
154
|
_incoming.add(reply({'count': 7}));
|
|
124
155
|
break;
|
|
@@ -232,7 +263,9 @@ class FakeRunner implements BridgeTransport {
|
|
|
232
263
|
break;
|
|
233
264
|
case 'watch':
|
|
234
265
|
lastWatchSubId = args['subId'] as String;
|
|
235
|
-
|
|
266
|
+
if (acknowledgeWatch) {
|
|
267
|
+
_incoming.add(reply({'subId': args['subId']}));
|
|
268
|
+
}
|
|
236
269
|
break;
|
|
237
270
|
case 'unwatch':
|
|
238
271
|
if (acknowledgeUnwatch) {
|
|
@@ -341,9 +374,6 @@ Future<Object?> _invoke(
|
|
|
341
374
|
payload: a['payload'],
|
|
342
375
|
actor: a['actor'] as String?,
|
|
343
376
|
domainHash: a['domainHash'] as String?,
|
|
344
|
-
attestations: (a['attestations'] as List?)
|
|
345
|
-
?.map((e) => (e as Map).cast<String, Object?>())
|
|
346
|
-
.toList(),
|
|
347
377
|
force: a['force'] as bool?,
|
|
348
378
|
);
|
|
349
379
|
default:
|
|
@@ -515,6 +545,39 @@ void main() {
|
|
|
515
545
|
await bridge.ready.timeout(const Duration(seconds: 1));
|
|
516
546
|
});
|
|
517
547
|
|
|
548
|
+
test('dispose closes active watches without mutating its iteration',
|
|
549
|
+
() async {
|
|
550
|
+
await bridge.ready;
|
|
551
|
+
final subscription =
|
|
552
|
+
bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
|
|
553
|
+
await Future<void>.delayed(Duration.zero);
|
|
554
|
+
|
|
555
|
+
await bridge.dispose();
|
|
556
|
+
await subscription.cancel();
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
test('dispose does not wait for a paused watch consumer', () async {
|
|
560
|
+
await bridge.ready;
|
|
561
|
+
final subscription =
|
|
562
|
+
bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
|
|
563
|
+
await Future<void>.delayed(Duration.zero);
|
|
564
|
+
subscription.pause();
|
|
565
|
+
|
|
566
|
+
await bridge.dispose().timeout(const Duration(seconds: 1));
|
|
567
|
+
await subscription.cancel();
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
test('dispose contains an unacknowledged watch registration error', () async {
|
|
571
|
+
await bridge.ready;
|
|
572
|
+
runner.acknowledgeWatch = false;
|
|
573
|
+
final subscription =
|
|
574
|
+
bridge.watch('entriesByOwner', {'owner': 'user:ada'}).listen((_) {});
|
|
575
|
+
await Future<void>.delayed(Duration.zero);
|
|
576
|
+
|
|
577
|
+
await bridge.dispose();
|
|
578
|
+
await subscription.cancel();
|
|
579
|
+
});
|
|
580
|
+
|
|
518
581
|
test('offer round-trips a typed head; args reach the runner verbatim',
|
|
519
582
|
() async {
|
|
520
583
|
await bridge.ready;
|
|
@@ -602,12 +665,17 @@ void main() {
|
|
|
602
665
|
});
|
|
603
666
|
|
|
604
667
|
test(
|
|
605
|
-
'connect / query / queryById / count / sync / lawStatus all wrap the runner',
|
|
668
|
+
'connect / query / queryPage / queryById / count / sync / lawStatus all wrap the runner',
|
|
606
669
|
() async {
|
|
607
670
|
await bridge.ready;
|
|
608
671
|
await bridge.connect(cloud: 'https://c', workspace: 'ws', clientId: 'c1');
|
|
609
672
|
expect((await bridge.query('byAuthor', {'author': 'ada'})).first['data'],
|
|
610
673
|
{'q': 'byAuthor'});
|
|
674
|
+
final page = await bridge.queryPage('byAuthor',
|
|
675
|
+
params: {'author': 'ada'}, pageSize: 1);
|
|
676
|
+
expect(page.rows.single['id'], 'page-a');
|
|
677
|
+
expect(page.cursor, 'opaque-next');
|
|
678
|
+
expect(page.done, isFalse);
|
|
611
679
|
expect((await bridge.queryById('Entry_1')).first['id'], 'Entry_1');
|
|
612
680
|
expect(await bridge.count('entries'), 7);
|
|
613
681
|
expect(await bridge.sync(), {'pushed': true});
|
|
@@ -615,6 +683,35 @@ void main() {
|
|
|
615
683
|
await bridge.lawStatus('abc'), {'installed': true, 'drifted': false});
|
|
616
684
|
});
|
|
617
685
|
|
|
686
|
+
test('version freshness returns the required sum type without resolving history',
|
|
687
|
+
() async {
|
|
688
|
+
await bridge.ready;
|
|
689
|
+
final reference = NmsInternalVersionedNomosRefs.create<Object, Object>(
|
|
690
|
+
pinned: NmsInternalNomosRefs.create<Object>(
|
|
691
|
+
workspace: 'catalogue',
|
|
692
|
+
type: 'catalogue.Publication',
|
|
693
|
+
id: 'publication:1',
|
|
694
|
+
),
|
|
695
|
+
series: NmsInternalNomosRefs.create<Object>(
|
|
696
|
+
workspace: 'catalogue',
|
|
697
|
+
type: 'catalogue.Series',
|
|
698
|
+
id: 'series:1',
|
|
699
|
+
),
|
|
700
|
+
currentField: 'currentPublication',
|
|
701
|
+
);
|
|
702
|
+
|
|
703
|
+
final freshness = await bridge.checkReferenceFreshness(reference);
|
|
704
|
+
expect(freshness, isA<ReferenceStale<Object>>());
|
|
705
|
+
expect((freshness as ReferenceStale<Object>).latest.id, 'publication:2');
|
|
706
|
+
final request = runner.sent.last;
|
|
707
|
+
expect(request['op'], 'checkRefFreshness');
|
|
708
|
+
final args = (request['args'] as Map).cast<String, Object?>();
|
|
709
|
+
final check = ((args['refs'] as List).single as Map).cast<String, Object?>();
|
|
710
|
+
expect(check['currentField'], 'currentPublication');
|
|
711
|
+
expect((check['pinned'] as Map)['id'], 'publication:1');
|
|
712
|
+
expect((check['series'] as Map)['id'], 'series:1');
|
|
713
|
+
});
|
|
714
|
+
|
|
618
715
|
test(
|
|
619
716
|
'moments and historic reads keep commit plumbing behind an opaque handle',
|
|
620
717
|
() async {
|
package/dart_types/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.8.1
|
|
2
|
+
|
|
3
|
+
- Carry the typed USDA-native kernel protocol, plan diagnostics, reference freshness and application
|
|
4
|
+
readiness shapes used by generated clients without exposing transport or runtime implementation details.
|
|
5
|
+
|
|
1
6
|
## 0.8.0
|
|
2
7
|
|
|
3
8
|
- Make `NomosRef<T>` the canonical identity of generated business records. References carry their workspace,
|
|
@@ -33,10 +33,19 @@ export 'src/foreign_ref.dart' show ForeignRef;
|
|
|
33
33
|
export 'src/activity.dart';
|
|
34
34
|
// NomosRef is inspectable but framework-created. Its constructor and wire codec stay behind the runtime.
|
|
35
35
|
export 'src/nomos_ref.dart' show NomosRef;
|
|
36
|
+
export 'src/versioned_nomos_ref.dart'
|
|
37
|
+
show
|
|
38
|
+
VersionedNomosRef,
|
|
39
|
+
ReferenceFreshness,
|
|
40
|
+
ReferenceCurrent,
|
|
41
|
+
ReferenceStale,
|
|
42
|
+
ReferenceFreshnessUnavailable;
|
|
43
|
+
export 'src/optional_ref.dart' show NomosOptionalRef;
|
|
36
44
|
export 'src/invitation.dart' show Identity, User, Recipient, Invitation;
|
|
37
45
|
// Branded identity wrappers (NomosPrincipal / NomosDeviceSecret) for the generated cross-workspace
|
|
38
46
|
// birth methods — actor/authorSecret are distinct types, so a transposition is a compile error.
|
|
39
47
|
export 'src/principal.dart';
|
|
48
|
+
export 'src/sha256_digest.dart';
|
|
40
49
|
// The CUSTODY-LIFECYCLE types (rebirth_and_custody_lifecycle.md): NomosCustodyBreak / NomosCustodyStatus /
|
|
41
50
|
// CustodyBreakPolicy — custody incompatibility as a first-class, typed, app-decidable event. Pure data.
|
|
42
51
|
export 'src/custody.dart';
|
|
@@ -69,6 +69,26 @@ abstract final class NmsInternalNomosRefs {
|
|
|
69
69
|
|
|
70
70
|
static String id<TAggregate>(NomosRef<TAggregate> reference) => reference._id;
|
|
71
71
|
|
|
72
|
+
/// Retype a concrete aggregate reference to a compiled public contract after
|
|
73
|
+
/// checking the stable wire kind. Generated version-pin factories use this
|
|
74
|
+
/// when a concrete catalogue row satisfies a cross-domain contract.
|
|
75
|
+
static NomosRef<TTo> retype<TTo>(
|
|
76
|
+
NomosRef<Object?> reference, {
|
|
77
|
+
required String expectedType,
|
|
78
|
+
}) {
|
|
79
|
+
final actual = reference._type;
|
|
80
|
+
if (actual != expectedType && !actual.endsWith('.$expectedType')) {
|
|
81
|
+
throw ArgumentError(
|
|
82
|
+
'Reference carries $actual; expected $expectedType',
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return NomosRef<TTo>._(
|
|
86
|
+
reference._workspace,
|
|
87
|
+
reference._type,
|
|
88
|
+
reference._id,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
72
92
|
static NomosRef<TAggregate> fromJson<TAggregate>(Object? value) {
|
|
73
93
|
if (value is String) return fromUri<TAggregate>(value);
|
|
74
94
|
final map = (value as Map).cast<String, dynamic>();
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// NOMOS — an optional relationship is a required business decision.
|
|
2
|
+
//
|
|
3
|
+
// Storage may legitimately omit a reference. Generated application inputs must
|
|
4
|
+
// not turn that into an optional named argument: callers choose absent or present.
|
|
5
|
+
library;
|
|
6
|
+
|
|
7
|
+
import 'nomos_ref.dart';
|
|
8
|
+
|
|
9
|
+
/// An explicit choice for an optional first-class Nomos relationship.
|
|
10
|
+
///
|
|
11
|
+
/// Generated business inputs use this instead of `NomosRef<T>?`. The input
|
|
12
|
+
/// parameter itself is required, so accidentally forgetting a relationship is a
|
|
13
|
+
/// compile error while a deliberately absent relationship remains representable.
|
|
14
|
+
sealed class NomosOptionalRef<TAggregate> {
|
|
15
|
+
const NomosOptionalRef();
|
|
16
|
+
|
|
17
|
+
/// Deliberately omit this relationship from the offered business facts.
|
|
18
|
+
const factory NomosOptionalRef.absent() = _AbsentNomosRef<TAggregate>;
|
|
19
|
+
|
|
20
|
+
/// Supply a framework-created reference for this relationship.
|
|
21
|
+
const factory NomosOptionalRef.present(NomosRef<TAggregate> reference) =
|
|
22
|
+
_PresentNomosRef<TAggregate>;
|
|
23
|
+
|
|
24
|
+
/// True when the relationship is deliberately absent.
|
|
25
|
+
bool get isAbsent => this is _AbsentNomosRef<TAggregate>;
|
|
26
|
+
|
|
27
|
+
/// True when the relationship carries a reference.
|
|
28
|
+
bool get isPresent => this is _PresentNomosRef<TAggregate>;
|
|
29
|
+
|
|
30
|
+
/// The supplied reference, or `null` when absence was chosen explicitly.
|
|
31
|
+
NomosRef<TAggregate>? get referenceOrNull => switch (this) {
|
|
32
|
+
_PresentNomosRef<TAggregate>(:final reference) => reference,
|
|
33
|
+
_ => null,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/// Exhaustively handle the two relationship choices.
|
|
37
|
+
R when<R>({
|
|
38
|
+
required R Function() absent,
|
|
39
|
+
required R Function(NomosRef<TAggregate> reference) present,
|
|
40
|
+
}) =>
|
|
41
|
+
switch (this) {
|
|
42
|
+
_AbsentNomosRef<TAggregate>() => absent(),
|
|
43
|
+
_PresentNomosRef<TAggregate>(:final reference) => present(reference),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/// Write this choice into an action payload. Absence omits the key; presence
|
|
47
|
+
/// writes the encoded reference value.
|
|
48
|
+
void writeTo(
|
|
49
|
+
Map<String, Object?> data,
|
|
50
|
+
String key,
|
|
51
|
+
Object? Function(NomosRef<TAggregate> reference) encode,
|
|
52
|
+
) {
|
|
53
|
+
switch (this) {
|
|
54
|
+
case _AbsentNomosRef<TAggregate>():
|
|
55
|
+
break;
|
|
56
|
+
case _PresentNomosRef<TAggregate>(:final reference):
|
|
57
|
+
data[key] = encode(reference);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@override
|
|
62
|
+
bool operator ==(Object other) =>
|
|
63
|
+
other is NomosOptionalRef<TAggregate> &&
|
|
64
|
+
other.runtimeType == runtimeType &&
|
|
65
|
+
other.referenceOrNull == referenceOrNull;
|
|
66
|
+
|
|
67
|
+
@override
|
|
68
|
+
int get hashCode => Object.hash(runtimeType, referenceOrNull);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
final class _AbsentNomosRef<TAggregate> extends NomosOptionalRef<TAggregate> {
|
|
72
|
+
const _AbsentNomosRef();
|
|
73
|
+
|
|
74
|
+
@override
|
|
75
|
+
String toString() => 'NomosOptionalRef<$TAggregate>.absent()';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
final class _PresentNomosRef<TAggregate> extends NomosOptionalRef<TAggregate> {
|
|
79
|
+
final NomosRef<TAggregate> reference;
|
|
80
|
+
|
|
81
|
+
const _PresentNomosRef(this.reference);
|
|
82
|
+
|
|
83
|
+
@override
|
|
84
|
+
String toString() => 'NomosOptionalRef<$TAggregate>.present($reference)';
|
|
85
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
|
|
2
|
+
// remotes are replaceable custody/transport, not truth.
|
|
3
|
+
|
|
4
|
+
/// A SHA-256 digest in Nomos's canonical wire spelling: exactly 64 lowercase
|
|
5
|
+
/// hexadecimal characters.
|
|
6
|
+
///
|
|
7
|
+
/// This extension type is zero-cost on the wire and nominal in Dart: a bare
|
|
8
|
+
/// [String], or a different semantic string type, cannot be passed where a
|
|
9
|
+
/// [Sha256Digest] is required. Construction validates before an offer can be
|
|
10
|
+
/// assembled, rather than deferring the mistake to kernel-side Zod validation.
|
|
11
|
+
extension type const Sha256Digest._(String value) {
|
|
12
|
+
factory Sha256Digest(String value) {
|
|
13
|
+
if (!_isLowercaseSha256(value)) {
|
|
14
|
+
throw FormatException(
|
|
15
|
+
'expected a 64-character lowercase hexadecimal SHA-256 digest',
|
|
16
|
+
value,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
return Sha256Digest._(value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// Parse a wire value. This is an explicit alias for generated decode sites
|
|
23
|
+
/// and application boundaries that prefer parser vocabulary.
|
|
24
|
+
static Sha256Digest parse(String value) => Sha256Digest(value);
|
|
25
|
+
|
|
26
|
+
/// Parse without throwing.
|
|
27
|
+
static Sha256Digest? tryParse(String value) {
|
|
28
|
+
if (!_isLowercaseSha256(value)) return null;
|
|
29
|
+
return Sha256Digest._(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
bool _isLowercaseSha256(String value) {
|
|
34
|
+
if (value.length != 64) return false;
|
|
35
|
+
for (final codeUnit in value.codeUnits) {
|
|
36
|
+
final digit = codeUnit >= 0x30 && codeUnit <= 0x39;
|
|
37
|
+
final lowercaseHex = codeUnit >= 0x61 && codeUnit <= 0x66;
|
|
38
|
+
if (!digit && !lowercaseHex) return false;
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// NOMOS — a version pin and its stable series (architecture/foreign_ref.md).
|
|
2
|
+
//
|
|
3
|
+
// This is deliberately a pure data type. The generated application owns the
|
|
4
|
+
// effectful freshness check because it owns the authenticated multi-workspace
|
|
5
|
+
// kernel bridge; a projected DTO never hides a runtime or global singleton.
|
|
6
|
+
library;
|
|
7
|
+
|
|
8
|
+
import 'nomos_ref.dart';
|
|
9
|
+
|
|
10
|
+
/// An immutable publication pin together with the stable series that declares
|
|
11
|
+
/// which publication is current.
|
|
12
|
+
///
|
|
13
|
+
/// Nomos can check this reference in O(current state): it reads the series' one
|
|
14
|
+
/// compiled current-pointer field and compares that address with [pinned]. It
|
|
15
|
+
/// does not resolve [pinned], reconstruct history, or retain an index of every
|
|
16
|
+
/// version ever published.
|
|
17
|
+
final class VersionedNomosRef<TVersion, TSeries> {
|
|
18
|
+
final NomosRef<TVersion> pinned;
|
|
19
|
+
final NomosRef<TSeries> series;
|
|
20
|
+
final String _currentField;
|
|
21
|
+
|
|
22
|
+
const VersionedNomosRef._(this.pinned, this.series, this._currentField);
|
|
23
|
+
|
|
24
|
+
@override
|
|
25
|
+
bool operator ==(Object other) =>
|
|
26
|
+
other is VersionedNomosRef<TVersion, TSeries> &&
|
|
27
|
+
other.pinned == pinned &&
|
|
28
|
+
other.series == series;
|
|
29
|
+
|
|
30
|
+
@override
|
|
31
|
+
int get hashCode => Object.hash(pinned, series);
|
|
32
|
+
|
|
33
|
+
@override
|
|
34
|
+
String toString() => 'VersionedNomosRef<$TVersion, $TSeries>';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// The typed answer to a generated application's current-version check.
|
|
38
|
+
sealed class ReferenceFreshness<TVersion> {
|
|
39
|
+
const ReferenceFreshness();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// The pinned publication is still the series' current publication.
|
|
43
|
+
final class ReferenceCurrent<TVersion> extends ReferenceFreshness<TVersion> {
|
|
44
|
+
final NomosRef<TVersion> latest;
|
|
45
|
+
const ReferenceCurrent(this.latest);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// The series now points at [latest], while the reference remains pinned to an
|
|
49
|
+
/// older immutable publication.
|
|
50
|
+
final class ReferenceStale<TVersion> extends ReferenceFreshness<TVersion> {
|
|
51
|
+
final NomosRef<TVersion> latest;
|
|
52
|
+
const ReferenceStale(this.latest);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Nomos could not establish freshness without guessing (for example, the
|
|
56
|
+
/// series is not local, denied, missing, or does not satisfy the compiled law).
|
|
57
|
+
final class ReferenceFreshnessUnavailable<TVersion>
|
|
58
|
+
extends ReferenceFreshness<TVersion> {
|
|
59
|
+
final String reason;
|
|
60
|
+
const ReferenceFreshnessUnavailable(this.reason);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// Framework-only construction and wire access for generated implementation
|
|
64
|
+
/// code. Tenant code receives [VersionedNomosRef] and the required sum result.
|
|
65
|
+
abstract final class NmsInternalVersionedNomosRefs {
|
|
66
|
+
static VersionedNomosRef<TVersion, TSeries> create<TVersion, TSeries>({
|
|
67
|
+
required NomosRef<TVersion> pinned,
|
|
68
|
+
required NomosRef<TSeries> series,
|
|
69
|
+
required String currentField,
|
|
70
|
+
}) =>
|
|
71
|
+
VersionedNomosRef<TVersion, TSeries>._(
|
|
72
|
+
pinned,
|
|
73
|
+
series,
|
|
74
|
+
currentField,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
static String currentField<TVersion, TSeries>(
|
|
78
|
+
VersionedNomosRef<TVersion, TSeries> reference,
|
|
79
|
+
) =>
|
|
80
|
+
reference._currentField;
|
|
81
|
+
}
|
package/dart_types/pubspec.yaml
CHANGED
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
|
|
10
10
|
no runtime. The hand-written serde-JSON-compatible types plus the offer codec,
|
|
11
11
|
reactive read engine, schema validation, and data-only error/trace types.
|
|
12
|
-
version: 0.8.
|
|
12
|
+
version: 0.8.1
|
|
13
13
|
|
|
14
14
|
environment:
|
|
15
15
|
sdk: ^3.5.0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import 'package:nomos_types/nomos_types.dart';
|
|
2
|
+
import 'package:nomos_types/src/nomos_ref.dart' show NmsInternalNomosRefs;
|
|
3
|
+
import 'package:test/test.dart';
|
|
4
|
+
|
|
5
|
+
final class Site {}
|
|
6
|
+
|
|
7
|
+
void main() {
|
|
8
|
+
test('NomosOptionalRef requires an explicit absent or present choice', () {
|
|
9
|
+
const absent = NomosOptionalRef<Site>.absent();
|
|
10
|
+
final site = NmsInternalNomosRefs.create<Site>(
|
|
11
|
+
workspace: 'estate',
|
|
12
|
+
type: 'EstateSite',
|
|
13
|
+
id: 'site-1',
|
|
14
|
+
);
|
|
15
|
+
final present = NomosOptionalRef.present(site);
|
|
16
|
+
|
|
17
|
+
expect(absent.isAbsent, isTrue);
|
|
18
|
+
expect(absent.referenceOrNull, isNull);
|
|
19
|
+
expect(present.isPresent, isTrue);
|
|
20
|
+
expect(present.referenceOrNull, site);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('NomosOptionalRef omits absence and encodes presence', () {
|
|
24
|
+
final data = <String, Object?>{};
|
|
25
|
+
const NomosOptionalRef<Site>.absent().writeTo(
|
|
26
|
+
data,
|
|
27
|
+
'siteId',
|
|
28
|
+
NmsInternalNomosRefs.id,
|
|
29
|
+
);
|
|
30
|
+
expect(data, isEmpty);
|
|
31
|
+
|
|
32
|
+
final site = NmsInternalNomosRefs.create<Site>(
|
|
33
|
+
workspace: 'estate',
|
|
34
|
+
type: 'EstateSite',
|
|
35
|
+
id: 'site-1',
|
|
36
|
+
);
|
|
37
|
+
NomosOptionalRef.present(site).writeTo(
|
|
38
|
+
data,
|
|
39
|
+
'siteId',
|
|
40
|
+
NmsInternalNomosRefs.id,
|
|
41
|
+
);
|
|
42
|
+
expect(data, {'siteId': 'site-1'});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import 'package:nomos_types/nomos_types.dart';
|
|
2
|
+
import 'package:test/test.dart';
|
|
3
|
+
|
|
4
|
+
void main() {
|
|
5
|
+
test('accepts exactly 64 lowercase hexadecimal characters', () {
|
|
6
|
+
final digest = Sha256Digest('0123456789abcdef' * 4);
|
|
7
|
+
expect(digest.value, '0123456789abcdef' * 4);
|
|
8
|
+
expect(digest.toString(), digest.value);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('refuses malformed, uppercase, and incorrectly sized values', () {
|
|
12
|
+
expect(() => Sha256Digest('abc'), throwsFormatException);
|
|
13
|
+
expect(() => Sha256Digest('A' * 64), throwsFormatException);
|
|
14
|
+
expect(() => Sha256Digest('g' * 64), throwsFormatException);
|
|
15
|
+
expect(Sha256Digest.tryParse('0' * 64)?.value, '0' * 64);
|
|
16
|
+
expect(Sha256Digest.tryParse('0' * 63), isNull);
|
|
17
|
+
});
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@githolon/dsl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.0",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
|
|
6
7
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
7
8
|
"repository": {
|
|
@@ -16,21 +17,22 @@
|
|
|
16
17
|
},
|
|
17
18
|
"exports": {
|
|
18
19
|
".": "./src/index.ts",
|
|
19
|
-
"./manifest": "./src/manifest.ts",
|
|
20
20
|
"./stable-ids": "./src/stable_ids.ts",
|
|
21
21
|
"./compose": "./src/compose.ts",
|
|
22
|
-
"./usd": "./src/usd.ts",
|
|
23
|
-
"./usd-layers": "./src/usd_layers.ts",
|
|
24
22
|
"./application-composition": "./src/application_composition.ts",
|
|
25
23
|
"./usd-state": "./src/usd_state.ts",
|
|
26
24
|
"./engine-entry": "./src/engine_entry.ts",
|
|
25
|
+
"./compile-proof": {
|
|
26
|
+
"types": "./compile_proof.d.mts",
|
|
27
|
+
"default": "./compile_proof.mjs"
|
|
28
|
+
},
|
|
27
29
|
"./workspace-type": "./src/workspace_type.ts",
|
|
28
30
|
"./workspace-routing": "./src/workspace_routing.ts",
|
|
29
31
|
"./workspace-sharding": "./src/workspace_sharding.ts",
|
|
30
32
|
"./build-package": "./src/build_package.ts",
|
|
31
|
-
"./compile-engine": "./src/compile_engine.ts",
|
|
32
33
|
"./codegen-dart": "./src/codegen_dart.ts",
|
|
33
34
|
"./codegen-dot": "./src/codegen_dot.ts",
|
|
35
|
+
"./codegen-usda": "./src/codegen_usda.ts",
|
|
34
36
|
"./codegen-provider": "./src/codegen_provider_dart.ts",
|
|
35
37
|
"./framework/disclosure": "./src/framework/disclosure.ts",
|
|
36
38
|
"./framework/bootstrap": "./src/framework/bootstrap.ts",
|
|
@@ -51,6 +53,8 @@
|
|
|
51
53
|
"!dart_types/.dart_tool",
|
|
52
54
|
"!dart_types/build",
|
|
53
55
|
"runtime",
|
|
56
|
+
"compile_proof.mjs",
|
|
57
|
+
"compile_proof.d.mts",
|
|
54
58
|
"compile_package.mjs",
|
|
55
59
|
"check_package.mjs",
|
|
56
60
|
"compat_package.mjs",
|