From feaa7cc830357c8dafa3054ea7e53e9b15f84bb8 Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Mon, 22 Dec 2025 21:39:07 +0100 Subject: [PATCH] UI: allow saving PEL program concepts --- src/amduatd.c | 55 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/amduatd.c b/src/amduatd.c index be61cd5..86639bb 100644 --- a/src/amduatd.c +++ b/src/amduatd.c @@ -224,14 +224,18 @@ static const char k_amduatd_ui_html[] = " \n" "
\n" " \n" - " \n" + " \n" " \n" "
\n" - " \n" + " \n" + "
\n" + " \n" + "
\n" "
\n" " \n" " \n" @@ -289,12 +293,22 @@ static const char k_amduatd_ui_html[] = " el('latestRef').value = j.latest_ref || '';\n" " el('programRef').value = name;\n" " if(!j.latest_ref){ el('editor').value=''; out(text); return; }\n" + " const mode = el('mode').value;\n" " const infoResp = await fetch(`/v1/artifacts/${j.latest_ref}?format=info`);\n" " if(infoResp.ok){ const info = JSON.parse(await infoResp.text()); el('typeTag').value = info.has_type_tag ? info.type_tag : ''; }\n" + " if(mode === 'pel_program'){\n" + " if(!el('editor').value.trim()){\n" + " el('editor').value = JSON.stringify({\n" + " nodes:[{id:1,op:{name:'pel.bytes.concat',version:1},inputs:[{external:{input_index:0}}],params_hex:''}],\n" + " roots:[{node_id:1,output_index:0}]\n" + " }, null, 2);\n" + " }\n" + " out(text);\n" + " return;\n" + " }\n" " const aResp = await fetch(`/v1/artifacts/${j.latest_ref}`);\n" " if(!aResp.ok){ out(await aResp.text()); return; }\n" " const u8 = new Uint8Array(await aResp.arrayBuffer());\n" - " const mode = el('mode').value;\n" " if(mode==='hex') el('editor').value = toHex(u8);\n" " else if(mode==='base64') el('editor').value = toB64(u8);\n" " else el('editor').value = td.decode(u8);\n" @@ -306,6 +320,19 @@ static const char k_amduatd_ui_html[] = " if(!name){ out('missing concept name'); return; }\n" " await ensureConcept(name);\n" " const mode = el('mode').value;\n" + " if(mode === 'pel_program'){\n" + " const body = JSON.parse(el('editor').value || '{}');\n" + " const mkResp = await fetch('/v1/pel/programs',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});\n" + " const mkText = await mkResp.text();\n" + " if(!mkResp.ok){ out(mkText); return; }\n" + " const mk = JSON.parse(mkText);\n" + " const pref = mk.program_ref;\n" + " const pubResp = await fetch(`/v1/concepts/${encodeURIComponent(name)}/publish`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ref:pref})});\n" + " const pubText = await pubResp.text();\n" + " out(pubText);\n" + " if(pubResp.ok){ el('typeTag').value = '0x00000101'; await loadConcept(); }\n" + " return;\n" + " }\n" " let u8;\n" " if(mode==='hex') u8 = fromHex(el('editor').value);\n" " else if(mode==='base64') u8 = fromB64(el('editor').value);\n" @@ -326,7 +353,21 @@ static const char k_amduatd_ui_html[] = " el('btnConceptCreate').addEventListener('click', async () => { try{ await ensureConcept(el('conceptName').value.trim()); out('{\"ok\":true}\\n'); }catch(e){ out(String(e)); } });\n" " el('btnLoad').addEventListener('click', () => loadConcept().catch(e => out(String(e))));\n" " el('btnSave').addEventListener('click', () => saveConcept().catch(e => out(String(e))));\n" - " el('mode').addEventListener('change', () => loadConcept().catch(() => {}));\n" + " el('mode').addEventListener('change', () => {\n" + " if(el('mode').value === 'pel_program'){\n" + " el('typeTag').value = '0x00000101';\n" + " }\n" + " loadConcept().catch(() => {});\n" + " });\n" + "\n" + " el('btnProgramTemplate').addEventListener('click', () => {\n" + " el('mode').value = 'pel_program';\n" + " el('typeTag').value = '0x00000101';\n" + " el('editor').value = JSON.stringify({\n" + " nodes:[{id:1,op:{name:'pel.bytes.concat',version:1},inputs:[{external:{input_index:0}}],params_hex:''}],\n" + " roots:[{node_id:1,output_index:0}]\n" + " }, null, 2);\n" + " });\n" "\n" " el('btnPublishRef').addEventListener('click', async () => {\n" " try{\n"