@opetope/runtime 0.1.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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +345 -0
- package/README.ru.md +344 -0
- package/dist/application-compiler-edges.d.ts +3 -0
- package/dist/application-compiler-edges.js +2 -0
- package/dist/application-compiler-edges.js.map +1 -0
- package/dist/application-compiler-graph.d.ts +8 -0
- package/dist/application-compiler-graph.js +2 -0
- package/dist/application-compiler-graph.js.map +1 -0
- package/dist/application-compiler.d.ts +116 -0
- package/dist/application-compiler.js +2 -0
- package/dist/application-compiler.js.map +1 -0
- package/dist/application-conditions.d.ts +18 -0
- package/dist/application-conditions.js +2 -0
- package/dist/application-conditions.js.map +1 -0
- package/dist/application-definition.d.ts +30 -0
- package/dist/application-definition.js +2 -0
- package/dist/application-definition.js.map +1 -0
- package/dist/application-error.d.ts +10 -0
- package/dist/application-error.js +2 -0
- package/dist/application-error.js.map +1 -0
- package/dist/application-execution.d.ts +43 -0
- package/dist/application-execution.js +2 -0
- package/dist/application-execution.js.map +1 -0
- package/dist/application-feature-bindings.d.ts +11 -0
- package/dist/application-feature-bindings.js +2 -0
- package/dist/application-feature-bindings.js.map +1 -0
- package/dist/application-feature-instance.d.ts +5 -0
- package/dist/application-feature-instance.js +2 -0
- package/dist/application-feature-instance.js.map +1 -0
- package/dist/application-group-order.d.ts +29 -0
- package/dist/application-group-order.js +2 -0
- package/dist/application-group-order.js.map +1 -0
- package/dist/application-instance-retirement.d.ts +36 -0
- package/dist/application-instance-retirement.js +2 -0
- package/dist/application-instance-retirement.js.map +1 -0
- package/dist/application-open-options.d.ts +29 -0
- package/dist/application-open-options.js +2 -0
- package/dist/application-open-options.js.map +1 -0
- package/dist/application-port-compiler.d.ts +28 -0
- package/dist/application-port-compiler.js +2 -0
- package/dist/application-port-compiler.js.map +1 -0
- package/dist/attachment-call-declaration.d.ts +43 -0
- package/dist/attachment-call-declaration.js +2 -0
- package/dist/attachment-call-declaration.js.map +1 -0
- package/dist/attachment-declaration.d.ts +68 -0
- package/dist/attachment-declaration.js +2 -0
- package/dist/attachment-declaration.js.map +1 -0
- package/dist/attachment-execution.d.ts +9 -0
- package/dist/attachment-execution.js +2 -0
- package/dist/attachment-execution.js.map +1 -0
- package/dist/attachment-retirement-scheduler.d.ts +14 -0
- package/dist/attachment-retirement-scheduler.js +2 -0
- package/dist/attachment-retirement-scheduler.js.map +1 -0
- package/dist/call-option-snapshot.d.ts +20 -0
- package/dist/call-option-snapshot.js +2 -0
- package/dist/call-option-snapshot.js.map +1 -0
- package/dist/compile-call-target-bindings.d.ts +14 -0
- package/dist/compile-call-target-bindings.js +2 -0
- package/dist/compile-call-target-bindings.js.map +1 -0
- package/dist/compile-module-template.d.ts +38 -0
- package/dist/compile-module-template.js +2 -0
- package/dist/compile-module-template.js.map +1 -0
- package/dist/condition-group-execution.d.ts +44 -0
- package/dist/condition-group-execution.js +2 -0
- package/dist/condition-group-execution.js.map +1 -0
- package/dist/condition-override.d.ts +28 -0
- package/dist/condition-override.js +2 -0
- package/dist/condition-override.js.map +1 -0
- package/dist/condition-source.d.ts +10 -0
- package/dist/condition-source.js +2 -0
- package/dist/condition-source.js.map +1 -0
- package/dist/condition-types.d.ts +14 -0
- package/dist/condition.d.ts +28 -0
- package/dist/condition.js +2 -0
- package/dist/condition.js.map +1 -0
- package/dist/control-registry.d.ts +56 -0
- package/dist/control-registry.js +2 -0
- package/dist/control-registry.js.map +1 -0
- package/dist/dynamic-scope-child.d.ts +23 -0
- package/dist/dynamic-scope-child.js +2 -0
- package/dist/dynamic-scope-child.js.map +1 -0
- package/dist/dynamic-scope-controller.d.ts +16 -0
- package/dist/dynamic-scope-controller.js +2 -0
- package/dist/dynamic-scope-controller.js.map +1 -0
- package/dist/feature-attachment-authoring-types.d.ts +51 -0
- package/dist/feature-attachment-lowering.d.ts +18 -0
- package/dist/feature-attachment-lowering.js +2 -0
- package/dist/feature-attachment-lowering.js.map +1 -0
- package/dist/feature-attachment.d.ts +45 -0
- package/dist/feature-attachment.js +2 -0
- package/dist/feature-attachment.js.map +1 -0
- package/dist/feature-authoring-types.d.ts +196 -0
- package/dist/feature-authoring.d.ts +15 -0
- package/dist/feature-authoring.js +2 -0
- package/dist/feature-authoring.js.map +1 -0
- package/dist/feature-body.d.ts +53 -0
- package/dist/feature-body.js +2 -0
- package/dist/feature-body.js.map +1 -0
- package/dist/feature-call-authority.d.ts +8 -0
- package/dist/feature-call-authority.js +2 -0
- package/dist/feature-call-authority.js.map +1 -0
- package/dist/feature-call-types.d.ts +39 -0
- package/dist/feature-call.d.ts +18 -0
- package/dist/feature-call.js +2 -0
- package/dist/feature-call.js.map +1 -0
- package/dist/feature-calls.d.ts +6 -0
- package/dist/feature-calls.js +2 -0
- package/dist/feature-calls.js.map +1 -0
- package/dist/feature-contract.d.ts +70 -0
- package/dist/feature-contract.js +2 -0
- package/dist/feature-contract.js.map +1 -0
- package/dist/feature-contribution-model.d.ts +38 -0
- package/dist/feature-contribution-model.js +2 -0
- package/dist/feature-contribution-model.js.map +1 -0
- package/dist/feature-contribution.d.ts +126 -0
- package/dist/feature-contribution.js +2 -0
- package/dist/feature-contribution.js.map +1 -0
- package/dist/feature-definition-api.d.ts +53 -0
- package/dist/feature-definition-support.d.ts +21 -0
- package/dist/feature-definition-support.js +2 -0
- package/dist/feature-definition-support.js.map +1 -0
- package/dist/feature-effect.d.ts +26 -0
- package/dist/feature-effect.js +2 -0
- package/dist/feature-effect.js.map +1 -0
- package/dist/feature-event.d.ts +32 -0
- package/dist/feature-event.js +2 -0
- package/dist/feature-event.js.map +1 -0
- package/dist/feature-generation.d.ts +34 -0
- package/dist/feature-generation.js +2 -0
- package/dist/feature-generation.js.map +1 -0
- package/dist/feature-lazy-generation.d.ts +6 -0
- package/dist/feature-lazy-generation.js +2 -0
- package/dist/feature-lazy-generation.js.map +1 -0
- package/dist/feature-lazy.d.ts +44 -0
- package/dist/feature-lazy.js +2 -0
- package/dist/feature-lazy.js.map +1 -0
- package/dist/feature-materialization-binding.d.ts +31 -0
- package/dist/feature-materialization-binding.js +2 -0
- package/dist/feature-materialization-binding.js.map +1 -0
- package/dist/feature-materialization-types.d.ts +45 -0
- package/dist/feature-model-dependencies.d.ts +23 -0
- package/dist/feature-model-dependencies.js +2 -0
- package/dist/feature-model-dependencies.js.map +1 -0
- package/dist/feature-model.d.ts +60 -0
- package/dist/feature-model.js +2 -0
- package/dist/feature-model.js.map +1 -0
- package/dist/feature-optional.d.ts +15 -0
- package/dist/feature-optional.js +2 -0
- package/dist/feature-optional.js.map +1 -0
- package/dist/feature-own-lowering.d.ts +22 -0
- package/dist/feature-own-lowering.js +2 -0
- package/dist/feature-own-lowering.js.map +1 -0
- package/dist/feature-port-binding.d.ts +6 -0
- package/dist/feature-port-binding.js +2 -0
- package/dist/feature-port-binding.js.map +1 -0
- package/dist/feature-port.d.ts +66 -0
- package/dist/feature-port.js +2 -0
- package/dist/feature-port.js.map +1 -0
- package/dist/feature-record.d.ts +6 -0
- package/dist/feature-record.js +2 -0
- package/dist/feature-record.js.map +1 -0
- package/dist/feature-resource.d.ts +29 -0
- package/dist/feature-resource.js +2 -0
- package/dist/feature-resource.js.map +1 -0
- package/dist/feature-scope-types.d.ts +35 -0
- package/dist/feature-scope.d.ts +29 -0
- package/dist/feature-scope.js +2 -0
- package/dist/feature-scope.js.map +1 -0
- package/dist/feature-stream.d.ts +37 -0
- package/dist/feature-stream.js +2 -0
- package/dist/feature-stream.js.map +1 -0
- package/dist/feature-timers.d.ts +14 -0
- package/dist/feature-timers.js +2 -0
- package/dist/feature-timers.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/inspection-activity-protocol.d.ts +63 -0
- package/dist/inspection-activity.d.ts +54 -0
- package/dist/inspection-activity.js +2 -0
- package/dist/inspection-activity.js.map +1 -0
- package/dist/inspection-diff.d.ts +10 -0
- package/dist/inspection-diff.js +2 -0
- package/dist/inspection-diff.js.map +1 -0
- package/dist/inspection-module-activity.d.ts +4 -0
- package/dist/inspection-module-activity.js +2 -0
- package/dist/inspection-module-activity.js.map +1 -0
- package/dist/inspection-observer.d.ts +38 -0
- package/dist/inspection-observer.js +2 -0
- package/dist/inspection-observer.js.map +1 -0
- package/dist/inspection-plan.d.ts +33 -0
- package/dist/inspection-plan.js +2 -0
- package/dist/inspection-plan.js.map +1 -0
- package/dist/inspection-protocol.d.ts +333 -0
- package/dist/inspection-protocol.js +2 -0
- package/dist/inspection-protocol.js.map +1 -0
- package/dist/inspection-registry.d.ts +41 -0
- package/dist/inspection-registry.js +2 -0
- package/dist/inspection-registry.js.map +1 -0
- package/dist/inspection-session.d.ts +92 -0
- package/dist/inspection-session.js +2 -0
- package/dist/inspection-session.js.map +1 -0
- package/dist/inspection-snapshot.d.ts +4 -0
- package/dist/inspection-snapshot.js +2 -0
- package/dist/inspection-snapshot.js.map +1 -0
- package/dist/inspection-state.d.ts +91 -0
- package/dist/inspection-state.js +2 -0
- package/dist/inspection-state.js.map +1 -0
- package/dist/instance-demand.d.ts +31 -0
- package/dist/instance-demand.js +2 -0
- package/dist/instance-demand.js.map +1 -0
- package/dist/internal.d.ts +41 -0
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -0
- package/dist/keyed-scope-controller.d.ts +11 -0
- package/dist/keyed-scope-controller.js +2 -0
- package/dist/keyed-scope-controller.js.map +1 -0
- package/dist/model-kernel.d.ts +18 -0
- package/dist/model-kernel.js +2 -0
- package/dist/model-kernel.js.map +1 -0
- package/dist/module-call-context.d.ts +7 -0
- package/dist/module-call-context.js +2 -0
- package/dist/module-call-context.js.map +1 -0
- package/dist/module-call-runtime.d.ts +21 -0
- package/dist/module-call-runtime.js +2 -0
- package/dist/module-call-runtime.js.map +1 -0
- package/dist/module-generation.d.ts +57 -0
- package/dist/module-generation.js +2 -0
- package/dist/module-generation.js.map +1 -0
- package/dist/module-instance-types.d.ts +156 -0
- package/dist/module-instance.d.ts +19 -0
- package/dist/module-instance.js +2 -0
- package/dist/module-instance.js.map +1 -0
- package/dist/module-runtime-identity.d.ts +4 -0
- package/dist/module-runtime-identity.js +2 -0
- package/dist/module-runtime-identity.js.map +1 -0
- package/dist/module-scope-open.d.ts +4 -0
- package/dist/module-scope-open.js +2 -0
- package/dist/module-scope-open.js.map +1 -0
- package/dist/module-scope-retirement.d.ts +3 -0
- package/dist/module-scope-retirement.js +2 -0
- package/dist/module-scope-retirement.js.map +1 -0
- package/dist/module-template-ir.d.ts +59 -0
- package/dist/owner-generation-retirement.d.ts +6 -0
- package/dist/owner-generation-retirement.js +2 -0
- package/dist/owner-generation-retirement.js.map +1 -0
- package/dist/owner-generation-state.d.ts +123 -0
- package/dist/owner-generation-state.js +2 -0
- package/dist/owner-generation-state.js.map +1 -0
- package/dist/owner-generation.d.ts +16 -0
- package/dist/owner-generation.js +2 -0
- package/dist/owner-generation.js.map +1 -0
- package/dist/public-module-definition.d.ts +9 -0
- package/dist/public-module-definition.js +2 -0
- package/dist/public-module-definition.js.map +1 -0
- package/dist/public-module-instance.d.ts +6 -0
- package/dist/public-module-instance.js +2 -0
- package/dist/public-module-instance.js.map +1 -0
- package/dist/public-module-retirement-diagnostics.d.ts +5 -0
- package/dist/public-module-retirement-diagnostics.js +2 -0
- package/dist/public-module-retirement-diagnostics.js.map +1 -0
- package/dist/public-module-retirement.d.ts +3 -0
- package/dist/public-module-retirement.js +2 -0
- package/dist/public-module-retirement.js.map +1 -0
- package/dist/public-module-scope.d.ts +5 -0
- package/dist/public-module-scope.js +2 -0
- package/dist/public-module-scope.js.map +1 -0
- package/dist/public-module-state.d.ts +28 -0
- package/dist/public-module-state.js +2 -0
- package/dist/public-module-state.js.map +1 -0
- package/dist/public-module-types.d.ts +295 -0
- package/dist/public-module.d.ts +4 -0
- package/dist/resource-cache.d.ts +12 -0
- package/dist/resource-cache.js +2 -0
- package/dist/resource-cache.js.map +1 -0
- package/dist/resource-controller.d.ts +29 -0
- package/dist/resource-controller.js +2 -0
- package/dist/resource-controller.js.map +1 -0
- package/dist/resource-policy.d.ts +16 -0
- package/dist/resource-policy.js +2 -0
- package/dist/resource-policy.js.map +1 -0
- package/dist/resource-snapshot.d.ts +12 -0
- package/dist/resource-snapshot.js +2 -0
- package/dist/resource-snapshot.js.map +1 -0
- package/dist/resource-types.d.ts +3 -0
- package/dist/runtime-error-reporting.d.ts +4 -0
- package/dist/runtime-error-reporting.js +2 -0
- package/dist/runtime-error-reporting.js.map +1 -0
- package/dist/stream-backpressure.d.ts +18 -0
- package/dist/stream-backpressure.js +2 -0
- package/dist/stream-backpressure.js.map +1 -0
- package/dist/stream-cleanup.d.ts +17 -0
- package/dist/stream-cleanup.js +2 -0
- package/dist/stream-cleanup.js.map +1 -0
- package/dist/stream-controller-types.d.ts +51 -0
- package/dist/stream-controller.d.ts +5 -0
- package/dist/stream-controller.js +2 -0
- package/dist/stream-controller.js.map +1 -0
- package/docs/agent-guide.md +214 -0
- package/docs/agent-guide.ru.md +208 -0
- package/docs/cookbook.md +734 -0
- package/docs/cookbook.ru.md +729 -0
- package/docs/decisions.md +1437 -0
- package/docs/devtools.md +423 -0
- package/docs/devtools.ru.md +419 -0
- package/docs/how-it-works.md +521 -0
- package/docs/how-it-works.ru.md +495 -0
- package/docs/releases.md +78 -0
- package/docs/releases.ru.md +78 -0
- package/docs/spec.md +874 -0
- package/docs/spec.ru.md +884 -0
- package/package.json +72 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The data the observation port of `docs/devtools.md` §3.3 publishes.
|
|
3
|
+
*
|
|
4
|
+
* These types are *implemented*, not imported: `@opetope/runtime` never depends on `@opetope/devtools` (`docs/devtools.md` §4), so the
|
|
5
|
+
* shapes are declared here and the match is checked structurally by a test. Ids stay plain strings on this side —
|
|
6
|
+
* the consumer brands them, and a brand is nominal, so the runtime cannot and should not mint one.
|
|
7
|
+
*
|
|
8
|
+
* The protocol is data-only (`docs/devtools.md` §6): no callbacks, no `FeatureInstance`, no model, resource or `Error` object, and no
|
|
9
|
+
* product value of any kind. A failure travels as the subject and the code of the runtime's own error classes.
|
|
10
|
+
*/
|
|
11
|
+
import type { RuntimeActivitySnapshot } from './inspection-activity-protocol.js';
|
|
12
|
+
type DiagnosticNodeId = string;
|
|
13
|
+
type DiagnosticEdgeId = string;
|
|
14
|
+
type DiagnosticConditionId = string;
|
|
15
|
+
type DiagnosticSequence = number;
|
|
16
|
+
type DiagnosticStateRevision = number;
|
|
17
|
+
/** Epoch milliseconds of a trigger. The only clock in the protocol: a commit itself is never stamped (T1). */
|
|
18
|
+
type DiagnosticTimestamp = number;
|
|
19
|
+
type DiagnosticPhase = 'close' | 'drain' | 'fence' | 'open' | 'retry' | 'rollback';
|
|
20
|
+
type DiagnosticFailureCode = Readonly<{
|
|
21
|
+
code: 'binding-invalid' | 'duplicate' | 'inactive' | 'missing';
|
|
22
|
+
subject: 'contribution';
|
|
23
|
+
}> | Readonly<{
|
|
24
|
+
code: 'cancelled' | 'closed' | 'publication-rejected' | 'unavailable';
|
|
25
|
+
subject: 'call';
|
|
26
|
+
}> | Readonly<{
|
|
27
|
+
code: 'cleanup-failed' | 'not-ready' | 'quarantined' | 'retired';
|
|
28
|
+
subject: 'feature';
|
|
29
|
+
}> | Readonly<{
|
|
30
|
+
code: 'closed';
|
|
31
|
+
subject: 'application';
|
|
32
|
+
}> | Readonly<{
|
|
33
|
+
code: 'closed';
|
|
34
|
+
subject: 'readable';
|
|
35
|
+
}> | Readonly<{
|
|
36
|
+
code: 'invalid-id';
|
|
37
|
+
subject: 'declaration';
|
|
38
|
+
}>;
|
|
39
|
+
type DiagnosticFailure = DiagnosticFailureCode & Readonly<{
|
|
40
|
+
cause?: DiagnosticCauseRef;
|
|
41
|
+
phase: DiagnosticPhase;
|
|
42
|
+
}>;
|
|
43
|
+
type DiagnosticCauseKind = 'activity-change' | 'condition-change' | 'contribution-change' | 'control-command' | 'failure' | 'group-transition' | 'instance-transition' | 'plan-replacement' | 'session-reset';
|
|
44
|
+
type DiagnosticCauseRef = Readonly<{
|
|
45
|
+
at?: DiagnosticTimestamp;
|
|
46
|
+
condition?: DiagnosticConditionId;
|
|
47
|
+
kind: DiagnosticCauseKind;
|
|
48
|
+
node?: DiagnosticNodeId;
|
|
49
|
+
sequence?: DiagnosticSequence;
|
|
50
|
+
}>;
|
|
51
|
+
type DiagnosticClosedReason = 'application-closed' | 'condition-inactive' | 'debug-override' | 'plan-replacement' | 'retired';
|
|
52
|
+
type DiagnosticWaitReason = 'awaiting-condition' | 'awaiting-hard-import' | 'awaiting-port' | 'awaiting-turn';
|
|
53
|
+
type DesiredAxis = 'active' | 'inactive';
|
|
54
|
+
type DiagnosticDesiredState = Readonly<{
|
|
55
|
+
effective: DesiredAxis;
|
|
56
|
+
override: 'force-inactive' | 'none';
|
|
57
|
+
source: DesiredAxis;
|
|
58
|
+
}>;
|
|
59
|
+
type ConditionState = Readonly<{
|
|
60
|
+
kind: 'false';
|
|
61
|
+
}> | Readonly<{
|
|
62
|
+
kind: 'source-closed';
|
|
63
|
+
}> | Readonly<{
|
|
64
|
+
kind: 'true';
|
|
65
|
+
}>;
|
|
66
|
+
type ConditionGroupState = Readonly<{
|
|
67
|
+
failure: DiagnosticFailure;
|
|
68
|
+
kind: 'failed';
|
|
69
|
+
}> | Readonly<{
|
|
70
|
+
kind: 'active';
|
|
71
|
+
}> | Readonly<{
|
|
72
|
+
kind: 'closed';
|
|
73
|
+
}> | Readonly<{
|
|
74
|
+
kind: 'inactive';
|
|
75
|
+
reason: DiagnosticClosedReason;
|
|
76
|
+
}> | Readonly<{
|
|
77
|
+
kind: 'opening';
|
|
78
|
+
opened: number;
|
|
79
|
+
total: number;
|
|
80
|
+
}> | Readonly<{
|
|
81
|
+
kind: 'retiring';
|
|
82
|
+
remaining: number;
|
|
83
|
+
}>;
|
|
84
|
+
type FeatureInstanceState = Readonly<{
|
|
85
|
+
blockedBy: readonly DiagnosticNodeId[];
|
|
86
|
+
kind: 'waiting';
|
|
87
|
+
reason: DiagnosticWaitReason;
|
|
88
|
+
}> | Readonly<{
|
|
89
|
+
failure: DiagnosticFailure;
|
|
90
|
+
kind: 'cleanup-failed';
|
|
91
|
+
}> | Readonly<{
|
|
92
|
+
failure: DiagnosticFailure;
|
|
93
|
+
kind: 'not-ready';
|
|
94
|
+
}> | Readonly<{
|
|
95
|
+
failure: DiagnosticFailure;
|
|
96
|
+
kind: 'quarantined';
|
|
97
|
+
}> | Readonly<{
|
|
98
|
+
kind: 'draining';
|
|
99
|
+
}> | Readonly<{
|
|
100
|
+
kind: 'fencing';
|
|
101
|
+
}> | Readonly<{
|
|
102
|
+
kind: 'opening';
|
|
103
|
+
}> | Readonly<{
|
|
104
|
+
kind: 'ready';
|
|
105
|
+
}> | Readonly<{
|
|
106
|
+
kind: 'retired';
|
|
107
|
+
reason: DiagnosticClosedReason;
|
|
108
|
+
}>;
|
|
109
|
+
type ContributionState = Readonly<{
|
|
110
|
+
failure: DiagnosticFailure;
|
|
111
|
+
kind: 'rejected';
|
|
112
|
+
}> | Readonly<{
|
|
113
|
+
kind: 'pending';
|
|
114
|
+
}> | Readonly<{
|
|
115
|
+
kind: 'published';
|
|
116
|
+
}> | Readonly<{
|
|
117
|
+
kind: 'withdrawn';
|
|
118
|
+
}> | Readonly<{
|
|
119
|
+
kind: 'withheld';
|
|
120
|
+
}>;
|
|
121
|
+
type PortState = Readonly<{
|
|
122
|
+
instance: DiagnosticNodeId;
|
|
123
|
+
kind: 'available';
|
|
124
|
+
}> | Readonly<{
|
|
125
|
+
kind: 'absent';
|
|
126
|
+
}> | Readonly<{
|
|
127
|
+
kind: 'unavailable';
|
|
128
|
+
provider: DiagnosticNodeId;
|
|
129
|
+
}>;
|
|
130
|
+
type HostContractState = Readonly<{
|
|
131
|
+
kind: 'bound';
|
|
132
|
+
}> | Readonly<{
|
|
133
|
+
kind: 'deferred';
|
|
134
|
+
}> | Readonly<{
|
|
135
|
+
kind: 'unbound';
|
|
136
|
+
}>;
|
|
137
|
+
type HardEdgeKind = 'hard-import' | 'requires-port';
|
|
138
|
+
type WeakEdgeKind = 'absent-import' | 'absent-port' | 'optional-import' | 'optional-port';
|
|
139
|
+
type StructuralEdgeKind = 'condition-control' | 'contributes-to' | 'on-demand-import' | 'owns' | 'provides-port';
|
|
140
|
+
type WeakEdgeState = 'found' | 'missing';
|
|
141
|
+
type DiagnosticEdgeBase = Readonly<{
|
|
142
|
+
from: DiagnosticNodeId;
|
|
143
|
+
id: DiagnosticEdgeId;
|
|
144
|
+
to: DiagnosticNodeId;
|
|
145
|
+
}>;
|
|
146
|
+
type DiagnosticEdge = (DiagnosticEdgeBase & Readonly<{
|
|
147
|
+
kind: HardEdgeKind;
|
|
148
|
+
pending: boolean;
|
|
149
|
+
}>) | (DiagnosticEdgeBase & Readonly<{
|
|
150
|
+
kind: StructuralEdgeKind;
|
|
151
|
+
}>) | (DiagnosticEdgeBase & Readonly<{
|
|
152
|
+
kind: WeakEdgeKind;
|
|
153
|
+
lookup: WeakEdgeState;
|
|
154
|
+
}>);
|
|
155
|
+
type PlanNodeBase = Readonly<{
|
|
156
|
+
id: DiagnosticNodeId;
|
|
157
|
+
label: string;
|
|
158
|
+
provenance?: string;
|
|
159
|
+
}>;
|
|
160
|
+
type ApplicationPlanNode = PlanNodeBase & Readonly<{
|
|
161
|
+
features: number;
|
|
162
|
+
groups: number;
|
|
163
|
+
kind: 'application';
|
|
164
|
+
}>;
|
|
165
|
+
type ConditionPlanNode = PlanNodeBase & Readonly<{
|
|
166
|
+
conditionId: DiagnosticConditionId;
|
|
167
|
+
kind: 'condition';
|
|
168
|
+
source: DiagnosticNodeId | 'host';
|
|
169
|
+
}>;
|
|
170
|
+
type ConditionGroupPlanNode = PlanNodeBase & Readonly<{
|
|
171
|
+
conditions: readonly DiagnosticConditionId[];
|
|
172
|
+
kind: 'condition-group';
|
|
173
|
+
order: readonly DiagnosticNodeId[];
|
|
174
|
+
}>;
|
|
175
|
+
type FeaturePlanNode = PlanNodeBase & Readonly<{
|
|
176
|
+
kind: 'feature';
|
|
177
|
+
owner: DiagnosticNodeId;
|
|
178
|
+
}>;
|
|
179
|
+
type PortPlanNode = PlanNodeBase & Readonly<{
|
|
180
|
+
kind: 'port';
|
|
181
|
+
provider?: DiagnosticNodeId;
|
|
182
|
+
}>;
|
|
183
|
+
type HostContractPlanNode = PlanNodeBase & Readonly<{
|
|
184
|
+
demand: 'instance' | 'onDemand';
|
|
185
|
+
kind: 'host-contract';
|
|
186
|
+
optional: boolean;
|
|
187
|
+
}>;
|
|
188
|
+
type AbsentProviderPlanNode = PlanNodeBase & Readonly<{
|
|
189
|
+
kind: 'absent-provider';
|
|
190
|
+
}>;
|
|
191
|
+
type ContributionTargetPlanNode = PlanNodeBase & Readonly<{
|
|
192
|
+
kind: 'contribution-target';
|
|
193
|
+
}>;
|
|
194
|
+
type ContributionPlanNode = PlanNodeBase & Readonly<{
|
|
195
|
+
contributor: DiagnosticNodeId;
|
|
196
|
+
kind: 'contribution';
|
|
197
|
+
priority: number;
|
|
198
|
+
target: DiagnosticNodeId;
|
|
199
|
+
}>;
|
|
200
|
+
type ApplicationPlanSnapshot = Readonly<{
|
|
201
|
+
absentProviders: readonly AbsentProviderPlanNode[];
|
|
202
|
+
application: ApplicationPlanNode;
|
|
203
|
+
conditions: readonly ConditionPlanNode[];
|
|
204
|
+
contributions: readonly ContributionPlanNode[];
|
|
205
|
+
edges: readonly DiagnosticEdge[];
|
|
206
|
+
features: readonly FeaturePlanNode[];
|
|
207
|
+
groups: readonly ConditionGroupPlanNode[];
|
|
208
|
+
hostContracts: readonly HostContractPlanNode[];
|
|
209
|
+
ports: readonly PortPlanNode[];
|
|
210
|
+
targets: readonly ContributionTargetPlanNode[];
|
|
211
|
+
}>;
|
|
212
|
+
type RuntimeNodeBase = Readonly<{
|
|
213
|
+
cause?: DiagnosticCauseRef;
|
|
214
|
+
declaration?: DiagnosticNodeId;
|
|
215
|
+
id: DiagnosticNodeId;
|
|
216
|
+
label: string;
|
|
217
|
+
}>;
|
|
218
|
+
type ConditionRuntimeNode = Readonly<{
|
|
219
|
+
kind: 'condition';
|
|
220
|
+
state: ConditionState;
|
|
221
|
+
}> & RuntimeNodeBase;
|
|
222
|
+
type ConditionGroupRuntimeNode = Readonly<{
|
|
223
|
+
desired: DiagnosticDesiredState;
|
|
224
|
+
kind: 'condition-group';
|
|
225
|
+
state: ConditionGroupState;
|
|
226
|
+
}> & RuntimeNodeBase;
|
|
227
|
+
type FeatureInstanceNode = Readonly<{
|
|
228
|
+
generation: number;
|
|
229
|
+
group?: DiagnosticNodeId;
|
|
230
|
+
kind: 'feature-instance';
|
|
231
|
+
previous?: number;
|
|
232
|
+
state: FeatureInstanceState;
|
|
233
|
+
}> & RuntimeNodeBase;
|
|
234
|
+
type AttachmentNode = Readonly<{
|
|
235
|
+
kind: 'attachment';
|
|
236
|
+
owner: DiagnosticNodeId;
|
|
237
|
+
state: AttachmentState;
|
|
238
|
+
}> & RuntimeNodeBase;
|
|
239
|
+
type AttachmentState = Readonly<{
|
|
240
|
+
failure: DiagnosticFailure;
|
|
241
|
+
kind: 'failed-close';
|
|
242
|
+
}> | Readonly<{
|
|
243
|
+
kind: 'closed';
|
|
244
|
+
}> | Readonly<{
|
|
245
|
+
kind: 'closing';
|
|
246
|
+
phase: 'close' | 'retry' | 'rollback';
|
|
247
|
+
}> | Readonly<{
|
|
248
|
+
kind: 'opening';
|
|
249
|
+
}> | Readonly<{
|
|
250
|
+
kind: 'ready';
|
|
251
|
+
}>;
|
|
252
|
+
type ContributionRuntimeNode = Readonly<{
|
|
253
|
+
contributor: DiagnosticNodeId;
|
|
254
|
+
kind: 'contribution';
|
|
255
|
+
state: ContributionState;
|
|
256
|
+
target: DiagnosticNodeId;
|
|
257
|
+
}> & RuntimeNodeBase;
|
|
258
|
+
type PortRuntimeNode = Readonly<{
|
|
259
|
+
kind: 'port';
|
|
260
|
+
state: PortState;
|
|
261
|
+
}> & RuntimeNodeBase;
|
|
262
|
+
type HostContractRuntimeNode = Readonly<{
|
|
263
|
+
kind: 'host-contract';
|
|
264
|
+
state: HostContractState;
|
|
265
|
+
}> & RuntimeNodeBase;
|
|
266
|
+
type DiagnosticRuntimeNode = AttachmentNode | ConditionGroupRuntimeNode | ConditionRuntimeNode | ContributionRuntimeNode | FeatureInstanceNode | HostContractRuntimeNode | PortRuntimeNode;
|
|
267
|
+
type RuntimeStateSnapshot = Readonly<{
|
|
268
|
+
attachments: readonly AttachmentNode[];
|
|
269
|
+
conditions: readonly ConditionRuntimeNode[];
|
|
270
|
+
contributions: readonly ContributionRuntimeNode[];
|
|
271
|
+
edges: readonly DiagnosticEdge[];
|
|
272
|
+
groups: readonly ConditionGroupRuntimeNode[];
|
|
273
|
+
hostContracts: readonly HostContractRuntimeNode[];
|
|
274
|
+
instances: readonly FeatureInstanceNode[];
|
|
275
|
+
ports: readonly PortRuntimeNode[];
|
|
276
|
+
}>;
|
|
277
|
+
declare const graphSchemaRevision = "opetope.devtools-graph/3";
|
|
278
|
+
declare const frameSchemaRevision = "opetope.devtools-frame/3";
|
|
279
|
+
type RuntimeGraphSnapshot = Readonly<{
|
|
280
|
+
activity?: RuntimeActivitySnapshot;
|
|
281
|
+
lastSequence: DiagnosticSequence;
|
|
282
|
+
plan: ApplicationPlanSnapshot;
|
|
283
|
+
planFingerprint: string;
|
|
284
|
+
runtime: RuntimeStateSnapshot;
|
|
285
|
+
schemaRevision: typeof graphSchemaRevision;
|
|
286
|
+
sessionId: string;
|
|
287
|
+
stateRevision: DiagnosticStateRevision;
|
|
288
|
+
topologyRevision: number;
|
|
289
|
+
}>;
|
|
290
|
+
type DiagnosticOperation = Readonly<{
|
|
291
|
+
edge: DiagnosticEdge;
|
|
292
|
+
op: 'upsert-edge';
|
|
293
|
+
}> | Readonly<{
|
|
294
|
+
id: DiagnosticEdgeId;
|
|
295
|
+
op: 'remove-edge';
|
|
296
|
+
}> | Readonly<{
|
|
297
|
+
id: DiagnosticNodeId;
|
|
298
|
+
op: 'remove-node';
|
|
299
|
+
}> | Readonly<{
|
|
300
|
+
node: DiagnosticRuntimeNode;
|
|
301
|
+
op: 'upsert-node';
|
|
302
|
+
}>;
|
|
303
|
+
type RuntimeGraphFrame = Readonly<{
|
|
304
|
+
activity?: RuntimeActivitySnapshot;
|
|
305
|
+
baseRevision: DiagnosticStateRevision;
|
|
306
|
+
cause?: DiagnosticCauseRef;
|
|
307
|
+
firstSequence: DiagnosticSequence;
|
|
308
|
+
lastSequence: DiagnosticSequence;
|
|
309
|
+
nextRevision: DiagnosticStateRevision;
|
|
310
|
+
operations: readonly DiagnosticOperation[];
|
|
311
|
+
schemaRevision: typeof frameSchemaRevision;
|
|
312
|
+
sessionId: string;
|
|
313
|
+
}>;
|
|
314
|
+
type ReadLimits = Readonly<{
|
|
315
|
+
maxBytes: number;
|
|
316
|
+
maxFrames: number;
|
|
317
|
+
}>;
|
|
318
|
+
type ReadResult = Readonly<{
|
|
319
|
+
frames: readonly RuntimeGraphFrame[];
|
|
320
|
+
kind: 'changes';
|
|
321
|
+
}> | Readonly<{
|
|
322
|
+
kind: 'resync-required';
|
|
323
|
+
snapshot: RuntimeGraphSnapshot;
|
|
324
|
+
}>;
|
|
325
|
+
/** The port itself (`docs/devtools.md` §3.3): pull by cursor, notify only, and a close that stops the client and not the application. */
|
|
326
|
+
interface RuntimeInspectionSession {
|
|
327
|
+
close(): void;
|
|
328
|
+
getSnapshot(): RuntimeGraphSnapshot;
|
|
329
|
+
readSince(cursor: DiagnosticSequence, limits: ReadLimits): ReadResult;
|
|
330
|
+
subscribe(listener: () => void): () => void;
|
|
331
|
+
}
|
|
332
|
+
export { frameSchemaRevision, graphSchemaRevision };
|
|
333
|
+
export type { AbsentProviderPlanNode, ApplicationPlanSnapshot, ConditionGroupPlanNode, ConditionGroupRuntimeNode, ConditionGroupState, ConditionPlanNode, ConditionRuntimeNode, ContributionPlanNode, ContributionRuntimeNode, ContributionState, ContributionTargetPlanNode, DesiredAxis, DiagnosticCauseRef, DiagnosticConditionId, DiagnosticEdge, DiagnosticEdgeId, DiagnosticFailure, DiagnosticNodeId, DiagnosticOperation, DiagnosticPhase, DiagnosticRuntimeNode, DiagnosticSequence, FeatureInstanceNode, FeatureInstanceState, FeaturePlanNode, HostContractPlanNode, HostContractRuntimeNode, HostContractState, PortPlanNode, PortRuntimeNode, PortState, ReadLimits, ReadResult, RuntimeGraphFrame, RuntimeGraphSnapshot, RuntimeInspectionSession, RuntimeStateSnapshot, WeakEdgeState, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection-protocol.js","sources":["../src/inspection-protocol.ts"],"sourcesContent":["/**\n * The data the observation port of `docs/devtools.md` §3.3 publishes.\n *\n * These types are *implemented*, not imported: `@opetope/runtime` never depends on `@opetope/devtools` (`docs/devtools.md` §4), so the\n * shapes are declared here and the match is checked structurally by a test. Ids stay plain strings on this side —\n * the consumer brands them, and a brand is nominal, so the runtime cannot and should not mint one.\n *\n * The protocol is data-only (`docs/devtools.md` §6): no callbacks, no `FeatureInstance`, no model, resource or `Error` object, and no\n * product value of any kind. A failure travels as the subject and the code of the runtime's own error classes.\n */\n\nimport type { RuntimeActivitySnapshot } from './inspection-activity-protocol';\n\ntype DiagnosticNodeId = string;\ntype DiagnosticEdgeId = string;\ntype DiagnosticConditionId = string;\ntype DiagnosticSequence = number;\ntype DiagnosticStateRevision = number;\n\n/** Epoch milliseconds of a trigger. The only clock in the protocol: a commit itself is never stamped (T1). */\ntype DiagnosticTimestamp = number;\n\ntype DiagnosticPhase = 'close' | 'drain' | 'fence' | 'open' | 'retry' | 'rollback';\n\ntype DiagnosticFailureCode =\n | Readonly<{ code: 'binding-invalid' | 'duplicate' | 'inactive' | 'missing'; subject: 'contribution' }>\n | Readonly<{ code: 'cancelled' | 'closed' | 'publication-rejected' | 'unavailable'; subject: 'call' }>\n | Readonly<{ code: 'cleanup-failed' | 'not-ready' | 'quarantined' | 'retired'; subject: 'feature' }>\n | Readonly<{ code: 'closed'; subject: 'application' }>\n | Readonly<{ code: 'closed'; subject: 'readable' }>\n | Readonly<{ code: 'invalid-id'; subject: 'declaration' }>;\n\ntype DiagnosticFailure = DiagnosticFailureCode & Readonly<{ cause?: DiagnosticCauseRef; phase: DiagnosticPhase }>;\n\ntype DiagnosticCauseKind =\n | 'activity-change'\n | 'condition-change'\n | 'contribution-change'\n | 'control-command'\n | 'failure'\n | 'group-transition'\n | 'instance-transition'\n | 'plan-replacement'\n | 'session-reset';\n\ntype DiagnosticCauseRef = Readonly<{\n at?: DiagnosticTimestamp;\n condition?: DiagnosticConditionId;\n kind: DiagnosticCauseKind;\n node?: DiagnosticNodeId;\n sequence?: DiagnosticSequence;\n}>;\n\ntype DiagnosticClosedReason =\n | 'application-closed'\n | 'condition-inactive'\n | 'debug-override'\n | 'plan-replacement'\n | 'retired';\n\ntype DiagnosticWaitReason = 'awaiting-condition' | 'awaiting-hard-import' | 'awaiting-port' | 'awaiting-turn';\n\ntype DesiredAxis = 'active' | 'inactive';\n\ntype DiagnosticDesiredState = Readonly<{\n effective: DesiredAxis;\n override: 'force-inactive' | 'none';\n source: DesiredAxis;\n}>;\n\ntype ConditionState = Readonly<{ kind: 'false' }> | Readonly<{ kind: 'source-closed' }> | Readonly<{ kind: 'true' }>;\n\ntype ConditionGroupState =\n | Readonly<{ failure: DiagnosticFailure; kind: 'failed' }>\n | Readonly<{ kind: 'active' }>\n | Readonly<{ kind: 'closed' }>\n | Readonly<{ kind: 'inactive'; reason: DiagnosticClosedReason }>\n | Readonly<{ kind: 'opening'; opened: number; total: number }>\n | Readonly<{ kind: 'retiring'; remaining: number }>;\n\ntype FeatureInstanceState =\n | Readonly<{ blockedBy: readonly DiagnosticNodeId[]; kind: 'waiting'; reason: DiagnosticWaitReason }>\n | Readonly<{ failure: DiagnosticFailure; kind: 'cleanup-failed' }>\n | Readonly<{ failure: DiagnosticFailure; kind: 'not-ready' }>\n | Readonly<{ failure: DiagnosticFailure; kind: 'quarantined' }>\n | Readonly<{ kind: 'draining' }>\n | Readonly<{ kind: 'fencing' }>\n | Readonly<{ kind: 'opening' }>\n | Readonly<{ kind: 'ready' }>\n | Readonly<{ kind: 'retired'; reason: DiagnosticClosedReason }>;\n\ntype ContributionState =\n | Readonly<{ failure: DiagnosticFailure; kind: 'rejected' }>\n | Readonly<{ kind: 'pending' }>\n | Readonly<{ kind: 'published' }>\n | Readonly<{ kind: 'withdrawn' }>\n | Readonly<{ kind: 'withheld' }>;\n\ntype PortState =\n | Readonly<{ instance: DiagnosticNodeId; kind: 'available' }>\n | Readonly<{ kind: 'absent' }>\n | Readonly<{ kind: 'unavailable'; provider: DiagnosticNodeId }>;\n\ntype HostContractState = Readonly<{ kind: 'bound' }> | Readonly<{ kind: 'deferred' }> | Readonly<{ kind: 'unbound' }>;\n\ntype HardEdgeKind = 'hard-import' | 'requires-port';\ntype WeakEdgeKind = 'absent-import' | 'absent-port' | 'optional-import' | 'optional-port';\ntype StructuralEdgeKind = 'condition-control' | 'contributes-to' | 'on-demand-import' | 'owns' | 'provides-port';\ntype WeakEdgeState = 'found' | 'missing';\n\ntype DiagnosticEdgeBase = Readonly<{ from: DiagnosticNodeId; id: DiagnosticEdgeId; to: DiagnosticNodeId }>;\n\ntype DiagnosticEdge =\n | (DiagnosticEdgeBase & Readonly<{ kind: HardEdgeKind; pending: boolean }>)\n | (DiagnosticEdgeBase & Readonly<{ kind: StructuralEdgeKind }>)\n | (DiagnosticEdgeBase & Readonly<{ kind: WeakEdgeKind; lookup: WeakEdgeState }>);\n\ntype PlanNodeBase = Readonly<{ id: DiagnosticNodeId; label: string; provenance?: string }>;\n\ntype ApplicationPlanNode = PlanNodeBase & Readonly<{ features: number; groups: number; kind: 'application' }>;\n\ntype ConditionPlanNode = PlanNodeBase &\n Readonly<{ conditionId: DiagnosticConditionId; kind: 'condition'; source: DiagnosticNodeId | 'host' }>;\n\ntype ConditionGroupPlanNode = PlanNodeBase &\n Readonly<{\n conditions: readonly DiagnosticConditionId[];\n kind: 'condition-group';\n order: readonly DiagnosticNodeId[];\n }>;\n\ntype FeaturePlanNode = PlanNodeBase & Readonly<{ kind: 'feature'; owner: DiagnosticNodeId }>;\ntype PortPlanNode = PlanNodeBase & Readonly<{ kind: 'port'; provider?: DiagnosticNodeId }>;\n\ntype HostContractPlanNode = PlanNodeBase &\n Readonly<{ demand: 'instance' | 'onDemand'; kind: 'host-contract'; optional: boolean }>;\n\ntype AbsentProviderPlanNode = PlanNodeBase & Readonly<{ kind: 'absent-provider' }>;\ntype ContributionTargetPlanNode = PlanNodeBase & Readonly<{ kind: 'contribution-target' }>;\n\ntype ContributionPlanNode = PlanNodeBase &\n Readonly<{\n contributor: DiagnosticNodeId;\n kind: 'contribution';\n priority: number;\n target: DiagnosticNodeId;\n }>;\n\ntype ApplicationPlanSnapshot = Readonly<{\n absentProviders: readonly AbsentProviderPlanNode[];\n application: ApplicationPlanNode;\n conditions: readonly ConditionPlanNode[];\n contributions: readonly ContributionPlanNode[];\n edges: readonly DiagnosticEdge[];\n features: readonly FeaturePlanNode[];\n groups: readonly ConditionGroupPlanNode[];\n hostContracts: readonly HostContractPlanNode[];\n ports: readonly PortPlanNode[];\n targets: readonly ContributionTargetPlanNode[];\n}>;\n\ntype RuntimeNodeBase = Readonly<{\n cause?: DiagnosticCauseRef;\n declaration?: DiagnosticNodeId;\n id: DiagnosticNodeId;\n label: string;\n}>;\n\ntype ConditionRuntimeNode = Readonly<{ kind: 'condition'; state: ConditionState }> & RuntimeNodeBase;\n\ntype ConditionGroupRuntimeNode = Readonly<{\n desired: DiagnosticDesiredState;\n kind: 'condition-group';\n state: ConditionGroupState;\n}> &\n RuntimeNodeBase;\n\ntype FeatureInstanceNode = Readonly<{\n generation: number;\n group?: DiagnosticNodeId;\n kind: 'feature-instance';\n previous?: number;\n state: FeatureInstanceState;\n}> &\n RuntimeNodeBase;\n\ntype AttachmentNode = Readonly<{ kind: 'attachment'; owner: DiagnosticNodeId; state: AttachmentState }> &\n RuntimeNodeBase;\n\ntype AttachmentState =\n | Readonly<{ failure: DiagnosticFailure; kind: 'failed-close' }>\n | Readonly<{ kind: 'closed' }>\n | Readonly<{ kind: 'closing'; phase: 'close' | 'retry' | 'rollback' }>\n | Readonly<{ kind: 'opening' }>\n | Readonly<{ kind: 'ready' }>;\n\ntype ContributionRuntimeNode = Readonly<{\n contributor: DiagnosticNodeId;\n kind: 'contribution';\n state: ContributionState;\n target: DiagnosticNodeId;\n}> &\n RuntimeNodeBase;\n\ntype PortRuntimeNode = Readonly<{ kind: 'port'; state: PortState }> & RuntimeNodeBase;\ntype HostContractRuntimeNode = Readonly<{ kind: 'host-contract'; state: HostContractState }> & RuntimeNodeBase;\n\ntype DiagnosticRuntimeNode =\n | AttachmentNode\n | ConditionGroupRuntimeNode\n | ConditionRuntimeNode\n | ContributionRuntimeNode\n | FeatureInstanceNode\n | HostContractRuntimeNode\n | PortRuntimeNode;\n\ntype RuntimeStateSnapshot = Readonly<{\n attachments: readonly AttachmentNode[];\n conditions: readonly ConditionRuntimeNode[];\n contributions: readonly ContributionRuntimeNode[];\n edges: readonly DiagnosticEdge[];\n groups: readonly ConditionGroupRuntimeNode[];\n hostContracts: readonly HostContractRuntimeNode[];\n instances: readonly FeatureInstanceNode[];\n ports: readonly PortRuntimeNode[];\n}>;\n\nconst graphSchemaRevision = 'opetope.devtools-graph/3';\nconst frameSchemaRevision = 'opetope.devtools-frame/3';\n\ntype RuntimeGraphSnapshot = Readonly<{\n activity?: RuntimeActivitySnapshot;\n lastSequence: DiagnosticSequence;\n plan: ApplicationPlanSnapshot;\n planFingerprint: string;\n runtime: RuntimeStateSnapshot;\n schemaRevision: typeof graphSchemaRevision;\n sessionId: string;\n stateRevision: DiagnosticStateRevision;\n topologyRevision: number;\n}>;\n\ntype DiagnosticOperation =\n | Readonly<{ edge: DiagnosticEdge; op: 'upsert-edge' }>\n | Readonly<{ id: DiagnosticEdgeId; op: 'remove-edge' }>\n | Readonly<{ id: DiagnosticNodeId; op: 'remove-node' }>\n | Readonly<{ node: DiagnosticRuntimeNode; op: 'upsert-node' }>;\n\ntype RuntimeGraphFrame = Readonly<{\n activity?: RuntimeActivitySnapshot;\n baseRevision: DiagnosticStateRevision;\n cause?: DiagnosticCauseRef;\n firstSequence: DiagnosticSequence;\n lastSequence: DiagnosticSequence;\n nextRevision: DiagnosticStateRevision;\n operations: readonly DiagnosticOperation[];\n schemaRevision: typeof frameSchemaRevision;\n sessionId: string;\n}>;\n\ntype ReadLimits = Readonly<{ maxBytes: number; maxFrames: number }>;\n\ntype ReadResult =\n | Readonly<{ frames: readonly RuntimeGraphFrame[]; kind: 'changes' }>\n | Readonly<{ kind: 'resync-required'; snapshot: RuntimeGraphSnapshot }>;\n\n/** The port itself (`docs/devtools.md` §3.3): pull by cursor, notify only, and a close that stops the client and not the application. */\ninterface RuntimeInspectionSession {\n close(): void;\n getSnapshot(): RuntimeGraphSnapshot;\n readSince(cursor: DiagnosticSequence, limits: ReadLimits): ReadResult;\n subscribe(listener: () => void): () => void;\n}\n\nexport { frameSchemaRevision, graphSchemaRevision };\nexport type {\n AbsentProviderPlanNode,\n ApplicationPlanSnapshot,\n ConditionGroupPlanNode,\n ConditionGroupRuntimeNode,\n ConditionGroupState,\n ConditionPlanNode,\n ConditionRuntimeNode,\n ContributionPlanNode,\n ContributionRuntimeNode,\n ContributionState,\n ContributionTargetPlanNode,\n DesiredAxis,\n DiagnosticCauseRef,\n DiagnosticConditionId,\n DiagnosticEdge,\n DiagnosticEdgeId,\n DiagnosticFailure,\n DiagnosticNodeId,\n DiagnosticOperation,\n DiagnosticPhase,\n DiagnosticRuntimeNode,\n DiagnosticSequence,\n FeatureInstanceNode,\n FeatureInstanceState,\n FeaturePlanNode,\n HostContractPlanNode,\n HostContractRuntimeNode,\n HostContractState,\n PortPlanNode,\n PortRuntimeNode,\n PortState,\n ReadLimits,\n ReadResult,\n RuntimeGraphFrame,\n RuntimeGraphSnapshot,\n RuntimeInspectionSession,\n RuntimeStateSnapshot,\n WeakEdgeState,\n};\n"],"names":["graphSchemaRevision","frameSchemaRevision"],"mappings":"AAmOA,MAAMA,EAAsB,2BACtBC,EAAsB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The trusted seam of `docs/devtools.md` §3.2: no process-wide singleton, no `window` hook, no public value. An
|
|
3
|
+
* application registers
|
|
4
|
+
* itself here when it opens, and the only way to reach it is to already hold the `ApplicationExecution` the host
|
|
5
|
+
* created — which is exactly the authority an integration layer has and a feature does not.
|
|
6
|
+
*/
|
|
7
|
+
import type { Readable } from '@opetope/core';
|
|
8
|
+
import type { CompiledApplicationPlanIR } from './application-compiler.js';
|
|
9
|
+
import type { Condition } from './condition.js';
|
|
10
|
+
import type { ControllableCondition } from './condition-override.js';
|
|
11
|
+
import type { ApplicationActivity } from './inspection-activity.js';
|
|
12
|
+
import type { ObservationSlot } from './inspection-observer.js';
|
|
13
|
+
import type { RuntimeInspectionSession } from './inspection-protocol.js';
|
|
14
|
+
import type { RuntimeErrorReporter } from './runtime-error-reporting.js';
|
|
15
|
+
type ObservableApplication = Readonly<{
|
|
16
|
+
activity: ApplicationActivity;
|
|
17
|
+
applicationId: string;
|
|
18
|
+
/** The debug overrides the control port may have set, read by the state so a group can report the badge (D176). */
|
|
19
|
+
conditionControls: ReadonlyMap<string, ControllableCondition>;
|
|
20
|
+
conditionReadables: ReadonlyMap<Condition, Readable<boolean>>;
|
|
21
|
+
importValues: ReadonlyMap<object, unknown>;
|
|
22
|
+
/** Which features have a live instance right now, and which of those already resolved `ready`. */
|
|
23
|
+
liveInstances: ReadonlyMap<number, unknown>;
|
|
24
|
+
observation: ObservationSlot;
|
|
25
|
+
plan: CompiledApplicationPlanIR;
|
|
26
|
+
readyInstances: ReadonlyMap<number, unknown>;
|
|
27
|
+
reporter: RuntimeErrorReporter;
|
|
28
|
+
}>;
|
|
29
|
+
/** The recorder cap of `docs/devtools.md` §3.3. It protects the producer, and it is independent of any cap the consumer keeps. */
|
|
30
|
+
type InspectionOptions = Readonly<{
|
|
31
|
+
activityCapacity?: number;
|
|
32
|
+
ringCapacity?: number;
|
|
33
|
+
}>;
|
|
34
|
+
declare function registerObservableApplication(execution: object, application: ObservableApplication): void;
|
|
35
|
+
/**
|
|
36
|
+
* Opens one inspection session on a running application. Until this is called the observation slot is empty, so an
|
|
37
|
+
* application nobody inspects records nothing; `close()` empties it again and stops the feed without touching the
|
|
38
|
+
* application (`docs/devtools.md` §3.4, §6).
|
|
39
|
+
*/
|
|
40
|
+
declare function createInspectionSession(execution: object, options?: InspectionOptions): RuntimeInspectionSession;
|
|
41
|
+
export { createInspectionSession, registerObservableApplication };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{nodeIds as p,projectApplicationPlan as l}from"./inspection-plan.js";import{InspectionSessionController as d}from"./inspection-session.js";const c=new WeakMap;function b(t,n){const e=[],r=new Set;for(const i of t.plan.contributions){const a=i.target;if(r.has(a))continue;r.add(a);const s=i.targetId;e.push(a.entries.subscribe(()=>n.contributionsChanged(s)))}return()=>{for(const i of e)i();e.length=0}}function u(t,n){c.set(t,n)}function f(t){const n=t.activityCapacity??256;if(!Number.isSafeInteger(n)||n<1||n>1e4)throw new RangeError("Inspection activityCapacity must be an integer from 1 to 10000.");return n}function y(t){const n=t.ringCapacity??256;if(!Number.isSafeInteger(n)||n<0)throw new RangeError("Inspection ringCapacity must be a non-negative safe integer.");return n}function g(t,n={}){const e=c.get(t),r=f(n),i=y(n);if(e===void 0)throw new TypeError("Inspection requires an application opened by openApplication.");if(e.observation.observer!==void 0)throw new TypeError("This application already has an inspection session.");const a=p.application(e.applicationId);let s=()=>{};const o=new d({activityCapacity:r,detach:()=>{s(),e.observation.closeSession=void 0,e.observation.observer=void 0},plan:l(e.plan,e.applicationId),reporter:e.reporter,ringCapacity:i,sources:{activity:e.activity,applicationId:a,boundContracts:new Set(e.importValues.keys()),conditionControls:e.conditionControls,conditionReadables:e.conditionReadables,plan:e.plan}});return e.observation.observer=o,e.observation.closeSession=o.close,o.seed(e.activity.owners.keys(),e.readyInstances),e.observation.completed?o.close():s=b(e,o),Object.freeze({close:o.close,getSnapshot:o.getSnapshot,readSince:o.readSince,subscribe:o.subscribe})}export{g as createInspectionSession,u as registerObservableApplication};
|
|
2
|
+
//# sourceMappingURL=inspection-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection-registry.js","sources":["../src/inspection-registry.ts"],"sourcesContent":["/**\n * The trusted seam of `docs/devtools.md` §3.2: no process-wide singleton, no `window` hook, no public value. An\n * application registers\n * itself here when it opens, and the only way to reach it is to already hold the `ApplicationExecution` the host\n * created — which is exactly the authority an integration layer has and a feature does not.\n */\n\nimport type { Readable } from '@opetope/core';\n\nimport type { CompiledApplicationPlanIR } from './application-compiler';\nimport type { Condition } from './condition';\nimport type { ControllableCondition } from './condition-override';\nimport type { ApplicationActivity } from './inspection-activity';\nimport type { ApplicationObserver, ObservationSlot } from './inspection-observer';\nimport { nodeIds, projectApplicationPlan } from './inspection-plan';\nimport type { RuntimeInspectionSession } from './inspection-protocol';\nimport { InspectionSessionController } from './inspection-session';\nimport type { RuntimeErrorReporter } from './runtime-error-reporting';\n\ntype ObservableApplication = Readonly<{\n activity: ApplicationActivity;\n applicationId: string;\n /** The debug overrides the control port may have set, read by the state so a group can report the badge (D176). */\n conditionControls: ReadonlyMap<string, ControllableCondition>;\n conditionReadables: ReadonlyMap<Condition, Readable<boolean>>;\n importValues: ReadonlyMap<object, unknown>;\n /** Which features have a live instance right now, and which of those already resolved `ready`. */\n liveInstances: ReadonlyMap<number, unknown>;\n observation: ObservationSlot;\n plan: CompiledApplicationPlanIR;\n readyInstances: ReadonlyMap<number, unknown>;\n reporter: RuntimeErrorReporter;\n}>;\n\n/** The recorder cap of `docs/devtools.md` §3.3. It protects the producer, and it is independent of any cap the consumer keeps. */\ntype InspectionOptions = Readonly<{ activityCapacity?: number; ringCapacity?: number }>;\n\nconst observable = new WeakMap<object, ObservableApplication>();\n\n/**\n * The `when` of a contribution moves inside the hub, so the port listens where the fact changes: one subscription per\n * distinct target, taken when a session attaches and released when it detaches. An application nobody inspects keeps\n * the empty slot and subscribes to nothing (`docs/devtools.md` §3.2, D126, D167).\n */\nfunction watchContributionTargets(application: ObservableApplication, observer: ApplicationObserver): () => void {\n const releases: (() => void)[] = [];\n const watched = new Set<object>();\n\n for (const contribution of application.plan.contributions) {\n const target = contribution.target;\n\n if (watched.has(target)) continue;\n\n watched.add(target);\n const targetId = contribution.targetId;\n releases.push(target.entries.subscribe(() => observer.contributionsChanged(targetId)));\n }\n\n return (): void => {\n for (const release of releases) release();\n\n releases.length = 0;\n };\n}\n\nfunction registerObservableApplication(execution: object, application: ObservableApplication): void {\n observable.set(execution, application);\n}\n\nfunction resolveActivityCapacity(options: InspectionOptions): number {\n const capacity = options.activityCapacity ?? 256;\n\n if (!Number.isSafeInteger(capacity) || capacity < 1 || capacity > 10000) {\n throw new RangeError('Inspection activityCapacity must be an integer from 1 to 10000.');\n }\n\n return capacity;\n}\n\nfunction resolveRingCapacity(options: InspectionOptions): number {\n const capacity = options.ringCapacity ?? 256;\n\n if (!Number.isSafeInteger(capacity) || capacity < 0) {\n throw new RangeError('Inspection ringCapacity must be a non-negative safe integer.');\n }\n\n return capacity;\n}\n\n/**\n * Opens one inspection session on a running application. Until this is called the observation slot is empty, so an\n * application nobody inspects records nothing; `close()` empties it again and stops the feed without touching the\n * application (`docs/devtools.md` §3.4, §6).\n */\nfunction createInspectionSession(execution: object, options: InspectionOptions = {}): RuntimeInspectionSession {\n const application = observable.get(execution);\n const activityCapacity = resolveActivityCapacity(options);\n const ringCapacity = resolveRingCapacity(options);\n\n if (application === undefined) throw new TypeError('Inspection requires an application opened by openApplication.');\n\n if (application.observation.observer !== undefined) {\n throw new TypeError('This application already has an inspection session.');\n }\n\n const applicationId = nodeIds.application(application.applicationId);\n let releaseTargets = (): void => undefined;\n const session = new InspectionSessionController({\n activityCapacity,\n detach: () => {\n releaseTargets();\n application.observation.closeSession = undefined;\n application.observation.observer = undefined;\n },\n plan: projectApplicationPlan(application.plan, application.applicationId),\n reporter: application.reporter,\n ringCapacity,\n sources: {\n activity: application.activity,\n applicationId,\n boundContracts: new Set(application.importValues.keys()),\n conditionControls: application.conditionControls,\n conditionReadables: application.conditionReadables,\n plan: application.plan,\n },\n });\n application.observation.observer = session;\n application.observation.closeSession = session.close;\n session.seed(application.activity.owners.keys(), application.readyInstances);\n\n if (application.observation.completed) session.close();\n else releaseTargets = watchContributionTargets(application, session);\n\n // `docs/devtools.md` §3.1: the consumer gets the four methods of the port and nothing else. The producer hooks — and\n // `seed` — stay on the controller the lifecycle holds, so a panel cannot drive the graph it is reading.\n return Object.freeze({\n close: session.close,\n getSnapshot: session.getSnapshot,\n readSince: session.readSince,\n subscribe: session.subscribe,\n });\n}\n\nexport { createInspectionSession, registerObservableApplication };\n"],"names":["observable","watchContributionTargets","application","observer","releases","watched","contribution","target","targetId","release","registerObservableApplication","execution","resolveActivityCapacity","options","capacity","resolveRingCapacity","createInspectionSession","activityCapacity","ringCapacity","applicationId","nodeIds","releaseTargets","session","InspectionSessionController","projectApplicationPlan"],"mappings":"iJAqCA,MAAMA,EAAa,IAAI,QAOvB,SAASC,EAAyBC,EAAoCC,EAA6B,CACjG,MAAMC,EAA2B,CAAA,EAC3BC,EAAU,IAAI,IAEpB,UAAWC,KAAgBJ,EAAY,KAAK,cAAe,CACzD,MAAMK,EAASD,EAAa,OAE5B,GAAID,EAAQ,IAAIE,CAAM,EAAG,SAEzBF,EAAQ,IAAIE,CAAM,EAClB,MAAMC,EAAWF,EAAa,SAC9BF,EAAS,KAAKG,EAAO,QAAQ,UAAU,IAAMJ,EAAS,qBAAqBK,CAAQ,CAAC,CAAC,CACvF,CAEA,MAAO,IAAW,CAChB,UAAWC,KAAWL,EAAUK,EAAO,EAEvCL,EAAS,OAAS,CACpB,CACF,CAEA,SAASM,EAA8BC,EAAmBT,EAAkC,CAC1FF,EAAW,IAAIW,EAAWT,CAAW,CACvC,CAEA,SAASU,EAAwBC,EAA0B,CACzD,MAAMC,EAAWD,EAAQ,kBAAoB,IAE7C,GAAI,CAAC,OAAO,cAAcC,CAAQ,GAAKA,EAAW,GAAKA,EAAW,IAChE,MAAM,IAAI,WAAW,iEAAiE,EAGxF,OAAOA,CACT,CAEA,SAASC,EAAoBF,EAA0B,CACrD,MAAMC,EAAWD,EAAQ,cAAgB,IAEzC,GAAI,CAAC,OAAO,cAAcC,CAAQ,GAAKA,EAAW,EAChD,MAAM,IAAI,WAAW,8DAA8D,EAGrF,OAAOA,CACT,CAOA,SAASE,EAAwBL,EAAmBE,EAA6B,GAAE,CACjF,MAAMX,EAAcF,EAAW,IAAIW,CAAS,EACtCM,EAAmBL,EAAwBC,CAAO,EAClDK,EAAeH,EAAoBF,CAAO,EAEhD,GAAIX,IAAgB,OAAW,MAAM,IAAI,UAAU,+DAA+D,EAElH,GAAIA,EAAY,YAAY,WAAa,OACvC,MAAM,IAAI,UAAU,qDAAqD,EAG3E,MAAMiB,EAAgBC,EAAQ,YAAYlB,EAAY,aAAa,EACnE,IAAImB,EAAiB,IAAA,GACrB,MAAMC,EAAU,IAAIC,EAA4B,CAC9C,iBAAAN,EACA,OAAQ,IAAK,CACXI,EAAc,EACdnB,EAAY,YAAY,aAAe,OACvCA,EAAY,YAAY,SAAW,MACrC,EACA,KAAMsB,EAAuBtB,EAAY,KAAMA,EAAY,aAAa,EACxE,SAAUA,EAAY,SACtB,aAAAgB,EACA,QAAS,CACP,SAAUhB,EAAY,SACtB,cAAAiB,EACA,eAAgB,IAAI,IAAIjB,EAAY,aAAa,KAAI,CAAE,EACvD,kBAAmBA,EAAY,kBAC/B,mBAAoBA,EAAY,mBAChC,KAAMA,EAAY,IACnB,CACF,CAAA,EACD,OAAAA,EAAY,YAAY,SAAWoB,EACnCpB,EAAY,YAAY,aAAeoB,EAAQ,MAC/CA,EAAQ,KAAKpB,EAAY,SAAS,OAAO,KAAI,EAAIA,EAAY,cAAc,EAEvEA,EAAY,YAAY,UAAWoB,EAAQ,MAAK,EAC/CD,EAAiBpB,EAAyBC,EAAaoB,CAAO,EAI5D,OAAO,OAAO,CACnB,MAAOA,EAAQ,MACf,YAAaA,EAAQ,YACrB,UAAWA,EAAQ,UACnB,UAAWA,EAAQ,SACpB,CAAA,CACH"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The transport of the observation port (`docs/devtools.md` §3.3): the runtime commits a frame
|
|
3
|
+
* and only notifies, the consumer reads batches by cursor. A slow or closed panel therefore cannot push back on the
|
|
4
|
+
* application, and a bounded ring turns a burst into a gap the consumer recovers from with one snapshot
|
|
5
|
+
* (`docs/devtools.md` §6).
|
|
6
|
+
*
|
|
7
|
+
* The listener runs after the transition it is told about is fully applied, so reading from inside it sees settled
|
|
8
|
+
* state and cannot reenter the lifecycle. A listener that throws is detached and its failure goes to the host
|
|
9
|
+
* reporter out of band, never back into this feed (`docs/devtools.md` §7).
|
|
10
|
+
*/
|
|
11
|
+
import type { ApplicationObserver } from './inspection-observer.js';
|
|
12
|
+
import type { ApplicationPlanSnapshot, ConditionGroupState, DiagnosticConditionId, DiagnosticNodeId, DiagnosticPhase, DiagnosticSequence, ReadLimits, ReadResult, RuntimeGraphSnapshot, RuntimeInspectionSession } from './inspection-protocol.js';
|
|
13
|
+
import type { InspectionSources } from './inspection-state.js';
|
|
14
|
+
import type { RuntimeErrorReporter } from './runtime-error-reporting.js';
|
|
15
|
+
type InspectionSessionOptions = Readonly<{
|
|
16
|
+
activityCapacity: number;
|
|
17
|
+
detach: () => void;
|
|
18
|
+
plan: ApplicationPlanSnapshot;
|
|
19
|
+
reporter: RuntimeErrorReporter;
|
|
20
|
+
ringCapacity: number;
|
|
21
|
+
sources: InspectionSources;
|
|
22
|
+
}>;
|
|
23
|
+
declare class InspectionSessionController implements ApplicationObserver, RuntimeInspectionSession {
|
|
24
|
+
readonly sessionId: string;
|
|
25
|
+
private activity;
|
|
26
|
+
private readonly activityCapacity;
|
|
27
|
+
private activityDirty;
|
|
28
|
+
private activityQueued;
|
|
29
|
+
private closed;
|
|
30
|
+
private detach;
|
|
31
|
+
private readonly featureIds;
|
|
32
|
+
private readonly groupMembers;
|
|
33
|
+
private lastActivity;
|
|
34
|
+
private readonly listeners;
|
|
35
|
+
private oldestServable;
|
|
36
|
+
private pendingCause;
|
|
37
|
+
private readonly plan;
|
|
38
|
+
private readonly planFingerprint;
|
|
39
|
+
private reporter;
|
|
40
|
+
private revision;
|
|
41
|
+
private readonly ring;
|
|
42
|
+
private readonly ringCapacity;
|
|
43
|
+
private sequence;
|
|
44
|
+
private state;
|
|
45
|
+
private workspaceSnapshot;
|
|
46
|
+
constructor(options: InspectionSessionOptions);
|
|
47
|
+
readonly activityChanged: () => void;
|
|
48
|
+
readonly close: () => void;
|
|
49
|
+
readonly conditionsChanged: (groupId: string) => void;
|
|
50
|
+
readonly contributionsChanged: (targetId: string) => void;
|
|
51
|
+
readonly controlAttributed: (node: DiagnosticNodeId, condition: DiagnosticConditionId | undefined) => void;
|
|
52
|
+
readonly currentSequence: () => number;
|
|
53
|
+
readonly getSnapshot: () => RuntimeGraphSnapshot;
|
|
54
|
+
readonly groupState: (groupId: string, state: ConditionGroupState) => void;
|
|
55
|
+
readonly instanceFailed: (featureIndex: number, error: unknown, phase: DiagnosticPhase) => void;
|
|
56
|
+
readonly instanceOpening: (featureIndex: number) => void;
|
|
57
|
+
readonly instanceReady: (featureIndex: number) => void;
|
|
58
|
+
readonly instanceRetired: (featureIndex: number) => void;
|
|
59
|
+
readonly instanceRetiring: (featureIndex: number) => void;
|
|
60
|
+
readonly readSince: (cursor: DiagnosticSequence, limits: ReadLimits) => ReadResult;
|
|
61
|
+
/**
|
|
62
|
+
* A session can attach long after the application opened, so it starts from what is already live rather than from
|
|
63
|
+
* an empty world. No frames or snapshots were recorded before this: the observation slot was empty (`docs/devtools.md` §3.2).
|
|
64
|
+
*/
|
|
65
|
+
seed(live: Iterable<number>, ready: ReadonlyMap<number, unknown>): void;
|
|
66
|
+
readonly subscribe: (listener: () => void) => (() => void);
|
|
67
|
+
/** One visible transaction. A commit that changed nothing publishes no frame: a frame that commits nothing lies. */
|
|
68
|
+
/** A control command claims the next frame, once: the transition it caused carries it instead of its own cause. */
|
|
69
|
+
private claimCause;
|
|
70
|
+
private commit;
|
|
71
|
+
private currentSnapshot;
|
|
72
|
+
private flushActivity;
|
|
73
|
+
private instanceCause;
|
|
74
|
+
private instanceNodeId;
|
|
75
|
+
private notify;
|
|
76
|
+
/**
|
|
77
|
+
* `docs/devtools.md` §3.3: observation never reaches the lifecycle. A hook runs inside this guard, so a broken condition readable
|
|
78
|
+
* pulled during a recompute, or any other failure of the observing half, goes to the host reporter out of band
|
|
79
|
+
* Instead of turning into a rejected `retire()` or `close()`.
|
|
80
|
+
*/
|
|
81
|
+
private observe;
|
|
82
|
+
private recordFrame;
|
|
83
|
+
private refreshActivity;
|
|
84
|
+
/**
|
|
85
|
+
* A group that is still opening is neither active nor inactive, and calling it `inactive` would claim a decision
|
|
86
|
+
* The machine has not made. The phase is read off the instances the group already has.
|
|
87
|
+
*/
|
|
88
|
+
private seededGroupState;
|
|
89
|
+
/** A bounded batch: the ring protects the producer, and the consumer's own limits protect its reducer (`docs/devtools.md` §3.3). */
|
|
90
|
+
private servable;
|
|
91
|
+
}
|
|
92
|
+
export { InspectionSessionController };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{FeatureError as d,CallError as u,ReadableError as l}from"@opetope/core";import{ApplicationError as f}from"./application-error.js";import{sameRecord as p}from"./inspection-diff.js";import{nodeIds as c}from"./inspection-plan.js";import{frameSchemaRevision as v,graphSchemaRevision as y}from"./inspection-protocol.js";import{InspectionState as g}from"./inspection-state.js";import{reportRuntimeFailure as o}from"./runtime-error-reporting.js";const m=2166136261,b=16777619;let h=0;function S(a){const t=JSON.stringify(a)??"";let e=m;for(let i=0;i<t.length;i+=1)e^=t.charCodeAt(i),e=Math.imul(e,b);return(e>>>0).toString(16).padStart(8,"0")}function C(a,t){return a instanceof d?{code:a.code,phase:t,subject:"feature"}:a instanceof u?{code:a.code,phase:t,subject:"call"}:a instanceof l?{code:a.code,phase:t,subject:"readable"}:a instanceof f?{code:a.code,phase:t,subject:"application"}:{code:"not-ready",phase:t,subject:"feature"}}class k{sessionId;activity;activityCapacity;activityDirty=!1;activityQueued=!1;closed=!1;detach;featureIds;groupMembers;lastActivity;listeners=new Set;oldestServable=1;pendingCause;plan;planFingerprint;reporter;revision=0;ring=[];ringCapacity;sequence=0;state;workspaceSnapshot;constructor(t){var e;this.activity=t.sources.activity,this.activityCapacity=t.activityCapacity,this.lastActivity=this.activity.snapshot(this.activityCapacity),this.detach=t.detach,this.featureIds=t.sources.plan.features.map(i=>i.featureId),this.groupMembers=t.sources.plan.groups.map(i=>({groupId:i.groupId,members:i.members})),this.plan=t.plan,this.reporter=t.reporter,this.ringCapacity=t.ringCapacity,h+=1,this.sessionId=`session-${String(h)}`,this.planFingerprint=S(t.plan),this.state=new g(t.sources),(e=this.state)==null||e.reconcile()}activityChanged=()=>{this.closed||(this.activityDirty=!0,!this.activityQueued&&(this.activityQueued=!0,queueMicrotask(()=>{this.activityQueued=!1,this.flushActivity()})))};close=()=>{var i;if(this.closed)return;this.flushActivity(),this.closed=!0;const t=((i=this.activity)==null?void 0:i.snapshot(this.activityCapacity))??this.lastActivity;this.lastActivity=Object.freeze({...t,freshness:"stale"}),this.workspaceSnapshot=this.currentSnapshot(),this.listeners.clear(),this.ring.length=0;const e=this.detach;this.detach=void 0,this.state=void 0,this.activity=void 0,this.reporter=void 0,this.pendingCause=void 0,e==null||e()};conditionsChanged=t=>{this.observe(()=>this.commit({at:Date.now(),kind:"condition-change",node:c.group(t)}))};contributionsChanged=t=>{this.observe(()=>this.commit({at:Date.now(),kind:"contribution-change",node:c.target(t)}))};controlAttributed=(t,e)=>{this.pendingCause=Object.freeze({at:Date.now(),...e===void 0?{}:{condition:e},kind:"control-command",node:t})};currentSequence=()=>this.sequence;getSnapshot=()=>(this.closed||(this.activityDirty=!0),this.flushActivity(),this.currentSnapshot());groupState=(t,e)=>{this.observe(()=>{var i;(i=this.state)==null||i.setGroupState(t,e,{kind:"group-transition",node:c.group(t)}),this.commit({kind:"group-transition",node:c.group(t)})})};instanceFailed=(t,e,i)=>{this.observe(()=>{var r;const s=C(e,i),n=s.subject==="feature"&&s.code==="quarantined"?{failure:s,kind:"quarantined"}:s.subject==="feature"&&s.code==="cleanup-failed"?{failure:s,kind:"cleanup-failed"}:{failure:s,kind:"not-ready"};(r=this.state)==null||r.setInstanceState(t,n,{kind:"failure",node:this.instanceNodeId(t)}),this.commit({kind:"failure",node:this.instanceNodeId(t)})})};instanceOpening=t=>{this.observe(()=>{var e;(e=this.state)==null||e.openInstance(t,this.instanceCause(t)),this.commit(this.instanceCause(t))})};instanceReady=t=>{this.observe(()=>{var e;(e=this.state)==null||e.setInstanceState(t,{kind:"ready"},this.instanceCause(t)),this.commit(this.instanceCause(t))})};instanceRetired=t=>{this.observe(()=>{var e;(e=this.state)==null||e.dropInstance(t),this.commit(this.instanceCause(t))})};instanceRetiring=t=>{this.observe(()=>{var e;(e=this.state)==null||e.setInstanceState(t,{kind:"fencing"},this.instanceCause(t)),this.commit(this.instanceCause(t))})};readSince=(t,e)=>this.closed?{frames:[],kind:"changes"}:(this.flushActivity(),t+1<this.oldestServable?{kind:"resync-required",snapshot:this.getSnapshot()}:{frames:this.servable(t,e),kind:"changes"});seed(t,e){const i=this.state;if(i!==void 0){for(const s of t)i.openInstance(s,void 0),e.has(s)&&i.setInstanceState(s,{kind:"ready"},void 0);for(const s of this.groupMembers)i.setGroupState(s.groupId,this.seededGroupState(s.members,e),void 0);i.reconcile()}}subscribe=t=>this.closed?()=>{}:(this.listeners.add(t),()=>{this.listeners.delete(t)});claimCause(t){const e=this.pendingCause??t;return this.pendingCause=void 0,e}commit(t){var r;if(this.closed)return;const e=this.claimCause(t),i=((r=this.state)==null?void 0:r.reconcile())??[],s=this.refreshActivity();if(i.length===0&&!s)return;this.sequence+=1;const n=Object.freeze({...s?{activity:this.lastActivity}:{},baseRevision:this.revision,cause:e,firstSequence:this.sequence,lastSequence:this.sequence,nextRevision:this.revision+1,operations:Object.freeze(i),schemaRevision:v,sessionId:this.sessionId});this.revision+=1,this.recordFrame(n),this.notify()}currentSnapshot(){if(this.workspaceSnapshot!==void 0)return this.workspaceSnapshot;const t=this.state;if(t===void 0)throw new TypeError("Inspection state is unavailable.");return Object.freeze({activity:this.lastActivity,lastSequence:this.sequence,plan:this.plan,planFingerprint:this.planFingerprint,runtime:t.snapshot(),schemaRevision:y,sessionId:this.sessionId,stateRevision:this.revision,topologyRevision:1})}flushActivity(){!this.activityDirty||this.closed||(this.activityDirty=!1,this.observe(()=>this.commit({kind:"activity-change"})))}instanceCause(t){return{kind:"instance-transition",node:this.instanceNodeId(t)}}instanceNodeId(t){return c.instance(this.featureIds[t]??String(t))}notify(){for(const t of[...this.listeners])try{t()}catch(e){this.listeners.delete(t),o(e,this.reporter)}}observe(t){if(!this.closed)try{t()}catch(e){o(e,this.reporter)}}recordFrame(t){for(this.ring.push({bytes:(JSON.stringify(t)??"").length,frame:t});this.ring.length>this.ringCapacity;){const e=this.ring.shift();e!==void 0&&(this.oldestServable=e.frame.lastSequence+1)}}refreshActivity(){var i;const t=((i=this.activity)==null?void 0:i.snapshot(this.activityCapacity))??this.lastActivity,e=!p(this.lastActivity,t);return e&&(this.lastActivity=t),this.activityDirty=!1,e}seededGroupState(t,e){if(t.filter(n=>{var r;return(r=this.state)==null?void 0:r.hasInstance(n)}).length===0)return{kind:"inactive",reason:"condition-inactive"};const s=t.filter(n=>e.has(n)).length;return s===t.length?{kind:"active"}:{kind:"opening",opened:s,total:t.length}}servable(t,e){const i=[];let s=0;for(const n of this.ring)if(!(n.frame.firstSequence<=t||i.length>=e.maxFrames)){if(i.length>0&&s+n.bytes>e.maxBytes)break;s+=n.bytes,i.push(n.frame)}return i}}export{k as InspectionSessionController};
|
|
2
|
+
//# sourceMappingURL=inspection-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection-session.js","sources":["../src/inspection-session.ts"],"sourcesContent":["/**\n * The transport of the observation port (`docs/devtools.md` §3.3): the runtime commits a frame\n * and only notifies, the consumer reads batches by cursor. A slow or closed panel therefore cannot push back on the\n * application, and a bounded ring turns a burst into a gap the consumer recovers from with one snapshot\n * (`docs/devtools.md` §6).\n *\n * The listener runs after the transition it is told about is fully applied, so reading from inside it sees settled\n * state and cannot reenter the lifecycle. A listener that throws is detached and its failure goes to the host\n * reporter out of band, never back into this feed (`docs/devtools.md` §7).\n */\n\nimport { CallError, FeatureError, ReadableError } from '@opetope/core';\n\nimport { ApplicationError } from './application-error';\nimport type { ApplicationActivity } from './inspection-activity';\nimport type { RuntimeActivitySnapshot } from './inspection-activity-protocol';\nimport { sameRecord } from './inspection-diff';\nimport type { ApplicationObserver } from './inspection-observer';\nimport { nodeIds } from './inspection-plan';\nimport { frameSchemaRevision, graphSchemaRevision } from './inspection-protocol';\nimport type {\n ApplicationPlanSnapshot,\n ConditionGroupState,\n DiagnosticCauseRef,\n DiagnosticConditionId,\n DiagnosticFailure,\n DiagnosticNodeId,\n DiagnosticPhase,\n DiagnosticSequence,\n ReadLimits,\n ReadResult,\n RuntimeGraphFrame,\n RuntimeGraphSnapshot,\n RuntimeInspectionSession,\n} from './inspection-protocol';\nimport { InspectionState } from './inspection-state';\nimport type { InspectionSources } from './inspection-state';\nimport { reportRuntimeFailure } from './runtime-error-reporting';\nimport type { RuntimeErrorReporter } from './runtime-error-reporting';\n\ntype RingEntry = { readonly bytes: number; readonly frame: RuntimeGraphFrame };\n\ntype InspectionSessionOptions = Readonly<{\n activityCapacity: number;\n detach: () => void;\n plan: ApplicationPlanSnapshot;\n reporter: RuntimeErrorReporter;\n ringCapacity: number;\n sources: InspectionSources;\n}>;\n\nconst fnvOffsetBasis = 0x81_1c_9d_c5;\nconst fnvPrime = 0x01_00_01_93;\n\nlet sessionCounter = 0;\n\n/** Not a cryptographic hash: it answers \"is this the same compiled plan\", and nothing else. */\nfunction fingerprint(value: unknown): string {\n const text = JSON.stringify(value) ?? '';\n let hash = fnvOffsetBasis;\n\n for (let index = 0; index < text.length; index += 1) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(hash, fnvPrime);\n }\n\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/** A failure travels as the subject and the code of the runtime's own error classes, never as text\n * (`docs/devtools.md` §2.5). */\nfunction describeFailure(error: unknown, phase: DiagnosticPhase): DiagnosticFailure {\n if (error instanceof FeatureError) return { code: error.code, phase, subject: 'feature' };\n\n if (error instanceof CallError) return { code: error.code, phase, subject: 'call' };\n\n if (error instanceof ReadableError) return { code: error.code, phase, subject: 'readable' };\n\n if (error instanceof ApplicationError) return { code: error.code, phase, subject: 'application' };\n\n return { code: 'not-ready', phase, subject: 'feature' };\n}\n\nclass InspectionSessionController implements ApplicationObserver, RuntimeInspectionSession {\n public readonly sessionId: string;\n\n private activity: ApplicationActivity | undefined;\n private readonly activityCapacity: number;\n private activityDirty = false;\n private activityQueued = false;\n private closed = false;\n private detach: (() => void) | undefined;\n private readonly featureIds: readonly string[];\n private readonly groupMembers: readonly Readonly<{ groupId: string; members: readonly number[] }>[];\n private lastActivity: RuntimeActivitySnapshot;\n private readonly listeners = new Set<() => void>();\n private oldestServable = 1;\n private pendingCause: DiagnosticCauseRef | undefined;\n private readonly plan: ApplicationPlanSnapshot;\n\n private readonly planFingerprint: string;\n\n private reporter: RuntimeErrorReporter | undefined;\n\n private revision = 0;\n\n private readonly ring: RingEntry[] = [];\n\n private readonly ringCapacity: number;\n\n private sequence = 0;\n\n private state: InspectionState | undefined;\n\n private workspaceSnapshot: RuntimeGraphSnapshot | undefined;\n\n public constructor(options: InspectionSessionOptions) {\n this.activity = options.sources.activity;\n this.activityCapacity = options.activityCapacity;\n this.lastActivity = this.activity.snapshot(this.activityCapacity);\n this.detach = options.detach;\n this.featureIds = options.sources.plan.features.map(feature => feature.featureId);\n this.groupMembers = options.sources.plan.groups.map(group => ({ groupId: group.groupId, members: group.members }));\n this.plan = options.plan;\n this.reporter = options.reporter;\n this.ringCapacity = options.ringCapacity;\n sessionCounter += 1;\n this.sessionId = `session-${String(sessionCounter)}`;\n this.planFingerprint = fingerprint(options.plan);\n this.state = new InspectionState(options.sources);\n this.state?.reconcile();\n }\n\n public readonly activityChanged = (): void => {\n if (this.closed) return;\n\n this.activityDirty = true;\n\n if (this.activityQueued) return;\n\n this.activityQueued = true;\n queueMicrotask(() => {\n this.activityQueued = false;\n this.flushActivity();\n });\n };\n\n public readonly close = (): void => {\n if (this.closed) return;\n\n // D206: publish the completed physical drain before the workspace session clears its transport.\n this.flushActivity();\n this.closed = true;\n const latest = this.activity?.snapshot(this.activityCapacity) ?? this.lastActivity;\n this.lastActivity = Object.freeze({ ...latest, freshness: 'stale' });\n this.workspaceSnapshot = this.currentSnapshot();\n this.listeners.clear();\n this.ring.length = 0;\n const detach = this.detach;\n this.detach = undefined;\n this.state = undefined;\n this.activity = undefined;\n this.reporter = undefined;\n this.pendingCause = undefined;\n detach?.();\n };\n\n public readonly conditionsChanged = (groupId: string): void => {\n this.observe(() => this.commit({ at: Date.now(), kind: 'condition-change', node: nodeIds.group(groupId) }));\n };\n\n public readonly contributionsChanged = (targetId: string): void => {\n this.observe(() => this.commit({ at: Date.now(), kind: 'contribution-change', node: nodeIds.target(targetId) }));\n };\n\n public readonly controlAttributed = (node: DiagnosticNodeId, condition: DiagnosticConditionId | undefined): void => {\n this.pendingCause = Object.freeze({\n at: Date.now(),\n ...(condition === undefined ? {} : { condition }),\n kind: 'control-command' as const,\n node,\n });\n };\n\n public readonly currentSequence = (): number => this.sequence;\n\n public readonly getSnapshot = (): RuntimeGraphSnapshot => {\n if (!this.closed) this.activityDirty = true;\n\n this.flushActivity();\n\n return this.currentSnapshot();\n };\n\n public readonly groupState = (groupId: string, state: ConditionGroupState): void => {\n this.observe(() => {\n this.state?.setGroupState(groupId, state, { kind: 'group-transition', node: nodeIds.group(groupId) });\n this.commit({ kind: 'group-transition', node: nodeIds.group(groupId) });\n });\n };\n\n public readonly instanceFailed = (featureIndex: number, error: unknown, phase: DiagnosticPhase): void => {\n this.observe(() => {\n const failure = describeFailure(error, phase);\n const state =\n failure.subject === 'feature' && failure.code === 'quarantined'\n ? ({ failure, kind: 'quarantined' } as const)\n : failure.subject === 'feature' && failure.code === 'cleanup-failed'\n ? ({ failure, kind: 'cleanup-failed' } as const)\n : ({ failure, kind: 'not-ready' } as const);\n\n this.state?.setInstanceState(featureIndex, state, { kind: 'failure', node: this.instanceNodeId(featureIndex) });\n this.commit({ kind: 'failure', node: this.instanceNodeId(featureIndex) });\n });\n };\n\n public readonly instanceOpening = (featureIndex: number): void => {\n this.observe(() => {\n this.state?.openInstance(featureIndex, this.instanceCause(featureIndex));\n this.commit(this.instanceCause(featureIndex));\n });\n };\n\n public readonly instanceReady = (featureIndex: number): void => {\n this.observe(() => {\n this.state?.setInstanceState(featureIndex, { kind: 'ready' }, this.instanceCause(featureIndex));\n this.commit(this.instanceCause(featureIndex));\n });\n };\n\n public readonly instanceRetired = (featureIndex: number): void => {\n this.observe(() => {\n this.state?.dropInstance(featureIndex);\n this.commit(this.instanceCause(featureIndex));\n });\n };\n\n public readonly instanceRetiring = (featureIndex: number): void => {\n this.observe(() => {\n this.state?.setInstanceState(featureIndex, { kind: 'fencing' }, this.instanceCause(featureIndex));\n this.commit(this.instanceCause(featureIndex));\n });\n };\n\n public readonly readSince = (cursor: DiagnosticSequence, limits: ReadLimits): ReadResult => {\n if (this.closed) return { frames: [], kind: 'changes' };\n\n this.flushActivity();\n\n if (cursor + 1 < this.oldestServable) return { kind: 'resync-required', snapshot: this.getSnapshot() };\n\n return { frames: this.servable(cursor, limits), kind: 'changes' };\n };\n\n /**\n * A session can attach long after the application opened, so it starts from what is already live rather than from\n * an empty world. No frames or snapshots were recorded before this: the observation slot was empty (`docs/devtools.md` §3.2).\n */\n public seed(live: Iterable<number>, ready: ReadonlyMap<number, unknown>): void {\n const state = this.state;\n\n if (state === undefined) return;\n\n for (const featureIndex of live) {\n state.openInstance(featureIndex, undefined);\n\n if (ready.has(featureIndex)) state.setInstanceState(featureIndex, { kind: 'ready' }, undefined);\n }\n\n for (const group of this.groupMembers) {\n state.setGroupState(group.groupId, this.seededGroupState(group.members, ready), undefined);\n }\n\n state.reconcile();\n }\n\n public readonly subscribe = (listener: () => void): (() => void) => {\n if (this.closed) return () => undefined;\n\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n /** One visible transaction. A commit that changed nothing publishes no frame: a frame that commits nothing lies. */\n /** A control command claims the next frame, once: the transition it caused carries it instead of its own cause. */\n private claimCause(cause: DiagnosticCauseRef): DiagnosticCauseRef {\n const attributed = this.pendingCause ?? cause;\n this.pendingCause = undefined;\n\n return attributed;\n }\n\n private commit(cause: DiagnosticCauseRef): void {\n if (this.closed) return;\n\n const attributed = this.claimCause(cause);\n const operations = this.state?.reconcile() ?? [];\n const changed = this.refreshActivity();\n\n if (operations.length === 0 && !changed) return;\n\n this.sequence += 1;\n const frame: RuntimeGraphFrame = Object.freeze({\n ...(changed ? { activity: this.lastActivity } : {}),\n baseRevision: this.revision,\n cause: attributed,\n firstSequence: this.sequence,\n lastSequence: this.sequence,\n nextRevision: this.revision + 1,\n operations: Object.freeze(operations),\n schemaRevision: frameSchemaRevision,\n sessionId: this.sessionId,\n });\n this.revision += 1;\n this.recordFrame(frame);\n\n this.notify();\n }\n\n private currentSnapshot(): RuntimeGraphSnapshot {\n if (this.workspaceSnapshot !== undefined) return this.workspaceSnapshot;\n\n const state = this.state;\n\n if (state === undefined) throw new TypeError('Inspection state is unavailable.');\n\n return Object.freeze({\n activity: this.lastActivity,\n lastSequence: this.sequence,\n plan: this.plan,\n planFingerprint: this.planFingerprint,\n runtime: state.snapshot(),\n schemaRevision: graphSchemaRevision,\n sessionId: this.sessionId,\n stateRevision: this.revision,\n topologyRevision: 1,\n });\n }\n\n private flushActivity(): void {\n if (!this.activityDirty || this.closed) return;\n\n this.activityDirty = false;\n this.observe(() => this.commit({ kind: 'activity-change' }));\n }\n\n private instanceCause(featureIndex: number): DiagnosticCauseRef {\n return { kind: 'instance-transition', node: this.instanceNodeId(featureIndex) };\n }\n\n private instanceNodeId(featureIndex: number): string {\n return nodeIds.instance(this.featureIds[featureIndex] ?? String(featureIndex));\n }\n\n private notify(): void {\n for (const listener of [...this.listeners]) {\n try {\n listener();\n } catch (error) {\n this.listeners.delete(listener);\n reportRuntimeFailure(error, this.reporter);\n }\n }\n }\n\n /**\n * `docs/devtools.md` §3.3: observation never reaches the lifecycle. A hook runs inside this guard, so a broken condition readable\n * pulled during a recompute, or any other failure of the observing half, goes to the host reporter out of band\n * Instead of turning into a rejected `retire()` or `close()`.\n */\n private observe(record: () => void): void {\n if (this.closed) return;\n\n try {\n record();\n } catch (error) {\n reportRuntimeFailure(error, this.reporter);\n }\n }\n\n private recordFrame(frame: RuntimeGraphFrame): void {\n this.ring.push({ bytes: (JSON.stringify(frame) ?? '').length, frame });\n\n while (this.ring.length > this.ringCapacity) {\n const dropped = this.ring.shift();\n\n if (dropped !== undefined) this.oldestServable = dropped.frame.lastSequence + 1;\n }\n }\n\n private refreshActivity(): boolean {\n const activity = this.activity?.snapshot(this.activityCapacity) ?? this.lastActivity;\n const changed = !sameRecord(this.lastActivity, activity);\n\n if (changed) this.lastActivity = activity;\n\n this.activityDirty = false;\n\n return changed;\n }\n\n /**\n * A group that is still opening is neither active nor inactive, and calling it `inactive` would claim a decision\n * The machine has not made. The phase is read off the instances the group already has.\n */\n private seededGroupState(members: readonly number[], ready: ReadonlyMap<number, unknown>): ConditionGroupState {\n const live = members.filter(member => this.state?.hasInstance(member));\n\n if (live.length === 0) return { kind: 'inactive', reason: 'condition-inactive' };\n\n const opened = members.filter(member => ready.has(member)).length;\n\n if (opened === members.length) return { kind: 'active' };\n\n return { kind: 'opening', opened, total: members.length };\n }\n\n /** A bounded batch: the ring protects the producer, and the consumer's own limits protect its reducer (`docs/devtools.md` §3.3). */\n private servable(cursor: DiagnosticSequence, limits: ReadLimits): readonly RuntimeGraphFrame[] {\n const frames: RuntimeGraphFrame[] = [];\n let bytes = 0;\n\n for (const entry of this.ring) {\n if (entry.frame.firstSequence <= cursor || frames.length >= limits.maxFrames) continue;\n\n if (frames.length > 0 && bytes + entry.bytes > limits.maxBytes) break;\n\n bytes += entry.bytes;\n frames.push(entry.frame);\n }\n\n return frames;\n }\n}\n\nexport { InspectionSessionController };\n"],"names":["fnvOffsetBasis","fnvPrime","sessionCounter","fingerprint","value","text","hash","index","describeFailure","error","phase","FeatureError","CallError","ReadableError","ApplicationError","InspectionSessionController","options","feature","group","InspectionState","_a","latest","detach","groupId","nodeIds","targetId","node","condition","state","featureIndex","failure","cursor","limits","live","ready","listener","cause","attributed","operations","changed","frame","frameSchemaRevision","graphSchemaRevision","reportRuntimeFailure","record","dropped","activity","sameRecord","members","member","opened","frames","bytes","entry"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** A data-only projection of the published maps. Reused until a graph operation changes either map. */
|
|
2
|
+
import type { DiagnosticEdge, DiagnosticRuntimeNode, RuntimeStateSnapshot } from './inspection-protocol.js';
|
|
3
|
+
declare function snapshotRuntimeState(nodes: Iterable<DiagnosticRuntimeNode>, edges: Iterable<DiagnosticEdge>): RuntimeStateSnapshot;
|
|
4
|
+
export { snapshotRuntimeState };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function n(o,e){const t=[];for(const c of o)c.kind===e&&t.push(c);return Object.freeze(t)}function i(o,e){const t=[...o];return Object.freeze({attachments:n(t,"attachment"),conditions:n(t,"condition"),contributions:n(t,"contribution"),edges:Object.freeze([...e]),groups:n(t,"condition-group"),hostContracts:n(t,"host-contract"),instances:n(t,"feature-instance"),ports:n(t,"port")})}export{i as snapshotRuntimeState};
|
|
2
|
+
//# sourceMappingURL=inspection-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection-snapshot.js","sources":["../src/inspection-snapshot.ts"],"sourcesContent":["/** A data-only projection of the published maps. Reused until a graph operation changes either map. */\nimport type { DiagnosticEdge, DiagnosticRuntimeNode, RuntimeStateSnapshot } from './inspection-protocol';\n\nfunction ofKind<Kind extends DiagnosticRuntimeNode['kind']>(\n nodes: readonly DiagnosticRuntimeNode[],\n kind: Kind,\n): readonly Extract<DiagnosticRuntimeNode, { readonly kind: Kind }>[] {\n const picked: Extract<DiagnosticRuntimeNode, { readonly kind: Kind }>[] = [];\n\n for (const node of nodes) {\n if (node.kind === kind) picked.push(node as Extract<DiagnosticRuntimeNode, { readonly kind: Kind }>);\n }\n\n return Object.freeze(picked);\n}\n\nfunction snapshotRuntimeState(\n nodes: Iterable<DiagnosticRuntimeNode>,\n edges: Iterable<DiagnosticEdge>,\n): RuntimeStateSnapshot {\n const all = [...nodes];\n\n return Object.freeze({\n attachments: ofKind(all, 'attachment'),\n conditions: ofKind(all, 'condition'),\n contributions: ofKind(all, 'contribution'),\n edges: Object.freeze([...edges]),\n groups: ofKind(all, 'condition-group'),\n hostContracts: ofKind(all, 'host-contract'),\n instances: ofKind(all, 'feature-instance'),\n ports: ofKind(all, 'port'),\n });\n}\n\nexport { snapshotRuntimeState };\n"],"names":["ofKind","nodes","kind","picked","node","snapshotRuntimeState","edges","all"],"mappings":"AAGA,SAASA,EACPC,EACAC,EAAU,CAEV,MAAMC,EAAoE,CAAA,EAE1E,UAAWC,KAAQH,EACbG,EAAK,OAASF,GAAMC,EAAO,KAAKC,CAA+D,EAGrG,OAAO,OAAO,OAAOD,CAAM,CAC7B,CAEA,SAASE,EACPJ,EACAK,EAA+B,CAE/B,MAAMC,EAAM,CAAC,GAAGN,CAAK,EAErB,OAAO,OAAO,OAAO,CACnB,YAAaD,EAAOO,EAAK,YAAY,EACrC,WAAYP,EAAOO,EAAK,WAAW,EACnC,cAAeP,EAAOO,EAAK,cAAc,EACzC,MAAO,OAAO,OAAO,CAAC,GAAGD,CAAK,CAAC,EAC/B,OAAQN,EAAOO,EAAK,iBAAiB,EACrC,cAAeP,EAAOO,EAAK,eAAe,EAC1C,UAAWP,EAAOO,EAAK,kBAAkB,EACzC,MAAOP,EAAOO,EAAK,MAAM,CAC1B,CAAA,CACH"}
|