feat(core): programs' threads, and FILIUS' echo server and generic client after Java, measured against Java

Programs run as generators that yield what they wait for (threads.ts); the
engine resumes them after every event. TCP connect, send, receive, accept
and name resolution exist as such steps; the blocking calls wrap them.
EchoRun records eight stories in Java FILIUS, frames, tables and each
program's window lines; echoJava.test.ts plays them card by card. Not
taken from Java: a connection without a route hangs for ever; a server
switched off leaves its connections' last FIN unanswered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 16:27:44 +00:00
co-authored by Claude Opus 5.5
parent 0abce60aef
commit de3a1d4dfe
24 changed files with 13454 additions and 28 deletions
+15
View File
@@ -12,14 +12,21 @@ import type {
DhcpClientConfiguration,
DhcpServerConfiguration,
DnsServerConfiguration,
EchoServerConfiguration,
FirewallConfiguration,
GatewayPortForwardingRow,
InterfaceConfiguration,
InterfaceKey,
ManualRoute,
SimpleClientConfiguration,
SwitchConfiguration,
} from './config.js';
/** An installed echo server: its port, and whether it is switched on (Java: ServerBaustein.aktiv). */
export interface EchoServerSnapshot extends EchoServerConfiguration {
readonly isActive: boolean;
}
export interface PortSnapshot {
readonly id: Id;
readonly label: string;
@@ -65,6 +72,10 @@ export interface TopologySnapshot {
readonly switchConfigurationsByNodeId: ReadonlyMap<Id, SwitchConfiguration>;
/** Nodes whose IP forwarding differs from their kind's (forwardsIPv4ByDefault): a host that forwards. */
readonly ipForwardingByNodeId: ReadonlyMap<Id, boolean>;
/** The installed echo servers (ServerBaustein), by node. */
readonly echoServersByNodeId: ReadonlyMap<Id, EchoServerSnapshot>;
/** The installed generic clients (ClientBaustein) with the server they last talked to, by node. */
readonly simpleClientsByNodeId: ReadonlyMap<Id, SimpleClientConfiguration>;
}
export interface TopologySnapshotInput {
@@ -81,6 +92,8 @@ export interface TopologySnapshotInput {
portForwardingRowsByNodeId?: ReadonlyMap<Id, readonly GatewayPortForwardingRow[]>;
switchConfigurationsByNodeId?: ReadonlyMap<Id, SwitchConfiguration>;
ipForwardingByNodeId?: ReadonlyMap<Id, boolean>;
echoServersByNodeId?: ReadonlyMap<Id, EchoServerSnapshot>;
simpleClientsByNodeId?: ReadonlyMap<Id, SimpleClientConfiguration>;
}
export function topologySnapshot(input: TopologySnapshotInput): TopologySnapshot {
@@ -98,6 +111,8 @@ export function topologySnapshot(input: TopologySnapshotInput): TopologySnapshot
portForwardingRowsByNodeId: input.portForwardingRowsByNodeId ?? new Map(),
switchConfigurationsByNodeId: input.switchConfigurationsByNodeId ?? new Map(),
ipForwardingByNodeId: input.ipForwardingByNodeId ?? new Map(),
echoServersByNodeId: input.echoServersByNodeId ?? new Map(),
simpleClientsByNodeId: input.simpleClientsByNodeId ?? new Map(),
};
}