SOURCE / PINNED RELEASE
Made of little things.
Napplet Machines V8
- Release
- f041ff5dc40c…
- Author-recorded commit
- 71c68951e1dd…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-b5572362d4a
Archive hash verified: 996282af7a380b0d…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import assert from 'node:assert/strict';
import test from 'node:test';
import { makeLoader } from './load.mjs';
const race = '12345678-1234-1234-1234-123456789abc',
host = 'a'.repeat(64),
guest = 'b'.repeat(64);
function fixture(bytes = async () => {}) {
const json = [],
binary = [],
errors = [];
const window = {
setTimeout,
clearTimeout,
setInterval,
clearInterval,
napplet: {
webrtc: {
sendBytes: async (id, value) => {
binary.push(value);
return bytes(id, value);
},
},
},
};
const sdk = {
webrtc: {
send: async (id, payload) => {
json.push({ id, payload });
},
},
cvm: {},
};
const load = makeLoader({ window, Error, crypto, clearTimeout, clearInterval }, sdk);
const { Multiplayer } = load('src/network.ts'),
{ createWorld } = load('src/physics.ts'),
{ Road, presets } = load('src/track.ts');
const world = createWorld(
[{ id: guest, name: 'Guest', car: 0, ai: false }],
new Road(presets[0]),
);
const m = new Multiplayer();
Object.assign(m, {
actor: guest,
authority: host,
room: { room: 'test', peers: [host, guest] },
session: 'control',
stateSession: 'state',
transient: true,
start: { type: 'start', race, world, track: presets[0] },
});
m.connected.add(host);
m.statePeers.add(host);
m.binaryPeers.add(host);
m.onError = (e) => errors.push(e);
return { m, json, binary, errors, world };
}
const command = (seq) => ({
seq,
input: { throttle: 1, steer: 0, boost: false, brake: false, reset: false },
});
test('reordered/duplicate snapshots never move backwards; inputs and reliable one-shot resets deduplicate', () => {
const { m, world } = fixture(),
ticks = [],
inputs = [],
resets = [];
m.onSnapshot = (w) => ticks.push(w.tick);
for (const tick of [8, 6, 8, 9])
m.receive(host, { type: 'world', race, world: { ...world, tick } });
assert.deepEqual(ticks, [8, 9]);
m.receive(guest, { type: 'world', race, world: { ...world, tick: 100 } });
assert.deepEqual(ticks, [8, 9]);
m.actor = host;
m.onInput = (_, c) => inputs.push(c.at(-1).seq);
m.onReset = (_, seq) => resets.push(seq);
for (const seq of [4, 3, 4, 5])
m.receive(guest, { type: 'input', race, commands: [command(seq)] });
m.receive(guest, { type: 'input', race, commands: [command(9), command(8)] });
m.receive(guest, {
type: 'input',
race,
commands: [{ ...command(10), input: { ...command(10).input, steer: NaN } }],
});
for (const seq of [3, 3, 2, 4]) m.receive(guest, { type: 'reset', race, seq });
assert.deepEqual(inputs, [4, 5]);
assert.deepEqual(resets, [3, 4]);
});
test('backpressure keeps only newest state and preserves the in-flight snapshot', async () => {
let complete;
const f = fixture(() => new Promise((r) => (complete = r)));
const packet = (tick) => ({ type: 'world', race, world: { ...f.world, tick } });
const sending = f.m.sendLatest(packet(1));
await f.m.sendLatest(packet(2));
await f.m.sendLatest(packet(3));
assert.equal(f.binary.length, 1);
assert.equal(f.m.queued.world.tick, 3);
complete();
await new Promise((r) => setTimeout(r, 0));
assert.equal(f.binary.length, 2);
complete();
await sending;
assert.equal(f.m.queued, null);
});
test('unsupported is an explicit safe JSON fallback, timeout never retries the same payload', async () => {
const packet = { type: 'world', race, world: fixture().world };
const unsupported = fixture(async () => {
throw new Error('unsupported');
});
await unsupported.m.sendLatest(packet);
assert.equal(unsupported.json.length, 1);
assert.equal(unsupported.binary.length, 1);
const timeout = fixture(async () => {
throw new Error('Request timed out');
});
await timeout.m.sendLatest(packet);
assert.equal(timeout.json.length, 0);
assert.equal(timeout.errors.length, 1);
await timeout.m.sendLatest({ ...packet, world: { ...packet.world, tick: 2 } });
assert.equal(timeout.json.length, 1);
assert.equal(timeout.binary.length, 1);
const full = fixture(async () => {
throw new Error('QUEUE_FULL');
});
await full.m.sendLatest(packet);
assert.equal(full.json.length, 0);
assert.ok(full.m.queued);
clearTimeout(full.m.retrySend);
});
test('missing peer capabilities use reliable JSON without probing with bytes', async () => {
const f = fixture();
f.m.statePeers.clear();
f.m.binaryPeers.clear();
await f.m.sendLatest({ type: 'input', race, commands: [command(1)] });
assert.equal(f.binary.length, 0);
assert.equal(f.json[0].id, 'control');
});
