@lunora/testing 1.0.0-alpha.137 → 1.0.0-alpha.139
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{agentHarness as o,finalTurn as t,toolCallTurn as a}from"./packem_shared/agentHarness-DA9onGVO.mjs";import{evaluationAttributes as l,recordEvaluation as n}from"./packem_shared/evaluationAttributes-CYLgTP1P.mjs";import{lunoraTest as s}from"./packem_shared/lunoraTest-
|
|
1
|
+
import{agentHarness as o,finalTurn as t,toolCallTurn as a}from"./packem_shared/agentHarness-DA9onGVO.mjs";import{evaluationAttributes as l,recordEvaluation as n}from"./packem_shared/evaluationAttributes-CYLgTP1P.mjs";import{lunoraTest as s}from"./packem_shared/lunoraTest-BOqU8mY2.mjs";import{groundednessScorer as p,mrrScorer as u,ndcgAtK as x,precisionAtK as S,recallAtK as f}from"./packem_shared/groundednessScorer-CznJBIjn.mjs";import{containsScorer as g,evaluate as A,exactMatchScorer as v,keywordScorer as K,llmScorer as M,regexScorer as T,scoreSample as k}from"./packem_shared/containsScorer-gv0Sdd86.mjs";import{extractLink as C,listCapturedMail as b,waitForMail as h}from"@lunora/mail/testing";export{o as agentHarness,g as containsScorer,A as evaluate,l as evaluationAttributes,v as exactMatchScorer,C as extractLink,t as finalTurn,p as groundednessScorer,K as keywordScorer,b as listCapturedMail,M as llmScorer,s as lunoraTest,u as mrrScorer,x as ndcgAtK,S as precisionAtK,f as recallAtK,n as recordEvaluation,T as regexScorer,k as scoreSample,a as toolCallTurn,h as waitForMail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as _}from"@lunora/errors";import{runShardMigrations as O,createShardCtxDb as z,RLS_UNWRAP_SYMBOL as Z}from"@lunora/shard-engine";import{evaluationAttributes as tt}from"./evaluationAttributes-CYLgTP1P.mjs";import{MAX_RETRY_ATTEMPTS as et,RETRY_BASE_DELAY_MS as nt}from"@lunora/scheduler";import{DatabaseSync as ot}from"node:sqlite";const rt=(r,c,s,u,g)=>{let p=g,y=1;const d=new Map,f=[],h=(e,l,a={})=>{const t=`fake-job-${String(y)}`;return y+=1,d.set(t,{args:a,enqueuedAt:p,functionPath:l,id:t,scheduledFor:e}),t},b=e=>typeof e=="string"?e:e.name??e.binding??"",P={cancel:e=>{const l=d.has(e);return d.delete(e),Promise.resolve({cancelled:l})},get:e=>Promise.resolve(d.get(e)??null),list:()=>Promise.resolve([...d.values()]),runAfter:(e,l,a)=>{const t=h(p+e,b(l),a);return Promise.resolve(t)},runAt:(e,l,a)=>{const t=h(e,b(l),a);return Promise.resolve(t)}},k=async e=>{d.delete(e.id);const l=u(),a=e.functionPath===void 0?void 0:l.get(e.functionPath);if(a===void 0){console.warn(`[fake-scheduler] unknown functionPath "${e.functionPath??"(workflow-targeted)"}" — job ${e.id} dropped`);return}if(a.kind==="mutation"||a.kind==="action"){const t=r(),n=a.kind==="action"?s():c();await t(a.kind,a,n,e.args)}else console.warn(`[fake-scheduler] functionPath "${e.functionPath??"(workflow-targeted)"}" is a ${a.kind} — only mutations and actions can be scheduled; job ${e.id} dropped`)},M=async e=>{const l=[...d.values()].filter(n=>n.scheduledFor<=e).toSorted((n,v)=>n.scheduledFor-v.scheduledFor),a=[];let t=0;for(const n of l)if(d.has(n.id)){t+=1;try{await k(n)}catch(v){const T=(n.attempts??0)+1;if(T>et){const N={args:n.args,error:v,functionPath:n.functionPath??"",id:n.id};a.push(N),f.push(N)}else{const N=nt*2**(T-1);d.set(n.id,{...n,attempts:T,scheduledFor:p+N})}}}return{executed:t,failed:a}},C=async(e,l)=>{const{executed:a,failed:t}=await M(e);if(t.length>0&&(l?.throwOnError??!0)){const[n]=t;throw t.length===1&&n!==void 0?n.error:new AggregateError(t.map(v=>v.error),`${String(t.length)} scheduled jobs failed: ${t.map(v=>v.functionPath).join(", ")}`)}return a};return{controls:{advance:(e,l)=>(p+=e,C(p,l)),failures:()=>[...f],list:()=>[...d.values()],runPending:e=>C(Number.POSITIVE_INFINITY,e)},scheduler:P}},st=()=>{const r=new ot(":memory:"),c=u=>({one(){if(u.length!==1)throw new _("INTERNAL",`expected exactly one row, received ${String(u.length)}`);const[g]=u;return g},[Symbol.iterator](){return u[Symbol.iterator]()},toArray(){return u}});return{close:()=>{r.close()},sql:{exec:(u,...g)=>{const y=r.prepare(u).all(...g);return c(y)}}}},q=r=>{if(typeof r!="object"||r===null)return;const{kind:c}=r;if(c==="query"||c==="mutation"||c==="action")return c},it=r=>typeof r=="object"&&r!==null&&r.visibility==="internal"?"internal":"public",Q=r=>{throw new _("INTERNAL",`ctx.${r} is not available in the in-memory @lunora/testing harness (v1)`)},w=r=>new Proxy((...c)=>Q(r),{apply:()=>Q(r),get:()=>Q(r)}),K={spanId:"0000000000000001",traceId:"00000000000000000000000000000001"},ct={addEvent:()=>{},addLink:()=>{},recordEvaluation:()=>{},recordException:()=>{},setAttribute:()=>{},setAttributes:()=>{},spanContext:()=>K},at=()=>{const r={attributes:{},events:[],links:[]},c={addEvent:(s,u)=>{r.events.push({...u===void 0?{}:{attributes:{...u}},name:s})},addLink:s=>{r.links.push({spanId:s.spanId,traceId:s.traceId})},recordEvaluation:s=>{Object.assign(r.attributes,tt(s))},recordException:s=>{const u={"exception.message":s instanceof Error?s.message:String(s),"exception.type":s instanceof Error?s.constructor.name:"Error"};s instanceof Error&&s.stack!==void 0&&(u["exception.stacktrace"]=s.stack),c.addEvent("exception",u)},setAttribute:(s,u)=>{r.attributes[s]=u},setAttributes:s=>{Object.assign(r.attributes,s)},spanContext:()=>K};return{handle:c,recorded:r}},D=async(r,c)=>await c(D,ct),Y={count:()=>{},gauge:()=>{},record:()=>{}},j={debug:()=>{},error:()=>{},event:()=>{},fatal:()=>{},info:()=>{},log:()=>{},trace:()=>{},warn:()=>{},with:()=>j},ut=(r,c,s)=>(g,p)=>{let y=!1;const d=[];let f,h,b=0,P=0;const k=()=>q(g)?r("query",g,c,p,!1):Promise.resolve(g(c)),M=(t,n)=>{if(t<P)return;P=t;const v={done:!1,value:n};if(d.length===0)f=v,h=void 0;else{f=void 0,h=void 0;for(const T of d.splice(0))T.resolve(v)}},C=(t,n)=>{if(!(t<P))if(P=t,d.length===0)h={error:n},f=void 0;else{f=void 0,h=void 0;for(const v of d.splice(0))v.reject(n)}},R=t=>n=>{M(t,n)},e=t=>n=>{C(t,n)},l=()=>{if(y)return;b+=1;const t=b;k().then(R(t)).catch(e(t))};s.add(l);const a={[Symbol.asyncIterator](){return a},next:()=>{if(y)return Promise.resolve({done:!0,value:void 0});if(P===b){if(h!==void 0){const{error:t}=h;return h=void 0,Promise.reject(t)}if(f!==void 0){const t=f;return f=void 0,Promise.resolve(t)}}return P<b?new Promise((t,n)=>{d.push({reject:n,resolve:t})}):k().then(t=>{if(h!==void 0){const{error:n}=h;throw h=void 0,n}if(f!==void 0){const n=f;return f=void 0,n}return{done:!1,value:t}})},return:()=>{y=!0,s.delete(l);for(const t of d.splice(0))t.resolve({done:!0,value:void 0});return Promise.resolve({done:!0,value:void 0})}};return k().then(R(0)).catch(e(0)),a},pt=(r,c)=>{const{close:s,sql:u}=st(),g=r;O(u,g);const p=z({enforceRls:c?.enforceRls??!0,schema:g,sql:u}),y=p[Z]??p,d=m=>{u.exec.call(u,m)};let f=Promise.resolve();const h=m=>{const E=async()=>{d("BEGIN");try{const S=await m();return d("COMMIT"),S}catch(S){try{d("ROLLBACK")}catch{}throw S}},x=f.then(E);return f=x.then(()=>{},()=>{}),x};let b=!1;const P=()=>{b||(b=!0,s())},k=new Map(Object.entries(c?.functions??{}).map(([m,E])=>[m,E])),M=new Set,C=()=>{for(const m of M)m()},R=m=>(C(),m);let e,l,a;const t=c?.now??Date.now(),n=at(),v=(m,E)=>{if(m===void 0)throw new _("INTERNAL",`[fake-scheduler] ${E} not yet available — scheduler.advance called before harness construction completed`);return m},{controls:T,scheduler:N}=rt(()=>v(e,"dispatch"),()=>v(l,"mutationContext"),()=>v(a,"actionContext"),()=>k,t),B=m=>{const E={getIdentity:()=>Promise.resolve(m??null),userId:m?.userId??null},x={auth:E,db:p,env:c?.env,log:j,metrics:Y,now:t,span:n.handle,trace:D,runQuery:((o,i)=>I("query",o,x,i)),secrets:w("secrets"),storage:w("storage"),vectors:w("vectors")},S={auth:E,db:p,env:c?.env,log:j,metrics:Y,now:t,span:n.handle,trace:D,runMutation:((o,i)=>I("mutation",o,S,i)),runQuery:((o,i)=>I("query",o,x,i)),scheduler:N,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};l??=S;const U={...S,db:y},F={auth:E,db:p,env:c?.env,fetch:c?.fetch??w("fetch"),log:j,metrics:Y,now:t,span:n.handle,trace:D,runAction:((o,i)=>I("action",o,F,i)),runMutation:((o,i)=>I("mutation",o,S,i)),runQuery:((o,i)=>I("query",o,x,i)),scheduler:N,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};a??=F;const $=(o,i,A,L,J)=>{const H=q(i);if(H!==o)throw new _("INTERNAL",`expected a registered ${o}, received a ${H??"non-function"} reference`);if(!J&&it(i)==="internal")throw new _("INTERNAL",`This ${o} is an internal function — it is unreachable from the external RPC boundary in production. Call it through ctx.run${o.charAt(0).toUpperCase()}${o.slice(1)} from another function instead.`);return Promise.resolve(i.handler(A,L??{}))},I=(o,i,A,L)=>$(o,i,A,L,!0);e??=(o,i,A,L)=>o==="mutation"?h(()=>$("mutation",i,A,L,!0)).then(R):I("action",i,A,L);const V=((o,i)=>q(o)?$("query",o,x,i,!1):Promise.resolve(o(x))),W=((o,i)=>{const A=q(o)?()=>$("mutation",o,S,i,!1):()=>o(S);return h(A).then(R)}),X=((o,i)=>q(o)?$("action",o,F,i,!1):Promise.resolve(o(F))),G=ut($,x,M);return{action:X,close:P,mutation:W,query:V,run:o=>h(()=>o(U)).then(R),scheduler:T,subscribe:G,wideEvent:()=>n.recorded,withIdentity:o=>B(o)}};return B(null)};export{pt as lunoraTest};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/testing",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.139",
|
|
4
4
|
"description": "Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@lunora/agent": "1.0.0-alpha.
|
|
54
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
55
|
-
"@lunora/mail": "1.0.0-alpha.
|
|
56
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
57
|
-
"@lunora/server": "1.0.0-alpha.
|
|
58
|
-
"@lunora/shard-engine": "1.0.0-alpha.
|
|
53
|
+
"@lunora/agent": "1.0.0-alpha.80",
|
|
54
|
+
"@lunora/errors": "1.0.0-alpha.28",
|
|
55
|
+
"@lunora/mail": "1.0.0-alpha.58",
|
|
56
|
+
"@lunora/scheduler": "1.0.0-alpha.48",
|
|
57
|
+
"@lunora/server": "1.0.0-alpha.98",
|
|
58
|
+
"@lunora/shard-engine": "1.0.0-alpha.51"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@playwright/test": "^1.61.1"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as _}from"@lunora/errors";import{runShardMigrations as O,createShardCtxDb as z,RLS_UNWRAP_SYMBOL as Z}from"@lunora/shard-engine";import{evaluationAttributes as tt}from"./evaluationAttributes-CYLgTP1P.mjs";import{MAX_RETRY_ATTEMPTS as et,RETRY_BASE_DELAY_MS as nt}from"@lunora/scheduler";import{DatabaseSync as ot}from"node:sqlite";const rt=(r,c,s,u,g)=>{let p=g,y=1;const d=new Map,f=[],h=(e,l,a={})=>{const t=`fake-job-${String(y)}`;return y+=1,d.set(t,{args:a,enqueuedAt:p,functionPath:l,id:t,scheduledFor:e}),t},b=e=>typeof e=="string"?e:e.name??e.binding??"",E={cancel:e=>{const l=d.has(e);return d.delete(e),Promise.resolve({cancelled:l})},get:e=>Promise.resolve(d.get(e)??null),list:()=>Promise.resolve([...d.values()]),runAfter:(e,l,a)=>{const t=h(p+e,b(l),a);return Promise.resolve(t)},runAt:(e,l,a)=>{const t=h(e,b(l),a);return Promise.resolve(t)}},k=async e=>{d.delete(e.id);const a=u().get(e.functionPath);if(a===void 0){console.warn(`[fake-scheduler] unknown functionPath "${e.functionPath}" — job ${e.id} dropped`);return}if(a.kind==="mutation"||a.kind==="action"){const t=r(),n=a.kind==="action"?s():c();await t(a.kind,a,n,e.args)}else console.warn(`[fake-scheduler] functionPath "${e.functionPath}" is a ${a.kind} — only mutations and actions can be scheduled; job ${e.id} dropped`)},M=async e=>{const l=[...d.values()].filter(n=>n.scheduledFor<=e).toSorted((n,v)=>n.scheduledFor-v.scheduledFor),a=[];let t=0;for(const n of l)if(d.has(n.id)){t+=1;try{await k(n)}catch(v){const T=(n.attempts??0)+1;if(T>et){const N={args:n.args,error:v,functionPath:n.functionPath,id:n.id};a.push(N),f.push(N)}else{const N=nt*2**(T-1);d.set(n.id,{...n,attempts:T,scheduledFor:p+N})}}}return{executed:t,failed:a}},C=async(e,l)=>{const{executed:a,failed:t}=await M(e);if(t.length>0&&(l?.throwOnError??!0)){const[n]=t;throw t.length===1&&n!==void 0?n.error:new AggregateError(t.map(v=>v.error),`${String(t.length)} scheduled jobs failed: ${t.map(v=>v.functionPath).join(", ")}`)}return a};return{controls:{advance:(e,l)=>(p+=e,C(p,l)),failures:()=>[...f],list:()=>[...d.values()],runPending:e=>C(Number.POSITIVE_INFINITY,e)},scheduler:E}},st=()=>{const r=new ot(":memory:"),c=u=>({one(){if(u.length!==1)throw new _("INTERNAL",`expected exactly one row, received ${String(u.length)}`);const[g]=u;return g},[Symbol.iterator](){return u[Symbol.iterator]()},toArray(){return u}});return{close:()=>{r.close()},sql:{exec:(u,...g)=>{const y=r.prepare(u).all(...g);return c(y)}}}},q=r=>{if(typeof r!="object"||r===null)return;const{kind:c}=r;if(c==="query"||c==="mutation"||c==="action")return c},it=r=>typeof r=="object"&&r!==null&&r.visibility==="internal"?"internal":"public",Q=r=>{throw new _("INTERNAL",`ctx.${r} is not available in the in-memory @lunora/testing harness (v1)`)},w=r=>new Proxy((...c)=>Q(r),{apply:()=>Q(r),get:()=>Q(r)}),K={spanId:"0000000000000001",traceId:"00000000000000000000000000000001"},ct={addEvent:()=>{},addLink:()=>{},recordEvaluation:()=>{},recordException:()=>{},setAttribute:()=>{},setAttributes:()=>{},spanContext:()=>K},at=()=>{const r={attributes:{},events:[],links:[]},c={addEvent:(s,u)=>{r.events.push({...u===void 0?{}:{attributes:{...u}},name:s})},addLink:s=>{r.links.push({spanId:s.spanId,traceId:s.traceId})},recordEvaluation:s=>{Object.assign(r.attributes,tt(s))},recordException:s=>{const u={"exception.message":s instanceof Error?s.message:String(s),"exception.type":s instanceof Error?s.constructor.name:"Error"};s instanceof Error&&s.stack!==void 0&&(u["exception.stacktrace"]=s.stack),c.addEvent("exception",u)},setAttribute:(s,u)=>{r.attributes[s]=u},setAttributes:s=>{Object.assign(r.attributes,s)},spanContext:()=>K};return{handle:c,recorded:r}},D=async(r,c)=>await c(D,ct),Y={count:()=>{},gauge:()=>{},record:()=>{}},j={debug:()=>{},error:()=>{},event:()=>{},fatal:()=>{},info:()=>{},log:()=>{},trace:()=>{},warn:()=>{},with:()=>j},ut=(r,c,s)=>(g,p)=>{let y=!1;const d=[];let f,h,b=0,E=0;const k=()=>q(g)?r("query",g,c,p,!1):Promise.resolve(g(c)),M=(t,n)=>{if(t<E)return;E=t;const v={done:!1,value:n};if(d.length===0)f=v,h=void 0;else{f=void 0,h=void 0;for(const T of d.splice(0))T.resolve(v)}},C=(t,n)=>{if(!(t<E))if(E=t,d.length===0)h={error:n},f=void 0;else{f=void 0,h=void 0;for(const v of d.splice(0))v.reject(n)}},R=t=>n=>{M(t,n)},e=t=>n=>{C(t,n)},l=()=>{if(y)return;b+=1;const t=b;k().then(R(t)).catch(e(t))};s.add(l);const a={[Symbol.asyncIterator](){return a},next:()=>{if(y)return Promise.resolve({done:!0,value:void 0});if(E===b){if(h!==void 0){const{error:t}=h;return h=void 0,Promise.reject(t)}if(f!==void 0){const t=f;return f=void 0,Promise.resolve(t)}}return E<b?new Promise((t,n)=>{d.push({reject:n,resolve:t})}):k().then(t=>{if(h!==void 0){const{error:n}=h;throw h=void 0,n}if(f!==void 0){const n=f;return f=void 0,n}return{done:!1,value:t}})},return:()=>{y=!0,s.delete(l);for(const t of d.splice(0))t.resolve({done:!0,value:void 0});return Promise.resolve({done:!0,value:void 0})}};return k().then(R(0)).catch(e(0)),a},pt=(r,c)=>{const{close:s,sql:u}=st(),g=r;O(u,g);const p=z({enforceRls:c?.enforceRls??!0,schema:g,sql:u}),y=p[Z]??p,d=m=>{u.exec.call(u,m)};let f=Promise.resolve();const h=m=>{const P=async()=>{d("BEGIN");try{const S=await m();return d("COMMIT"),S}catch(S){try{d("ROLLBACK")}catch{}throw S}},x=f.then(P);return f=x.then(()=>{},()=>{}),x};let b=!1;const E=()=>{b||(b=!0,s())},k=new Map(Object.entries(c?.functions??{}).map(([m,P])=>[m,P])),M=new Set,C=()=>{for(const m of M)m()},R=m=>(C(),m);let e,l,a;const t=c?.now??Date.now(),n=at(),v=(m,P)=>{if(m===void 0)throw new _("INTERNAL",`[fake-scheduler] ${P} not yet available — scheduler.advance called before harness construction completed`);return m},{controls:T,scheduler:N}=rt(()=>v(e,"dispatch"),()=>v(l,"mutationContext"),()=>v(a,"actionContext"),()=>k,t),B=m=>{const P={getIdentity:()=>Promise.resolve(m??null),userId:m?.userId??null},x={auth:P,db:p,env:c?.env,log:j,metrics:Y,now:t,span:n.handle,trace:D,runQuery:((o,i)=>I("query",o,x,i)),secrets:w("secrets"),storage:w("storage"),vectors:w("vectors")},S={auth:P,db:p,env:c?.env,log:j,metrics:Y,now:t,span:n.handle,trace:D,runMutation:((o,i)=>I("mutation",o,S,i)),runQuery:((o,i)=>I("query",o,x,i)),scheduler:N,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};l??=S;const U={...S,db:y},F={auth:P,db:p,env:c?.env,fetch:c?.fetch??w("fetch"),log:j,metrics:Y,now:t,span:n.handle,trace:D,runAction:((o,i)=>I("action",o,F,i)),runMutation:((o,i)=>I("mutation",o,S,i)),runQuery:((o,i)=>I("query",o,x,i)),scheduler:N,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};a??=F;const $=(o,i,A,L,J)=>{const H=q(i);if(H!==o)throw new _("INTERNAL",`expected a registered ${o}, received a ${H??"non-function"} reference`);if(!J&&it(i)==="internal")throw new _("INTERNAL",`This ${o} is an internal function — it is unreachable from the external RPC boundary in production. Call it through ctx.run${o.charAt(0).toUpperCase()}${o.slice(1)} from another function instead.`);return Promise.resolve(i.handler(A,L??{}))},I=(o,i,A,L)=>$(o,i,A,L,!0);e??=(o,i,A,L)=>o==="mutation"?h(()=>$("mutation",i,A,L,!0)).then(R):I("action",i,A,L);const V=((o,i)=>q(o)?$("query",o,x,i,!1):Promise.resolve(o(x))),W=((o,i)=>{const A=q(o)?()=>$("mutation",o,S,i,!1):()=>o(S);return h(A).then(R)}),X=((o,i)=>q(o)?$("action",o,F,i,!1):Promise.resolve(o(F))),G=ut($,x,M);return{action:X,close:E,mutation:W,query:V,run:o=>h(()=>o(U)).then(R),scheduler:T,subscribe:G,wideEvent:()=>n.recorded,withIdentity:o=>B(o)}};return B(null)};export{pt as lunoraTest};
|