@opetope/devtools 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 +105 -0
- package/README.ru.md +105 -0
- package/dist/activity-export.d.ts +4 -0
- package/dist/activity.d.ts +63 -0
- package/dist/conformance-activity.d.ts +8 -0
- package/dist/conformance.d.ts +37 -0
- package/dist/control-subject.d.ts +15 -0
- package/dist/control-ui-DMmVy9Ob.js +16 -0
- package/dist/control-ui-DMmVy9Ob.js.map +1 -0
- package/dist/control.d.ts +45 -0
- package/dist/corpus.d.ts +33 -0
- package/dist/decode-activity.d.ts +4 -0
- package/dist/decode-shapes.d.ts +32 -0
- package/dist/decode-values.d.ts +36 -0
- package/dist/decode.d.ts +41 -0
- package/dist/digest.d.ts +17 -0
- package/dist/export-run-DIQZax_d.js +2 -0
- package/dist/export-run-DIQZax_d.js.map +1 -0
- package/dist/export-snapshot-Buw-c6ZG.js +2 -0
- package/dist/export-snapshot-Buw-c6ZG.js.map +1 -0
- package/dist/export-snapshot.d.ts +34 -0
- package/dist/extension-points.d.ts +45 -0
- package/dist/fixture-plan.d.ts +62 -0
- package/dist/fixture-runtime.d.ts +37 -0
- package/dist/fixture.d.ts +23 -0
- package/dist/fold-snapshot-DjiURn8v.js +2 -0
- package/dist/fold-snapshot-DjiURn8v.js.map +1 -0
- package/dist/fold-snapshot.d.ts +15 -0
- package/dist/graph-index.d.ts +104 -0
- package/dist/graph-store.d.ts +77 -0
- package/dist/graph.d.ts +211 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector.d.ts +70 -0
- package/dist/install.d.ts +44 -0
- package/dist/install.js +2 -0
- package/dist/install.js.map +1 -0
- package/dist/integration.d.ts +42 -0
- package/dist/integration.js +2 -0
- package/dist/integration.js.map +1 -0
- package/dist/legend-DT7j0_pD.js +2 -0
- package/dist/legend-DT7j0_pD.js.map +1 -0
- package/dist/node-facts.d.ts +20 -0
- package/dist/node-state.d.ts +152 -0
- package/dist/optional.d.ts +9 -0
- package/dist/panel-5jvisQBr.js +367 -0
- package/dist/panel-5jvisQBr.js.map +1 -0
- package/dist/producer-ids.d.ts +15 -0
- package/dist/protocol-joKTjlMj.js +2 -0
- package/dist/protocol-joKTjlMj.js.map +1 -0
- package/dist/protocol.d.ts +238 -0
- package/dist/react/activity-rows.d.ts +12 -0
- package/dist/react/activity-view.d.ts +9 -0
- package/dist/react/control-locale.d.ts +25 -0
- package/dist/react/control-styles.d.ts +7 -0
- package/dist/react/control-ui.d.ts +37 -0
- package/dist/react/edge-filter.d.ts +36 -0
- package/dist/react/edge-filters.d.ts +17 -0
- package/dist/react/export-delivery.d.ts +33 -0
- package/dist/react/export-run.d.ts +20 -0
- package/dist/react/format.d.ts +17 -0
- package/dist/react/glyph.d.ts +20 -0
- package/dist/react/graph-layout.d.ts +67 -0
- package/dist/react/graph-view.d.ts +30 -0
- package/dist/react/graph-viewport.d.ts +48 -0
- package/dist/react/icons.d.ts +12 -0
- package/dist/react/inspector-view.d.ts +29 -0
- package/dist/react/label.d.ts +28 -0
- package/dist/react/lazy-module.d.ts +38 -0
- package/dist/react/legend-locale.d.ts +23 -0
- package/dist/react/legend.d.ts +10 -0
- package/dist/react/locale-context.d.ts +17 -0
- package/dist/react/locale.d.ts +115 -0
- package/dist/react/main-column.d.ts +22 -0
- package/dist/react/panel-header.d.ts +20 -0
- package/dist/react/panel-mode.d.ts +3 -0
- package/dist/react/panel-status.d.ts +19 -0
- package/dist/react/panel.d.ts +41 -0
- package/dist/react/search-results.d.ts +18 -0
- package/dist/react/selection.d.ts +15 -0
- package/dist/react/styles.d.ts +13 -0
- package/dist/react/theme.d.ts +39 -0
- package/dist/react/timeline-locale.d.ts +20 -0
- package/dist/react/timeline-view.d.ts +14 -0
- package/dist/react/tree.d.ts +26 -0
- package/dist/react/use-store.d.ts +11 -0
- package/dist/react.d.ts +16 -0
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -0
- package/dist/search-CC7avy6I.js +2 -0
- package/dist/search-CC7avy6I.js.map +1 -0
- package/dist/search.d.ts +20 -0
- package/dist/session-qjKT0E69.js +2 -0
- package/dist/session-qjKT0E69.js.map +1 -0
- package/dist/session.d.ts +59 -0
- package/dist/testing.d.ts +10 -0
- package/dist/testing.js +4 -0
- package/dist/testing.js.map +1 -0
- package/dist/timeline-view-ByPB1a7-.js +2 -0
- package/dist/timeline-view-ByPB1a7-.js.map +1 -0
- package/dist/timeline.d.ts +57 -0
- package/dist/visual-axes.d.ts +35 -0
- package/package.json +107 -0
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two projections of the diagnostic protocol: the immutable `plan` the application compiler produced and the
|
|
3
|
+
* `runtime` state of the world it opened. They are not one mutable graph object — a feature keeps its declaration
|
|
4
|
+
* while instances of it come and go — and merging them is exactly the mistake this protocol exists to prevent.
|
|
5
|
+
*
|
|
6
|
+
* `docs/devtools.md` §2 had a third, `resolutions`, holding frozen selection and admission
|
|
7
|
+
* reasons for capability resolution. The current compiler has no such history: a port has exactly one provider,
|
|
8
|
+
* chosen when `defineApplication` compiles the topology, and two providers are a compile error. The projection is
|
|
9
|
+
* gone rather than kept empty.
|
|
10
|
+
*
|
|
11
|
+
* The plan mirrors `runtime/src/application-compiler.ts` one node kind at a time: `CompiledApplicationFeatureIR`,
|
|
12
|
+
* `CompiledConditionGroupIR`, `ApplicationPortProviderIR`, `CompiledApplicationRequirementIR`,
|
|
13
|
+
* `ApplicationImportProviderIR` and `CompiledApplicationContributionIR`.
|
|
14
|
+
*/
|
|
15
|
+
import type { RuntimeActivitySnapshot } from './activity.js';
|
|
16
|
+
import type { AttachmentState, ConditionGroupState, ConditionState, ContributionState, FeatureInstanceState, HostContractState, PortState } from './node-state.js';
|
|
17
|
+
import type { DiagnosticCauseRef, DiagnosticConditionId, DiagnosticDesiredState, DiagnosticEdge, DiagnosticEdgeId, DiagnosticLabel, DiagnosticNodeId, DiagnosticPlanFingerprint, DiagnosticProvenance, DiagnosticSequence, DiagnosticSessionId, DiagnosticStateRevision, DiagnosticTopologyRevision, HostContractDemand } from './protocol.js';
|
|
18
|
+
declare const graphSchemaRevision = "opetope.devtools-graph/3";
|
|
19
|
+
declare const frameSchemaRevision = "opetope.devtools-frame/3";
|
|
20
|
+
type GraphSchemaRevision = typeof graphSchemaRevision;
|
|
21
|
+
type FrameSchemaRevision = typeof frameSchemaRevision;
|
|
22
|
+
type PlanNodeBase = Readonly<{
|
|
23
|
+
id: DiagnosticNodeId;
|
|
24
|
+
label: DiagnosticLabel;
|
|
25
|
+
provenance?: DiagnosticProvenance;
|
|
26
|
+
}>;
|
|
27
|
+
type ApplicationPlanNode = PlanNodeBase & Readonly<{
|
|
28
|
+
features: number;
|
|
29
|
+
groups: number;
|
|
30
|
+
kind: 'application';
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* A condition declaration. `defineCondition({ id })` is bound by the host at `openApplication`; `source` names the
|
|
34
|
+
* feature instead when `defineCondition({ from, id, select })` computes the fact from that feature's exports, and
|
|
35
|
+
* the host is then not allowed to bind the id at all (D102).
|
|
36
|
+
*/
|
|
37
|
+
type ConditionPlanNode = PlanNodeBase & Readonly<{
|
|
38
|
+
conditionId: DiagnosticConditionId;
|
|
39
|
+
kind: 'condition';
|
|
40
|
+
source: DiagnosticNodeId | 'host';
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* The inferred owner of activation: features whose `when` names the same set of conditions form one group (D93). The
|
|
44
|
+
* set decides membership, not the order; `order` is the canonical opening order the compiler derived from the hard
|
|
45
|
+
* edges, and closing runs it in reverse.
|
|
46
|
+
*/
|
|
47
|
+
type ConditionGroupPlanNode = PlanNodeBase & Readonly<{
|
|
48
|
+
conditions: readonly DiagnosticConditionId[];
|
|
49
|
+
kind: 'condition-group';
|
|
50
|
+
order: readonly DiagnosticNodeId[];
|
|
51
|
+
}>;
|
|
52
|
+
/** One `defineFeature`. `owner` is the application node for an empty `when`, otherwise its condition group. */
|
|
53
|
+
type FeaturePlanNode = PlanNodeBase & Readonly<{
|
|
54
|
+
kind: 'feature';
|
|
55
|
+
owner: DiagnosticNodeId;
|
|
56
|
+
}>;
|
|
57
|
+
/** One `definePort`. `provider` is absent when only `optional(port)` requires it and nothing provides it (D101). */
|
|
58
|
+
type PortPlanNode = PlanNodeBase & Readonly<{
|
|
59
|
+
kind: 'port';
|
|
60
|
+
provider?: DiagnosticNodeId;
|
|
61
|
+
}>;
|
|
62
|
+
/** One `defineHostContract`, seen as the `application-input` provider of the plan (D68, D83). */
|
|
63
|
+
type HostContractPlanNode = PlanNodeBase & Readonly<{
|
|
64
|
+
demand: HostContractDemand;
|
|
65
|
+
kind: 'host-contract';
|
|
66
|
+
optional: boolean;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* A feature export contract the plan names with nothing behind it: `ApplicationImportProviderIR` of kind `absent`,
|
|
70
|
+
* produced by `optional(featureDefinition)` when the application never enabled that feature. It is a node so an
|
|
71
|
+
* `absent-import` edge has an origin to point at; it never opens, and it has no owner (D105).
|
|
72
|
+
*/
|
|
73
|
+
type AbsentProviderPlanNode = PlanNodeBase & Readonly<{
|
|
74
|
+
kind: 'absent-provider';
|
|
75
|
+
}>;
|
|
76
|
+
/** A `defineSlot`, `definePipe` or `defineRegistry` target. Targets are declared standalone and own nothing. */
|
|
77
|
+
type ContributionTargetPlanNode = PlanNodeBase & Readonly<{
|
|
78
|
+
kind: 'contribution-target';
|
|
79
|
+
}>;
|
|
80
|
+
type ContributionPlanNode = PlanNodeBase & Readonly<{
|
|
81
|
+
contributor: DiagnosticNodeId;
|
|
82
|
+
kind: 'contribution';
|
|
83
|
+
priority: number;
|
|
84
|
+
target: DiagnosticNodeId;
|
|
85
|
+
}>;
|
|
86
|
+
type DiagnosticPlanNode = AbsentProviderPlanNode | ApplicationPlanNode | ConditionGroupPlanNode | ConditionPlanNode | ContributionPlanNode | ContributionTargetPlanNode | FeaturePlanNode | HostContractPlanNode | PortPlanNode;
|
|
87
|
+
/** Immutable inside one diagnostic session; a plan replacement opens a new `sessionId` instead of mutating (§2.1). */
|
|
88
|
+
type ApplicationPlanSnapshot = Readonly<{
|
|
89
|
+
absentProviders: readonly AbsentProviderPlanNode[];
|
|
90
|
+
application: ApplicationPlanNode;
|
|
91
|
+
conditions: readonly ConditionPlanNode[];
|
|
92
|
+
contributions: readonly ContributionPlanNode[];
|
|
93
|
+
/** Declaration-level edges. Instance-level ones live in `RuntimeStateSnapshot.edges`. */
|
|
94
|
+
edges: readonly DiagnosticEdge[];
|
|
95
|
+
features: readonly FeaturePlanNode[];
|
|
96
|
+
groups: readonly ConditionGroupPlanNode[];
|
|
97
|
+
hostContracts: readonly HostContractPlanNode[];
|
|
98
|
+
ports: readonly PortPlanNode[];
|
|
99
|
+
targets: readonly ContributionTargetPlanNode[];
|
|
100
|
+
}>;
|
|
101
|
+
type RuntimeNodeBase = Readonly<{
|
|
102
|
+
/** Immediate reason for the current state. Required for every state that is not healthy (§2.4). */
|
|
103
|
+
cause?: DiagnosticCauseRef;
|
|
104
|
+
/** The plan node this runtime record belongs to, when it is not itself a declaration. */
|
|
105
|
+
declaration?: DiagnosticNodeId;
|
|
106
|
+
id: DiagnosticNodeId;
|
|
107
|
+
label: DiagnosticLabel;
|
|
108
|
+
}>;
|
|
109
|
+
type ConditionRuntimeNode = Readonly<{
|
|
110
|
+
kind: 'condition';
|
|
111
|
+
state: ConditionState;
|
|
112
|
+
}> & RuntimeNodeBase;
|
|
113
|
+
type ConditionGroupRuntimeNode = Readonly<{
|
|
114
|
+
desired: DiagnosticDesiredState;
|
|
115
|
+
kind: 'condition-group';
|
|
116
|
+
state: ConditionGroupState;
|
|
117
|
+
}> & RuntimeNodeBase;
|
|
118
|
+
/**
|
|
119
|
+
* One open of one feature. `generation` is the kernel's counter, kept as a number and not as a concept (D110); it
|
|
120
|
+
* makes a restart visible without pretending the panel can address a past life.
|
|
121
|
+
*/
|
|
122
|
+
type FeatureInstanceNode = Readonly<{
|
|
123
|
+
generation: number;
|
|
124
|
+
/** The condition group that owns the desired axis, absent for a feature the application itself owns. */
|
|
125
|
+
group?: DiagnosticNodeId;
|
|
126
|
+
kind: 'feature-instance';
|
|
127
|
+
previous?: number;
|
|
128
|
+
state: FeatureInstanceState;
|
|
129
|
+
}> & RuntimeNodeBase;
|
|
130
|
+
type AttachmentNode = Readonly<{
|
|
131
|
+
kind: 'attachment';
|
|
132
|
+
owner: DiagnosticNodeId;
|
|
133
|
+
state: AttachmentState;
|
|
134
|
+
}> & RuntimeNodeBase;
|
|
135
|
+
type ContributionRuntimeNode = Readonly<{
|
|
136
|
+
contributor: DiagnosticNodeId;
|
|
137
|
+
kind: 'contribution';
|
|
138
|
+
state: ContributionState;
|
|
139
|
+
target: DiagnosticNodeId;
|
|
140
|
+
}> & RuntimeNodeBase;
|
|
141
|
+
type PortRuntimeNode = Readonly<{
|
|
142
|
+
kind: 'port';
|
|
143
|
+
state: PortState;
|
|
144
|
+
}> & RuntimeNodeBase;
|
|
145
|
+
type HostContractRuntimeNode = Readonly<{
|
|
146
|
+
kind: 'host-contract';
|
|
147
|
+
state: HostContractState;
|
|
148
|
+
}> & RuntimeNodeBase;
|
|
149
|
+
type DiagnosticRuntimeNode = AttachmentNode | ConditionGroupRuntimeNode | ConditionRuntimeNode | ContributionRuntimeNode | FeatureInstanceNode | HostContractRuntimeNode | PortRuntimeNode;
|
|
150
|
+
type DiagnosticNode = DiagnosticPlanNode | DiagnosticRuntimeNode;
|
|
151
|
+
/** Only the live world: current instances, their attachments, and the facts that decide what opens next. */
|
|
152
|
+
type RuntimeStateSnapshot = Readonly<{
|
|
153
|
+
attachments: readonly AttachmentNode[];
|
|
154
|
+
conditions: readonly ConditionRuntimeNode[];
|
|
155
|
+
contributions: readonly ContributionRuntimeNode[];
|
|
156
|
+
/** Instance-level edges: `owns`, live hard waits and the `Lookup` of every weak edge. */
|
|
157
|
+
edges: readonly DiagnosticEdge[];
|
|
158
|
+
groups: readonly ConditionGroupRuntimeNode[];
|
|
159
|
+
hostContracts: readonly HostContractRuntimeNode[];
|
|
160
|
+
instances: readonly FeatureInstanceNode[];
|
|
161
|
+
ports: readonly PortRuntimeNode[];
|
|
162
|
+
}>;
|
|
163
|
+
type RuntimeGraphSnapshot = Readonly<{
|
|
164
|
+
activity?: RuntimeActivitySnapshot;
|
|
165
|
+
lastSequence: DiagnosticSequence;
|
|
166
|
+
plan: ApplicationPlanSnapshot;
|
|
167
|
+
planFingerprint: DiagnosticPlanFingerprint;
|
|
168
|
+
runtime: RuntimeStateSnapshot;
|
|
169
|
+
schemaRevision: GraphSchemaRevision;
|
|
170
|
+
sessionId: DiagnosticSessionId;
|
|
171
|
+
stateRevision: DiagnosticStateRevision;
|
|
172
|
+
topologyRevision: DiagnosticTopologyRevision;
|
|
173
|
+
}>;
|
|
174
|
+
/**
|
|
175
|
+
* §6: a frame costs `O(changed nodes + changed edges)`, so it carries whole changed records rather than a copy of
|
|
176
|
+
* the graph. Plan nodes never appear here — topology is immutable within a session.
|
|
177
|
+
*/
|
|
178
|
+
type DiagnosticOperation = Readonly<{
|
|
179
|
+
edge: DiagnosticEdge;
|
|
180
|
+
op: 'upsert-edge';
|
|
181
|
+
}> | Readonly<{
|
|
182
|
+
id: DiagnosticEdgeId;
|
|
183
|
+
op: 'remove-edge';
|
|
184
|
+
}> | Readonly<{
|
|
185
|
+
id: DiagnosticNodeId;
|
|
186
|
+
op: 'remove-node';
|
|
187
|
+
}> | Readonly<{
|
|
188
|
+
node: DiagnosticRuntimeNode;
|
|
189
|
+
op: 'upsert-node';
|
|
190
|
+
}>;
|
|
191
|
+
/**
|
|
192
|
+
* One visible scheduler transaction. The panel must never see a state where a contribution is published but its
|
|
193
|
+
* owning instance is not yet committed, or where a contribution is still visible after a fence (§2).
|
|
194
|
+
*
|
|
195
|
+
* There is no commit timestamp. The only clock in the protocol is `cause.at`, which stamps the trigger; a frame with
|
|
196
|
+
* no cause has no time, and the timeline renders that column empty instead of stamping the moment the panel happened
|
|
197
|
+
* to reduce it.
|
|
198
|
+
*/
|
|
199
|
+
type RuntimeGraphFrame = Readonly<{
|
|
200
|
+
activity?: RuntimeActivitySnapshot;
|
|
201
|
+
baseRevision: DiagnosticStateRevision;
|
|
202
|
+
cause?: DiagnosticCauseRef;
|
|
203
|
+
firstSequence: DiagnosticSequence;
|
|
204
|
+
lastSequence: DiagnosticSequence;
|
|
205
|
+
nextRevision: DiagnosticStateRevision;
|
|
206
|
+
operations: readonly DiagnosticOperation[];
|
|
207
|
+
schemaRevision: FrameSchemaRevision;
|
|
208
|
+
sessionId: DiagnosticSessionId;
|
|
209
|
+
}>;
|
|
210
|
+
export { frameSchemaRevision, graphSchemaRevision };
|
|
211
|
+
export type { AbsentProviderPlanNode, ApplicationPlanNode, ApplicationPlanSnapshot, AttachmentNode, ConditionGroupPlanNode, ConditionGroupRuntimeNode, ConditionPlanNode, ConditionRuntimeNode, ContributionPlanNode, ContributionRuntimeNode, ContributionTargetPlanNode, DiagnosticNode, DiagnosticOperation, DiagnosticPlanNode, DiagnosticRuntimeNode, FeatureInstanceNode, FeaturePlanNode, GraphSchemaRevision, HostContractPlanNode, HostContractRuntimeNode, PortPlanNode, PortRuntimeNode, RuntimeGraphFrame, RuntimeGraphSnapshot, RuntimeStateSnapshot, };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type { ActivityOwner, CallActivity, FeatureActivity, ResourceActivity, ResourceLoadActivity, RuntimeActivitySnapshot, } from './activity.js';
|
|
2
|
+
export type { ControlAuditEntry, ControlCommand, ControlOutcome, ControlRejection, RuntimeControlSession, } from './control.js';
|
|
3
|
+
export { countEdges, countNodes, generateCorpus, largeCorpusShape, smallCorpusShape } from './corpus.js';
|
|
4
|
+
export type { Corpus, CorpusShape } from './corpus.js';
|
|
5
|
+
export { decodeFrame, decodeSnapshot, defaultDecodeLimits, DevtoolsDecodeError, parseProtocolText } from './decode.js';
|
|
6
|
+
export type { DecodeLimits } from './decode.js';
|
|
7
|
+
export { canonicalJson, digestOf, sameProtocolValue } from './digest.js';
|
|
8
|
+
export { exportSnapshot } from './export-snapshot.js';
|
|
9
|
+
export type { DevtoolsExport, ExportLimits } from './export-snapshot.js';
|
|
10
|
+
export { projectExtensionPoints } from './extension-points.js';
|
|
11
|
+
export type { ExtensionPointsProjection, ExtensionRow } from './extension-points.js';
|
|
12
|
+
export { foldFrames } from './fold-snapshot.js';
|
|
13
|
+
export type { AbsentProviderPlanNode, ApplicationPlanNode, ApplicationPlanSnapshot, AttachmentNode, ConditionGroupPlanNode, ConditionGroupRuntimeNode, ConditionPlanNode, ConditionRuntimeNode, ContributionPlanNode, ContributionRuntimeNode, ContributionTargetPlanNode, DiagnosticNode, DiagnosticOperation, DiagnosticPlanNode, DiagnosticRuntimeNode, FeatureInstanceNode, FeaturePlanNode, HostContractPlanNode, HostContractRuntimeNode, PortPlanNode, PortRuntimeNode, RuntimeGraphFrame, RuntimeGraphSnapshot, RuntimeStateSnapshot, } from './graph.js';
|
|
14
|
+
export { frameSchemaRevision, graphSchemaRevision } from './graph.js';
|
|
15
|
+
export { DiagnosticGraphIndex } from './graph-index.js';
|
|
16
|
+
export type { TreeFeatureRow, TreeGroupRow } from './graph-index.js';
|
|
17
|
+
export { DevtoolsGraphStore } from './graph-store.js';
|
|
18
|
+
export type { DevtoolsStoreStatus, FrameOutcome, FrameRejection } from './graph-store.js';
|
|
19
|
+
export { projectInspector } from './inspector.js';
|
|
20
|
+
export type { InspectorBlocker, InspectorBreadcrumb, InspectorOwned, InspectorProjection, InspectorWhy, } from './inspector.js';
|
|
21
|
+
export { failureOf, generationOf, progressOf } from './node-facts.js';
|
|
22
|
+
export type { AttachmentState, ConditionGroupState, ConditionState, ContributionState, DiagnosticCausalStep, DiagnosticNodeState, FeatureInstanceState, HostContractState, PortState, } from './node-state.js';
|
|
23
|
+
export { DevtoolsProtocolError, isDependencyEdge, isHardEdge, isWeakEdge } from './protocol.js';
|
|
24
|
+
export { diagnosticConditionId, diagnosticEdgeId, diagnosticNodeId, diagnosticPlanFingerprint, diagnosticSequence, diagnosticSessionId, diagnosticStateRevision, diagnosticTopologyRevision, } from './protocol.js';
|
|
25
|
+
export type { DesiredAxis, DiagnosticCauseKind, DiagnosticCauseRef, DiagnosticClosedReason, DiagnosticConditionId, DiagnosticDesiredState, DiagnosticEdge, DiagnosticEdgeId, DiagnosticEdgeKind, DiagnosticFailure, DiagnosticFailureCode, DiagnosticLabel, DiagnosticNodeId, DiagnosticNodeKind, DiagnosticOverride, DiagnosticPhase, DiagnosticPlanFingerprint, DiagnosticProvenance, DiagnosticSequence, DiagnosticSessionId, DiagnosticStateRevision, DiagnosticTimestamp, DiagnosticTopologyRevision, DiagnosticWaitReason, HardEdgeKind, HealthAxis, HostContractDemand, LifecycleAxis, StructuralEdgeKind, WeakEdgeKind, WeakEdgeState, } from './protocol.js';
|
|
26
|
+
export { searchGraph } from './search.js';
|
|
27
|
+
export type { SearchField, SearchHit } from './search.js';
|
|
28
|
+
export { connectDevtoolsSession } from './session.js';
|
|
29
|
+
export type { DevtoolsSession, DevtoolsSessionFailure, DevtoolsSessionOptions, ReadLimits, ReadResult, RuntimeInspectionSession, } from './session.js';
|
|
30
|
+
export { defaultTimelineLimits, DevtoolsTimeline } from './timeline.js';
|
|
31
|
+
export type { TimelineEntry, TimelineFrameEntry, TimelineGapEntry, TimelineLimits } from './timeline.js';
|
|
32
|
+
export { nodeAxes, nodeDisplayState, nodePosition } from './visual-axes.js';
|
|
33
|
+
export type { DiagnosticAxes, NodeDisplayState } from './visual-axes.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{g as H,f as V}from"./session-qjKT0E69.js";import{D as qn,a as Cn,b as Fn,c as Bn,d as Ln,n as An,e as Kn,h as Tn}from"./session-qjKT0E69.js";import{d as ce,a as K,b as T,c as b,e as de,f as ue,g as M,h as q,D as fe,m as _e,i as De,j as qe}from"./protocol-joKTjlMj.js";import{k as Gn,l as Jn,n as Un}from"./protocol-joKTjlMj.js";import{c as zn,d as Hn,f as Vn,s as Qn}from"./fold-snapshot-DjiURn8v.js";import{e as Yn}from"./export-snapshot-Buw-c6ZG.js";import{f as et,g as nt,p as tt,a as ot,b as rt,s as it}from"./search-CC7avy6I.js";const pe=de("corpus"),Ce=ue("corpus"),Q=b("corpus.application");function X(e){return b(`corpus.feature.${e}`)}function y(e){return b(`instance:corpus.feature.${e}`)}function C(e){return b(`group:corpus.${e}`)}function Y(e){return b(`corpus.condition.${e}`)}function G(e){return b(`host:corpus.feature.${e}`)}function F(e){return b(`port:corpus.${e}`)}function J(e){return b(`target:corpus.${e}`)}function B(e){return b(`contribution:corpus.${e}`)}function le(e){return b(`attachment:corpus.feature.${e}`)}function O(e,n,t){return{from:n,id:q(`${e}:${n}:${t}`),kind:e,to:t}}function ge(e,n){return{from:e,id:q(`hard-import:${e}:${n}`),kind:"hard-import",pending:!1,to:n}}function Fe(e,n){return{from:e,id:q(`requires-port:${e}:${n}`),kind:"requires-port",pending:!1,to:n}}function Z(e,n){return e%2===0?Q:C(e%n)}function ee(e){return e%4===0}function me(e){return e%2===1}function Be(e){const n=[],t=[],o=[],r=[],i=[],c=[];for(let a=0;a<e.features;a+=1){const m=X(a),w=Z(a,e.groups);n.push({id:m,kind:"feature",label:`corpus.feature.${a}`,owner:w}),t.push({demand:"instance",id:G(a),kind:"host-contract",label:`host ${a}`,optional:!1}),c.push(O("owns",w,m)),ee(a)&&(o.push({id:F(a),kind:"port",label:`port ${a}`,provider:m}),c.push(O("provides-port",m,F(a)))),me(a)&&(r.push({id:J(a),kind:"contribution-target",label:`target ${a}`}),i.push({contributor:m,id:B(a),kind:"contribution",label:`contribution ${a}`,priority:0,target:J(a)}),c.push(O("owns",m,B(a))),c.push(O("contributes-to",B(a),J(a))))}const d=[],s=[];for(let a=0;a<e.groups;a+=1){const m=n.filter(w=>w.owner===C(a)).map(w=>w.id);d.push({conditionId:M(`corpus.condition.${a}`),id:Y(a),kind:"condition",label:`corpus.condition.${a}`,source:"host"}),s.push({conditions:[M(`corpus.condition.${a}`)],id:C(a),kind:"condition-group",label:`group ${a}`,order:m}),c.push(O("condition-control",Y(a),C(a)))}return{absentProviders:[],application:{features:e.features,groups:e.groups,id:Q,kind:"application",label:"corpus"},conditions:d,contributions:i,edges:c,features:n,groups:s,hostContracts:t,ports:o,targets:r}}function Le(e){const n=[];for(let t=0;t<e.features;t+=1){n.push(O("owns",Z(t,e.groups),y(t))),n.push(O("owns",y(t),le(t))),n.push(ge(G(t),y(t)));for(let o=1;o<=e.importsPerFeature;o+=1){const r=(t+o*7)%e.features;r!==t&&n.push(ge(y(r),y(t)))}ee(t)||n.push(Fe(F(t-t%4),y(t)))}return n}function Ae(e){const n=[],t=[],o=[],r=[],i=[];for(let s=0;s<e.features;s+=1){const a=Z(s,e.groups);n.push({declaration:X(s),generation:1,...a===Q?{}:{group:a},id:y(s),kind:"feature-instance",label:`corpus.feature.${s}`,state:{kind:"ready"}}),t.push({id:le(s),kind:"attachment",label:`attachment ${s}`,owner:y(s),state:{kind:"ready"}}),r.push({declaration:G(s),id:G(s),kind:"host-contract",label:`host ${s}`,state:{kind:"bound"}}),ee(s)&&o.push({declaration:F(s),id:F(s),kind:"port",label:`port ${s}`,state:{instance:y(s),kind:"available"}}),me(s)&&i.push({contributor:y(s),declaration:B(s),id:B(s),kind:"contribution",label:`contribution ${s}`,state:{kind:"published"},target:J(s)})}const c=Array.from({length:e.groups},(s,a)=>({id:Y(a),kind:"condition",label:`corpus.condition.${a}`,state:{kind:"true"}})),d=Array.from({length:e.groups},(s,a)=>({desired:{effective:"active",override:"none",source:"active"},id:C(a),kind:"condition-group",label:`group ${a}`,state:{kind:"active"}}));return{lastSequence:T(0),plan:Be(e),planFingerprint:Ce,runtime:{attachments:t,conditions:c,contributions:i,edges:Le(e),groups:d,hostContracts:r,instances:n,ports:o},schemaRevision:H,sessionId:pe,stateRevision:K(0),topologyRevision:ce(1)}}function Ke(e,n){return Array.from({length:n},(t,o)=>{const r=o%e.features;return{baseRevision:K(o),cause:{kind:"instance-transition",node:y(r)},firstSequence:T(o+1),lastSequence:T(o+1),nextRevision:K(o+1),operations:[{node:{declaration:X(r),generation:1,id:y(r),kind:"feature-instance",label:`corpus.feature.${r}`,state:{kind:"fencing"}},op:"upsert-node"}],schemaRevision:V,sessionId:pe}})}function Te(e,n=0){return{frames:Ke(e,n),shape:e,snapshot:Ae(e)}}const Me={features:250,groups:8,importsPerFeature:14},Ge={features:5e3,groups:40,importsPerFeature:8};function Je(e){const{plan:n,runtime:t}=e;return 1+n.absentProviders.length+n.conditions.length+n.contributions.length+n.features.length+n.groups.length+n.hostContracts.length+n.ports.length+n.targets.length+t.attachments.length+t.instances.length}function Ue(e){return e.plan.edges.length+e.runtime.edges.length}class v extends Error{code;path;constructor(n,t,o){super(`${o} (at ${t})`),this.code=n,this.path=t,this.name="DevtoolsDecodeError"}}const We=new Set(["__proto__","constructor","prototype"]);function p(e,n){throw new v("malformed",e,n)}function ze(e,n){if(typeof e!="string")throw new v("unsafe-key",n,"Record has a symbol key");if(We.has(e))throw new v("unsafe-key",n,`Record has the key ${e}`);return e}function He(e,n,t){const o=Object.getOwnPropertyDescriptor(e,n);if((o==null?void 0:o.enumerable)===!0)return"value"in o||p(`${t}.${n}`,"Expected a data field, found an accessor"),{value:o.value}}function k(e,n){(typeof e!="object"||e===null||Array.isArray(e))&&p(n,"Expected a record");const t=new Map;for(const o of Reflect.ownKeys(e)){const r=ze(o,n),i=He(e,r,n);i!==void 0&&t.set(r,i.value)}return t}function R(e,n,t){if(typeof e!="string"&&p(n,"Expected a string"),e.length>t)throw new v("budget-exceeded",n,`String is longer than ${t}`);return e}function U(e,n){return(typeof e!="number"||!Number.isSafeInteger(e)||e<0)&&p(n,"Expected a non-negative safe integer"),e}function Ve(e,n){const t=U(e,n);return t>864e13&&p(n,"Expected a timestamp within the Date range"),t}function Qe(e,n){return(typeof e!="number"||!Number.isFinite(e))&&p(n,"Expected a finite number"),e}function he(e,n){return typeof e!="boolean"&&p(n,"Expected a boolean"),e}function W(e,n,t){Array.isArray(e)||p(n,"Expected an array");const{length:o}=e;if(o>t)throw new v("budget-exceeded",n,`Array holds more than ${t} entries`);const r=[];for(let i=0;i<o;i+=1){const c=Object.getOwnPropertyDescriptor(e,i);c===void 0&&p(`${n}[${i}]`,"Expected an entry, found a hole"),"value"in c||p(`${n}[${i}]`,"Expected a data entry, found an accessor"),r.push(c.value)}return r}function f(e,n,t){if(typeof e!="string"||!t.includes(e))throw new v("unknown-kind",n,`Expected one of ${t.join(", ")}`);return e}const be=Symbol("optional");function h(e){const n=(t,o,r)=>e(t,o,r);return Object.defineProperty(n,be,{value:!0}),n}function Xe(e){return e[be]===!0}function ne(e,n){return(t,o)=>{try{return e(R(t,o,n))}catch(r){throw r instanceof fe&&p(o,r.message),r}}}const u=ne(b,qe),ye=ne(q,De),te=ne(M,_e),S=(e,n,t)=>R(e,n,t.maxStringLength),l=(e,n)=>U(e,n),$e=(e,n)=>he(e,n);function x(e,n,t,o){const r=k(e,t),i={};for(const[c,d]of Object.entries(n)){const s=r.get(c);if(s===void 0){Xe(d)||p(`${t}.${c}`,"Required field is absent");continue}i[c]=d(s,`${t}.${c}`,o)}for(const c of r.keys())Object.prototype.hasOwnProperty.call(n,c)||p(`${t}.${c}`,"Unexpected field");return i}function L(e){return(n,t,o)=>W(n,t,o.maxEntries).map((r,i)=>e(r,`${t}[${i}]`,o))}const Ye=["activity-change","condition-change","contribution-change","control-command","failure","group-transition","instance-transition","plan-replacement","session-reset"],Ze=["close","drain","fence","open","retry","rollback"],ke={application:["closed"],call:["cancelled","closed","publication-rejected","unavailable"],contribution:["binding-invalid","duplicate","inactive","missing"],declaration:["invalid-id"],feature:["cleanup-failed","not-ready","quarantined","retired"],readable:["closed"]},oe=(e,n,t)=>{const o={at:h(Ve),condition:h(te),kind:(r,i)=>f(r,i,Ye),node:h(u),sequence:h(l)};return x(e,o,n,t)},j=(e,n,t)=>{const o=Object.keys(ke),r={cause:h(oe),code:S,phase:(d,s)=>f(d,s,Ze),subject:(d,s)=>f(d,s,o)},i=x(e,r,n,t),c=ke[i.subject]??[];return f(i.code,`${n}.code`,c),i},en=["application-closed","condition-inactive","debug-override","plan-replacement","retired"],nn=["awaiting-condition","awaiting-hard-import","awaiting-port","awaiting-turn"],xe=(e,n)=>f(e,n,en),tn=(e,n)=>f(e,n,nn),on={attachment:{closed:{},closing:{phase:(e,n)=>f(e,n,["close","retry","rollback"])},"failed-close":{failure:j},opening:{},ready:{}},condition:{false:{},"source-closed":{},true:{}},"condition-group":{active:{},closed:{},failed:{failure:j},inactive:{reason:xe},opening:{opened:l,total:l},retiring:{remaining:l}},contribution:{pending:{},published:{},rejected:{failure:j},withdrawn:{},withheld:{}},"feature-instance":{"cleanup-failed":{failure:j},draining:{},fencing:{},"not-ready":{failure:j},opening:{},quarantined:{failure:j},ready:{},retired:{reason:xe},waiting:{blockedBy:L(u),reason:tn}},"host-contract":{bound:{},deferred:{},unbound:{}},port:{absent:{},available:{instance:u},unavailable:{provider:u}}};function rn(e){return(n,t,o)=>{const r=on[e]??p(t,`No automaton for node kind ${e}`),i=k(n,t),c=f(i.get("kind"),`${t}.kind`,Object.keys(r));return{...x(n,{...r[c],kind:S},t,o),kind:c}}}const we={cause:h(oe),declaration:h(u),id:u,label:S},ve={attachment:{owner:u},condition:{},"condition-group":{desired:(e,n,t)=>x(e,{effective:(o,r)=>f(o,r,["active","inactive"]),override:(o,r)=>f(o,r,["force-inactive","none"]),source:(o,r)=>f(o,r,["active","inactive"])},n,t)},contribution:{contributor:u,target:u},"feature-instance":{generation:l,group:h(u),previous:h(l)},"host-contract":{},port:{}},sn={id:u,label:S,provenance:h(S)},an={"absent-provider":{},application:{features:l,groups:l},condition:{conditionId:te,source:S},"condition-group":{conditions:L(te),order:L(u)},contribution:{contributor:u,priority:Qe,target:u},"contribution-target":{},feature:{owner:u},"host-contract":{demand:(e,n)=>f(e,n,["instance","onDemand"]),optional:$e},port:{provider:h(u)}},cn=["hard-import","requires-port"],dn=["absent-import","absent-port","optional-import","optional-port"],un=["condition-control","contributes-to","on-demand-import","owns","provides-port"],re={from:u,id:ye,to:u};function fn(e,n){return cn.includes(e)?{...re,kind:S,pending:$e}:dn.includes(e)?{...re,kind:S,lookup:(t,o)=>f(t,o,["found","missing"])}:un.includes(e)?{...re,kind:S}:p(n,`Unknown edge kind ${e}`)}const Se=(e,n,t)=>{const o=k(e,n),r=R(o.get("kind"),`${n}.kind`,t.maxStringLength);return x(e,fn(r,`${n}.kind`),n,t)};function ie(e,n,t,o){return(r,i,c)=>{const d=k(r,i),s=f(d.get("kind"),`${i}.kind`,o===void 0?Object.keys(e):[o]),a={...n,...e[s],kind:S,...t?{state:rn(s)}:{}};return x(r,a,i,c)}}const pn=ie(ve,we,!0);function E(e){return ie(an,sn,!1,e)}function N(e){return ie(ve,we,!0,e)}const $=(e,n,t)=>R(e,n,t.maxStringLength),P=(e,n)=>U(e,n),Ee=(e,n)=>he(e,n),g=e=>(n,t)=>f(n,t,e),se=e=>(n,t,o)=>n==="unknown"?n:e(n,t,o),I=e=>(n,t,o)=>x(n,e,t,o),ae={feature:$,generation:P,instance:$},ln=I({...ae,body:g(["eager","loaded","loading","not-loaded","unknown"]),demandCount:g(["unknown"]),id:$,phase:g(["draining","failed","fenced","opening","quarantined","ready"])}),gn=I({blockedBy:se(L($)),declaration:$,id:$}),mn=I({callId:$,declaration:$,id:$,lane:(e,n,t)=>e===null?null:gn(e,n,t),owner:I(ae),pendingWaiters:P,state:g(["draining","queued","running"])}),hn=I({attempt:P,generation:P,id:$,state:g(["draining","running","scheduled"])});function Re(e,n,t){const o=k(e,n),r=U(o.get("capacity"),`${n}.capacity`);let i=Math.min(r,t.maxEntries);const c=s=>(a,m,w)=>{const A=W(a,m,i);return i-=A.length,A.map((Pe,je)=>s(Pe,`${m}[${je}]`,w))},d=I({generation:P,id:$,kind:g(["resource","stream"]),loads:se(c(hn)),owner:I(ae),retainers:se(P),retention:g(["observer","scope","unknown"]),state:g(["error","fenced","idle","opening","ready","refreshing"])});return x(e,{calls:c(mn),capacity:P,closed:Ee,coverage:I({calls:g(["feature-and-owned-model"]),hostDemand:g(["unknown"]),resources:g(["registered-resource-controllers"]),streams:g(["state-only"]),uiModels:g(["unknown"])}),executionId:$,features:c(ln),freshness:g(["live","stale"]),resources:c(d),schemaRevision:g(["opetope.runtime-activity/1"]),truncated:Ee},n,t)}const z={maxBytes:16*1024*1024,maxEdges:6e4,maxNodes:2e4,maxOperations:1e4,maxStringLength:512};function _(e,n){return{maxEntries:n,maxStringLength:e.maxStringLength}}function Ie(e,n,t,o,r){const i=k(e,o),c={};let d=r.maxNodes;for(const[s,a]of Object.entries(n)){const m=W(i.get(s),`${o}.${s}`,d);if(d-=m.length,d<0)throw new v("budget-exceeded",o,`Snapshot holds more than ${r.maxNodes} nodes`);c[s]=m.map((w,A)=>a(w,`${o}.${s}[${A}]`,_(r,r.maxNodes)))}for(const s of i.keys())!Object.prototype.hasOwnProperty.call(n,s)&&!t.includes(s)&&p(`${o}.${s}`,"Unexpected field");return c}const bn=E("application"),yn={absentProviders:E("absent-provider"),conditions:E("condition"),contributions:E("contribution"),features:E("feature"),groups:E("condition-group"),hostContracts:E("host-contract"),ports:E("port"),targets:E("contribution-target")},$n={attachments:N("attachment"),conditions:N("condition"),contributions:N("contribution"),groups:N("condition-group"),hostContracts:N("host-contract"),instances:N("feature-instance"),ports:N("port")};function Oe(e,n,t){const o=_(t,t.maxEdges);return W(e,n,t.maxEdges).map((r,i)=>Se(r,`${n}[${i}]`,o))}function kn(e,n,t){const o=k(e,n),r=bn(o.get("application"),`${n}.application`,_(t,1));return{...Ie(e,yn,["application","edges"],n,t),application:r,edges:Oe(o.get("edges"),`${n}.edges`,t)}}function xn(e,n,t){const o=k(e,n);return{...Ie(e,$n,["edges"],n,t),edges:Oe(o.get("edges"),`${n}.edges`,t)}}function wn(e,n=z){const t="snapshot",o=k(e,t);f(o.get("schemaRevision"),`${t}.schemaRevision`,[H]);const r={activity:h(Re),lastSequence:l,plan:(i,c)=>kn(i,c,n),planFingerprint:(i,c)=>R(i,c,n.maxStringLength),runtime:(i,c)=>xn(i,c,n),schemaRevision:(i,c)=>R(i,c,n.maxStringLength),sessionId:(i,c)=>R(i,c,n.maxStringLength),stateRevision:l,topologyRevision:l};return x(e,r,t,_(n,n.maxNodes))}function D(e,n,t){return R(e,n,t.maxStringLength)}const Ne={"remove-edge":{id:ye,op:D},"remove-node":{id:u,op:D},"upsert-edge":{edge:Se,op:D},"upsert-node":{node:pn,op:D}};function vn(e,n,t){const o=k(e,n),r=f(o.get("op"),`${n}.op`,Object.keys(Ne)),i=Ne[r];return i===void 0&&p(`${n}.op`,`No shape for operation ${r}`),x(e,i,n,t)}function Sn(e,n=z){const t="frame",o=k(e,t);f(o.get("schemaRevision"),`${t}.schemaRevision`,[V]);const r=_(n,n.maxOperations),i={activity:h((c,d)=>Re(c,d,_(n,n.maxNodes))),baseRevision:l,cause:h(oe),firstSequence:l,lastSequence:l,nextRevision:l,operations:L(vn),schemaRevision:D,sessionId:D};return x(e,i,t,r)}function En(e){return e>=55296&&e<=56319}function Rn(e){return e>=56320&&e<=57343}function In(e){return e<128?1:e<2048?2:3}function On(e){let n=0;for(let t=0;t<e.length;t+=1){const o=e.charCodeAt(t),r=En(o)&&Rn(e.charCodeAt(t+1));r&&(t+=1),n+=r?4:In(o)}return n}function Nn(e,n=z){if(e.length>n.maxBytes||e.length*3>n.maxBytes&&On(e)>n.maxBytes)throw new v("budget-exceeded","text",`Payload is larger than ${n.maxBytes} bytes`);try{return JSON.parse(e)}catch(o){throw new v("malformed","text",`Payload is not JSON: ${String(o)}`)}}export{v as DevtoolsDecodeError,qn as DevtoolsGraphStore,fe as DevtoolsProtocolError,Cn as DevtoolsTimeline,Fn as DiagnosticGraphIndex,zn as canonicalJson,Bn as connectDevtoolsSession,Ue as countEdges,Je as countNodes,Sn as decodeFrame,wn as decodeSnapshot,z as defaultDecodeLimits,Ln as defaultTimelineLimits,M as diagnosticConditionId,q as diagnosticEdgeId,b as diagnosticNodeId,ue as diagnosticPlanFingerprint,T as diagnosticSequence,de as diagnosticSessionId,K as diagnosticStateRevision,ce as diagnosticTopologyRevision,Hn as digestOf,Yn as exportSnapshot,et as failureOf,Vn as foldFrames,V as frameSchemaRevision,Te as generateCorpus,nt as generationOf,H as graphSchemaRevision,Gn as isDependencyEdge,Jn as isHardEdge,Un as isWeakEdge,Ge as largeCorpusShape,An as nodeAxes,Kn as nodeDisplayState,Tn as nodePosition,Nn as parseProtocolText,tt as progressOf,ot as projectExtensionPoints,rt as projectInspector,Qn as sameProtocolValue,it as searchGraph,Me as smallCorpusShape};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/corpus.ts","../src/decode-values.ts","../src/decode-shapes.ts","../src/decode-activity.ts","../src/decode.ts"],"sourcesContent":["/**\n * A synthetic application graph for the performance gates of `docs/devtools.md` §6, and the\n * frames that move it.\n *\n * It is generated, not captured, and deterministic by construction: no clock, no randomness, node and edge counts a\n * pure function of the shape asked for. That is what lets §6's \"deterministic digest\" be an assertion rather than\n * a hope, and it lets one corpus be compared against another run, another machine and another revision.\n *\n * The shape mirrors a real application rather than a star or a chain: features are split across condition groups,\n * each feature imports a host contract and a few peers, a quarter of them provide a port, and half contribute.\n */\n\nimport type {\n ApplicationPlanSnapshot,\n AttachmentNode,\n ConditionGroupPlanNode,\n ConditionGroupRuntimeNode,\n ConditionPlanNode,\n ContributionPlanNode,\n ContributionRuntimeNode,\n ContributionTargetPlanNode,\n FeatureInstanceNode,\n FeaturePlanNode,\n HostContractPlanNode,\n HostContractRuntimeNode,\n PortPlanNode,\n PortRuntimeNode,\n RuntimeGraphFrame,\n RuntimeGraphSnapshot,\n} from './graph';\nimport { frameSchemaRevision, graphSchemaRevision } from './graph';\nimport type { DiagnosticEdge, DiagnosticNodeId } from './protocol';\nimport {\n diagnosticConditionId,\n diagnosticEdgeId,\n diagnosticNodeId,\n diagnosticPlanFingerprint,\n diagnosticSequence,\n diagnosticSessionId,\n diagnosticStateRevision,\n diagnosticTopologyRevision,\n} from './protocol';\n\ntype CorpusShape = Readonly<{\n features: number;\n groups: number;\n /** Peers each feature imports. Drives the edge count without changing the node count. */\n importsPerFeature: number;\n}>;\n\ntype Corpus = Readonly<{\n /** One frame per changed instance, each carrying one operation: the `O(delta)` case of §6. */\n frames: readonly RuntimeGraphFrame[];\n shape: CorpusShape;\n snapshot: RuntimeGraphSnapshot;\n}>;\n\nconst sessionId = diagnosticSessionId('corpus');\nconst planFingerprint = diagnosticPlanFingerprint('corpus');\nconst applicationId = diagnosticNodeId('corpus.application');\n\nfunction featureId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`corpus.feature.${index}`);\n}\n\nfunction instanceId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`instance:corpus.feature.${index}`);\n}\n\nfunction groupId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`group:corpus.${index}`);\n}\n\nfunction conditionNodeId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`corpus.condition.${index}`);\n}\n\nfunction hostId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`host:corpus.feature.${index}`);\n}\n\nfunction portId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`port:corpus.${index}`);\n}\n\nfunction targetId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`target:corpus.${index}`);\n}\n\nfunction contributionId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`contribution:corpus.${index}`);\n}\n\nfunction attachmentId(index: number): DiagnosticNodeId {\n return diagnosticNodeId(`attachment:corpus.feature.${index}`);\n}\n\nfunction edge(\n kind: 'condition-control' | 'contributes-to' | 'owns' | 'provides-port',\n from: DiagnosticNodeId,\n to: DiagnosticNodeId,\n): DiagnosticEdge {\n return { from, id: diagnosticEdgeId(`${kind}:${from}:${to}`), kind, to };\n}\n\nfunction hardImport(from: DiagnosticNodeId, to: DiagnosticNodeId): DiagnosticEdge {\n return { from, id: diagnosticEdgeId(`hard-import:${from}:${to}`), kind: 'hard-import', pending: false, to };\n}\n\nfunction requiresPort(from: DiagnosticNodeId, to: DiagnosticNodeId): DiagnosticEdge {\n return { from, id: diagnosticEdgeId(`requires-port:${from}:${to}`), kind: 'requires-port', pending: false, to };\n}\n\n/** A feature belongs to the application when its index is even, to a condition group otherwise. */\nfunction ownerOf(index: number, groups: number): DiagnosticNodeId {\n return index % 2 === 0 ? applicationId : groupId(index % groups);\n}\n\nfunction providesPort(index: number): boolean {\n return index % 4 === 0;\n}\n\nfunction contributes(index: number): boolean {\n return index % 2 === 1;\n}\n\nfunction buildPlan(shape: CorpusShape): ApplicationPlanSnapshot {\n const features: FeaturePlanNode[] = [];\n const hostContracts: HostContractPlanNode[] = [];\n const ports: PortPlanNode[] = [];\n const targets: ContributionTargetPlanNode[] = [];\n const contributions: ContributionPlanNode[] = [];\n const edges: DiagnosticEdge[] = [];\n\n for (let index = 0; index < shape.features; index += 1) {\n const feature = featureId(index);\n const owner = ownerOf(index, shape.groups);\n\n features.push({ id: feature, kind: 'feature', label: `corpus.feature.${index}`, owner });\n hostContracts.push({\n demand: 'instance',\n id: hostId(index),\n kind: 'host-contract',\n label: `host ${index}`,\n optional: false,\n });\n edges.push(edge('owns', owner, feature));\n\n if (providesPort(index)) {\n ports.push({ id: portId(index), kind: 'port', label: `port ${index}`, provider: feature });\n edges.push(edge('provides-port', feature, portId(index)));\n }\n\n if (contributes(index)) {\n targets.push({ id: targetId(index), kind: 'contribution-target', label: `target ${index}` });\n contributions.push({\n contributor: feature,\n id: contributionId(index),\n kind: 'contribution',\n label: `contribution ${index}`,\n priority: 0,\n target: targetId(index),\n });\n edges.push(edge('owns', feature, contributionId(index)));\n edges.push(edge('contributes-to', contributionId(index), targetId(index)));\n }\n }\n\n const conditions: ConditionPlanNode[] = [];\n const groups: ConditionGroupPlanNode[] = [];\n\n for (let index = 0; index < shape.groups; index += 1) {\n const members = features.filter(feature => feature.owner === groupId(index)).map(feature => feature.id);\n\n conditions.push({\n conditionId: diagnosticConditionId(`corpus.condition.${index}`),\n id: conditionNodeId(index),\n kind: 'condition',\n label: `corpus.condition.${index}`,\n source: 'host',\n });\n groups.push({\n conditions: [diagnosticConditionId(`corpus.condition.${index}`)],\n id: groupId(index),\n kind: 'condition-group',\n label: `group ${index}`,\n order: members,\n });\n edges.push(edge('condition-control', conditionNodeId(index), groupId(index)));\n }\n\n return {\n absentProviders: [],\n application: {\n features: shape.features,\n groups: shape.groups,\n id: applicationId,\n kind: 'application',\n label: 'corpus',\n },\n conditions,\n contributions,\n edges,\n features,\n groups,\n hostContracts,\n ports,\n targets,\n };\n}\n\nfunction buildRuntimeEdges(shape: CorpusShape): readonly DiagnosticEdge[] {\n const edges: DiagnosticEdge[] = [];\n\n for (let index = 0; index < shape.features; index += 1) {\n edges.push(edge('owns', ownerOf(index, shape.groups), instanceId(index)));\n edges.push(edge('owns', instanceId(index), attachmentId(index)));\n edges.push(hardImport(hostId(index), instanceId(index)));\n\n for (let step = 1; step <= shape.importsPerFeature; step += 1) {\n const provider = (index + step * 7) % shape.features;\n\n if (provider === index) continue;\n\n edges.push(hardImport(instanceId(provider), instanceId(index)));\n }\n\n if (!providesPort(index)) {\n edges.push(requiresPort(portId(index - (index % 4)), instanceId(index)));\n }\n }\n\n return edges;\n}\n\nfunction buildSnapshot(shape: CorpusShape): RuntimeGraphSnapshot {\n const instances: FeatureInstanceNode[] = [];\n const attachments: AttachmentNode[] = [];\n const ports: PortRuntimeNode[] = [];\n const hostContracts: HostContractRuntimeNode[] = [];\n const contributions: ContributionRuntimeNode[] = [];\n\n for (let index = 0; index < shape.features; index += 1) {\n const owner = ownerOf(index, shape.groups);\n\n instances.push({\n declaration: featureId(index),\n generation: 1,\n ...(owner === applicationId ? {} : { group: owner }),\n id: instanceId(index),\n kind: 'feature-instance',\n label: `corpus.feature.${index}`,\n state: { kind: 'ready' },\n });\n attachments.push({\n id: attachmentId(index),\n kind: 'attachment',\n label: `attachment ${index}`,\n owner: instanceId(index),\n state: { kind: 'ready' },\n });\n hostContracts.push({\n declaration: hostId(index),\n id: hostId(index),\n kind: 'host-contract',\n label: `host ${index}`,\n state: { kind: 'bound' },\n });\n\n if (providesPort(index)) {\n ports.push({\n declaration: portId(index),\n id: portId(index),\n kind: 'port',\n label: `port ${index}`,\n state: { instance: instanceId(index), kind: 'available' },\n });\n }\n\n if (contributes(index)) {\n contributions.push({\n contributor: instanceId(index),\n declaration: contributionId(index),\n id: contributionId(index),\n kind: 'contribution',\n label: `contribution ${index}`,\n state: { kind: 'published' },\n target: targetId(index),\n });\n }\n }\n\n const conditions = Array.from({ length: shape.groups }, (_unused, index) => ({\n id: conditionNodeId(index),\n kind: 'condition' as const,\n label: `corpus.condition.${index}`,\n state: { kind: 'true' as const },\n }));\n const groups: ConditionGroupRuntimeNode[] = Array.from({ length: shape.groups }, (_unused, index) => ({\n desired: { effective: 'active', override: 'none', source: 'active' },\n id: groupId(index),\n kind: 'condition-group',\n label: `group ${index}`,\n state: { kind: 'active' },\n }));\n\n return {\n lastSequence: diagnosticSequence(0),\n plan: buildPlan(shape),\n planFingerprint,\n runtime: {\n attachments,\n conditions,\n contributions,\n edges: buildRuntimeEdges(shape),\n groups,\n hostContracts,\n instances,\n ports,\n },\n schemaRevision: graphSchemaRevision,\n sessionId,\n stateRevision: diagnosticStateRevision(0),\n topologyRevision: diagnosticTopologyRevision(1),\n };\n}\n\n/** One commit per frame, one changed record per commit: the smallest delta a producer can publish. */\nfunction buildFrames(shape: CorpusShape, count: number): readonly RuntimeGraphFrame[] {\n return Array.from({ length: count }, (_unused, step) => {\n const index = step % shape.features;\n\n return {\n baseRevision: diagnosticStateRevision(step),\n cause: { kind: 'instance-transition' as const, node: instanceId(index) },\n firstSequence: diagnosticSequence(step + 1),\n lastSequence: diagnosticSequence(step + 1),\n nextRevision: diagnosticStateRevision(step + 1),\n operations: [\n {\n node: {\n declaration: featureId(index),\n generation: 1,\n id: instanceId(index),\n kind: 'feature-instance' as const,\n label: `corpus.feature.${index}`,\n state: { kind: 'fencing' as const },\n },\n op: 'upsert-node' as const,\n },\n ],\n schemaRevision: frameSchemaRevision,\n sessionId,\n };\n });\n}\n\nfunction generateCorpus(shape: CorpusShape, frames = 0): Corpus {\n return { frames: buildFrames(shape, frames), shape, snapshot: buildSnapshot(shape) };\n}\n\n/** Roughly 1k nodes and 5k edges: the interactive budget of §6. */\nconst smallCorpusShape: CorpusShape = { features: 250, groups: 8, importsPerFeature: 14 };\n\n/** Roughly 20k nodes and 60k edges: the headless budget of §6. */\nconst largeCorpusShape: CorpusShape = { features: 5_000, groups: 40, importsPerFeature: 8 };\n\nfunction countNodes(snapshot: RuntimeGraphSnapshot): number {\n const { plan, runtime } = snapshot;\n\n return (\n 1 +\n plan.absentProviders.length +\n plan.conditions.length +\n plan.contributions.length +\n plan.features.length +\n plan.groups.length +\n plan.hostContracts.length +\n plan.ports.length +\n plan.targets.length +\n runtime.attachments.length +\n runtime.instances.length\n );\n}\n\nfunction countEdges(snapshot: RuntimeGraphSnapshot): number {\n return snapshot.plan.edges.length + snapshot.runtime.edges.length;\n}\n\nexport { countEdges, countNodes, generateCorpus, largeCorpusShape, smallCorpusShape };\nexport type { Corpus, CorpusShape };\n","/**\n * Primitive readers for the hostile boundary of `docs/devtools.md` §7 and `spec.md` §4\n * (\"hostile-boundary валидация только на входе внешних данных\").\n *\n * Two hostile shapes are handled here rather than anywhere else. A property that is not a *data* descriptor is\n * rejected before it is read — a field of a record and an entry of an array alike — so a getter cannot run code\n * inside the decoder; and the three keys that reach `Object.prototype` are rejected outright, so a decoded record\n * can never pollute it.\n *\n * There is no depth budget because there is no unbounded recursion to budget: the decoder only ever descends into\n * shapes it declares, so a deeply nested payload is rejected at the first field that is not of the declared type.\n */\n\nclass DevtoolsDecodeError extends Error {\n public constructor(\n public readonly code: 'budget-exceeded' | 'malformed' | 'unknown-kind' | 'unsafe-key',\n public readonly path: string,\n message: string,\n ) {\n super(`${message} (at ${path})`);\n this.name = 'DevtoolsDecodeError';\n }\n}\n\nconst unsafeKeys: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype']);\n\nfunction malformed(path: string, message: string): never {\n throw new DevtoolsDecodeError('malformed', path, message);\n}\n\nfunction requireSafeKey(key: PropertyKey, path: string): string {\n if (typeof key !== 'string') throw new DevtoolsDecodeError('unsafe-key', path, 'Record has a symbol key');\n\n if (unsafeKeys.has(key)) throw new DevtoolsDecodeError('unsafe-key', path, `Record has the key ${key}`);\n\n return key;\n}\n\n/** The value of one own field, or `undefined` when the field is not enumerable and therefore not part of the record. */\nfunction fieldValue(source: object, key: string, path: string): { readonly value: unknown } | undefined {\n const descriptor = Object.getOwnPropertyDescriptor(source, key);\n\n if (descriptor?.enumerable !== true) return undefined;\n\n if (!('value' in descriptor)) malformed(`${path}.${key}`, 'Expected a data field, found an accessor');\n\n return { value: descriptor.value };\n}\n\n/** Own enumerable data fields only: an accessor would let the payload execute code during decoding. */\nfunction dataFields(value: unknown, path: string): ReadonlyMap<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) malformed(path, 'Expected a record');\n\n const fields = new Map<string, unknown>();\n\n for (const raw of Reflect.ownKeys(value)) {\n const key = requireSafeKey(raw, path);\n const field = fieldValue(value, key, path);\n\n if (field !== undefined) fields.set(key, field.value);\n }\n\n return fields;\n}\n\nfunction readString(value: unknown, path: string, maxLength: number): string {\n if (typeof value !== 'string') malformed(path, 'Expected a string');\n\n if (value.length > maxLength) {\n throw new DevtoolsDecodeError('budget-exceeded', path, `String is longer than ${maxLength}`);\n }\n\n return value;\n}\n\nfunction readCount(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n malformed(path, 'Expected a non-negative safe integer');\n }\n\n return value;\n}\n\n/** Epoch milliseconds also have to fit Date's range before a consumer can format them. */\nfunction readTimestamp(value: unknown, path: string): number {\n const timestamp = readCount(value, path);\n\n if (timestamp > 8_640_000_000_000_000) malformed(path, 'Expected a timestamp within the Date range');\n\n return timestamp;\n}\n\n/** D212: ordering priority is any finite number; sequence/revision/count fields keep their integer domain. */\nfunction readFiniteNumber(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) malformed(path, 'Expected a finite number');\n\n return value;\n}\n\nfunction readBoolean(value: unknown, path: string): boolean {\n if (typeof value !== 'boolean') malformed(path, 'Expected a boolean');\n\n return value;\n}\n\n/**\n * Entries are copied out by index through their own descriptors, never by `map` or any other method of the incoming\n * array: an element can be an accessor just as a field can, and the array's own methods can be replaced. The result\n * is a fresh array the callers may iterate with their own `map` safely.\n */\nfunction readArray(value: unknown, path: string, budget: number): readonly unknown[] {\n if (!Array.isArray(value)) malformed(path, 'Expected an array');\n\n const { length } = value;\n\n if (length > budget) {\n throw new DevtoolsDecodeError('budget-exceeded', path, `Array holds more than ${budget} entries`);\n }\n\n const entries: unknown[] = [];\n\n for (let index = 0; index < length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(value, index);\n\n if (descriptor === undefined) malformed(`${path}[${index}]`, 'Expected an entry, found a hole');\n\n if (!('value' in descriptor)) malformed(`${path}[${index}]`, 'Expected a data entry, found an accessor');\n\n entries.push(descriptor.value);\n }\n\n return entries;\n}\n\n/** A literal from a closed set. Anything else is an unknown kind, which is a rejected record, never a default. */\nfunction readLiteral<Value extends string>(value: unknown, path: string, allowed: readonly Value[]): Value {\n if (typeof value !== 'string' || !(allowed as readonly string[]).includes(value)) {\n throw new DevtoolsDecodeError('unknown-kind', path, `Expected one of ${allowed.join(', ')}`);\n }\n\n return value as Value;\n}\n\nexport {\n dataFields,\n DevtoolsDecodeError,\n malformed,\n readArray,\n readBoolean,\n readCount,\n readFiniteNumber,\n readLiteral,\n readString,\n readTimestamp,\n};\n","/**\n * The schema of the protocol, expressed as shapes a decoder can walk. Every node kind, every state of every automaton\n * and every edge kind is listed once here, so a payload that names a state the runtime cannot be in is rejected\n * rather than passed through as an unknown string (§7).\n *\n * A shape is a record of readers. `readShape` requires exactly those keys — a missing one is malformed and an extra\n * one is malformed too, because the schema revision, not tolerance, is what carries compatibility forward.\n */\n\nimport {\n dataFields,\n malformed,\n readArray,\n readBoolean,\n readCount,\n readFiniteNumber,\n readLiteral,\n readString,\n readTimestamp,\n} from './decode-values';\nimport {\n DevtoolsProtocolError,\n diagnosticConditionId,\n diagnosticEdgeId,\n diagnosticNodeId,\n maxEdgeId,\n maxEncodedAtom,\n maxNodeId,\n} from './protocol';\n\ntype DecodeContext = Readonly<{\n maxEntries: number;\n maxStringLength: number;\n}>;\n\ntype Reader = (value: unknown, path: string, context: DecodeContext) => unknown;\n\ntype Shape = Readonly<Record<string, Reader>>;\n\nconst optionalMarker = Symbol('optional');\n\ntype OptionalReader = Reader & { readonly [optionalMarker]?: true };\n\nfunction optional(reader: Reader): OptionalReader {\n const wrapped: OptionalReader = (value, path, context) => reader(value, path, context);\n\n Object.defineProperty(wrapped, optionalMarker, { value: true });\n\n return wrapped;\n}\n\nfunction isOptional(reader: Reader): boolean {\n return (reader as OptionalReader)[optionalMarker] === true;\n}\n\n/** Branded ids reuse the protocol's own validator, so the decoder and the producer agree on what an id is. */\n/**\n * An id is read against its own length, not against the label budget: a composed id is legitimately longer than a\n * label, and `maxStringLength` bounds prose. The record and byte budgets of the payload are untouched by this.\n */\nfunction brandedId<Value>(make: (value: string) => Value, limit: number): Reader {\n return (value, path) => {\n try {\n return make(readString(value, path, limit));\n } catch (error) {\n if (error instanceof DevtoolsProtocolError) malformed(path, error.message);\n\n throw error;\n }\n };\n}\n\nconst readNodeId = brandedId(diagnosticNodeId, maxNodeId);\nconst readEdgeId = brandedId(diagnosticEdgeId, maxEdgeId);\nconst readConditionId = brandedId(diagnosticConditionId, maxEncodedAtom);\nconst readLabel: Reader = (value, path, context) => readString(value, path, context.maxStringLength);\nconst readNumber: Reader = (value, path) => readCount(value, path);\nconst readFlag: Reader = (value, path) => readBoolean(value, path);\n\nfunction readShape(value: unknown, shape: Shape, path: string, context: DecodeContext): Record<string, unknown> {\n const fields = dataFields(value, path);\n const result: Record<string, unknown> = {};\n\n for (const [key, reader] of Object.entries(shape)) {\n const field = fields.get(key);\n\n if (field === undefined) {\n if (!isOptional(reader)) malformed(`${path}.${key}`, 'Required field is absent');\n\n continue;\n }\n\n result[key] = reader(field, `${path}.${key}`, context);\n }\n\n for (const key of fields.keys()) {\n if (!Object.prototype.hasOwnProperty.call(shape, key)) malformed(`${path}.${key}`, 'Unexpected field');\n }\n\n return result;\n}\n\nfunction listOf(reader: Reader): Reader {\n return (value, path, context) =>\n readArray(value, path, context.maxEntries).map((entry, index) => reader(entry, `${path}[${index}]`, context));\n}\n\nconst causeKinds = [\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] as const;\n\nconst phases = ['close', 'drain', 'fence', 'open', 'retry', 'rollback'] as const;\n\n/** Subject and code are one union, so a contribution code can never arrive under a feature failure (D69). */\nconst failureCodesBySubject: Readonly<Record<string, readonly string[]>> = {\n application: ['closed'],\n call: ['cancelled', 'closed', 'publication-rejected', 'unavailable'],\n contribution: ['binding-invalid', 'duplicate', 'inactive', 'missing'],\n declaration: ['invalid-id'],\n feature: ['cleanup-failed', 'not-ready', 'quarantined', 'retired'],\n readable: ['closed'],\n};\n\nconst readCause: Reader = (value, path, context) => {\n const shape: Shape = {\n at: optional(readTimestamp),\n condition: optional(readConditionId),\n kind: (kind, at) => readLiteral(kind, at, causeKinds),\n node: optional(readNodeId),\n sequence: optional(readNumber),\n };\n\n return readShape(value, shape, path, context);\n};\n\nconst readFailure: Reader = (value, path, context) => {\n const subjects = Object.keys(failureCodesBySubject);\n const shape: Shape = {\n cause: optional(readCause),\n code: readLabel,\n phase: (phase, at) => readLiteral(phase, at, phases),\n subject: (subject, at) => readLiteral(subject, at, subjects),\n };\n const record = readShape(value, shape, path, context);\n const codes = failureCodesBySubject[record['subject'] as string] ?? [];\n\n readLiteral(record['code'], `${path}.code`, codes);\n\n return record;\n};\n\nconst closedReasons = [\n 'application-closed',\n 'condition-inactive',\n 'debug-override',\n 'plan-replacement',\n 'retired',\n] as const;\n\nconst waitReasons = ['awaiting-condition', 'awaiting-hard-import', 'awaiting-port', 'awaiting-turn'] as const;\n\nconst readClosedReason: Reader = (value, path) => readLiteral(value, path, closedReasons);\nconst readWaitReason: Reader = (value, path) => readLiteral(value, path, waitReasons);\n\n/** Every automaton of `node-state.ts`, state by state. A state not listed here is an unknown kind, not a default. */\nconst stateShapes: Readonly<Record<string, Readonly<Record<string, Shape>>>> = {\n attachment: {\n closed: {},\n closing: { phase: (value, path) => readLiteral(value, path, ['close', 'retry', 'rollback'] as const) },\n 'failed-close': { failure: readFailure },\n opening: {},\n ready: {},\n },\n condition: { false: {}, 'source-closed': {}, true: {} },\n 'condition-group': {\n active: {},\n closed: {},\n failed: { failure: readFailure },\n inactive: { reason: readClosedReason },\n opening: { opened: readNumber, total: readNumber },\n retiring: { remaining: readNumber },\n },\n contribution: {\n pending: {},\n published: {},\n rejected: { failure: readFailure },\n withdrawn: {},\n withheld: {},\n },\n 'feature-instance': {\n 'cleanup-failed': { failure: readFailure },\n draining: {},\n fencing: {},\n 'not-ready': { failure: readFailure },\n opening: {},\n quarantined: { failure: readFailure },\n ready: {},\n retired: { reason: readClosedReason },\n waiting: { blockedBy: listOf(readNodeId), reason: readWaitReason },\n },\n 'host-contract': { bound: {}, deferred: {}, unbound: {} },\n port: {\n absent: {},\n available: { instance: readNodeId },\n unavailable: { provider: readNodeId },\n },\n};\n\nfunction readState(kind: string): Reader {\n return (value, path, context) => {\n const byKind = stateShapes[kind] ?? malformed(path, `No automaton for node kind ${kind}`);\n const fields = dataFields(value, path);\n const stateKind = readLiteral(fields.get('kind'), `${path}.kind`, Object.keys(byKind));\n\n return { ...readShape(value, { ...byKind[stateKind], kind: readLabel }, path, context), kind: stateKind };\n };\n}\n\nconst runtimeNodeBase: Shape = {\n cause: optional(readCause),\n declaration: optional(readNodeId),\n id: readNodeId,\n label: readLabel,\n};\n\n/** The extra fields each runtime node kind carries beyond the base, mirroring `graph.ts`. */\nconst runtimeNodeShapes: Readonly<Record<string, Shape>> = {\n attachment: { owner: readNodeId },\n condition: {},\n 'condition-group': {\n desired: (value, path, context) =>\n readShape(\n value,\n {\n effective: (axis, at) => readLiteral(axis, at, ['active', 'inactive'] as const),\n override: (axis, at) => readLiteral(axis, at, ['force-inactive', 'none'] as const),\n source: (axis, at) => readLiteral(axis, at, ['active', 'inactive'] as const),\n },\n path,\n context,\n ),\n },\n contribution: { contributor: readNodeId, target: readNodeId },\n 'feature-instance': { generation: readNumber, group: optional(readNodeId), previous: optional(readNumber) },\n 'host-contract': {},\n port: {},\n};\n\nconst planNodeBase: Shape = { id: readNodeId, label: readLabel, provenance: optional(readLabel) };\n\nconst planNodeShapes: Readonly<Record<string, Shape>> = {\n 'absent-provider': {},\n application: { features: readNumber, groups: readNumber },\n condition: { conditionId: readConditionId, source: readLabel },\n 'condition-group': { conditions: listOf(readConditionId), order: listOf(readNodeId) },\n contribution: { contributor: readNodeId, priority: readFiniteNumber, target: readNodeId },\n 'contribution-target': {},\n feature: { owner: readNodeId },\n 'host-contract': {\n demand: (value, path) => readLiteral(value, path, ['instance', 'onDemand'] as const),\n optional: readFlag,\n },\n port: { provider: optional(readNodeId) },\n};\n\nconst hardEdgeKinds = ['hard-import', 'requires-port'] as const;\nconst weakEdgeKinds = ['absent-import', 'absent-port', 'optional-import', 'optional-port'] as const;\nconst structuralEdgeKinds = [\n 'condition-control',\n 'contributes-to',\n 'on-demand-import',\n 'owns',\n 'provides-port',\n] as const;\n\nconst edgeBase: Shape = { from: readNodeId, id: readEdgeId, to: readNodeId };\n\n/** State lives on the kinds that have one, so a weak edge cannot arrive pending and a hard one cannot carry a lookup. */\nfunction edgeShapeFor(kind: string, path: string): Shape {\n if ((hardEdgeKinds as readonly string[]).includes(kind)) return { ...edgeBase, kind: readLabel, pending: readFlag };\n\n if ((weakEdgeKinds as readonly string[]).includes(kind)) {\n return {\n ...edgeBase,\n kind: readLabel,\n lookup: (value, at) => readLiteral(value, at, ['found', 'missing'] as const),\n };\n }\n\n if ((structuralEdgeKinds as readonly string[]).includes(kind)) return { ...edgeBase, kind: readLabel };\n\n return malformed(path, `Unknown edge kind ${kind}`);\n}\n\nconst readEdge: Reader = (value, path, context) => {\n const fields = dataFields(value, path);\n const kind = readString(fields.get('kind'), `${path}.kind`, context.maxStringLength);\n\n return readShape(value, edgeShapeFor(kind, `${path}.kind`), path, context);\n};\n\n/**\n * A node reader. `only` narrows the admissible kinds to one, which is what a bucket needs: `plan.groups` holds\n * condition groups and nothing else, and a feature record found there is a malformed snapshot rather than a node\n * the graph should try to walk (§7).\n */\nfunction readNodeOfKind(\n kinds: Readonly<Record<string, Shape>>,\n base: Shape,\n withState: boolean,\n only?: string,\n): Reader {\n return (value, path, context) => {\n const fields = dataFields(value, path);\n const kind = readLiteral(fields.get('kind'), `${path}.kind`, only === undefined ? Object.keys(kinds) : [only]);\n const shape: Shape = {\n ...base,\n ...kinds[kind],\n kind: readLabel,\n ...(withState ? { state: readState(kind) } : {}),\n };\n\n return readShape(value, shape, path, context);\n };\n}\n\nconst readRuntimeNode = readNodeOfKind(runtimeNodeShapes, runtimeNodeBase, true);\n\n/** Readers bound to one kind, for the buckets and for `plan.application`, whose kind is equally fixed. */\nfunction planNodeOf(kind: string): Reader {\n return readNodeOfKind(planNodeShapes, planNodeBase, false, kind);\n}\n\nfunction runtimeNodeOf(kind: string): Reader {\n return readNodeOfKind(runtimeNodeShapes, runtimeNodeBase, true, kind);\n}\n\nexport {\n listOf,\n optional,\n planNodeOf,\n readCause,\n readEdge,\n readEdgeId,\n readNodeId,\n readNumber,\n readRuntimeNode,\n readShape,\n runtimeNodeOf,\n};\nexport type { DecodeContext, Reader, Shape };\n","import type { DecodeContext, Reader, Shape } from './decode-shapes';\nimport { listOf, readShape } from './decode-shapes';\nimport { dataFields, readArray, readBoolean, readCount, readLiteral, readString } from './decode-values';\n\nconst text: Reader = (value, path, context) => readString(value, path, context.maxStringLength);\nconst count: Reader = (value, path) => readCount(value, path);\nconst flag: Reader = (value, path) => readBoolean(value, path);\nconst literal =\n (values: readonly string[]): Reader =>\n (value, path) =>\n readLiteral(value, path, values);\nconst unknownOr =\n (reader: Reader): Reader =>\n (value, path, context) =>\n value === 'unknown' ? value : reader(value, path, context);\nconst record =\n (shape: Shape): Reader =>\n (value, path, context) =>\n readShape(value, shape, path, context);\n\nconst owner: Shape = { feature: text, generation: count, instance: text };\nconst feature = record({\n ...owner,\n body: literal(['eager', 'loaded', 'loading', 'not-loaded', 'unknown']),\n demandCount: literal(['unknown']),\n id: text,\n phase: literal(['draining', 'failed', 'fenced', 'opening', 'quarantined', 'ready']),\n});\nconst lane = record({ blockedBy: unknownOr(listOf(text)), declaration: text, id: text });\nconst call = record({\n callId: text,\n declaration: text,\n id: text,\n lane: (value, path, context) => (value === null ? null : lane(value, path, context)),\n owner: record(owner),\n pendingWaiters: count,\n state: literal(['draining', 'queued', 'running']),\n});\nconst load = record({\n attempt: count,\n generation: count,\n id: text,\n state: literal(['draining', 'running', 'scheduled']),\n});\n\n/** The shared budget includes nested loads, not just top-level controllers. */\nfunction readActivity(value: unknown, path: string, context: DecodeContext): unknown {\n const fields = dataFields(value, path);\n const capacity = readCount(fields.get('capacity'), `${path}.capacity`);\n let remaining = Math.min(capacity, context.maxEntries);\n const entries =\n (reader: Reader): Reader =>\n (items, at, scope) => {\n const values = readArray(items, at, remaining);\n remaining -= values.length;\n\n return values.map((entry, index) => reader(entry, `${at}[${index}]`, scope));\n };\n const resource = record({\n generation: count,\n id: text,\n kind: literal(['resource', 'stream']),\n loads: unknownOr(entries(load)),\n owner: record(owner),\n retainers: unknownOr(count),\n retention: literal(['observer', 'scope', 'unknown']),\n state: literal(['error', 'fenced', 'idle', 'opening', 'ready', 'refreshing']),\n });\n\n return readShape(\n value,\n {\n calls: entries(call),\n capacity: count,\n closed: flag,\n coverage: record({\n calls: literal(['feature-and-owned-model']),\n hostDemand: literal(['unknown']),\n resources: literal(['registered-resource-controllers']),\n streams: literal(['state-only']),\n uiModels: literal(['unknown']),\n }),\n executionId: text,\n features: entries(feature),\n freshness: literal(['live', 'stale']),\n resources: entries(resource),\n schemaRevision: literal(['opetope.runtime-activity/1']),\n truncated: flag,\n },\n path,\n context,\n );\n}\n\nexport { readActivity };\n","/**\n * The hostile boundary of `docs/devtools.md` §7 and §8: a snapshot or a frame that arrives as\n * untrusted data is decoded under explicit budgets, and anything malformed is rejected instead of partially applied.\n *\n * This is the only place in the package that treats protocol values as untrusted. The in-process observation port is\n * a trusted seam and does not need it; an export replayed from a file, a fixture from a bug report, or any future\n * transport does. Budgets are per record count and per byte, because a payload can be well-formed and still be an\n * attack on the panel's memory.\n */\n\nimport { readActivity } from './decode-activity';\nimport type { DecodeContext, Shape } from './decode-shapes';\nimport {\n listOf,\n optional,\n planNodeOf,\n readCause,\n readEdge,\n readEdgeId,\n readNodeId,\n readNumber,\n readRuntimeNode,\n readShape,\n runtimeNodeOf,\n} from './decode-shapes';\nimport { dataFields, DevtoolsDecodeError, malformed, readArray, readLiteral, readString } from './decode-values';\nimport type { RuntimeGraphFrame, RuntimeGraphSnapshot } from './graph';\nimport { frameSchemaRevision, graphSchemaRevision } from './graph';\n\ntype DecodeLimits = Readonly<{\n /**\n * UTF-8 size of the incoming text, checked before `JSON.parse` so a huge payload never becomes a huge object\n * graph. Bytes, not code units: a limit named in bytes that counts UTF-16 units lets any non-ASCII payload\n * through at up to three times its budget.\n */\n maxBytes: number;\n maxEdges: number;\n maxNodes: number;\n maxOperations: number;\n maxStringLength: number;\n}>;\n\nconst defaultDecodeLimits: DecodeLimits = {\n maxBytes: 16 * 1024 * 1024,\n maxEdges: 60_000,\n maxNodes: 20_000,\n maxOperations: 10_000,\n maxStringLength: 512,\n};\n\nfunction contextFor(limits: DecodeLimits, maxEntries: number): DecodeContext {\n return { maxEntries, maxStringLength: limits.maxStringLength };\n}\n\n/**\n * Node buckets share one budget: a payload cannot slip past `maxNodes` by spreading records across seven arrays.\n *\n * A bucket also fixes the kind of what it holds, and the reader is bound to that kind. Reading every bucket with a\n * reader that accepts any node let a well-formed feature sit in `plan.groups`, where the graph later walked it for\n * an `order` it never had — a decoder that admits that has published a lie the store cannot survive (§7).\n */\nfunction nodeBuckets(\n value: unknown,\n buckets: Readonly<Record<string, typeof readRuntimeNode>>,\n besides: readonly string[],\n path: string,\n limits: DecodeLimits,\n): Record<string, unknown> {\n const fields = dataFields(value, path);\n const result: Record<string, unknown> = {};\n let budget = limits.maxNodes;\n\n for (const [key, reader] of Object.entries(buckets)) {\n const entries = readArray(fields.get(key), `${path}.${key}`, budget);\n\n budget -= entries.length;\n\n if (budget < 0) {\n throw new DevtoolsDecodeError('budget-exceeded', path, `Snapshot holds more than ${limits.maxNodes} nodes`);\n }\n\n result[key] = entries.map((entry, index) =>\n reader(entry, `${path}.${key}[${index}]`, contextFor(limits, limits.maxNodes)),\n );\n }\n\n for (const key of fields.keys()) {\n // Own membership only: a plain `buckets[key]` reads through the prototype, so `toString` and its neighbours\n // would answer for a bucket that does not exist and an unexpected field would pass as a known one (§7).\n // `Object.hasOwn` is newer than the browser floor this package builds for, so the call is spelled out.\n const known = Object.prototype.hasOwnProperty.call(buckets, key);\n\n if (!known && !besides.includes(key)) malformed(`${path}.${key}`, 'Unexpected field');\n }\n\n return result;\n}\n\nconst readApplicationNode = planNodeOf('application');\n\nconst planBuckets = {\n absentProviders: planNodeOf('absent-provider'),\n conditions: planNodeOf('condition'),\n contributions: planNodeOf('contribution'),\n features: planNodeOf('feature'),\n groups: planNodeOf('condition-group'),\n hostContracts: planNodeOf('host-contract'),\n ports: planNodeOf('port'),\n targets: planNodeOf('contribution-target'),\n};\n\nconst runtimeBuckets = {\n attachments: runtimeNodeOf('attachment'),\n conditions: runtimeNodeOf('condition'),\n contributions: runtimeNodeOf('contribution'),\n groups: runtimeNodeOf('condition-group'),\n hostContracts: runtimeNodeOf('host-contract'),\n instances: runtimeNodeOf('feature-instance'),\n ports: runtimeNodeOf('port'),\n};\n\nfunction readEdges(value: unknown, path: string, limits: DecodeLimits): unknown {\n const context = contextFor(limits, limits.maxEdges);\n\n return readArray(value, path, limits.maxEdges).map((entry, index) => readEdge(entry, `${path}[${index}]`, context));\n}\n\nfunction readPlan(value: unknown, path: string, limits: DecodeLimits): unknown {\n const fields = dataFields(value, path);\n const application = readApplicationNode(fields.get('application'), `${path}.application`, contextFor(limits, 1));\n const buckets = nodeBuckets(value, planBuckets, ['application', 'edges'], path, limits);\n\n return { ...buckets, application, edges: readEdges(fields.get('edges'), `${path}.edges`, limits) };\n}\n\nfunction readRuntime(value: unknown, path: string, limits: DecodeLimits): unknown {\n const fields = dataFields(value, path);\n const buckets = nodeBuckets(value, runtimeBuckets, ['edges'], path, limits);\n\n return { ...buckets, edges: readEdges(fields.get('edges'), `${path}.edges`, limits) };\n}\n\n/**\n * Decodes an untrusted snapshot. The schema revision is checked first: a payload from another revision is rejected\n * whole, because a decoder that guesses at an unknown shape is how a debugger starts showing a graph nobody has.\n */\nfunction decodeSnapshot(value: unknown, limits: DecodeLimits = defaultDecodeLimits): RuntimeGraphSnapshot {\n const path = 'snapshot';\n const fields = dataFields(value, path);\n\n readLiteral(fields.get('schemaRevision'), `${path}.schemaRevision`, [graphSchemaRevision]);\n\n const shape: Shape = {\n activity: optional(readActivity),\n lastSequence: readNumber,\n plan: (plan, at) => readPlan(plan, at, limits),\n planFingerprint: (fingerprint, at) => readString(fingerprint, at, limits.maxStringLength),\n runtime: (runtime, at) => readRuntime(runtime, at, limits),\n schemaRevision: (revision, at) => readString(revision, at, limits.maxStringLength),\n sessionId: (session, at) => readString(session, at, limits.maxStringLength),\n stateRevision: readNumber,\n topologyRevision: readNumber,\n };\n\n return readShape(value, shape, path, contextFor(limits, limits.maxNodes)) as unknown as RuntimeGraphSnapshot;\n}\n\nfunction readLabelField(value: unknown, path: string, context: DecodeContext): unknown {\n return readString(value, path, context.maxStringLength);\n}\n\n/**\n * A removal names the same id the snapshot and the upsert named, so it is read by the same branded reader (D200,\n * §7). Reading it as prose would hold an identity to the budget written for labels, and a legal application that\n * composes a long edge id could be loaded but never replayed: the snapshot would arrive and its next frame would not.\n */\nconst operationShapes: Readonly<Record<string, Shape>> = {\n 'remove-edge': { id: readEdgeId, op: readLabelField },\n 'remove-node': { id: readNodeId, op: readLabelField },\n 'upsert-edge': { edge: readEdge, op: readLabelField },\n 'upsert-node': { node: readRuntimeNode, op: readLabelField },\n};\n\nfunction readOperation(value: unknown, path: string, context: DecodeContext): unknown {\n const fields = dataFields(value, path);\n const op = readLiteral(fields.get('op'), `${path}.op`, Object.keys(operationShapes));\n const shape = operationShapes[op];\n\n if (shape === undefined) malformed(`${path}.op`, `No shape for operation ${op}`);\n\n return readShape(value, shape, path, context);\n}\n\n/** Decodes an untrusted frame. Bounds and continuity are the store's job; shape and budget are this one's. */\nfunction decodeFrame(value: unknown, limits: DecodeLimits = defaultDecodeLimits): RuntimeGraphFrame {\n const path = 'frame';\n const fields = dataFields(value, path);\n\n readLiteral(fields.get('schemaRevision'), `${path}.schemaRevision`, [frameSchemaRevision]);\n\n const context = contextFor(limits, limits.maxOperations);\n const shape: Shape = {\n activity: optional((activity, at) => readActivity(activity, at, contextFor(limits, limits.maxNodes))),\n baseRevision: readNumber,\n cause: optional(readCause),\n firstSequence: readNumber,\n lastSequence: readNumber,\n nextRevision: readNumber,\n operations: listOf(readOperation),\n schemaRevision: readLabelField,\n sessionId: readLabelField,\n };\n\n return readShape(value, shape, path, context) as unknown as RuntimeGraphFrame;\n}\n\nfunction isHighSurrogate(code: number): boolean {\n return code >= 0xd8_00 && code <= 0xdb_ff;\n}\n\nfunction isLowSurrogate(code: number): boolean {\n return code >= 0xdc_00 && code <= 0xdf_ff;\n}\n\n/** Bytes of one non-surrogate code unit. A lone surrogate encodes as U+FFFD, which is three bytes as well. */\nfunction charCodeBytes(code: number): number {\n if (code < 0x80) return 1;\n\n return code < 0x8_00 ? 2 : 3;\n}\n\n/** Exact UTF-8 length without building the encoded copy: the copy of a payload at the budget would be the attack. */\nfunction utf8Length(text: string): number {\n let bytes = 0;\n\n for (let index = 0; index < text.length; index += 1) {\n const code = text.charCodeAt(index);\n const paired = isHighSurrogate(code) && isLowSurrogate(text.charCodeAt(index + 1));\n\n if (paired) index += 1;\n\n bytes += paired ? 4 : charCodeBytes(code);\n }\n\n return bytes;\n}\n\n/**\n * Enforces the byte budget before parsing, so an oversized payload never becomes an object graph at all.\n *\n * Two bounds keep the exact count off the hot path: one code unit is never less than one byte and never more than\n * three, so a text longer than the budget is over it, and a text three times shorter is under it. Only the band\n * between them is counted unit by unit.\n */\nfunction parseProtocolText(text: string, limits: DecodeLimits = defaultDecodeLimits): unknown {\n const oversized =\n text.length > limits.maxBytes || (text.length * 3 > limits.maxBytes && utf8Length(text) > limits.maxBytes);\n\n if (oversized) {\n throw new DevtoolsDecodeError('budget-exceeded', 'text', `Payload is larger than ${limits.maxBytes} bytes`);\n }\n\n try {\n return JSON.parse(text) as unknown;\n } catch (error) {\n throw new DevtoolsDecodeError('malformed', 'text', `Payload is not JSON: ${String(error)}`);\n }\n}\n\nexport { decodeFrame, decodeSnapshot, defaultDecodeLimits, DevtoolsDecodeError, parseProtocolText };\nexport type { DecodeLimits };\n"],"names":["sessionId","diagnosticSessionId","planFingerprint","diagnosticPlanFingerprint","applicationId","diagnosticNodeId","featureId","index","instanceId","groupId","conditionNodeId","hostId","portId","targetId","contributionId","attachmentId","edge","kind","from","to","diagnosticEdgeId","hardImport","requiresPort","ownerOf","groups","providesPort","contributes","buildPlan","shape","features","hostContracts","ports","targets","contributions","edges","feature","owner","conditions","members","diagnosticConditionId","buildRuntimeEdges","step","provider","buildSnapshot","instances","attachments","_unused","diagnosticSequence","graphSchemaRevision","diagnosticStateRevision","diagnosticTopologyRevision","buildFrames","count","frameSchemaRevision","generateCorpus","frames","smallCorpusShape","largeCorpusShape","countNodes","snapshot","plan","runtime","countEdges","DevtoolsDecodeError","code","path","message","unsafeKeys","malformed","requireSafeKey","key","fieldValue","source","descriptor","dataFields","value","fields","raw","field","readString","maxLength","readCount","readTimestamp","timestamp","readFiniteNumber","readBoolean","readArray","budget","length","entries","readLiteral","allowed","optionalMarker","optional","reader","wrapped","context","isOptional","brandedId","make","limit","error","DevtoolsProtocolError","readNodeId","maxNodeId","readEdgeId","maxEdgeId","readConditionId","maxEncodedAtom","readLabel","readNumber","readFlag","readShape","result","listOf","entry","causeKinds","phases","failureCodesBySubject","readCause","at","readFailure","subjects","phase","subject","record","codes","closedReasons","waitReasons","readClosedReason","readWaitReason","stateShapes","readState","byKind","stateKind","runtimeNodeBase","runtimeNodeShapes","axis","planNodeBase","planNodeShapes","hardEdgeKinds","weakEdgeKinds","structuralEdgeKinds","edgeBase","edgeShapeFor","readEdge","readNodeOfKind","kinds","base","withState","only","readRuntimeNode","planNodeOf","runtimeNodeOf","text","flag","literal","values","unknownOr","lane","call","load","readActivity","capacity","remaining","items","scope","resource","defaultDecodeLimits","contextFor","limits","maxEntries","nodeBuckets","buckets","besides","readApplicationNode","planBuckets","runtimeBuckets","readEdges","readPlan","application","readRuntime","decodeSnapshot","fingerprint","revision","session","readLabelField","operationShapes","readOperation","op","decodeFrame","activity","isHighSurrogate","isLowSurrogate","charCodeBytes","utf8Length","bytes","paired","parseProtocolText"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the inspector — and the graph canvas next to it — is allowed to know about the selected node.
|
|
3
|
+
*
|
|
4
|
+
* §2 is explicit that the UI neither computes state nor parses error text, so this projection resolves refs into
|
|
5
|
+
* typed facts and stops there. It counts blockers, it does not phrase "all three hard imports were already ready";
|
|
6
|
+
* the panel composes that sentence from the counts. §4.3 fixes the contents: id, kind, provenance, current state and
|
|
7
|
+
* instance, the immediate cause, incoming dependencies, what the instance owns, and the last causal chain.
|
|
8
|
+
*/
|
|
9
|
+
import type { RuntimeActivitySnapshot } from './activity.js';
|
|
10
|
+
import type { DiagnosticRuntimeNode } from './graph.js';
|
|
11
|
+
import type { DevtoolsGraphStore } from './graph-store.js';
|
|
12
|
+
import type { DiagnosticCausalStep } from './node-state.js';
|
|
13
|
+
import type { DiagnosticCauseRef, DiagnosticEdge, DiagnosticEdgeKind, DiagnosticFailure, DiagnosticLabel, DiagnosticNodeId, DiagnosticNodeKind, DiagnosticOverride, DiagnosticProvenance, WeakEdgeState } from './protocol.js';
|
|
14
|
+
import type { DiagnosticAxes, NodeDisplayState } from './visual-axes.js';
|
|
15
|
+
/**
|
|
16
|
+
* One incoming dependency. A hard edge is satisfied when it is no longer pending; a weak edge is never pending and
|
|
17
|
+
* reports the `Lookup` its consumer reads instead, so `missing` shows as unsatisfied without claiming a wait (D105).
|
|
18
|
+
*/
|
|
19
|
+
type InspectorBlocker = Readonly<{
|
|
20
|
+
display: NodeDisplayState;
|
|
21
|
+
kind: DiagnosticEdgeKind;
|
|
22
|
+
label: DiagnosticLabel;
|
|
23
|
+
lookup?: WeakEdgeState;
|
|
24
|
+
node: DiagnosticNodeId;
|
|
25
|
+
/** Whether this dependency is satisfied. A satisfied edge stays visible: "0 of 3" is the useful answer. */
|
|
26
|
+
ready: boolean;
|
|
27
|
+
weak: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
type InspectorOwned = Readonly<{
|
|
30
|
+
/** 0 for what the node owns directly, 1 for what its own children own in turn. */
|
|
31
|
+
depth: number;
|
|
32
|
+
display: NodeDisplayState;
|
|
33
|
+
edge: DiagnosticEdge;
|
|
34
|
+
node: DiagnosticRuntimeNode;
|
|
35
|
+
}>;
|
|
36
|
+
type InspectorWhy = Readonly<{
|
|
37
|
+
cause?: DiagnosticCauseRef;
|
|
38
|
+
failure?: DiagnosticFailure;
|
|
39
|
+
/** How far a condition group has walked its canonical order, when it is walking it. */
|
|
40
|
+
progress?: string;
|
|
41
|
+
readyBlockers: number;
|
|
42
|
+
totalBlockers: number;
|
|
43
|
+
}>;
|
|
44
|
+
type InspectorBreadcrumb = Readonly<{
|
|
45
|
+
id?: DiagnosticNodeId;
|
|
46
|
+
label: DiagnosticLabel;
|
|
47
|
+
}>;
|
|
48
|
+
type InspectorProjection = Readonly<{
|
|
49
|
+
applicationActivity: RuntimeActivitySnapshot | undefined;
|
|
50
|
+
axes: DiagnosticAxes;
|
|
51
|
+
blockers: readonly InspectorBlocker[];
|
|
52
|
+
breadcrumbs: readonly InspectorBreadcrumb[];
|
|
53
|
+
chain: readonly DiagnosticCausalStep[];
|
|
54
|
+
display: NodeDisplayState;
|
|
55
|
+
/** The kernel's instance counter, a number and not a concept (D110). */
|
|
56
|
+
generation?: number;
|
|
57
|
+
groupLabel?: DiagnosticLabel;
|
|
58
|
+
id: DiagnosticNodeId;
|
|
59
|
+
kind: DiagnosticNodeKind;
|
|
60
|
+
label: DiagnosticLabel;
|
|
61
|
+
node?: DiagnosticRuntimeNode;
|
|
62
|
+
override: DiagnosticOverride;
|
|
63
|
+
owned: readonly InspectorOwned[];
|
|
64
|
+
provenance?: DiagnosticProvenance;
|
|
65
|
+
why: InspectorWhy;
|
|
66
|
+
}>;
|
|
67
|
+
/** Everything the selected-node views read. `undefined` means the selection no longer exists in this session. */
|
|
68
|
+
declare function projectInspector(store: DevtoolsGraphStore, id: DiagnosticNodeId): InspectorProjection | undefined;
|
|
69
|
+
export { projectInspector };
|
|
70
|
+
export type { InspectorBlocker, InspectorBreadcrumb, InspectorOwned, InspectorProjection, InspectorWhy };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the panel is composed once the ports exist: the drawer, the connection and the React root, acquired in order
|
|
3
|
+
* and given back in reverse. This module is internal to the package — the surface an application uses is
|
|
4
|
+
* `installDevtools` in `./integration`, which owns the ports as well (D248).
|
|
5
|
+
*
|
|
6
|
+
* The panel mounts in its own React root, outside the application's tree: it belongs to no condition group that
|
|
7
|
+
* could switch it off, receives no application `ViewRoot`, and opening or closing it never re-renders the
|
|
8
|
+
* application (`docs/devtools.md` §3, §3.1).
|
|
9
|
+
*/
|
|
10
|
+
import type { RuntimeControlSession } from './control.js';
|
|
11
|
+
import type { DevtoolsMode } from './react/panel.js';
|
|
12
|
+
import type { DevtoolsTheme } from './react/theme.js';
|
|
13
|
+
import type { DevtoolsSessionOptions, RuntimeInspectionSession } from './session.js';
|
|
14
|
+
/**
|
|
15
|
+
* Every optional member also accepts `undefined`, unlike the public options: this is what `./integration` forwards
|
|
16
|
+
* into, and a forwarding call that has to spread five absent members conditionally is harder to read than it is
|
|
17
|
+
* worth.
|
|
18
|
+
*/
|
|
19
|
+
type InstallPanelOptions = Readonly<{
|
|
20
|
+
/** Where the drawer mounts. Defaults to a `div` appended to `document.body`, owned by this call. */
|
|
21
|
+
container?: HTMLElement | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The write port (§5). It is owned from here on: `close()` closes it, which drops every override the panel put in
|
|
24
|
+
* place. Absent for a read-only panel, which then never even fetches the chunk that would write.
|
|
25
|
+
*/
|
|
26
|
+
control?: RuntimeControlSession | undefined;
|
|
27
|
+
mode?: DevtoolsMode | undefined;
|
|
28
|
+
/** The observation port. Closing the connection closes it, so one `close()` takes the whole panel down. */
|
|
29
|
+
session: RuntimeInspectionSession;
|
|
30
|
+
sessionOptions?: DevtoolsSessionOptions | undefined;
|
|
31
|
+
theme?: DevtoolsTheme | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
type DevtoolsHandle = Readonly<{
|
|
34
|
+
/** Detaches the observer, unmounts the panel and releases the store. The application keeps running (§7). */
|
|
35
|
+
close: () => void;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Installation is transactional: what it has taken by the time something throws is given back before the throw
|
|
39
|
+
* leaves this call (§7). The observation session can fail on its very first snapshot — that failure is part of its
|
|
40
|
+
* contract — and the drawer and the write port are already acquired by then.
|
|
41
|
+
*/
|
|
42
|
+
declare function installPanel(options: InstallPanelOptions): DevtoolsHandle;
|
|
43
|
+
export { installPanel };
|
|
44
|
+
export type { DevtoolsHandle, InstallPanelOptions };
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createElement as s}from"react";import{createRoot as f}from"react-dom/client";import{D as a}from"./panel-5jvisQBr.js";import{c as d}from"./session-qjKT0E69.js";const u="position:fixed;left:0;right:0;bottom:0;height:min(600px,66vh);z-index:2147483000";function m(){const e=document.createElement("div");return e.setAttribute("data-opetope-devtools-root",""),e.setAttribute("style",u),document.body.append(e),e}function i(e){let o,n=!1;for(const r of e.splice(0))try{r()}catch(t){n||(n=!0,o=t)}return{failed:n,failure:o}}function h(e){return()=>{if(e.length===0)return;const o=i(e);if(o.failed)throw o.failure}}function v(e){const o=e.container===void 0,n=e.container??m(),r=[()=>{var t;return(t=e.control)==null?void 0:t.close()},()=>{o&&n.remove()}];try{const t=d(e.session,e.sessionOptions??{});r.unshift(()=>t.close());const c=f(n);r.unshift(()=>c.unmount());const l=h(r);return c.render(s(a,{...e.control===void 0?{}:{control:e.control},...e.mode===void 0?{}:{mode:e.mode},onClose:l,store:t.store,...e.theme===void 0?{}:{theme:e.theme}})),{close:l}}catch(t){throw i(r),t}}export{v as installPanel};
|
|
2
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sources":["../src/install.ts"],"sourcesContent":["/**\n * How the panel is composed once the ports exist: the drawer, the connection and the React root, acquired in order\n * and given back in reverse. This module is internal to the package — the surface an application uses is\n * `installDevtools` in `./integration`, which owns the ports as well (D248).\n *\n * The panel mounts in its own React root, outside the application's tree: it belongs to no condition group that\n * could switch it off, receives no application `ViewRoot`, and opening or closing it never re-renders the\n * application (`docs/devtools.md` §3, §3.1).\n */\n\nimport { createElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\n\nimport type { RuntimeControlSession } from './control';\nimport type { DevtoolsMode } from './react/panel';\nimport { DevtoolsPanel } from './react/panel';\nimport type { DevtoolsTheme } from './react/theme';\nimport { connectDevtoolsSession } from './session';\nimport type { DevtoolsSessionOptions, RuntimeInspectionSession } from './session';\n\n/**\n * Every optional member also accepts `undefined`, unlike the public options: this is what `./integration` forwards\n * into, and a forwarding call that has to spread five absent members conditionally is harder to read than it is\n * worth.\n */\ntype InstallPanelOptions = Readonly<{\n /** Where the drawer mounts. Defaults to a `div` appended to `document.body`, owned by this call. */\n container?: HTMLElement | undefined;\n /**\n * The write port (§5). It is owned from here on: `close()` closes it, which drops every override the panel put in\n * place. Absent for a read-only panel, which then never even fetches the chunk that would write.\n */\n control?: RuntimeControlSession | undefined;\n mode?: DevtoolsMode | undefined;\n /** The observation port. Closing the connection closes it, so one `close()` takes the whole panel down. */\n session: RuntimeInspectionSession;\n sessionOptions?: DevtoolsSessionOptions | undefined;\n theme?: DevtoolsTheme | undefined;\n}>;\n\ntype DevtoolsHandle = Readonly<{\n /** Detaches the observer, unmounts the panel and releases the store. The application keeps running (§7). */\n close: () => void;\n}>;\n\nconst drawerStyle = 'position:fixed;left:0;right:0;bottom:0;height:min(600px,66vh);z-index:2147483000';\n\nfunction defaultContainer(): HTMLElement {\n const element = document.createElement('div');\n\n element.setAttribute('data-opetope-devtools-root', '');\n element.setAttribute('style', drawerStyle);\n document.body.append(element);\n\n return element;\n}\n\n/**\n * Runs every release even when one of them throws, and reports the first failure afterwards. A cleanup that gives up\n * halfway is how a failed install leaves a drawer in the document and a write port nobody can take again.\n */\nfunction releaseAll(releases: (() => void)[]): { readonly failed: boolean; readonly failure: unknown } {\n let failure: unknown;\n let failed = false;\n\n for (const release of releases.splice(0)) {\n try {\n release();\n } catch (error) {\n if (!failed) {\n failed = true;\n failure = error;\n }\n }\n }\n\n return { failed, failure };\n}\n\n/** The workspace handle captures only its cleanup list, not the installation's root, options or connection. */\nfunction createClose(releases: (() => void)[]): () => void {\n return () => {\n if (releases.length === 0) return;\n\n const outcome = releaseAll(releases);\n\n if (outcome.failed) throw outcome.failure;\n };\n}\n\n/**\n * Installation is transactional: what it has taken by the time something throws is given back before the throw\n * leaves this call (§7). The observation session can fail on its very first snapshot — that failure is part of its\n * contract — and the drawer and the write port are already acquired by then.\n */\nfunction installPanel(options: InstallPanelOptions): DevtoolsHandle {\n const owned = options.container === undefined;\n const container = options.container ?? defaultContainer();\n const acquired: (() => void)[] = [\n () => options.control?.close(),\n () => {\n if (owned) container.remove();\n },\n ];\n\n try {\n const connection = connectDevtoolsSession(options.session, options.sessionOptions ?? {});\n\n acquired.unshift(() => connection.close());\n\n const root: Root = createRoot(container);\n\n acquired.unshift(() => root.unmount());\n\n const close = createClose(acquired);\n\n root.render(\n createElement(DevtoolsPanel, {\n ...(options.control === undefined ? {} : { control: options.control }),\n ...(options.mode === undefined ? {} : { mode: options.mode }),\n onClose: close,\n store: connection.store,\n ...(options.theme === undefined ? {} : { theme: options.theme }),\n }),\n );\n\n return { close };\n } catch (error) {\n // The reason the install failed is what the host has to see; a release that also failed must not replace it.\n releaseAll(acquired);\n\n throw error;\n }\n}\n\nexport { installPanel };\nexport type { DevtoolsHandle, InstallPanelOptions };\n"],"names":["drawerStyle","defaultContainer","element","releaseAll","releases","failure","failed","release","error","createClose","outcome","installPanel","options","owned","container","acquired","_a","connection","connectDevtoolsSession","root","createRoot","close","createElement","DevtoolsPanel"],"mappings":"sKA8CA,MAAMA,EAAc,mFAEpB,SAASC,GAAgB,CACvB,MAAMC,EAAU,SAAS,cAAc,KAAK,EAE5C,OAAAA,EAAQ,aAAa,6BAA8B,EAAE,EACrDA,EAAQ,aAAa,QAASF,CAAW,EACzC,SAAS,KAAK,OAAOE,CAAO,EAErBA,CACT,CAMA,SAASC,EAAWC,EAAwB,CAC1C,IAAIC,EACAC,EAAS,GAEb,UAAWC,KAAWH,EAAS,OAAO,CAAC,EACrC,GAAI,CACFG,EAAO,CACT,OAASC,EAAO,CACTF,IACHA,EAAS,GACTD,EAAUG,EAEd,CAGF,MAAO,CAAE,OAAAF,EAAQ,QAAAD,CAAO,CAC1B,CAGA,SAASI,EAAYL,EAAwB,CAC3C,MAAO,IAAK,CACV,GAAIA,EAAS,SAAW,EAAG,OAE3B,MAAMM,EAAUP,EAAWC,CAAQ,EAEnC,GAAIM,EAAQ,OAAQ,MAAMA,EAAQ,OACpC,CACF,CAOA,SAASC,EAAaC,EAA4B,CAChD,MAAMC,EAAQD,EAAQ,YAAc,OAC9BE,EAAYF,EAAQ,WAAaX,EAAgB,EACjDc,EAA2B,CAC/B,WAAM,OAAAC,EAAAJ,EAAQ,UAAR,YAAAI,EAAiB,SACvB,IAAK,CACCH,GAAOC,EAAU,OAAM,CAC7B,GAGF,GAAI,CACF,MAAMG,EAAaC,EAAuBN,EAAQ,QAASA,EAAQ,gBAAkB,EAAE,EAEvFG,EAAS,QAAQ,IAAME,EAAW,MAAK,CAAE,EAEzC,MAAME,EAAaC,EAAWN,CAAS,EAEvCC,EAAS,QAAQ,IAAMI,EAAK,QAAO,CAAE,EAErC,MAAME,EAAQZ,EAAYM,CAAQ,EAElC,OAAAI,EAAK,OACHG,EAAcC,EAAe,CAC3B,GAAIX,EAAQ,UAAY,OAAY,CAAA,EAAK,CAAE,QAASA,EAAQ,SAC5D,GAAIA,EAAQ,OAAS,OAAY,CAAA,EAAK,CAAE,KAAMA,EAAQ,MACtD,QAASS,EACT,MAAOJ,EAAW,MAClB,GAAIL,EAAQ,QAAU,OAAY,CAAA,EAAK,CAAE,MAAOA,EAAQ,MACzD,CAAA,CAAC,EAGG,CAAE,MAAAS,CAAK,CAChB,OAASb,EAAO,CAEd,MAAAL,EAAWY,CAAQ,EAEbP,CACR,CACF"}
|