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
+10 -2
View File
@@ -4,9 +4,11 @@
//
// Only the cables count: a host's SSID connects nothing at run time, as in
// Java (Swift joins a wireless host to the switch of its SSID; not taken).
// A DNS server runs only when it is switched on (Java: DNSServer.aktiv).
// A DNS server runs only when it is switched on (Java: DNSServer.aktiv); an
// echo server is there either way, switched on or off (it can be switched at
// run time).
import { portSnapshot, topologySnapshot, type DnsServerConfiguration, type Id, type TopologySnapshot } from '@mdg-filius/core';
import { portSnapshot, topologySnapshot, type DnsServerConfiguration, type EchoServerSnapshot, type Id, type TopologySnapshot } from '@mdg-filius/core';
import type { ImportedProject } from './importProject.js';
export function projectSnapshot(project: ImportedProject): TopologySnapshot {
@@ -14,6 +16,10 @@ export function projectSnapshot(project: ImportedProject): TopologySnapshot {
for (const [nodeId, configuration] of project.dnsServerConfigurations) {
if (project.activePrograms.get(nodeId)?.has('dnsServer') === true) dnsServers.set(nodeId, configuration);
}
const echoServers = new Map<Id, EchoServerSnapshot>();
for (const [nodeId, configuration] of project.echoServerConfigurations) {
echoServers.set(nodeId, { ...configuration, isActive: project.activePrograms.get(nodeId)?.has('echoServer') === true });
}
return topologySnapshot({
nodes: project.graph.nodes.map((node) => ({
id: node.id,
@@ -32,5 +38,7 @@ export function projectSnapshot(project: ImportedProject): TopologySnapshot {
portForwardingRowsByNodeId: project.portForwardingRowsByNodeId,
switchConfigurationsByNodeId: project.switchConfigurations,
ipForwardingByNodeId: project.ipForwardingByNodeId,
echoServersByNodeId: echoServers,
simpleClientsByNodeId: project.simpleClientConfigurations,
});
}