@lunora/testing 1.0.0-alpha.93 → 1.0.0-alpha.95
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-0b923YYC.mjs";import{evaluationAttributes as c,recordEvaluation as n}from"./packem_shared/evaluationAttributes-GZvtFa1N.mjs";import{lunoraTest as u}from"./packem_shared/lunoraTest-
|
|
1
|
+
import{agentHarness as o,finalTurn as t,toolCallTurn as a}from"./packem_shared/agentHarness-0b923YYC.mjs";import{evaluationAttributes as c,recordEvaluation as n}from"./packem_shared/evaluationAttributes-GZvtFa1N.mjs";import{lunoraTest as u}from"./packem_shared/lunoraTest-RV15r0tW.mjs";import{containsScorer as m,evaluate as p,exactMatchScorer as s,keywordScorer as f,llmScorer as S,regexScorer as d,scoreSample as v}from"./packem_shared/containsScorer-Dr5tjL-M.mjs";import{extractLink as T,listCapturedMail as g,waitForMail as k}from"@lunora/mail/testing";export{o as agentHarness,m as containsScorer,p as evaluate,c as evaluationAttributes,s as exactMatchScorer,T as extractLink,t as finalTurn,f as keywordScorer,g as listCapturedMail,S as llmScorer,u as lunoraTest,n as recordEvaluation,d as regexScorer,v as scoreSample,a as toolCallTurn,k as waitForMail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as C}from"@lunora/errors";import{runShardMigrations as z,createShardCtxDb as X,RLS_UNWRAP_SYMBOL as Z}from"@lunora/shard-engine";import{evaluationAttributes as ee}from"./evaluationAttributes-GZvtFa1N.mjs";import{DatabaseSync as te}from"node:sqlite";const re=(s,c,n,l,I)=>{let m=I,w=1;const u=new Map,h=[],b=(t,a,d={})=>{const e=`fake-job-${String(w)}`;return w+=1,u.set(e,{args:d,enqueuedAt:m,functionPath:a,id:e,scheduledFor:t}),e},p=t=>typeof t=="string"?t:t.name??t.binding??"",A={cancel:t=>{const a=u.has(t);return u.delete(t),Promise.resolve({cancelled:a})},get:t=>Promise.resolve(u.get(t)??null),list:()=>Promise.resolve([...u.values()]),runAfter:(t,a,d)=>{const e=b(m+t,p(a),d);return Promise.resolve(e)},runAt:(t,a,d)=>{const e=b(t,p(a),d);return Promise.resolve(e)}},R=async t=>{u.delete(t.id);const a=l().get(t.functionPath);if(a===void 0){console.warn(`[fake-scheduler] unknown functionPath "${t.functionPath}" — job ${t.id} dropped`);return}if(a.kind==="mutation"||a.kind==="action"){const d=s(),e=a.kind==="action"?n():c();await d(a.kind,a,e,t.args)}else console.warn(`[fake-scheduler] functionPath "${t.functionPath}" is a ${a.kind} — only mutations and actions can be scheduled; job ${t.id} dropped`)},S=async t=>{const a=[...u.values()].filter(o=>o.scheduledFor<=t).toSorted((o,f)=>o.scheduledFor-f.scheduledFor),d=[];let e=0;for(const o of a)if(u.has(o.id)){e+=1;try{await R(o)}catch(f){const k={args:o.args,error:f,functionPath:o.functionPath,id:o.id};d.push(k),h.push(k)}}return{executed:e,failed:d}},$=async(t,a)=>{const{executed:d,failed:e}=await S(t);if(e.length>0&&(a?.throwOnError??!0)){const[o]=e;throw e.length===1&&o!==void 0?o.error:new AggregateError(e.map(f=>f.error),`${String(e.length)} scheduled jobs failed: ${e.map(f=>f.functionPath).join(", ")}`)}return d};return{controls:{advance:(t,a)=>(m+=t,$(m,a)),failures:()=>[...h],list:()=>[...u.values()],runPending:t=>$(Number.POSITIVE_INFINITY,t)},scheduler:A}},ne=()=>{const s=new te(":memory:"),c=n=>({one(){if(n.length!==1)throw new C("INTERNAL",`expected exactly one row, received ${String(n.length)}`);const[l]=n;return l},[Symbol.iterator](){return n[Symbol.iterator]()},toArray(){return n}});return{close:()=>{s.close()},sql:{exec:(n,...l)=>{const I=s.prepare(n).all(...l);return c(I)}}}},q=s=>{if(typeof s!="object"||s===null)return;const{kind:c}=s;if(c==="query"||c==="mutation"||c==="action")return c},oe=s=>typeof s=="object"&&s!==null&&s.visibility==="internal"?"internal":"public",F=s=>{throw new C("INTERNAL",`ctx.${s} is not available in the in-memory @lunora/testing harness (v1)`)},g=s=>new Proxy((...c)=>F(s),{apply:()=>F(s),get:()=>F(s)}),U={spanId:"0000000000000001",traceId:"00000000000000000000000000000001"},se={addEvent:()=>{},addLink:()=>{},recordEvaluation:()=>{},recordException:()=>{},setAttribute:()=>{},setAttributes:()=>{},spanContext:()=>U},ae=()=>{const s={attributes:{},events:[],links:[]},c={addEvent:(n,l)=>{s.events.push({...l===void 0?{}:{attributes:{...l}},name:n})},addLink:n=>{s.links.push({spanId:n.spanId,traceId:n.traceId})},recordEvaluation:n=>{Object.assign(s.attributes,ee(n))},recordException:n=>{const l={"exception.message":n instanceof Error?n.message:String(n),"exception.type":n instanceof Error?n.constructor.name:"Error"};n instanceof Error&&n.stack!==void 0&&(l["exception.stacktrace"]=n.stack),c.addEvent("exception",l)},setAttribute:(n,l)=>{s.attributes[n]=l},setAttributes:n=>{Object.assign(s.attributes,n)},spanContext:()=>U};return{handle:c,recorded:s}},M=async(s,c)=>await c(M,se),D={count:()=>{},gauge:()=>{},record:()=>{}},O={debug:()=>{},error:()=>{},event:()=>{},fatal:()=>{},info:()=>{},log:()=>{},trace:()=>{},warn:()=>{},with:()=>O},ie=(s,c,n)=>(l,I)=>{let m=!1;const w=[];let u,h,b=0,p=0;const A=()=>q(l)?s("query",l,c,I,!1):Promise.resolve(l(c)),R=(e,o)=>{if(e<p)return;p=e;const f={done:!1,value:o};if(w.length===0)u=f,h=void 0;else{u=void 0,h=void 0;for(const k of w.splice(0))k.resolve(f)}},S=(e,o)=>{if(!(e<p))if(p=e,w.length===0)h={error:o},u=void 0;else{u=void 0,h=void 0;for(const f of w.splice(0))f.reject(o)}},$=e=>o=>{R(e,o)},t=e=>o=>{S(e,o)},a=()=>{if(m)return;b+=1;const e=b;A().then($(e)).catch(t(e))};n.add(a);const d={[Symbol.asyncIterator](){return d},next:()=>{if(m)return Promise.resolve({done:!0,value:void 0});if(p===b){if(h!==void 0){const{error:e}=h;return h=void 0,Promise.reject(e)}if(u!==void 0){const e=u;return u=void 0,Promise.resolve(e)}}return p<b?new Promise((e,o)=>{w.push({reject:o,resolve:e})}):A().then(e=>{if(h!==void 0){const{error:o}=h;throw h=void 0,o}if(u!==void 0){const o=u;return u=void 0,o}return{done:!1,value:e}})},return:()=>{m=!0,n.delete(a);for(const e of w.splice(0))e.resolve({done:!0,value:void 0});return Promise.resolve({done:!0,value:void 0})}};return A().then($(0)).catch(t(0)),d},fe=(s,c)=>{const{close:n,sql:l}=ne(),I=s;z(l,I);const m=X({enforceRls:c?.enforceRls??!0,schema:I,sql:l}),w=m[Z]??m,u=v=>{l.exec.call(l,v)};let h=Promise.resolve();const b=v=>{const P=async()=>{u("BEGIN");try{const y=await v();return u("COMMIT"),y}catch(y){try{u("ROLLBACK")}catch{}throw y}},x=h.then(P);return h=x.then(()=>{},()=>{}),x};let p=!1;const A=()=>{p||(p=!0,n())},R=new Map(Object.entries(c?.functions??{}).map(([v,P])=>[v,P])),S=new Set,$=()=>{for(const v of S)v()},t=v=>($(),v);let a,d,e;const o=c?.now??Date.now(),f=ae(),k=(v,P)=>{if(v===void 0)throw new C("INTERNAL",`[fake-scheduler] ${P} not yet available — scheduler.advance called before harness construction completed`);return v},{controls:G,scheduler:B}=re(()=>k(a,"dispatch"),()=>k(d,"mutationContext"),()=>k(e,"actionContext"),()=>R,o),_=v=>{const P={getIdentity:()=>Promise.resolve(v??null),userId:v?.userId??null},x={auth:P,db:m,env:c?.env,log:O,metrics:D,now:o,span:f.handle,trace:M,runQuery:((r,i)=>N("query",r,x,i)),secrets:g("secrets"),storage:g("storage"),vectors:g("vectors")},y={auth:P,db:m,env:c?.env,log:O,metrics:D,now:o,span:f.handle,trace:M,runMutation:((r,i)=>N("mutation",r,y,i)),runQuery:((r,i)=>N("query",r,x,i)),scheduler:B,secrets:g("secrets"),storage:g("storage"),vectors:g("vectors"),workflows:g("workflows")};d??=y;const K={...y,db:w},T={auth:P,db:m,env:c?.env,fetch:c?.fetch??g("fetch"),log:O,metrics:D,now:o,span:f.handle,trace:M,runAction:((r,i)=>N("action",r,T,i)),runMutation:((r,i)=>N("mutation",r,y,i)),runQuery:((r,i)=>N("query",r,x,i)),scheduler:B,secrets:g("secrets"),storage:g("storage"),vectors:g("vectors"),workflows:g("workflows")};e??=T;const j=(r,i,E,L,J)=>{const Q=q(i);if(Q!==r)throw new C("INTERNAL",`expected a registered ${r}, received a ${Q??"non-function"} reference`);if(!J&&oe(i)==="internal")throw new C("INTERNAL",`This ${r} is an internal function — it is unreachable from the external RPC boundary in production. Call it through ctx.run${r.charAt(0).toUpperCase()}${r.slice(1)} from another function instead.`);return Promise.resolve(i.handler(E,L??{}))},N=(r,i,E,L)=>j(r,i,E,L,!0);a??=(r,i,E,L)=>r==="mutation"?b(()=>j("mutation",i,E,L,!0)).then(t):N("action",i,E,L);const V=((r,i)=>q(r)?j("query",r,x,i,!1):Promise.resolve(r(x))),W=((r,i)=>{const E=q(r)?()=>j("mutation",r,y,i,!1):()=>r(y);return b(E).then(t)}),Y=((r,i)=>q(r)?j("action",r,T,i,!1):Promise.resolve(r(T))),H=ie(j,x,S);return{action:Y,close:A,mutation:W,query:V,run:r=>b(()=>r(K)).then(t),scheduler:G,subscribe:H,wideEvent:()=>f.recorded,withIdentity:r=>_(r)}};return _(null)};export{fe 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.95",
|
|
4
4
|
"description": "Testing toolkit for Lunora: an in-memory harness for queries, mutations, and actions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -50,11 +50,11 @@
|
|
|
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/server": "1.0.0-alpha.
|
|
57
|
-
"@lunora/shard-engine": "1.0.0-alpha.
|
|
53
|
+
"@lunora/agent": "1.0.0-alpha.44",
|
|
54
|
+
"@lunora/errors": "1.0.0-alpha.16",
|
|
55
|
+
"@lunora/mail": "1.0.0-alpha.43",
|
|
56
|
+
"@lunora/server": "1.0.0-alpha.64",
|
|
57
|
+
"@lunora/shard-engine": "1.0.0-alpha.14"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@playwright/test": "^1.61.1"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as R}from"@lunora/errors";import{runShardMigrations as J,createShardCtxDb as W,RLS_UNWRAP_SYMBOL as z}from"@lunora/shard-engine";import{evaluationAttributes as X}from"./evaluationAttributes-GZvtFa1N.mjs";import{DatabaseSync as Z}from"node:sqlite";const ee=(s,i,n,l,E)=>{let f=E,g=1;const u=new Map,h=[],m=(t,a,d={})=>{const e=`fake-job-${String(g)}`;return g+=1,u.set(e,{args:d,enqueuedAt:f,functionPath:a,id:e,scheduledFor:t}),e},p=t=>typeof t=="string"?t:t.name??t.binding??"",x={cancel:t=>{const a=u.has(t);return u.delete(t),Promise.resolve({cancelled:a})},get:t=>Promise.resolve(u.get(t)??null),list:()=>Promise.resolve([...u.values()]),runAfter:(t,a,d)=>{const e=m(f+t,p(a),d);return Promise.resolve(e)},runAt:(t,a,d)=>{const e=m(t,p(a),d);return Promise.resolve(e)}},T=async t=>{u.delete(t.id);const a=l().get(t.functionPath);if(a===void 0){console.warn(`[fake-scheduler] unknown functionPath "${t.functionPath}" — job ${t.id} dropped`);return}if(a.kind==="mutation"||a.kind==="action"){const d=s(),e=a.kind==="action"?n():i();await d(a.kind,a,e,t.args)}else console.warn(`[fake-scheduler] functionPath "${t.functionPath}" is a ${a.kind} — only mutations and actions can be scheduled; job ${t.id} dropped`)},j=async t=>{const a=[...u.values()].filter(o=>o.scheduledFor<=t).toSorted((o,v)=>o.scheduledFor-v.scheduledFor),d=[];let e=0;for(const o of a)if(u.has(o.id)){e+=1;try{await T(o)}catch(v){const A={args:o.args,error:v,functionPath:o.functionPath,id:o.id};d.push(A),h.push(A)}}return{executed:e,failed:d}},b=async(t,a)=>{const{executed:d,failed:e}=await j(t);if(e.length>0&&(a?.throwOnError??!0)){const[o]=e;throw e.length===1&&o!==void 0?o.error:new AggregateError(e.map(v=>v.error),`${String(e.length)} scheduled jobs failed: ${e.map(v=>v.functionPath).join(", ")}`)}return d};return{controls:{advance:(t,a)=>(f+=t,b(f,a)),failures:()=>[...h],list:()=>[...u.values()],runPending:t=>b(Number.POSITIVE_INFINITY,t)},scheduler:x}},te=()=>{const s=new Z(":memory:"),i=n=>({one(){if(n.length!==1)throw new R("INTERNAL",`expected exactly one row, received ${String(n.length)}`);const[l]=n;return l},[Symbol.iterator](){return n[Symbol.iterator]()},toArray(){return n}});return{close:()=>{s.close()},sql:{exec:(n,...l)=>{const E=s.prepare(n).all(...l);return i(E)}}}},q=s=>{if(typeof s!="object"||s===null)return;const{kind:i}=s;if(i==="query"||i==="mutation"||i==="action")return i},re=s=>typeof s=="object"&&s!==null&&s.visibility==="internal"?"internal":"public",Q=s=>{throw new R("INTERNAL",`ctx.${s} is not available in the in-memory @lunora/testing harness (v1)`)},w=s=>new Proxy((...i)=>Q(s),{apply:()=>Q(s),get:()=>Q(s)}),U={spanId:"0000000000000001",traceId:"00000000000000000000000000000001"},ne={addEvent:()=>{},addLink:()=>{},recordEvaluation:()=>{},recordException:()=>{},setAttribute:()=>{},setAttributes:()=>{},spanContext:()=>U},oe=()=>{const s={attributes:{},events:[],links:[]},i={addEvent:(n,l)=>{s.events.push({...l===void 0?{}:{attributes:{...l}},name:n})},addLink:n=>{s.links.push({spanId:n.spanId,traceId:n.traceId})},recordEvaluation:n=>{Object.assign(s.attributes,X(n))},recordException:n=>{const l={"exception.message":n instanceof Error?n.message:String(n),"exception.type":n instanceof Error?n.constructor.name:"Error"};n instanceof Error&&n.stack!==void 0&&(l["exception.stacktrace"]=n.stack),i.addEvent("exception",l)},setAttribute:(n,l)=>{s.attributes[n]=l},setAttributes:n=>{Object.assign(s.attributes,n)},spanContext:()=>U};return{handle:i,recorded:s}},M=async(s,i)=>await i(M,ne),B={count:()=>{},gauge:()=>{},record:()=>{}},O={debug:()=>{},error:()=>{},event:()=>{},fatal:()=>{},info:()=>{},log:()=>{},trace:()=>{},warn:()=>{},with:()=>O},se=(s,i,n)=>(l,E)=>{let f=!1;const g=[];let u,h,m=0,p=0;const x=()=>q(l)?s("query",l,i,E,!1):Promise.resolve(l(i)),T=(e,o)=>{if(e<p)return;p=e;const v={done:!1,value:o};if(g.length===0)u=v,h=void 0;else{u=void 0,h=void 0;for(const A of g.splice(0))A.resolve(v)}},j=(e,o)=>{if(!(e<p))if(p=e,g.length===0)h={error:o},u=void 0;else{u=void 0,h=void 0;for(const v of g.splice(0))v.reject(o)}},b=e=>o=>{T(e,o)},t=e=>o=>{j(e,o)},a=()=>{if(f)return;m+=1;const e=m;x().then(b(e)).catch(t(e))};n.add(a);const d={[Symbol.asyncIterator](){return d},next:()=>{if(f)return Promise.resolve({done:!0,value:void 0});if(p===m){if(h!==void 0){const{error:e}=h;return h=void 0,Promise.reject(e)}if(u!==void 0){const e=u;return u=void 0,Promise.resolve(e)}}return p<m?new Promise((e,o)=>{g.push({reject:o,resolve:e})}):x().then(e=>{if(h!==void 0){const{error:o}=h;throw h=void 0,o}if(u!==void 0){const o=u;return u=void 0,o}return{done:!1,value:e}})},return:()=>{f=!0,n.delete(a);for(const e of g.splice(0))e.resolve({done:!0,value:void 0});return Promise.resolve({done:!0,value:void 0})}};return x().then(b(0)).catch(t(0)),d},le=(s,i)=>{const{close:n,sql:l}=te(),E=s;J(l,E);const f=W({enforceRls:i?.enforceRls??!0,schema:E,sql:l}),g=f[z]??f,u=y=>{l.exec.call(l,y)};let h=Promise.resolve();const m=y=>{const N=async()=>{u("BEGIN");try{const P=await y();return u("COMMIT"),P}catch(P){try{u("ROLLBACK")}catch{}throw P}},k=h.then(N);return h=k.then(()=>{},()=>{}),k};let p=!1;const x=()=>{p||(p=!0,n())},T=new Map(Object.entries(i?.functions??{}).map(([y,N])=>[y,N])),j=new Set,b=()=>{for(const y of j)y()};let t,a,d;const e=i?.now??Date.now(),o=oe(),{controls:v,scheduler:A}=ee(()=>{if(t===void 0)throw new R("INTERNAL","[fake-scheduler] dispatch not yet available — scheduler.advance called before harness construction completed");return t},()=>{if(a===void 0)throw new R("INTERNAL","[fake-scheduler] mutationContext not yet available — scheduler.advance called before harness construction completed");return a},()=>{if(d===void 0)throw new R("INTERNAL","[fake-scheduler] actionContext not yet available — scheduler.advance called before harness construction completed");return d},()=>T,e),D=y=>{const N={getIdentity:()=>Promise.resolve(y??null),userId:y?.userId??null},k={auth:N,db:f,env:i?.env,log:O,metrics:B,now:e,span:o.handle,trace:M,runQuery:((r,c)=>$("query",r,k,c)),secrets:w("secrets"),storage:w("storage"),vectors:w("vectors")},P={auth:N,db:f,env:i?.env,log:O,metrics:B,now:e,span:o.handle,trace:M,runMutation:((r,c)=>$("mutation",r,P,c)),runQuery:((r,c)=>$("query",r,k,c)),scheduler:A,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};a??=P;const K={...P,db:g},C={auth:N,db:f,env:i?.env,fetch:i?.fetch??w("fetch"),log:O,metrics:B,now:e,span:o.handle,trace:M,runAction:((r,c)=>$("action",r,C,c)),runMutation:((r,c)=>$("mutation",r,P,c)),runQuery:((r,c)=>$("query",r,k,c)),scheduler:A,secrets:w("secrets"),storage:w("storage"),vectors:w("vectors"),workflows:w("workflows")};d??=C;const L=(r,c,I,S,F)=>{const _=q(c);if(_!==r)throw new R("INTERNAL",`expected a registered ${r}, received a ${_??"non-function"} reference`);if(!F&&re(c)==="internal")throw new R("INTERNAL",`This ${r} is an internal function — it is unreachable from the external RPC boundary in production. Call it through ctx.run${r.charAt(0).toUpperCase()}${r.slice(1)} from another function instead.`);return Promise.resolve(c.handler(I,S??{}))},$=(r,c,I,S)=>L(r,c,I,S,!0);t??=(r,c,I,S)=>r==="mutation"?m(()=>L("mutation",c,I,S,!0)).then(F=>(b(),F)):$("action",c,I,S);const V=((r,c)=>q(r)?L("query",r,k,c,!1):Promise.resolve(r(k))),Y=((r,c)=>q(r)?m(()=>L("mutation",r,P,c,!1)).then(I=>(b(),I)):m(()=>r(P)).then(I=>(b(),I))),G=((r,c)=>q(r)?L("action",r,C,c,!1):Promise.resolve(r(C))),H=se(L,k,j);return{action:G,close:x,mutation:Y,query:V,run:r=>m(()=>r(K)).then(c=>(b(),c)),scheduler:v,subscribe:H,wideEvent:()=>o.recorded,withIdentity:r=>D(r)}};return D(null)};export{le as lunoraTest};
|