20 lines
6.3 KiB
JavaScript
20 lines
6.3 KiB
JavaScript
#!/usr/bin/env node
|
|
import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import {createRequire} from "node:module"; import {pathToFileURL} from "node:url"; import {execFileSync} from "node:child_process";
|
|
const root="/home/mes123456/FreeCADWasmDev/working/FreeCAD", build=path.resolve(process.argv[2]??path.join(root,"freecad-source/build-web/techdraw-native-configure/bin"));
|
|
const batch=JSON.parse(fs.readFileSync(path.join(root,"docs/current/module-batch-manifest.json"),"utf8"));
|
|
if(batch.status!=="ready"||batch.selected?.module!=="TechDraw"||batch.selected?.tier!=="tier-3-stateful"||batch.selected?.family!=="lifecycle-command"||batch.records.length!==batch.selected.recordCount) throw new Error("unexpected TechDraw lifecycle batch manifest");
|
|
const family=batch.selected.family;
|
|
const records=batch.records.map(([apiId,name,disposition,sourcePath,sourceLine])=>({apiId,name,family,kind:apiId.includes(":class:")?"class":apiId.includes(":function:")?"function":"method",sourcePath,sourceLine,disposition}));
|
|
const out="/tmp/freecad-techdraw-generic-object-gate"; fs.mkdirSync(out,{recursive:true}); execFileSync(path.join(root,"web/node_modules/.bin/tsc"),["--target","ES2022","--module","ESNext","--moduleResolution","Bundler","--strict","--skipLibCheck","--outDir",out,"--declaration","false","--noEmit","false",path.join(root,"web/src/facade-envelope.ts"),path.join(root,"web/src/techdraw-python-family-facade.ts")],{cwd:root,stdio:"inherit"});
|
|
const facade=await import(pathToFileURL(path.join(out,"techdraw-python-family-facade.js"))), env=await import(pathToFileURL(path.join(out,"facade-envelope.js"))); globalThis.__dirname=build; globalThis.require=createRequire(import.meta.url);
|
|
const workerJs=path.join(build,"FreeCADWebTechDrawRuntimeProbe.worker.js"), workerCjs=path.join(build,"FreeCADWebTechDrawRuntimeProbe.worker.cjs"); if(!fs.existsSync(workerCjs)&&fs.existsSync(workerJs)) fs.copyFileSync(workerJs,workerCjs);
|
|
const mod=await import(pathToFileURL(path.join(build,"FreeCADWebTechDrawRuntimeProbe.js"))); const kernel=await mod.default({wasmBinary:fs.readFileSync(path.join(build,"FreeCADWebTechDrawRuntimeProbe.wasm")),locateFile:f=>f.endsWith(".worker.js")&&fs.existsSync(workerCjs)?workerCjs:path.join(build,f),print:()=>{},printErr:()=>{}});
|
|
const q=new env.FacadeSerialQueue(), request=id=>facade.createTechDrawPythonFamilyRequest(id,records,"tier-3-stateful"); const first=await facade.dispatchTechDrawPythonFamily(q,request("techdraw-lifecycle-command"),kernel), repeat=await facade.dispatchTechDrawPythonFamily(q,request("techdraw-lifecycle-command-repeat"),kernel);
|
|
if(first.kind!=="result"||repeat.kind!=="result") throw new Error(`native dispatch failed: ${JSON.stringify({first,repeat})}`); const result=first.result;
|
|
const invalidRecord=result.records.findIndex((r,i)=>!["exposed","not_implemented","restricted","nonportable"].includes(r.status)||r.native!==true||r.resourcesReleased!==true||r.sourceEntry!==records[i].sourcePath||typeof r.sourceRevision!=="string");
|
|
const replayRecord=result.records.findIndex((r,i)=>JSON.stringify(r)!==JSON.stringify(repeat.result.records?.[i]));
|
|
if(result.count!==records.length||result.resourcesReleased!==true||JSON.stringify(result)!==JSON.stringify(repeat.result)||result.records?.length!==records.length||invalidRecord!==-1) throw new Error(`invalid TechDraw lifecycle-command native result: ${JSON.stringify({count:result.count,resourcesReleased:result.resourcesReleased,replayEqual:JSON.stringify(result)===JSON.stringify(repeat.result),recordsLength:result.records?.length,invalidRecord,record:invalidRecord===-1?null:result.records[invalidRecord],expected:invalidRecord===-1?null:records[invalidRecord],replayRecord,first:replayRecord===-1?null:result.records[replayRecord],repeat:replayRecord===-1?null:repeat.result.records?.[replayRecord]})}`);
|
|
const hash=v=>crypto.createHash("sha256").update(JSON.stringify(v)).digest("hex"), fileHash=f=>crypto.createHash("sha256").update(fs.readFileSync(f)).digest("hex"), counts=Object.fromEntries(["exposed","restricted","nonportable","not_implemented"].map(s=>[s,result.records.filter(r=>r.status===s).length]));
|
|
const evidence=`docs/p6/techdraw-lifecycle-command-module-batch-${batch.batchId}-runtime.json`; const report={schema:"freecad-web-techdraw-lifecycle-command-module-batch-runtime/v1",taskId:"FW-P6-FPA-Y",batchId:batch.batchId,module:"TechDraw",tier:"tier-3-stateful",family, status:(counts.restricted||counts.nonportable||counts.not_implemented)?"pass_with_boundaries":"pass",route:{command:"techdraw.pythonFamilyBatch",native:"freecad-source/src/WebAssembly/FreeCADCoreProbe/TechDrawRuntimeProbe.cpp:fc_web_dispatch_json",facade:"web/src/techdraw-python-family-facade.ts",worker:"web/src/techdraw-python.worker.ts"},input:{cmd:"techdraw.pythonFamilyBatch",args:{tier:"tier-3-stateful",records}},result,resultSha256:hash(result),replay:{equal:true,resultSha256:hash(repeat.result)},dispositionCounts:counts,records:result.records.map((r,i)=>({...r,sourceLine:records[i].sourceLine,sourceVerified:r.sourceEntry===records[i].sourcePath,evidenceSha256:hash(r)})),resources:{resourcesReleased:true,documentMutation:"none-headless-gui-boundary"},artifacts:{module:"TechDraw",worker:"techdraw-python.worker.ts",revision:result.records[0]?.sourceRevision,runtimeUrl:"/modules/TechDraw/FreeCADWebTechDrawRuntimeProbe.js",wasmUrl:"/modules/TechDraw/FreeCADWebTechDrawRuntimeProbe.wasm",dataUrl:null,assetBaseUrl:"/modules/TechDraw/",runtimeSha256:fileHash(path.join(build,"FreeCADWebTechDrawRuntimeProbe.js")),wasmSha256:fileHash(path.join(build,"FreeCADWebTechDrawRuntimeProbe.wasm")),buildProfile:"fast-dev"},boundaries:["These GuiCommand classes require FreeCADGui selection, dialogs, or active-view resources unavailable in the headless Web runtime; the compiled native dispatcher reports that boundary per record.","JavaScript transports and validates native dispatcher results only; it does not emulate command outcomes."]};
|
|
fs.writeFileSync(path.join(root,evidence),JSON.stringify(report,null,2)+"\n"); fs.writeFileSync(path.join(root,`docs/freecad-p6-techdraw-lifecycle-command-module-batch-${batch.batchId}.log`),JSON.stringify({status:report.status,count:records.length,dispositionCounts:counts,resultSha256:report.resultSha256})+"\n"); console.log(JSON.stringify({status:report.status,count:records.length,dispositionCounts:counts,resultSha256:report.resultSha256,evidence})); process.exit(0);
|