SOURCE / PINNED RELEASE
Made of little things.
Napcraft
- Release
- ee47ac6a25df…
- Author-recorded commit
- 410dea87e109…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-52f9e22f5ce
Archive hash verified: 9e6e0cabb18d0d46…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import test from 'node:test';
import assert from 'node:assert/strict';
import {readFileSync} from 'node:fs';
import path from 'node:path';
import {runInNewContext} from 'node:vm';
import ts from 'typescript';
const cache = new Map();
function load(file) {
file = path.resolve(file);
if (cache.has(file)) return cache.get(file);
const exports = {}; cache.set(file,exports);
const source = ts.transpileModule(readFileSync(file,'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022}}).outputText;
runInNewContext(source,{exports,structuredClone,setTimeout,clearTimeout,Date,crypto,require:name=>load(path.resolve(path.dirname(file),name+'.ts'))});
return exports;
}
const {SharedEditor} = load('src/shared-editor.ts');
const {BackendCallError} = load('docs/examples/backend-client.ts');
const {practiceWorld} = load('src/world.ts');
const target={module:{napplet:'test',name:'worlds'},release:'a'.repeat(64),instance:'island'};
const edit={x:9,y:3,z:10,expected:0,block:4};
const wait=ms=>new Promise(r=>setTimeout(r,ms));
async function until(f) { for(let i=0;i<200;i++) {if(f())return;await wait(2);}throw Error('condition timeout'); }
function deferred(){let resolve,reject;const promise=new Promise((a,b)=>{resolve=a;reject=b;});return {promise,resolve,reject};}
function fixture({journal,world=practiceWorld(),revision=0,gate,lose=false,reject=false,compact=false}={}) {
let state=structuredClone(world),rev=revision,view,edits=0,lost=false;
const receipts=new Map(),history=[],saved=[],notices=[];
const api={
intent:(target,operation,input)=>({target,operation,input,requestId:crypto.randomUUID(),expiresAt:Math.floor(Date.now()/1000)+240}),
async invoke(intent) {
history.push(structuredClone(intent));
if(intent.operation==='readWorld')return {result:structuredClone(state),revision:rev};
if(intent.operation==='readUpdates') return {result:{from:intent.input.after,edits:state.edits,locked:state.locked,reset:false,changes:[]},revision:rev};
if(gate)await gate.promise;
if(reject)throw new BackendCallError('CONFLICT',true,'CONFLICT');
if(receipts.has(intent.requestId))return structuredClone(receipts.get(intent.requestId));
const batch=intent.operation==='editBlocks'?intent.input.edits:[intent.input];
const changes=[];
for(const e of batch){state.blocks[e.x+e.z*18+e.y*324]=e.block;state.edits++;edits++;changes.push({...e,n:state.edits});}
const r={revision:++rev,result:intent.operation==='editBlocks'?{from:intent.input.after,edits:state.edits,locked:state.locked,reset:false,changes}:structuredClone(state)};
receipts.set(intent.requestId,structuredClone(r));
if(lose&&!lost){lost=true;throw new BackendCallError('lost reply',false);}
return r;
},
async call(){if(gate)await gate.promise;return {revision:rev};},
};
const editor=new SharedEditor(target,world,revision,compact,api,{change:v=>view=v,persist:async j=>saved.push(structuredClone(j)),saved:()=>{},notice:n=>notices.push(n)},journal ? {actor:"a".repeat(64),...journal} : undefined,"a".repeat(64));
editor.start();
return {editor,api,history,saved,notices,view:()=>view,edits:()=>edits,state:()=>state,receipts};
}
test('immediate feedback, bounded queue and no dropped input during a background read',async()=>{
const gate=deferred(),f=fixture({gate});
try{
f.editor.sync(); // query in progress must not disable editing
for(let i=0;i<24;i++)assert.equal(f.editor.enqueue({...edit,expected:i%2?4:0,block:i%2?0:4}),true);
assert.equal(f.view().pending,24); assert.equal(f.view().world.edits,24);
assert.equal(f.view().confirmedEdits,0);
assert.equal(f.editor.enqueue(edit),false);
gate.resolve(); await until(()=>f.view().pending===0);
assert.equal(f.edits(),24);
}finally{f.editor.dispose();}
});
test('atomic batches drain a rapid queue without one network round trip per input',async()=>{
const gate=deferred(),f=fixture({gate,compact:true});
try{
for(let i=0;i<12;i++)f.editor.enqueue({...edit,expected:i%2?4:0,block:i%2?0:4});
gate.resolve(); await until(()=>f.view().pending===0);
assert.equal(f.edits(),12);
assert.equal(f.history.filter(x=>x.operation==='editBlocks').length,3); // 1 in flight, then 8, then 3
}finally{f.editor.dispose();}
});
test('lost commit response retries exact ID, expiry and payload and never duplicates a block',async()=>{
const f=fixture({lose:true});
try{
f.editor.enqueue(edit); await until(()=>f.editor.uncertain);
assert.equal(f.view().pending,1); assert.equal(f.edits(),1);
const journal=f.saved.filter(Boolean).at(-1);
assert.deepEqual(journal.active.intent,f.history[0]);
f.editor.retry(); await until(()=>f.view().pending===0);
assert.equal(f.edits(),1); assert.deepEqual(f.history[0],f.history[1]);
assert.equal(f.view().world.edits,1); assert.equal(f.view().confirmedEdits,1);
}finally{f.editor.dispose();}
});
test('definitive conflict cancels dependent predictions and refreshes before new input',async()=>{
const gate=deferred(),f=fixture({gate,reject:true});
try{
f.editor.enqueue(edit); f.editor.enqueue({...edit,y:4});
f.state().blocks[9+10*18+3*324]=6;
gate.resolve(); await until(()=>f.view().pending===0&&!f.editor.hasWork);
assert.equal(f.view().world.edits,0);
assert.equal(f.history.filter(x=>x.operation==='editBlock').length,1);
assert.ok(f.history.some(x=>x.operation==='readWorld'));
}finally{f.editor.dispose();}
});
test('expired uncertain intent refreshes without manufacturing a new command',async()=>{
const intent={target,operation:'editBlock',input:edit,requestId:'expired',expiresAt:1};
const f=fixture({journal:{target,queue:[edit],active:{intent,count:1}}});
try{
await until(()=>!f.editor.hasWork);
assert.equal(f.history.filter(x=>x.operation==='editBlock').length,0);
assert.equal(f.view().world.edits,0);
assert.ok(f.notices.some(x=>x.includes('expired')));
}finally{f.editor.dispose();}
});
test('recovered cached receipt cannot roll back a newer snapshot after reload',async()=>{
const intent={target,operation:'editBlock',input:edit,requestId:'committed',expiresAt:Math.floor(Date.now()/1000)+240};
const world=practiceWorld(); world.edits=3;world.blocks[9+10*18+3*324]=6;
const f=fixture({world,revision:3,journal:{target,queue:[edit],active:{intent,count:1}}});
f.receipts.set('committed',{revision:1,result:{...world,edits:1}});
try{await until(()=>!f.editor.hasWork);assert.equal(f.view().world.edits,3);assert.equal(f.view().revision,3);assert.equal(f.edits(),0);}finally{f.editor.dispose();}
});
test('closing session ignores late completions; forged refresh floods are bounded',async()=>{
const gate=deferred(),f=fixture({gate});
f.editor.enqueue(edit);await until(()=>f.history.length===1);
const view=f.view(),writes=f.saved.length;
f.editor.dispose();gate.resolve();await wait(10);
assert.equal(f.view(),view);assert.equal(f.saved.length,writes);
const other=fixture();try{
for(let i=0;i<100;i++)other.editor.sync(true);
await wait(10);
assert.equal(other.history.filter(i=>i.operation==='readWorld').length,1);
assert.equal(other.view().world.edits,0);
}finally{other.editor.dispose();}
});
test('instance contention refreshes and revalidates an independent edit before a new intent',async()=>{
const f=fixture(),invoke=f.api.invoke;
let rejected;
f.api.invoke=async intent=>{
if(intent.operation==='editBlock'&&!rejected){rejected=structuredClone(intent);throw new BackendCallError('instance busy',true,'CONFLICT');}
return invoke(intent);
};
try{
f.editor.enqueue(edit);await until(()=>!f.editor.hasWork);
assert.equal(f.edits(),1);
const retry=f.history.find(i=>i.operation==='editBlock');
assert.notEqual(retry.requestId,rejected.requestId);
assert.ok(f.history.findIndex(i=>i.operation==='readWorld')<f.history.indexOf(retry));
}finally{f.editor.dispose();}
});
test('coalesced peer hints retain the final refresh of a fast save burst',async()=>{
const f=fixture();
try {
f.editor.sync(true); await wait(10);
f.state().edits=1;f.state().blocks[9+10*18+3*324]=4;
for(let i=0;i<100;i++)f.editor.sync(true);
await wait(550);
assert.equal(f.history.filter(i=>i.operation==='readWorld').length,2);
assert.equal(f.view().world.edits,1);
}finally{f.editor.dispose();}
});
test('a recovered receipt from another transport cannot replay an ABA edit',async()=>{
const intent={target,operation:'editBlock',input:edit,requestId:'old-guest',expiresAt:Math.floor(Date.now()/1000)+240};
const f=fixture({journal:{actor:'b'.repeat(64),target,queue:[edit],active:{intent,count:1}}});
try{await until(()=>!f.editor.hasWork);assert.equal(f.edits(),0,'another actor cannot replay even when the cell became empty again');}finally{f.editor.dispose();}
});
