@ttsc/graph 0.30.4 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -30
- package/lib/CapturedProcessOutput.d.ts +47 -0
- package/lib/CapturedProcessOutput.js +3 -0
- package/lib/CapturedProcessOutput.js.map +1 -0
- package/lib/ILauncherOption.d.ts +22 -0
- package/lib/ILauncherOption.js +3 -0
- package/lib/ILauncherOption.js.map +1 -0
- package/lib/IProjectOptions.d.ts +18 -0
- package/lib/IProjectOptions.js +3 -0
- package/lib/IProjectOptions.js.map +1 -0
- package/lib/ParsedLauncherOptions.d.ts +13 -0
- package/lib/ParsedLauncherOptions.js +3 -0
- package/lib/ParsedLauncherOptions.js.map +1 -0
- package/lib/TtscGraphApplication.d.ts +38 -1
- package/lib/TtscGraphApplication.js +26 -1
- package/lib/TtscGraphApplication.js.map +1 -1
- package/lib/TtscGraphLauncherArguments.d.ts +115 -0
- package/lib/TtscGraphLauncherArguments.js +181 -0
- package/lib/TtscGraphLauncherArguments.js.map +1 -0
- package/lib/TtscGraphViewSnapshot.d.ts +35 -0
- package/lib/TtscGraphViewSnapshot.js +48 -0
- package/lib/TtscGraphViewSnapshot.js.map +1 -0
- package/lib/index.d.ts +9 -24
- package/lib/index.js +6 -128
- package/lib/index.js.map +1 -1
- package/lib/internal/GraphProcessTrace.d.ts +1 -0
- package/lib/internal/GraphProcessTrace.js +235 -0
- package/lib/internal/GraphProcessTrace.js.map +1 -0
- package/lib/launcherArgs.d.ts +75 -16
- package/lib/launcherArgs.js +77 -8
- package/lib/launcherArgs.js.map +1 -1
- package/lib/model/IArtifactDirectory.d.ts +26 -0
- package/lib/model/IArtifactDirectory.js +3 -0
- package/lib/model/IArtifactDirectory.js.map +1 -0
- package/lib/model/IArtifactInputs.d.ts +19 -0
- package/lib/model/IArtifactInputs.js +3 -0
- package/lib/model/IArtifactInputs.js.map +1 -0
- package/lib/model/IPublishedArtifacts.d.ts +76 -0
- package/lib/model/IPublishedArtifacts.js +3 -0
- package/lib/model/IPublishedArtifacts.js.map +1 -0
- package/lib/model/IPublishedArtifactsResident.d.ts +19 -0
- package/lib/model/IPublishedArtifactsResident.js +3 -0
- package/lib/model/IPublishedArtifactsResident.js.map +1 -0
- package/lib/model/ITtscLintDaemonTarget.d.ts +20 -0
- package/lib/model/ITtscLintDaemonTarget.js +3 -0
- package/lib/model/ITtscLintDaemonTarget.js.map +1 -0
- package/lib/model/TtscGraphLinePeer.d.ts +146 -0
- package/lib/model/TtscGraphLinePeer.js +213 -0
- package/lib/model/TtscGraphLinePeer.js.map +1 -0
- package/lib/model/TtscGraphMemory.d.ts +156 -16
- package/lib/model/TtscGraphMemory.js +228 -222
- package/lib/model/TtscGraphMemory.js.map +1 -1
- package/lib/model/TtscGraphNativeArguments.d.ts +40 -0
- package/lib/model/TtscGraphNativeArguments.js +64 -0
- package/lib/model/TtscGraphNativeArguments.js.map +1 -0
- package/lib/model/TtscGraphNodeId.d.ts +55 -3
- package/lib/model/TtscGraphNodeId.js +40 -2
- package/lib/model/TtscGraphNodeId.js.map +1 -1
- package/lib/model/TtscGraphProjection.d.ts +156 -0
- package/lib/model/TtscGraphProjection.js +390 -0
- package/lib/model/TtscGraphProjection.js.map +1 -0
- package/lib/model/TtscGraphProtocol.d.ts +28 -0
- package/lib/model/TtscGraphProtocol.js +928 -0
- package/lib/model/TtscGraphProtocol.js.map +1 -0
- package/lib/model/TtscGraphReadonly.d.ts +15 -0
- package/lib/model/TtscGraphReadonly.js +3 -0
- package/lib/model/TtscGraphReadonly.js.map +1 -0
- package/lib/model/TtscGraphRequestOptions.d.ts +16 -0
- package/lib/model/TtscGraphRequestOptions.js +3 -0
- package/lib/model/TtscGraphRequestOptions.js.map +1 -0
- package/lib/model/TtscGraphSession.d.ts +82 -36
- package/lib/model/TtscGraphSession.js +164 -1238
- package/lib/model/TtscGraphSession.js.map +1 -1
- package/lib/model/TtscGraphSessionOptions.d.ts +20 -0
- package/lib/model/TtscGraphSessionOptions.js +3 -0
- package/lib/model/TtscGraphSessionOptions.js.map +1 -0
- package/lib/model/TtscGraphSessionState.d.ts +187 -0
- package/lib/model/TtscGraphSessionState.js +417 -0
- package/lib/model/TtscGraphSessionState.js.map +1 -0
- package/lib/model/TtscGraphShardStore.d.ts +64 -3
- package/lib/model/TtscGraphShardStore.js +85 -15
- package/lib/model/TtscGraphShardStore.js.map +1 -1
- package/lib/model/TtscGraphSourceReader.d.ts +31 -8
- package/lib/model/TtscGraphSourceReader.js +37 -13
- package/lib/model/TtscGraphSourceReader.js.map +1 -1
- package/lib/model/TtscLintDaemon.d.ts +35 -17
- package/lib/model/TtscLintDaemon.js +39 -117
- package/lib/model/TtscLintDaemon.js.map +1 -1
- package/lib/model/TtscLintDaemonState.d.ts +69 -0
- package/lib/model/TtscLintDaemonState.js +166 -0
- package/lib/model/TtscLintDaemonState.js.map +1 -0
- package/lib/model/copyGraphRecords.d.ts +14 -0
- package/lib/model/copyGraphRecords.js +19 -0
- package/lib/model/copyGraphRecords.js.map +1 -0
- package/lib/model/copyGraphSnapshot.d.ts +17 -0
- package/lib/model/copyGraphSnapshot.js +33 -0
- package/lib/model/copyGraphSnapshot.js.map +1 -0
- package/lib/model/loadGraph.d.ts +19 -10
- package/lib/model/loadGraph.js +21 -12
- package/lib/model/loadGraph.js.map +1 -1
- package/lib/model/publishedArtifacts.d.ts +78 -97
- package/lib/model/publishedArtifacts.js +271 -85
- package/lib/model/publishedArtifacts.js.map +1 -1
- package/lib/nativeExecutable.d.ts +19 -8
- package/lib/nativeExecutable.js +75 -15
- package/lib/nativeExecutable.js.map +1 -1
- package/lib/reduce.d.ts +19 -45
- package/lib/reduce.js +19 -3
- package/lib/reduce.js.map +1 -1
- package/lib/resolveGraphBinary.d.ts +9 -0
- package/lib/resolveGraphBinary.js +11 -3
- package/lib/resolveGraphBinary.js.map +1 -1
- package/lib/runGraph.d.ts +21 -0
- package/lib/runGraph.js +83 -0
- package/lib/runGraph.js.map +1 -0
- package/lib/server/IResolvedGraphHandle.d.ts +22 -0
- package/lib/server/IResolvedGraphHandle.js +3 -0
- package/lib/server/IResolvedGraphHandle.js.map +1 -0
- package/lib/server/createServer.d.ts +14 -10
- package/lib/server/createServer.js +42 -39
- package/lib/server/createServer.js.map +1 -1
- package/lib/server/exportSurface.d.ts +23 -1
- package/lib/server/exportSurface.js +23 -1
- package/lib/server/exportSurface.js.map +1 -1
- package/lib/server/formatGraphFailure.d.ts +20 -0
- package/lib/server/formatGraphFailure.js +35 -0
- package/lib/server/formatGraphFailure.js.map +1 -0
- package/lib/server/pathPolicy.d.ts +70 -5
- package/lib/server/pathPolicy.js +66 -4
- package/lib/server/pathPolicy.js.map +1 -1
- package/lib/server/resolveHandle.d.ts +10 -5
- package/lib/server/resolveHandle.js +39 -7
- package/lib/server/resolveHandle.js.map +1 -1
- package/lib/server/resultAudit.d.ts +17 -14
- package/lib/server/resultAudit.js +56 -27
- package/lib/server/resultAudit.js.map +1 -1
- package/lib/server/resultNext.d.ts +26 -1
- package/lib/server/resultNext.js +14 -0
- package/lib/server/resultNext.js.map +1 -1
- package/lib/server/runDetails.d.ts +72 -15
- package/lib/server/runDetails.js +104 -69
- package/lib/server/runDetails.js.map +1 -1
- package/lib/server/runEntrypoints.d.ts +9 -0
- package/lib/server/runEntrypoints.js +9 -0
- package/lib/server/runEntrypoints.js.map +1 -1
- package/lib/server/runLookup.d.ts +13 -3
- package/lib/server/runLookup.js +19 -6
- package/lib/server/runLookup.js.map +1 -1
- package/lib/server/runOverview.d.ts +13 -4
- package/lib/server/runOverview.js +13 -4
- package/lib/server/runOverview.js.map +1 -1
- package/lib/server/runTour.d.ts +9 -0
- package/lib/server/runTour.js +33 -65
- package/lib/server/runTour.js.map +1 -1
- package/lib/server/runTrace.d.ts +25 -1
- package/lib/server/runTrace.js +133 -88
- package/lib/server/runTrace.js.map +1 -1
- package/lib/server/startServer.d.ts +16 -0
- package/lib/server/startServer.js +24 -1
- package/lib/server/startServer.js.map +1 -1
- package/lib/structures/ITtscGraphApplication.d.ts +95 -41
- package/lib/structures/ITtscGraphDecorator.d.ts +18 -0
- package/lib/structures/ITtscGraphDetails.d.ts +81 -6
- package/lib/structures/ITtscGraphDocTag.d.ts +17 -8
- package/lib/structures/ITtscGraphDump.d.ts +106 -8
- package/lib/structures/ITtscGraphEdge.d.ts +14 -2
- package/lib/structures/ITtscGraphEntrypoints.d.ts +81 -6
- package/lib/structures/ITtscGraphEscape.d.ts +24 -2
- package/lib/structures/ITtscGraphEvidence.d.ts +9 -0
- package/lib/structures/ITtscGraphLookup.d.ts +42 -9
- package/lib/structures/ITtscGraphNext.d.ts +12 -1
- package/lib/structures/ITtscGraphNode.d.ts +38 -11
- package/lib/structures/ITtscGraphOverview.d.ts +81 -6
- package/lib/structures/ITtscGraphSnapshot.d.ts +97 -2
- package/lib/structures/ITtscGraphSpan.d.ts +9 -0
- package/lib/structures/ITtscGraphTour.d.ts +83 -9
- package/lib/structures/ITtscGraphTrace.d.ts +99 -14
- package/lib/structures/RawDump.d.ts +22 -0
- package/lib/structures/RawDump.js +3 -0
- package/lib/structures/RawDump.js.map +1 -0
- package/lib/structures/RawEdge.d.ts +20 -0
- package/lib/structures/RawEdge.js +3 -0
- package/lib/structures/RawEdge.js.map +1 -0
- package/lib/structures/RawNode.d.ts +26 -0
- package/lib/structures/RawNode.js +3 -0
- package/lib/structures/RawNode.js.map +1 -0
- package/lib/structures/TtscGraphArtifactNodeKind.d.ts +9 -0
- package/lib/structures/TtscGraphArtifactNodeKind.js +9 -0
- package/lib/structures/TtscGraphArtifactNodeKind.js.map +1 -1
- package/lib/structures/TtscGraphDumpEdgeKind.d.ts +15 -1
- package/lib/structures/TtscGraphDumpNodeKind.d.ts +9 -0
- package/lib/structures/TtscGraphEdgeKind.d.ts +13 -4
- package/lib/structures/TtscGraphNodeKind.d.ts +9 -0
- package/lib/structures/TtscGraphNodeModifier.d.ts +9 -0
- package/lib/structures/ViewerLink.d.ts +20 -0
- package/lib/structures/ViewerLink.js +3 -0
- package/lib/structures/ViewerLink.js.map +1 -0
- package/lib/structures/ViewerNode.d.ts +24 -0
- package/lib/structures/ViewerNode.js +3 -0
- package/lib/structures/ViewerNode.js.map +1 -0
- package/lib/structures/ViewerPayload.d.ts +42 -0
- package/lib/structures/ViewerPayload.js +3 -0
- package/lib/structures/ViewerPayload.js.map +1 -0
- package/lib/view.d.ts +9 -0
- package/lib/view.js +203 -91
- package/lib/view.js.map +1 -1
- package/lib/viewer/viewer.js +1 -1
- package/package.json +8 -6
- package/src/CapturedProcessOutput.ts +50 -0
- package/src/ILauncherOption.ts +24 -0
- package/src/IProjectOptions.ts +19 -0
- package/src/ParsedLauncherOptions.ts +13 -0
- package/src/TtscGraphApplication.ts +38 -1
- package/src/TtscGraphLauncherArguments.ts +207 -0
- package/src/TtscGraphViewSnapshot.ts +46 -0
- package/src/index.ts +9 -160
- package/src/internal/GraphProcessTrace.ts +242 -0
- package/src/launcherArgs.ts +89 -23
- package/src/model/IArtifactDirectory.ts +27 -0
- package/src/model/IArtifactInputs.ts +21 -0
- package/src/model/IPublishedArtifacts.ts +81 -0
- package/src/model/IPublishedArtifactsResident.ts +24 -0
- package/src/model/ITtscLintDaemonTarget.ts +22 -0
- package/src/model/TtscGraphLinePeer.ts +318 -0
- package/src/model/TtscGraphMemory.ts +284 -246
- package/src/model/TtscGraphNativeArguments.ts +67 -0
- package/src/model/TtscGraphNodeId.ts +57 -3
- package/src/model/TtscGraphProjection.ts +473 -0
- package/src/model/TtscGraphProtocol.ts +90 -0
- package/src/model/TtscGraphReadonly.ts +17 -0
- package/src/model/TtscGraphRequestOptions.ts +16 -0
- package/src/model/TtscGraphSession.ts +196 -475
- package/src/model/TtscGraphSessionOptions.ts +22 -0
- package/src/model/TtscGraphSessionState.ts +558 -0
- package/src/model/TtscGraphShardStore.ts +99 -23
- package/src/model/TtscGraphSourceReader.ts +37 -15
- package/src/model/TtscLintDaemon.ts +55 -136
- package/src/model/TtscLintDaemonState.ts +174 -0
- package/src/model/copyGraphRecords.ts +17 -0
- package/src/model/copyGraphSnapshot.ts +30 -0
- package/src/model/loadGraph.ts +23 -12
- package/src/model/publishedArtifacts.ts +361 -182
- package/src/nativeExecutable.ts +93 -26
- package/src/reduce.ts +24 -51
- package/src/resolveGraphBinary.ts +13 -3
- package/src/runGraph.ts +90 -0
- package/src/server/IResolvedGraphHandle.ts +24 -0
- package/src/server/createServer.ts +16 -22
- package/src/server/exportSurface.ts +23 -1
- package/src/server/formatGraphFailure.ts +32 -0
- package/src/server/pathPolicy.ts +70 -5
- package/src/server/resolveHandle.ts +45 -14
- package/src/server/resultAudit.ts +58 -27
- package/src/server/resultNext.ts +26 -1
- package/src/server/runDetails.ts +138 -73
- package/src/server/runEntrypoints.ts +13 -1
- package/src/server/runLookup.ts +23 -7
- package/src/server/runOverview.ts +17 -5
- package/src/server/runTour.ts +44 -82
- package/src/server/runTrace.ts +175 -102
- package/src/server/startServer.ts +29 -1
- package/src/structures/ITtscGraphApplication.ts +95 -41
- package/src/structures/ITtscGraphDecorator.ts +18 -0
- package/src/structures/ITtscGraphDetails.ts +81 -6
- package/src/structures/ITtscGraphDocTag.ts +17 -8
- package/src/structures/ITtscGraphDump.ts +106 -8
- package/src/structures/ITtscGraphEdge.ts +14 -2
- package/src/structures/ITtscGraphEntrypoints.ts +81 -6
- package/src/structures/ITtscGraphEscape.ts +24 -2
- package/src/structures/ITtscGraphEvidence.ts +9 -0
- package/src/structures/ITtscGraphLookup.ts +42 -9
- package/src/structures/ITtscGraphNext.ts +12 -1
- package/src/structures/ITtscGraphNode.ts +38 -11
- package/src/structures/ITtscGraphOverview.ts +88 -6
- package/src/structures/ITtscGraphSnapshot.ts +117 -2
- package/src/structures/ITtscGraphSpan.ts +9 -0
- package/src/structures/ITtscGraphTour.ts +83 -9
- package/src/structures/ITtscGraphTrace.ts +100 -14
- package/src/structures/RawDump.ts +25 -0
- package/src/structures/RawEdge.ts +22 -0
- package/src/structures/RawNode.ts +31 -0
- package/src/structures/TtscGraphArtifactNodeKind.ts +9 -0
- package/src/structures/TtscGraphDumpEdgeKind.ts +15 -1
- package/src/structures/TtscGraphDumpNodeKind.ts +9 -0
- package/src/structures/TtscGraphEdgeKind.ts +13 -4
- package/src/structures/TtscGraphNodeKind.ts +9 -0
- package/src/structures/TtscGraphNodeModifier.ts +9 -0
- package/src/structures/ViewerLink.ts +22 -0
- package/src/structures/ViewerNode.ts +28 -0
- package/src/structures/ViewerPayload.ts +52 -0
- package/src/view.ts +208 -110
- package/src/viewer/legend.ts +119 -27
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construction options for a resident native graph session.
|
|
3
|
+
*
|
|
4
|
+
* @evidence contracts/common.md#principled-implementation Project coordinates and optional binary determine the native producer for one resident session.
|
|
5
|
+
* @evidence contracts/common.md#clear-and-simple-design Construction identity is separate from per-call cancellation controls.
|
|
6
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts An explicit binary remains supported rather than injecting a fixture-dependent resolver.
|
|
7
|
+
* @evidence contracts/common.md#meaningful-documentation Member comments document producer project coordinates, binary absoluteness and project-relative resolution.
|
|
8
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources data shape only: it holds no handle, task or retained state.
|
|
9
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms data shape only: it contains no loop or algorithm.
|
|
10
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work data shape only: it computes nothing another request could share.
|
|
11
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation data shape only: it touches no file, path or process.
|
|
12
|
+
*/
|
|
13
|
+
export interface TtscGraphSessionOptions {
|
|
14
|
+
/** Project root passed to `ttscgraph serve`. */
|
|
15
|
+
cwd: string;
|
|
16
|
+
|
|
17
|
+
/** Project tsconfig passed to `ttscgraph serve`. */
|
|
18
|
+
tsconfig: string;
|
|
19
|
+
|
|
20
|
+
/** Absolute native binary path, resolved from `cwd` when omitted. */
|
|
21
|
+
binary?: string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import { ITtscGraphSnapshot } from "../structures/ITtscGraphSnapshot";
|
|
2
|
+
import { TtscGraphLinePeer } from "./TtscGraphLinePeer";
|
|
3
|
+
import { TtscGraphMemory } from "./TtscGraphMemory";
|
|
4
|
+
import { TtscGraphShardStore } from "./TtscGraphShardStore";
|
|
5
|
+
import { DUMP_SCHEMA_VERSION } from "./loadGraph";
|
|
6
|
+
|
|
7
|
+
const GRAPH_SNAPSHOT_PROTOCOL_VERSION = 1;
|
|
8
|
+
|
|
9
|
+
interface Pending {
|
|
10
|
+
child: TtscGraphLinePeer.Connection;
|
|
11
|
+
resolve: (response: ITtscGraphSnapshot) => void;
|
|
12
|
+
reject: (error: Error) => void;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
abort?: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Queue, request correlation and generation ownership for one resident graph.
|
|
19
|
+
*
|
|
20
|
+
* The host supplies artifact synchronization and validated line decoding; this
|
|
21
|
+
* owner accepts typed envelopes, atomically replaces graph generations, and
|
|
22
|
+
* retires a peer when its transport or generation cannot be trusted. It is
|
|
23
|
+
* internal to the graph facade, not an alternate public session API.
|
|
24
|
+
*
|
|
25
|
+
* @evidence contracts/common.md#principled-implementation Serialized admission and identity-checked reply settlement protect one atomic shard generation across abort, close and peer replacement.
|
|
26
|
+
* @evidence contracts/common.md#clear-and-simple-design Artifact discovery and generated schema decoding remain host responsibilities; this owner controls queue, pending replies, memory and shard retirement.
|
|
27
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Typed receive requires validated envelopes from the actual decoder; it supplies no schema substitute or fabricated fallback facts.
|
|
28
|
+
* @evidence contracts/common.md#meaningful-documentation Native prose states the validated-input premise and internal ownership; receive and failure events distinguish peer identity and lifecycle effects.
|
|
29
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms graph/receive/close own admission, frame processing and retirement; this declaration groups their retained state.
|
|
30
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work graph/receive/close establish continued peer/model reuse, not the class descriptor independently.
|
|
31
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources graph/receive/close control acquisition and release; the class declaration adds no separate lifecycle transition.
|
|
32
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation keeps queue and pending-request state in memory and reaches the process only through the Host and Connection operations it is given.
|
|
33
|
+
*/
|
|
34
|
+
export class TtscGraphSessionState {
|
|
35
|
+
private child: TtscGraphLinePeer.Connection | undefined;
|
|
36
|
+
private nextId = 0;
|
|
37
|
+
private readonly pending = new Map<number, Pending>();
|
|
38
|
+
private queue: Promise<void> = Promise.resolve();
|
|
39
|
+
private waiting:
|
|
40
|
+
| {
|
|
41
|
+
controller: AbortController;
|
|
42
|
+
started: boolean;
|
|
43
|
+
consumers: Set<{
|
|
44
|
+
settled: boolean;
|
|
45
|
+
resolve: (graph: TtscGraphMemory) => void;
|
|
46
|
+
reject: (error: Error) => void;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
| undefined;
|
|
50
|
+
private current: TtscGraphMemory | undefined;
|
|
51
|
+
private shardStore = new TtscGraphShardStore();
|
|
52
|
+
private closed = false;
|
|
53
|
+
private closing: Promise<void> | undefined;
|
|
54
|
+
private readonly retirements = new Set<Promise<void>>();
|
|
55
|
+
|
|
56
|
+
public constructor(private readonly host: TtscGraphSessionState.Host) {}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Whether artifact refresh currently has a peer to update.
|
|
60
|
+
*
|
|
61
|
+
* @evidence contracts/common.md#principled-implementation The presence of owned peer state distinguishes an active publication target from a yet-unopened or retired session.
|
|
62
|
+
* @evidence contracts/common.md#clear-and-simple-design One read-only query lets the artifact facade retain its original live-peer refresh precondition.
|
|
63
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Ownership is observed directly rather than guessed from previous artifact values or a clock.
|
|
64
|
+
* @evidence contracts/common.md#meaningful-documentation The headline states why the facade asks this ownership question.
|
|
65
|
+
* @evidence contracts/performance.md#efficient-algorithms This constant-time reference check scans no pending or shard population.
|
|
66
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The query returns current ownership and coordinates no completed computation.
|
|
67
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources It acquires or releases nothing; graph and close own the queried peer.
|
|
68
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation reads one field.
|
|
69
|
+
*/
|
|
70
|
+
public hasPeer(): boolean {
|
|
71
|
+
return this.child !== undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Refresh one graph for callers admitted before its freshness check starts.
|
|
76
|
+
*
|
|
77
|
+
* Later arrivals form another group. Cancellation releases only that caller;
|
|
78
|
+
* the native request is aborted when every caller in its group has left.
|
|
79
|
+
*
|
|
80
|
+
* @evidence contracts/common.md#principled-implementation A group closes before refresh starts, so its one validation is after every member's admission; later arrivals cannot inherit a check already in progress. Each consumer settles once and owns only its cancellation.
|
|
81
|
+
* @evidence contracts/common.md#clear-and-simple-design Admission groups callers, refresh owns artifact synchronization and atomic model replacement, and the group's controller owns the shared producer independently of caller signals.
|
|
82
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Sharing is justified by admission before validation, without a clock, cooldown or quiet-watcher assumption. The last active consumer's abort cancels shared work and retires a peer with an outstanding native request rather than returning fabricated facts.
|
|
83
|
+
* @evidence contracts/common.md#meaningful-documentation Native paragraphs state the admission boundary and distinguish individual cancellation from producer cancellation; receive separately states its validation premise.
|
|
84
|
+
* @evidence contracts/performance.md#efficient-algorithms Set insertion/removal is expected constant time per consumer and settlement visits each live consumer once. One frame and artifact validation serve each group; changed transactions retain complete validation and reference scans while equivalent immutable projection components and ordered index buckets are reused.
|
|
85
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Callers admitted before a refresh starts share its validation and immutable model. A later group validates again, changed responses replace memory atomically, and retirement clears reusable generation state.
|
|
86
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources Queued groups and live consumer sets grow with outstanding demand. Settlement removes consumers and abort listeners immediately; completed queue callbacks release their groups, while one current peer/model/store remains session-owned.
|
|
87
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation queues a request and calls injected host operations; it opens no file or process itself.
|
|
88
|
+
*/
|
|
89
|
+
public graph(
|
|
90
|
+
options: { signal?: AbortSignal } = {},
|
|
91
|
+
): Promise<TtscGraphMemory> {
|
|
92
|
+
if (this.closed) {
|
|
93
|
+
return Promise.reject(new Error("@ttsc/graph: native session is closed"));
|
|
94
|
+
}
|
|
95
|
+
let resolve!: (graph: TtscGraphMemory) => void;
|
|
96
|
+
let reject!: (error: Error) => void;
|
|
97
|
+
let group = this.waiting;
|
|
98
|
+
const created = group === undefined;
|
|
99
|
+
if (group === undefined) {
|
|
100
|
+
group = {
|
|
101
|
+
controller: new AbortController(),
|
|
102
|
+
started: false,
|
|
103
|
+
consumers: new Set(),
|
|
104
|
+
};
|
|
105
|
+
this.waiting = group;
|
|
106
|
+
}
|
|
107
|
+
const consumer = {
|
|
108
|
+
settled: false,
|
|
109
|
+
resolve: undefined! as (graph: TtscGraphMemory) => void,
|
|
110
|
+
reject: undefined! as (error: Error) => void,
|
|
111
|
+
};
|
|
112
|
+
const result = new Promise<TtscGraphMemory>((res, rej) => {
|
|
113
|
+
resolve = (graph) => {
|
|
114
|
+
if (consumer.settled) return;
|
|
115
|
+
consumer.settled = true;
|
|
116
|
+
group.consumers.delete(consumer);
|
|
117
|
+
options.signal?.removeEventListener("abort", cancelQueued);
|
|
118
|
+
res(graph);
|
|
119
|
+
};
|
|
120
|
+
reject = (error) => {
|
|
121
|
+
if (consumer.settled) return;
|
|
122
|
+
consumer.settled = true;
|
|
123
|
+
group.consumers.delete(consumer);
|
|
124
|
+
options.signal?.removeEventListener("abort", cancelQueued);
|
|
125
|
+
rej(error);
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
const cancelQueued = () => {
|
|
129
|
+
reject(cancelledError(options.signal));
|
|
130
|
+
if (group.started && group.consumers.size === 0)
|
|
131
|
+
group.controller.abort(options.signal?.reason);
|
|
132
|
+
};
|
|
133
|
+
consumer.resolve = resolve;
|
|
134
|
+
consumer.reject = reject;
|
|
135
|
+
group.consumers.add(consumer);
|
|
136
|
+
if (options.signal?.aborted) {
|
|
137
|
+
reject(cancelledError(options.signal));
|
|
138
|
+
} else {
|
|
139
|
+
options.signal?.addEventListener("abort", cancelQueued, { once: true });
|
|
140
|
+
}
|
|
141
|
+
if (!created) return result;
|
|
142
|
+
this.queue = this.queue
|
|
143
|
+
.catch(() => undefined)
|
|
144
|
+
.then(async () => {
|
|
145
|
+
group.started = true;
|
|
146
|
+
if (this.waiting === group) this.waiting = undefined;
|
|
147
|
+
if (group.consumers.size === 0) return;
|
|
148
|
+
try {
|
|
149
|
+
const graph = await this.refresh(group.controller.signal);
|
|
150
|
+
for (const item of group.consumers) item.resolve(graph);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
for (const item of group.consumers) item.reject(asError(error));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Close the native session. Safe to call more than once.
|
|
160
|
+
*
|
|
161
|
+
* Retires artifact sidecars and rejects pending native requests. Queued
|
|
162
|
+
* requests observe the closed state before they can create another child.
|
|
163
|
+
*
|
|
164
|
+
* @evidence contracts/common.md#principled-implementation The closed flag precedes sidecar disposal and child failure, so every pending or subsequent native operation observes retired ownership.
|
|
165
|
+
* @evidence contracts/common.md#clear-and-simple-design The explicit close path reuses failChild/failPending cleanup instead of a second cancellation implementation.
|
|
166
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Disposing a session cannot trigger a compensating respawn or pretend outstanding requests succeeded.
|
|
167
|
+
* @evidence contracts/common.md#meaningful-documentation Native prose documents idempotence, pending rejection and queued-request behavior.
|
|
168
|
+
* @evidence contracts/performance.md#efficient-algorithms Shutdown invokes the artifact host once and visits pending owners once; the actual peer adapter owns any native kill timer.
|
|
169
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Closure ends this owner's permission to reuse native Program, model and sidecars; subsequent graph calls reject.
|
|
170
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources The host retires artifact sidecars, pending listeners are removed, current model/shards are cleared and peer.close transfers reader/process disposal to its actual adapter.
|
|
171
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation marks the state closed and calls the injected host and peer close operations; the process work lives there.
|
|
172
|
+
*/
|
|
173
|
+
public close(): Promise<void> {
|
|
174
|
+
if (this.closing !== undefined) return this.closing;
|
|
175
|
+
this.closed = true;
|
|
176
|
+
const hostClose = Promise.resolve().then(() => this.host.close());
|
|
177
|
+
void hostClose.catch(() => undefined);
|
|
178
|
+
const error = new Error("@ttsc/graph: native session closed");
|
|
179
|
+
if (this.child !== undefined) this.failChild(this.child, error);
|
|
180
|
+
else this.failPending(error);
|
|
181
|
+
this.closing = (async () => {
|
|
182
|
+
await this.queue;
|
|
183
|
+
const results = await Promise.allSettled([
|
|
184
|
+
hostClose,
|
|
185
|
+
...this.retirements,
|
|
186
|
+
]);
|
|
187
|
+
const failures = results
|
|
188
|
+
.filter(
|
|
189
|
+
(result): result is PromiseRejectedResult =>
|
|
190
|
+
result.status === "rejected",
|
|
191
|
+
)
|
|
192
|
+
.map((result) => result.reason);
|
|
193
|
+
if (failures.length > 0)
|
|
194
|
+
throw new AggregateError(
|
|
195
|
+
failures,
|
|
196
|
+
"@ttsc/graph: session shutdown failed",
|
|
197
|
+
);
|
|
198
|
+
})();
|
|
199
|
+
void this.closing.catch(() => undefined);
|
|
200
|
+
return this.closing;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private async refresh(signal?: AbortSignal): Promise<TtscGraphMemory> {
|
|
204
|
+
if (this.closed) throw new Error("@ttsc/graph: native session is closed");
|
|
205
|
+
await Promise.all(this.retirements);
|
|
206
|
+
if (this.closed) throw new Error("@ttsc/graph: native session is closed");
|
|
207
|
+
// The protocol version and envelope shape were settled by the host decoder,
|
|
208
|
+
// before this frame was ever routed here.
|
|
209
|
+
await this.host.beforeRequest(signal);
|
|
210
|
+
if (this.closed) throw new Error("@ttsc/graph: native session is closed");
|
|
211
|
+
const response = await this.request(signal);
|
|
212
|
+
this.assertResponseSemantics(response);
|
|
213
|
+
if (response.error !== undefined) {
|
|
214
|
+
throw new Error(`@ttsc/graph: ${response.error}`);
|
|
215
|
+
}
|
|
216
|
+
if (response.changed) {
|
|
217
|
+
if (response.snapshot !== undefined) {
|
|
218
|
+
try {
|
|
219
|
+
this.current = this.shardStore.applyProjection(
|
|
220
|
+
response.snapshot,
|
|
221
|
+
(dump) => TtscGraphMemory.fromResident(dump, this.current),
|
|
222
|
+
);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
const failure = asError(error);
|
|
225
|
+
if (this.child !== undefined) this.failChild(this.child, failure);
|
|
226
|
+
throw failure;
|
|
227
|
+
}
|
|
228
|
+
} else if (response.dump !== undefined) {
|
|
229
|
+
// A serve-protocol-v1 binary predating graph shard negotiation ignores
|
|
230
|
+
// the optional request field and retains the complete-dump response.
|
|
231
|
+
this.current = TtscGraphMemory.from(response.dump);
|
|
232
|
+
} else {
|
|
233
|
+
throw new Error(
|
|
234
|
+
`@ttsc/graph: native ${response.mode} response omitted both graph snapshot protocol v${String(GRAPH_SNAPSHOT_PROTOCOL_VERSION)} data and a compatible dump`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (this.current === undefined) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
"@ttsc/graph: native session returned no initial graph snapshot",
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
return this.current;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private assertResponseSemantics(response: ITtscGraphSnapshot): void {
|
|
247
|
+
const bodies =
|
|
248
|
+
Number(response.dump !== undefined) +
|
|
249
|
+
Number(response.snapshot !== undefined);
|
|
250
|
+
let problem: string | undefined;
|
|
251
|
+
if (response.error !== undefined) {
|
|
252
|
+
if (response.mode !== "error" || response.changed || bodies !== 0) {
|
|
253
|
+
problem = "an error response carried snapshot state";
|
|
254
|
+
}
|
|
255
|
+
} else if (response.mode === "error") {
|
|
256
|
+
problem = "an error-mode response omitted its error";
|
|
257
|
+
} else if (response.changed) {
|
|
258
|
+
if (response.mode === "unchanged" || bodies !== 1) {
|
|
259
|
+
problem = "a changed response did not carry exactly one snapshot body";
|
|
260
|
+
}
|
|
261
|
+
} else if (response.mode !== "unchanged" || bodies !== 0) {
|
|
262
|
+
problem = "an unchanged response carried changed mode or snapshot state";
|
|
263
|
+
}
|
|
264
|
+
if (problem === undefined) return;
|
|
265
|
+
const error = new Error(`@ttsc/graph: native session returned ${problem}`);
|
|
266
|
+
if (this.child !== undefined) this.failChild(this.child, error);
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
private request(signal?: AbortSignal): Promise<ITtscGraphSnapshot> {
|
|
270
|
+
if (signal?.aborted) throw cancelledError(signal);
|
|
271
|
+
const child = this.ensureChild();
|
|
272
|
+
const id = ++this.nextId;
|
|
273
|
+
return new Promise<ITtscGraphSnapshot>((resolve, reject) => {
|
|
274
|
+
const pending: Pending = {
|
|
275
|
+
child,
|
|
276
|
+
resolve,
|
|
277
|
+
reject,
|
|
278
|
+
signal,
|
|
279
|
+
};
|
|
280
|
+
if (signal !== undefined) {
|
|
281
|
+
pending.abort = () =>
|
|
282
|
+
this.failChild(child, cancelledError(signal, child));
|
|
283
|
+
signal.addEventListener("abort", pending.abort, { once: true });
|
|
284
|
+
}
|
|
285
|
+
this.pending.set(id, pending);
|
|
286
|
+
if (signal?.aborted) {
|
|
287
|
+
pending.abort!();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
child.write(
|
|
291
|
+
`${JSON.stringify({
|
|
292
|
+
id,
|
|
293
|
+
graphSnapshotVersion: GRAPH_SNAPSHOT_PROTOCOL_VERSION,
|
|
294
|
+
// Empty when the project publishes nothing, which withdraws whatever
|
|
295
|
+
// the server holds: a publisher the user removed must stop being
|
|
296
|
+
// answered with, and omitting the field instead would say only that
|
|
297
|
+
// this client has no opinion. Omitted only before a child exists,
|
|
298
|
+
// which no request reaches.
|
|
299
|
+
artifacts: this.host.artifacts(),
|
|
300
|
+
})}\n`,
|
|
301
|
+
(error) => {
|
|
302
|
+
if (error === null || error === undefined) return;
|
|
303
|
+
if (this.pending.get(id) !== pending) return;
|
|
304
|
+
this.failChild(
|
|
305
|
+
child,
|
|
306
|
+
new Error(
|
|
307
|
+
`@ttsc/graph: could not request native snapshot: ${error.message}`,
|
|
308
|
+
),
|
|
309
|
+
);
|
|
310
|
+
},
|
|
311
|
+
);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private ensureChild(): TtscGraphLinePeer.Connection {
|
|
316
|
+
if (this.closed) throw new Error("@ttsc/graph: native session is closed");
|
|
317
|
+
if (this.child !== undefined && this.child.alive()) return this.child;
|
|
318
|
+
const child = this.host.open({
|
|
319
|
+
line: (line) => {
|
|
320
|
+
if (this.child !== child) return;
|
|
321
|
+
try {
|
|
322
|
+
this.receive(child, this.host.decode(line));
|
|
323
|
+
} catch (error) {
|
|
324
|
+
this.failChild(child, asError(error));
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
error: (error) =>
|
|
328
|
+
this.failChild(
|
|
329
|
+
child,
|
|
330
|
+
new Error(`@ttsc/graph: native session failed: ${error.message}`),
|
|
331
|
+
),
|
|
332
|
+
exit: (code, signal) =>
|
|
333
|
+
this.failChild(
|
|
334
|
+
child,
|
|
335
|
+
new Error(
|
|
336
|
+
`@ttsc/graph: native session exited (code=${String(code)}, signal=${String(signal)})${stderrSuffix(child)}`,
|
|
337
|
+
),
|
|
338
|
+
),
|
|
339
|
+
});
|
|
340
|
+
this.child = child;
|
|
341
|
+
return child;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Admit a decoded envelope from the current peer; stale peers cannot publish.
|
|
346
|
+
*
|
|
347
|
+
* Callers must supply the actual decoder's validated envelope. This operation
|
|
348
|
+
* checks body schema agreement and correlation; it does not substitute for
|
|
349
|
+
* full envelope shape validation.
|
|
350
|
+
*
|
|
351
|
+
* @evidence contracts/common.md#principled-implementation Peer identity precedes body compatibility and request-id lookup; only the matching pending owner may receive this typed envelope.
|
|
352
|
+
* @evidence contracts/common.md#clear-and-simple-design Wire shape belongs to the decoder; body version and pending correlation belong to the state that will consume its generation.
|
|
353
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Unknown request ids cannot settle the live caller, and incompatible body versions retire ownership rather than trusting absent fields.
|
|
354
|
+
* @evidence contracts/common.md#meaningful-documentation Native prose states the validated-input premise and the checks this operation actually performs.
|
|
355
|
+
* @evidence contracts/performance.md#efficient-algorithms Schema checks and pending-map lookup are constant-time before one settlement; body facts are processed by refresh only for the matching request.
|
|
356
|
+
* @evidence contracts/performance.md#reuse-equivalent-work This routes a validated frame; refresh alone permits memory reuse after an unchanged response, and schema failure clears the reusable peer generation.
|
|
357
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources Settlement removes exactly one pending entry and its abort listener; mismatch retirement clears this peer's current model/store and fails its pending owners.
|
|
358
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation correlates a decoded envelope with its pending request in memory.
|
|
359
|
+
*/
|
|
360
|
+
public receive(
|
|
361
|
+
child: TtscGraphLinePeer.Connection,
|
|
362
|
+
response: ITtscGraphSnapshot,
|
|
363
|
+
): void {
|
|
364
|
+
if (this.child !== child) return;
|
|
365
|
+
// The envelope's version is not the body's, and only the envelope has been
|
|
366
|
+
// held to one so far. A producer can speak this protocol and still carry a
|
|
367
|
+
// dump from another schema — the two move apart the moment a node field is
|
|
368
|
+
// added without the frame around it changing — and then the facts that field
|
|
369
|
+
// holds are silently absent rather than refused. `literals` is exactly that
|
|
370
|
+
// shape: an older producer resolves no value set, so a union comes back
|
|
371
|
+
// looking like a type with no members. Hold the body to its own number too,
|
|
372
|
+
// once the frame is understood.
|
|
373
|
+
if (
|
|
374
|
+
(response.dump !== undefined &&
|
|
375
|
+
response.dump.provenance.schemaVersion !== DUMP_SCHEMA_VERSION) ||
|
|
376
|
+
(response.snapshot !== undefined &&
|
|
377
|
+
response.snapshot.schemaVersion !== DUMP_SCHEMA_VERSION)
|
|
378
|
+
) {
|
|
379
|
+
// Session-wide, for the same reason the protocol mismatch above is: it is
|
|
380
|
+
// the wrong binary, not one bad frame.
|
|
381
|
+
this.failChild(
|
|
382
|
+
child,
|
|
383
|
+
new Error(
|
|
384
|
+
`@ttsc/graph: ttscgraph sends dump schema v${String(
|
|
385
|
+
response.dump?.provenance.schemaVersion ??
|
|
386
|
+
response.snapshot?.schemaVersion,
|
|
387
|
+
)}, this client reads v${String(DUMP_SCHEMA_VERSION)}. ` +
|
|
388
|
+
"Install a matching `ttsc` (the binary resolves from the target " +
|
|
389
|
+
"project, or from TTSC_GRAPH_BINARY).",
|
|
390
|
+
),
|
|
391
|
+
);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const pending = this.pending.get(response.id);
|
|
396
|
+
if (pending === undefined || pending.child !== child) return;
|
|
397
|
+
this.settlePending(response.id, pending, response);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
private failChild(child: TtscGraphLinePeer.Connection, error: Error): void {
|
|
401
|
+
if (this.child !== child) return;
|
|
402
|
+
this.child = undefined;
|
|
403
|
+
this.current = undefined;
|
|
404
|
+
this.shardStore = new TtscGraphShardStore();
|
|
405
|
+
child.close(false);
|
|
406
|
+
this.failPending(error, child);
|
|
407
|
+
// Even an exited process must join its stdio before release is known.
|
|
408
|
+
const retirement = Promise.resolve(child.close(true));
|
|
409
|
+
this.retirements.add(retirement);
|
|
410
|
+
void retirement.then(
|
|
411
|
+
() => this.retirements.delete(retirement),
|
|
412
|
+
() => undefined,
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private failPending(
|
|
417
|
+
error: Error,
|
|
418
|
+
child?: TtscGraphLinePeer.Connection,
|
|
419
|
+
): void {
|
|
420
|
+
for (const [id, pending] of this.pending) {
|
|
421
|
+
if (child === undefined || pending.child === child) {
|
|
422
|
+
this.settlePending(id, pending, error);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private settlePending(
|
|
428
|
+
id: number,
|
|
429
|
+
pending: Pending,
|
|
430
|
+
result: ITtscGraphSnapshot | Error,
|
|
431
|
+
): void {
|
|
432
|
+
if (this.pending.get(id) !== pending) return;
|
|
433
|
+
this.pending.delete(id);
|
|
434
|
+
if (pending.signal !== undefined && pending.abort !== undefined) {
|
|
435
|
+
pending.signal.removeEventListener("abort", pending.abort);
|
|
436
|
+
}
|
|
437
|
+
if (result instanceof Error) pending.reject(result);
|
|
438
|
+
else pending.resolve(result);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** Host operations separate compiler/schema production from state transitions. */
|
|
443
|
+
export namespace TtscGraphSessionState {
|
|
444
|
+
/**
|
|
445
|
+
* Actual session dependencies, provided once by its facade.
|
|
446
|
+
*
|
|
447
|
+
* @evidence contracts/common.md#principled-implementation Host capability identity is fixed for one state owner; artifact synchronization and decoding remain actual facade dependencies.
|
|
448
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
449
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
450
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
451
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
452
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
453
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
454
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
455
|
+
*/
|
|
456
|
+
export interface Host {
|
|
457
|
+
/**
|
|
458
|
+
* Open the native peer for the current published artifacts.
|
|
459
|
+
*
|
|
460
|
+
* @evidence contracts/common.md#principled-implementation Opening supplies one owned connection and its event callbacks for the current artifact answer.
|
|
461
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
462
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
463
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
464
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
465
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
466
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
467
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
468
|
+
*/
|
|
469
|
+
open(events: TtscGraphLinePeer.Events): TtscGraphLinePeer.Connection;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Decode one complete line with the installed generated envelope validator.
|
|
473
|
+
*
|
|
474
|
+
* @evidence contracts/common.md#principled-implementation The decoder capability requires JSON/protocol/full-envelope validation before returning a typed frame.
|
|
475
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
476
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
477
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
478
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
479
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
480
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
481
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
482
|
+
*/
|
|
483
|
+
decode(line: string): ITtscGraphSnapshot;
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Synchronize changed artifact inputs before a refresh.
|
|
487
|
+
*
|
|
488
|
+
* @evidence contracts/common.md#principled-implementation The asynchronous precondition completes artifact synchronization before any graph request is written.
|
|
489
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
490
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
491
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
492
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
493
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
494
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
495
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
496
|
+
*/
|
|
497
|
+
beforeRequest(signal?: AbortSignal): Promise<void>;
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Current artifact answer; an empty string explicitly withdraws it.
|
|
501
|
+
*
|
|
502
|
+
* @evidence contracts/common.md#principled-implementation Undefined, empty and file-path artifact answers retain their distinct wire meanings.
|
|
503
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
504
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
505
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
506
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
507
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
508
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
509
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
510
|
+
*/
|
|
511
|
+
artifacts(): string | undefined;
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Retire sidecars owned by this session.
|
|
515
|
+
*
|
|
516
|
+
* @evidence contracts/common.md#principled-implementation Host closure relinquishes sidecars when terminal state ends their permission to remain live.
|
|
517
|
+
* @evidence contracts/common.md#clear-and-simple-design The signature delegates this capability to the facade while state owns request correlation and lifecycle.
|
|
518
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The declared operation requires the real capability; no canned response or substitute validator belongs to this contract.
|
|
519
|
+
* @evidence contracts/common.md#meaningful-documentation The native member comment states the capability and its ownership or optional-state premise.
|
|
520
|
+
* @evidenceExclude contracts/performance.md#efficient-algorithms This capability signature declares its result; its actual host implementation and graph operation own processing cost.
|
|
521
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work The signature describes a dependency; graph and actual artifact owner establish whether previous work may be reused.
|
|
522
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The signature acquires no resource itself; its actual implementation and state close control lifetime.
|
|
523
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation signature only: the implementer owns any path or process work.
|
|
524
|
+
*/
|
|
525
|
+
close(): void | Promise<void>;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function cancelledError(
|
|
529
|
+
signal?: AbortSignal,
|
|
530
|
+
child?: TtscGraphLinePeer.Connection,
|
|
531
|
+
): Error {
|
|
532
|
+
const error = new Error(
|
|
533
|
+
`@ttsc/graph: native snapshot request cancelled${abortDetail(signal)}${
|
|
534
|
+
child === undefined ? "" : stderrSuffix(child)
|
|
535
|
+
}`,
|
|
536
|
+
);
|
|
537
|
+
error.name = "AbortError";
|
|
538
|
+
return error;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function abortDetail(signal?: AbortSignal): string {
|
|
542
|
+
const reason = signal?.reason;
|
|
543
|
+
if (reason === undefined) return "";
|
|
544
|
+
try {
|
|
545
|
+
return `: ${reason instanceof Error ? reason.message : String(reason)}`;
|
|
546
|
+
} catch {
|
|
547
|
+
return "";
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function stderrSuffix(child: TtscGraphLinePeer.Connection): string {
|
|
552
|
+
const stderr = child.stderr.trim();
|
|
553
|
+
return stderr === "" ? "" : `: ${stderr}`;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function asError(error: unknown): Error {
|
|
557
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
558
|
+
}
|