| 12345678910111213141516171819202122232425262728293031 |
- // Isolated PostgreSQL fixture. No production credentials or network are used.
- import fs from 'node:fs';
- import vm from 'node:vm';
- import {execFileSync} from 'node:child_process';
- import {PGlite} from '@electric-sql/pglite';
- export async function localRuntime({scale=0,legacyDelayMs=0}={}){
- const db=new PGlite();
- const today=new Intl.DateTimeFormat('en-CA',{timeZone:'Asia/Shanghai'}).format(new Date());
- const schema=fs.readFileSync('scripts/tests/fixtures/teacher-review-schema.sql','utf8').replaceAll('2026-10-14',today);
- await db.exec(schema);
- if(scale)await db.exec(`INSERT INTO "MemoryPracticeRecord" SELECT 'scale'||i,'co',i,30,20,100,1,'0','2026-10-20','2026-10-20' FROM generate_series(2000,${1999+Number(scale)}) i;
- INSERT INTO "CommonModel" (company,"modelId","generalId","itemId") SELECT company,60,id+100000,id FROM "MemoryPracticeRecord" WHERE id>=2000;`);
- await db.exec(`CREATE INDEX ON "MemoryPracticeRecord"(company,yhid,xxjlid,kywsj,id);CREATE INDEX ON "CommonModel"(company,"modelId","itemId");CREATE INDEX ON "CommonModel"(company,"modelId","generalId");CREATE INDEX ON "DailyStudyRecord"(company,id);CREATE INDEX ON "ReviewRewardIncome"(company,"taskId");ANALYZE;`);
- const sources={before:execFileSync('git',['show','81f8b44:scripts/cloud/mobile-teaching.js'],{encoding:'utf8'}),after:fs.readFileSync('scripts/cloud/mobile-teaching.js','utf8')};
- const results=[];
- async function review(variant,input,coach=false){
- const metrics={variant,coach,legacyCalls:0,queries:[],versionCalls:0},start=performance.now();
- const query=async(sql,args)=>{if(!sql.startsWith('SELECT '))throw Error('Unexpected write in local benchmark');const at=performance.now();const result=await db.query(sql,args);metrics.queries.push({ms:performance.now()-at,sql,args});return result.rows;};
- const context=vm.createContext({Date,Promise,DEFAULT_COMPANY_ID:'co',number:(v,f=0)=>Number.isFinite(Number(v))?Number(v):f,
- authorizeRequestedUser:async()=>coach?30:20,appReviewTarget:async()=>20,appOverviewToday:()=>today,legacyAliases:r=>r,
- syncLegacyReviews:async()=>{metrics.legacyCalls++;if(legacyDelayMs)await new Promise(r=>setTimeout(r,legacyDelayMs));return {state:'unavailable'};},
- appLiveSyncStatus:async()=>({state:'delayed',lastSuccessAt:'',lagSeconds:null,pending:0}),
- appLiveVersionSnapshot:async()=>{metrics.versionCalls++;return {version:'v1',scopeVersions:{review:'v1'},syncStatus:{state:'delayed'},refreshedAt:new Date().toISOString()};},
- Psql:{query,one:async(s,a)=>(await query(s,a))[0]}});
- vm.runInContext(sources[variant],context);
- const value=JSON.parse(JSON.stringify(await context.appReviewPage(input,{get:()=>coach?3:1})));
- metrics.ms=performance.now()-start;metrics.bytes=Buffer.byteLength(JSON.stringify(value));results.push(metrics);
- return {value,metrics};
- }
- return {db,today,review,results,close:()=>db.close()};
- }
|