feat(core): event queue, Ethernet, switch, ARP, IPv4, ICMP, routing and firewall

First slice of the TypeScript port of the filius-ipad runtime engine,
with 29 tests ported from the Swift suite. Parts not ported yet throw
NotPortedError instead of guessing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 19:22:57 +00:00
co-authored by Claude Opus 5.5
parent 7caee33b3d
commit 696334aa5a
29 changed files with 6199 additions and 11 deletions
+37
View File
@@ -0,0 +1,37 @@
/**
* Structural equality for the runtime's value types — what Swift's synthesized
* `Equatable` gives a struct or enum for free. Handles plain objects, arrays,
* `Uint8Array`, `Map` and `Set`; everything else is compared with `Object.is`.
*/
export function deepEqual(lhs: unknown, rhs: unknown): boolean {
if (Object.is(lhs, rhs)) return true;
if (typeof lhs !== 'object' || typeof rhs !== 'object' || lhs === null || rhs === null) {
return false;
}
if (lhs instanceof Uint8Array || rhs instanceof Uint8Array) {
if (!(lhs instanceof Uint8Array && rhs instanceof Uint8Array)) return false;
return lhs.length === rhs.length && lhs.every((byte, index) => byte === rhs[index]);
}
if (Array.isArray(lhs) || Array.isArray(rhs)) {
if (!(Array.isArray(lhs) && Array.isArray(rhs)) || lhs.length !== rhs.length) return false;
return lhs.every((item, index) => deepEqual(item, rhs[index]));
}
if (lhs instanceof Map || rhs instanceof Map) {
if (!(lhs instanceof Map && rhs instanceof Map) || lhs.size !== rhs.size) return false;
for (const [key, value] of lhs) {
if (!rhs.has(key) || !deepEqual(value, rhs.get(key))) return false;
}
return true;
}
if (lhs instanceof Set || rhs instanceof Set) {
if (!(lhs instanceof Set && rhs instanceof Set) || lhs.size !== rhs.size) return false;
for (const value of lhs) if (!rhs.has(value)) return false;
return true;
}
const leftKeys = Object.keys(lhs).filter((key) => (lhs as Record<string, unknown>)[key] !== undefined);
const rightKeys = Object.keys(rhs).filter((key) => (rhs as Record<string, unknown>)[key] !== undefined);
if (leftKeys.length !== rightKeys.length) return false;
return leftKeys.every((key) =>
deepEqual((lhs as Record<string, unknown>)[key], (rhs as Record<string, unknown>)[key]),
);
}