testforce-engine 1.0.0-rc-1 → 1.0.0-rc-2

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.js CHANGED
@@ -1 +1 @@
1
- "use strict";var re=Object.create;var P=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ie=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty;var ae=(t,e)=>{for(var n in e)P(t,n,{get:e[n],enumerable:!0})},Z=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of oe(e))!ue.call(t,o)&&o!==n&&P(t,o,{get:()=>e[o],enumerable:!(r=se(e,o))||r.enumerable});return t};var O=(t,e,n)=>(n=t!=null?re(ie(t)):{},Z(e||!t||!t.__esModule?P(n,"default",{value:t,enumerable:!0}):n,t)),ce=t=>Z(P({},"__esModule",{value:!0}),t);var be={};ae(be,{AttemptStatus:()=>U,TestEngineProvider:()=>ee,useQuestionTimer:()=>J,useQuestions:()=>q,useTestActions:()=>X,useTestEngine:()=>x,useTestEngineV2Store:()=>i,useTestTimer:()=>Y});module.exports=ce(be);var N=O(require("react"));var B=require("zustand"),V=require("zustand/middleware");var le=()=>typeof globalThis>"u"||!globalThis.localStorage?null:(console.log("[STORAGE]: Using localStorage"),{setItem:(t,e)=>{globalThis.localStorage.setItem(t,e)},getItem:t=>globalThis.localStorage.getItem(t)??null,removeItem:t=>{globalThis.localStorage.removeItem(t)}}),de=()=>{try{let t=require("@react-native-async-storage/async-storage").default;return console.log("[STORAGE]: Using AsyncStorage"),{setItem:async(e,n)=>{await t.setItem(e,n)},getItem:async e=>await t.getItem(e)??null,removeItem:async e=>{await t.removeItem(e)}}}catch{return console.log("[STORAGE]: AsyncStorage not available, trying MMKV Storage"),null}},me=()=>{try{let{MMKV:t}=require("react-native-mmkv"),e=new t;return console.log("[STORAGE]: Using MMKV Storage"),{setItem:(n,r)=>{e.set(n,r)},getItem:n=>e.getString(n)??null,removeItem:n=>{e.delete(n)}}}catch{return console.log("[STORAGE]: MMKV Storage not available, falling back to memory storage"),null}},K={},Te=()=>({setItem:(t,e)=>{K[t]=e},getItem:t=>K[t]??null,removeItem:t=>{delete K[t]}}),D=le()||de()||me()||Te();var $=O(require("react")),W={test:void 0,solutions:{},currentQuestionIndex:0,currentSectionIndex:0,currentQuestionAnswer:{},userSettings:{},isSolution:!1,submitting:!1,timer:{},isHydrated:!1},w=$.default.createContext([W,()=>{}]);w.displayName="TestEngineContext";var i=(0,B.create)()((0,V.persist)(t=>({...W,setQuestionCoordinates:(e,n)=>t(r=>{let s=r.test?.sections[e]?.questions[n]?._id,c=null;return r.isSolution||(r.solutions[s]?c={...r.solutions,[s]:{...r.solutions[s],timeTaken:r.timer[s]||0}}:c={...r.solutions,[s]:{}}),{currentSectionIndex:e,currentQuestionIndex:n,currentQuestionAnswer:c?.[s]||{},...c&&{solutions:c}}}),setTest:(e,n)=>t(()=>{if(!n)return{test:e};let r={},o={},u=0,s=0;e?.sections?.forEach((E,p)=>{E?.questions?.forEach((S,k)=>{if(S?.questionResponse&&(r={...r,[S?._id]:{markedSolution:S?.questionResponse?.markedSolution||[],markedForReview:S?.questionResponse?.markedForReview||!1,timeTaken:S?.questionResponse?.timeTaken||0,isSaved:!0}},o={...o,[S?._id]:S?.questionResponse?.timeTaken||0}),e?.status==="Paused"&&S._id===e?.lastVisitedQuestionId)u=p,s=k;else{let T=e?.sections[0]?.questions[0]?._id;r[T]||(r[T]={})}})}),e?.type==="TEST"&&(o[e?._id]=e?.timeTaken&&e?.timeTaken[e?._id]>0?+e?.timeTaken[e?._id]:+e?.duration);let c=e?.sections[u]?.questions[s]?._id,m=r[c]||{};return{test:e,solutions:r,timer:o,currentSectionIndex:u,currentQuestionIndex:s,currentQuestionAnswer:m}}),setSolution:(e,n)=>t(r=>({solutions:{...r.solutions,[e]:{...r.solutions[e],...n}},currentQuestionAnswer:{...r.solutions[e],...n}})),incrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)+1}})),decrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)-1}})),setTimer:(e,n)=>t(r=>({timer:{...r.timer,[e]:n}})),setCurrentAnswer:e=>t({currentQuestionAnswer:e}),setUserSettings:e=>t({userSettings:e}),setTestSubmitting:e=>t({submitting:e}),reset:()=>t(W),setIsHydrated:e=>t({isHydrated:e})}),{name:"test-engine-v2-store",storage:(0,V.createJSONStorage)(()=>D)}));var Se=()=>{let t=N.default.useContext(w);if(t===void 0)throw new Error("useTestEngineV2 must be use within TestEngineProvider");let[e,n]=t;if(!e.test)throw new Error("Please provide test data to useTestEngineV2");let r=i(T=>T.test),o=i(T=>T.setTestSubmitting),u=i(T=>T.solutions),s=i(T=>T.currentQuestionIndex),c=i(T=>T.currentSectionIndex),m=(0,N.useMemo)(()=>r?.sections[c],[r,c]),E=(0,N.useMemo)(()=>m?.questions[s],[m,s]),p=i(T=>T.setTimer),S=i(T=>T.timer);return{handleSubmitTest:(T=!1,_=!1)=>{o(!0);let A=[];r?.sections?.forEach(g=>{g?.questions?.forEach(l=>{u[l._id]&&A.push({questionId:l._id,markedSolution:u[l._id]?.isSaved?u[l._id]?.markedSolution:[],timeTaken:S[l._id]||u[l._id]?.timeTaken||0,markedForReview:u[l._id]?.markedForReview||!1})})});let Q={submittedBy:_?"autoSubmit":"user",questionResponses:A,testMappingId:r?.testMappingId,type:T?"Pause":"Submit",testId:r?._id,...T?{lastVisitedQuestionId:E?._id}:{},...r?.type==="TEST"&&T&&S[r?._id]?{timeTaken:{[r?._id]:S[r?._id]}}:{}};return A.length||delete Q.questionResponses,o(!1),n({payload:Q,pause:T,autoSubmit:_}),Q},currentSection:m,currentQuestion:E,...i.getState(),...e}},x=Se;var F=require("react");var ge=()=>{let{isSolution:t,handleSubmitTest:e}=x(),n=i(m=>m.test),r=i(m=>m.timer),o=i(m=>m.decrementTimer),u=i(m=>m.isHydrated),s=(0,F.useRef)(null),c=()=>{n&&u&&o(n?._id),s.current=setTimeout(()=>{c()},1e3)};return(0,F.useEffect)(()=>{if(u&&n&&typeof r[n?._id]=="number"&&r[n?._id]<=0){console.log(r[n?._id],"Timer","Test ID",n?._id),clearTimeout(s.current),e(!1,!0);return}},[r,n,u]),(0,F.useEffect)(()=>{if(!(t||n?.type==="QUIZ"))return c(),()=>{s.current&&clearTimeout(s.current)}},[n,u]),{timer:r[n._id]||0}},Y=ge;var M=O(require("react"));var U=(s=>(s.ATTEMPTED="ATTEMPTED",s.NOT_ATTEMPTED="NOT_ATTEMPTED",s.NOT_VISITED="NOT_VISITED",s.MARKED_FOR_REVIEW="MARKED_FOR_REVIEW",s.ATTEMPTED_AND_MARKED_FOR_REVIEW="ATTEMPTED_AND_MARKED_FOR_REVIEW",s.ACITVE_QUESTION="ACITVE_QUESTION",s))(U||{});var j={1:{label:"A"},2:{label:"B"},3:{label:"C"},4:{label:"D"}},Ee=({includeAllSections:t}={})=>{let e=i(g=>g.test),n=i(g=>g.solutions),r=i(g=>g.isSolution),o=i(g=>g.currentSectionIndex),{currentQuestion:u,currentSection:s}=x(),c=i(g=>g.currentQuestionIndex),[m,E]=M.default.useState({MARKED_FOR_REVIEW:{count:0},ATTEMPTED:{count:0},ATTEMPTED_AND_MARKED_FOR_REVIEW:{count:0},NOT_ATTEMPTED:{count:0},NOT_VISITED:{count:0},ACITVE_QUESTION:{count:0}}),p=(0,M.useCallback)((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?f?.markedSolution&&f?.markedSolution?.length>0&&f?.markedForReview?"ATTEMPTED_AND_MARKED_FOR_REVIEW":f?.markedSolution&&f?.markedSolution?.length>0?"ATTEMPTED":f?.markedForReview?"MARKED_FOR_REVIEW":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),S=(0,M.useCallback)((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?.markedSolution?.length?T(f.markedSolution,a.solution)?"ATTEMPTED":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),k=(0,M.useCallback)(()=>{let g={...m};Object.values(g).forEach(l=>l.count=0),t?e?.sections?.forEach((l,a)=>{l?.questions?.forEach((f,y)=>{let L=r||e.type==="QUIZ"?S(y,a):p(y,a);g[L].count+=1})}):e?.sections[o]?.questions.forEach((l,a)=>{let f=r||e.type==="QUIZ"?S(a,o):p(a,o);g[f].count+=1}),E(g)},[S,p,t,r,e,o,n]);M.default.useEffect(()=>{k()},[c,n,o]);function T(g,l){let a=g.slice().sort(),f=l.slice().sort();if(a.length!==f.length)return!1;for(let y=0;y<a.length;y++)if(a[y]!==f[y])return!1;return!0}let _=M.default.useMemo(()=>S(c,o)==="ATTEMPTED"?"correct":S(c,o)==="NOT_ATTEMPTED"?"incorrect":"skipped",[c,o,S]),A=M.default.useMemo(()=>{switch(_){case"correct":return e?.marksLevel==="TEST"?"+"+e.positiveMarks:"+"+s?.positiveMarks;case"incorrect":return e?.marksLevel==="TEST"?e.isNegativeMarkingEnabled?"-"+e.negativeMarks:0:s?.isNegativeMarkingEnabled?"-"+s?.negativeMarks:0;case"skipped":return 0}},[_]),Q=M.default.useMemo(()=>{if(!u)return"";if(u.type==="INTEGER")return u.solution[0];if(u.type==="SINGLE"){let g=u.options.findIndex(l=>l._id===u.solution[0]);return j[g+1]?.label||""}return u.type==="MULTIPLE"?u.solution.map(l=>{let a=u.options.findIndex(f=>f._id===l);return j[a+1]?.label||""}).join(", "):""},[u]);return{getQuestionStatus:p,questionStatusMap:m,getAnsweredQuestionStatus:S,areArraysEqual:T,currentQuestionStatus:_,currentAnswerMarks:A,correctAnswer:Q}},q=Ee;var G=require("react");var pe=()=>{let{currentQuestion:t,isSolution:e}=x(),n=i(m=>m.timer),r=i(m=>m.incrementTimer),o=i(m=>m.solutions),u=i(m=>m.isHydrated),s=(0,G.useRef)(null),c=()=>{t&&!o[t?._id]?.markedSolution?.length&&u&&r(t?._id),s.current=setTimeout(()=>{c()},1e3)};return(0,G.useEffect)(()=>{if(!e)return c(),()=>{s.current&&clearTimeout(s.current)}},[t,o,u]),{timer:n[t._id]||0}},J=pe;var I=O(require("react"));var Ie=()=>{let t=i(d=>d.test),e=i(d=>d.solutions),{currentQuestion:n,currentSection:r,currentQuestionAnswer:o}=x(),u=i(d=>d.currentQuestionIndex),s=i(d=>d.currentSectionIndex),c=i(d=>d.userSettings),m=i(d=>d.isSolution),E=i(d=>d.setQuestionCoordinates),p=i(d=>d.setSolution),S=i(d=>d.setCurrentAnswer),{getAnsweredQuestionStatus:k}=q(),T=I.default.useMemo(()=>t?.type==="QUIZ"&&!!e[n?._id]?.markedSolution?.length,[t,e,n]),_=(0,I.useCallback)(()=>{S({...o,markedSolution:[],isSaved:!1}),p(n?._id,{...o,markedSolution:[]})},[o,n,p]),A=(0,I.useCallback)(d=>{if(!(m||T))if(o?.markedSolution?.includes(d)){let b=o.markedSolution.filter(R=>R!==d);if(b?.length===0)return _();S({...o,markedSolution:b,isSaved:!1});return}else if(n?.type==="SINGLE"){S({...o,markedSolution:[d],isSaved:!1});return}else{let b=o?.markedSolution?.length?o?.markedSolution:[];S({...o,markedSolution:[...b,d],isSaved:!1});return}},[m,T,n,o,S,_]),Q=(0,I.useCallback)(d=>{m||T||(S({...o,markedSolution:d?[d]:[],isSaved:!1}),d||_())},[m,T,o,_]),g=(0,I.useCallback)(()=>{S({...o,markedForReview:!o?.markedForReview}),p(n._id,{...o,markedForReview:!o?.markedForReview})},[p,S,o,n]),[l,a]=(0,I.useState)([]);(0,I.useEffect)(()=>{if(c?.selectedFilter){let d=r?.questions?.map((b,R)=>{if(c?.selectedFilter===k(R,s))return R})?.filter(b=>b!==void 0);a(d),d?.length&&E(s,d[0]||0)}else a([])},[c,r]);let f=(0,I.useCallback)(()=>{o?.isSaved||p(n?._id,{...o,isSaved:!0})},[o,n,p]),y=(0,I.useCallback)(()=>{if(c?.selectedFilter){let R=l?.findIndex(H=>H===u);R>=0&&l[R+1]>=0&&E(s,l[R+1]);return}let d=r?.questions[u+1]?s:t?.sections[s+1]?s+1:s,b=r?.questions[u+1]?u+1:0;E(d,b)},[c?.selectedFilter,l,u,s,r,t,E]),L=(0,I.useCallback)(()=>{if(c?.selectedFilter){let R=l?.findIndex(H=>H===u);R>=0&&l[R-1]>=0&&E(s,l[R-1]);return}let d=r?.questions[u-1]?s:t?.sections[s-1]?s-1:s,b=r?.questions[u-1]?u-1:t.sections[d]?.questions?.length-1;E(d,b)},[c?.selectedFilter,l,u,s,r,t,E]),te=(0,I.useMemo)(()=>{if(c?.selectedFilter){let d=l?.findIndex(b=>b===u);return!l[d+1]}return!t?.sections[s+1]&&!r?.questions[u+1]},[s,u,l,c?.selectedFilter,t,r]),ne=(0,I.useMemo)(()=>c?.selectedFilter?l?.findIndex(b=>b===u)<=0:s===0&&u===0,[s,u,l,c?.selectedFilter]);return{isQuizAnswer:T,handleClearResponse:_,handleSelectOption:A,handleIntegerInputChange:Q,handleMarkForReview:g,handleNext:y,handlePrevious:L,handleSaveAnswer:f,isLastQuestion:te,isFirstQuestion:ne}},X=Ie;var h=require("react"),z=O(require("react"));var _e=(0,h.forwardRef)(({test:t,isSolution:e,submitTest:n,children:r},o)=>{let u=i(a=>a.setTest),s=i(a=>a.setIsHydrated),c=i(a=>a.isHydrated),m=i(a=>a.test),E=i(a=>a.solutions),p=i(a=>a.currentQuestionIndex),S=i(a=>a.currentSectionIndex),k=i(a=>a.currentQuestionAnswer),T=i(a=>a.userSettings),_=i(a=>a.submitting),A=i(a=>a.timer),Q=i(a=>a.reset),g=z.default.useMemo(()=>({test:m,solutions:E,currentQuestionIndex:p,currentSectionIndex:S,userSettings:T,isSolution:e||!1,submitting:_,timer:A,isHydrated:c,currentQuestionAnswer:k}),[m,E,p,S,T,e,_,A,c,k]),l=()=>{console.log("[RESET]: Called"),Q(),D.removeItem(`${t?._id}-test-initiated`),D.removeItem(`test-engine-v2-store-${t?._id}`),D.removeItem("test-engine-v2-store")};return(0,h.useImperativeHandle)(o,()=>({reset:l})),(0,h.useEffect)(()=>{(async()=>{if(!(c&&t?._id===m?._id))try{if(!t?._id)return console.error("[TEST_ENGINE]: Test ID is missing. Cannot initialize store.");i.persist.setOptions({name:`test-engine-v2-store-${t?._id}`}),await i.persist.rehydrate(),D.removeItem("test-engine-v2-store"),await D.getItem(`${t?._id}-test-initiated`)?(console.log("[TEST_ENGINE]: Test already initiated, loading existing state"),u(t,!1)):(console.log("[TEST_ENGINE]: Test not initiated, initializing new state"),u(t,!0),e||D.setItem(`${t?._id}-test-initiated`,"true")),s(!0)}catch(f){console.error("Error initializing test engine store:",f),s(!0)}})()},[t?._id,c,u,s]),!c||!m?null:z.default.createElement(w.Provider,{value:[g,n]},r)}),ee=_e;0&&(module.exports={AttemptStatus,TestEngineProvider,useQuestionTimer,useQuestions,useTestActions,useTestEngine,useTestEngineV2Store,useTestTimer});
1
+ "use strict";var re=Object.create;var P=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ie=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty;var ae=(t,e)=>{for(var n in e)P(t,n,{get:e[n],enumerable:!0})},Z=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of oe(e))!ue.call(t,o)&&o!==n&&P(t,o,{get:()=>e[o],enumerable:!(r=se(e,o))||r.enumerable});return t};var O=(t,e,n)=>(n=t!=null?re(ie(t)):{},Z(e||!t||!t.__esModule?P(n,"default",{value:t,enumerable:!0}):n,t)),ce=t=>Z(P({},"__esModule",{value:!0}),t);var be={};ae(be,{AttemptStatus:()=>U,TestEngineProvider:()=>ee,useQuestionTimer:()=>J,useQuestions:()=>q,useTestActions:()=>X,useTestEngine:()=>x,useTestEngineV2Store:()=>i,useTestTimer:()=>Y});module.exports=ce(be);var N=O(require("react"));var B=require("zustand"),V=require("zustand/middleware");var le=()=>typeof globalThis>"u"||!globalThis.localStorage?null:(console.log("[STORAGE]: Using localStorage"),{setItem:(t,e)=>{globalThis.localStorage.setItem(t,e)},getItem:t=>globalThis.localStorage.getItem(t)??null,removeItem:t=>{globalThis.localStorage.removeItem(t)}}),de=()=>{try{let t=require("@react-native-async-storage/async-storage").default;return console.log("[STORAGE]: Using AsyncStorage"),{setItem:async(e,n)=>{await t.setItem(e,n)},getItem:async e=>await t.getItem(e)??null,removeItem:async e=>{await t.removeItem(e)}}}catch{return console.log("[STORAGE]: AsyncStorage not available, trying MMKV Storage"),null}},me=()=>{try{let{MMKV:t}=require("react-native-mmkv"),e=new t;return console.log("[STORAGE]: Using MMKV Storage"),{setItem:(n,r)=>{e.set(n,r)},getItem:n=>e.getString(n)??null,removeItem:n=>{e.delete(n)}}}catch{return console.log("[STORAGE]: MMKV Storage not available, falling back to memory storage"),null}},K={},Te=()=>({setItem:(t,e)=>{K[t]=e},getItem:t=>K[t]??null,removeItem:t=>{delete K[t]}}),D=le()||de()||me()||Te();var $=O(require("react")),W={test:void 0,solutions:{},currentQuestionIndex:0,currentSectionIndex:0,currentQuestionAnswer:{},userSettings:{},isSolution:!1,submitting:!1,timer:{},isHydrated:!1},w=$.default.createContext([W,()=>{}]);w.displayName="TestEngineContext";var i=(0,B.create)()((0,V.persist)(t=>({...W,setQuestionCoordinates:(e,n)=>t(r=>{let s=r.test?.sections[e]?.questions[n]?._id,c=null;return r.isSolution||(r.solutions[s]?c={...r.solutions,[s]:{...r.solutions[s],timeTaken:r.timer[s]||0}}:c={...r.solutions,[s]:{}}),{currentSectionIndex:e,currentQuestionIndex:n,currentQuestionAnswer:c?.[s]||{},...c&&{solutions:c}}}),setTest:(e,n)=>t(()=>{if(!n)return{test:e};let r={},o={},u=0,s=0;e?.sections?.forEach((E,p)=>{E?.questions?.forEach((T,k)=>{T?.questionResponse&&(r={...r,[T?._id]:{markedSolution:T?.questionResponse?.markedSolution||[],markedForReview:T?.questionResponse?.markedForReview||!1,timeTaken:T?.questionResponse?.timeTaken||0,isSaved:!0}},o={...o,[T?._id]:T?.questionResponse?.timeTaken||0}),e?.status==="Paused"&&T._id===e?.lastVisitedQuestionId&&(u=p,s=k)})}),e?.type==="TEST"&&(o[e?._id]=e?.timeTaken&&e?.timeTaken[e?._id]>0?+e?.timeTaken[e?._id]:+e?.duration);let c=e?.sections[u]?.questions[s]?._id,m=r[c]||{};return r[c]||(r[c]={}),{test:e,solutions:r,timer:o,currentSectionIndex:u,currentQuestionIndex:s,currentQuestionAnswer:m}}),setSolution:(e,n)=>t(r=>({solutions:{...r.solutions,[e]:{...r.solutions[e],...n}},currentQuestionAnswer:{...r.solutions[e],...n}})),incrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)+1}})),decrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)-1}})),setTimer:(e,n)=>t(r=>({timer:{...r.timer,[e]:n}})),setCurrentAnswer:e=>t({currentQuestionAnswer:e}),setUserSettings:e=>t({userSettings:e}),setTestSubmitting:e=>t({submitting:e}),reset:()=>t(W),setIsHydrated:e=>t({isHydrated:e})}),{name:"test-engine-v2-store",storage:(0,V.createJSONStorage)(()=>D)}));var Se=()=>{let t=N.default.useContext(w);if(t===void 0)throw new Error("useTestEngineV2 must be use within TestEngineProvider");let[e,n]=t;if(!e.test)throw new Error("Please provide test data to useTestEngineV2");let r=i(S=>S.test),o=i(S=>S.setTestSubmitting),u=i(S=>S.solutions),s=i(S=>S.currentQuestionIndex),c=i(S=>S.currentSectionIndex),m=(0,N.useMemo)(()=>r?.sections[c],[r,c]),E=(0,N.useMemo)(()=>m?.questions[s],[m,s]),p=i(S=>S.setTimer),T=i(S=>S.timer);return{handleSubmitTest:(S=!1,_=!1)=>{o(!0);let A=[];r?.sections?.forEach(g=>{g?.questions?.forEach(l=>{u[l._id]&&A.push({questionId:l._id,markedSolution:u[l._id]?.isSaved?u[l._id]?.markedSolution:[],timeTaken:T[l._id]||u[l._id]?.timeTaken||0,markedForReview:u[l._id]?.markedForReview||!1})})});let Q={submittedBy:_?"autoSubmit":"user",questionResponses:A,testMappingId:r?.testMappingId,type:S?"Pause":"Submit",testId:r?._id,...S?{lastVisitedQuestionId:E?._id}:{},...r?.type==="TEST"&&S&&T[r?._id]?{timeTaken:{[r?._id]:T[r?._id]}}:{}};return A.length||delete Q.questionResponses,o(!1),n({payload:Q,pause:S,autoSubmit:_}),Q},currentSection:m,currentQuestion:E,...i.getState(),...e}},x=Se;var F=require("react");var ge=()=>{let{isSolution:t,handleSubmitTest:e}=x(),n=i(m=>m.test),r=i(m=>m.timer),o=i(m=>m.decrementTimer),u=i(m=>m.isHydrated),s=(0,F.useRef)(null),c=()=>{n&&u&&o(n?._id),s.current=setTimeout(()=>{c()},1e3)};return(0,F.useEffect)(()=>{if(u&&n&&typeof r[n?._id]=="number"&&r[n?._id]<=0){console.log(r[n?._id],"Timer","Test ID",n?._id),clearTimeout(s.current),e(!1,!0);return}},[r,n,u]),(0,F.useEffect)(()=>{if(!(t||n?.type==="QUIZ"))return c(),()=>{s.current&&clearTimeout(s.current)}},[n,u]),{timer:r[n._id]||0}},Y=ge;var M=O(require("react"));var U=(s=>(s.ATTEMPTED="ATTEMPTED",s.NOT_ATTEMPTED="NOT_ATTEMPTED",s.NOT_VISITED="NOT_VISITED",s.MARKED_FOR_REVIEW="MARKED_FOR_REVIEW",s.ATTEMPTED_AND_MARKED_FOR_REVIEW="ATTEMPTED_AND_MARKED_FOR_REVIEW",s.ACITVE_QUESTION="ACITVE_QUESTION",s))(U||{});var j={1:{label:"A"},2:{label:"B"},3:{label:"C"},4:{label:"D"}},Ee=({includeAllSections:t}={})=>{let e=i(g=>g.test),n=i(g=>g.solutions),r=i(g=>g.isSolution),o=i(g=>g.currentSectionIndex),{currentQuestion:u,currentSection:s}=x(),c=i(g=>g.currentQuestionIndex),[m,E]=M.default.useState({MARKED_FOR_REVIEW:{count:0},ATTEMPTED:{count:0},ATTEMPTED_AND_MARKED_FOR_REVIEW:{count:0},NOT_ATTEMPTED:{count:0},NOT_VISITED:{count:0},ACITVE_QUESTION:{count:0}}),p=(0,M.useCallback)((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?f?.markedSolution&&f?.markedSolution?.length>0&&f?.markedForReview?"ATTEMPTED_AND_MARKED_FOR_REVIEW":f?.markedSolution&&f?.markedSolution?.length>0?"ATTEMPTED":f?.markedForReview?"MARKED_FOR_REVIEW":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),T=(0,M.useCallback)((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?.markedSolution?.length?S(f.markedSolution,a.solution)?"ATTEMPTED":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),k=(0,M.useCallback)(()=>{let g={...m};Object.values(g).forEach(l=>l.count=0),t?e?.sections?.forEach((l,a)=>{l?.questions?.forEach((f,y)=>{let L=r||e.type==="QUIZ"?T(y,a):p(y,a);g[L].count+=1})}):e?.sections[o]?.questions.forEach((l,a)=>{let f=r||e.type==="QUIZ"?T(a,o):p(a,o);g[f].count+=1}),E(g)},[T,p,t,r,e,o,n]);M.default.useEffect(()=>{k()},[c,n,o]);function S(g,l){let a=g.slice().sort(),f=l.slice().sort();if(a.length!==f.length)return!1;for(let y=0;y<a.length;y++)if(a[y]!==f[y])return!1;return!0}let _=M.default.useMemo(()=>T(c,o)==="ATTEMPTED"?"correct":T(c,o)==="NOT_ATTEMPTED"?"incorrect":"skipped",[c,o,T]),A=M.default.useMemo(()=>{switch(_){case"correct":return e?.marksLevel==="TEST"?"+"+e.positiveMarks:"+"+s?.positiveMarks;case"incorrect":return e?.marksLevel==="TEST"?e.isNegativeMarkingEnabled?"-"+e.negativeMarks:0:s?.isNegativeMarkingEnabled?"-"+s?.negativeMarks:0;case"skipped":return 0}},[_]),Q=M.default.useMemo(()=>{if(!u)return"";if(u.type==="INTEGER")return u.solution[0];if(u.type==="SINGLE"){let g=u.options.findIndex(l=>l._id===u.solution[0]);return j[g+1]?.label||""}return u.type==="MULTIPLE"?u.solution.map(l=>{let a=u.options.findIndex(f=>f._id===l);return j[a+1]?.label||""}).join(", "):""},[u]);return{getQuestionStatus:p,questionStatusMap:m,getAnsweredQuestionStatus:T,areArraysEqual:S,currentQuestionStatus:_,currentAnswerMarks:A,correctAnswer:Q}},q=Ee;var G=require("react");var pe=()=>{let{currentQuestion:t,isSolution:e}=x(),n=i(m=>m.timer),r=i(m=>m.incrementTimer),o=i(m=>m.solutions),u=i(m=>m.isHydrated),s=(0,G.useRef)(null),c=()=>{t&&!o[t?._id]?.markedSolution?.length&&u&&r(t?._id),s.current=setTimeout(()=>{c()},1e3)};return(0,G.useEffect)(()=>{if(!e)return c(),()=>{s.current&&clearTimeout(s.current)}},[t,o,u]),{timer:n[t._id]||0}},J=pe;var I=O(require("react"));var Ie=()=>{let t=i(d=>d.test),e=i(d=>d.solutions),{currentQuestion:n,currentSection:r,currentQuestionAnswer:o}=x(),u=i(d=>d.currentQuestionIndex),s=i(d=>d.currentSectionIndex),c=i(d=>d.userSettings),m=i(d=>d.isSolution),E=i(d=>d.setQuestionCoordinates),p=i(d=>d.setSolution),T=i(d=>d.setCurrentAnswer),{getAnsweredQuestionStatus:k}=q(),S=I.default.useMemo(()=>t?.type==="QUIZ"&&!!e[n?._id]?.markedSolution?.length,[t,e,n]),_=(0,I.useCallback)(()=>{T({...o,markedSolution:[],isSaved:!1}),p(n?._id,{...o,markedSolution:[]})},[o,n,p]),A=(0,I.useCallback)(d=>{if(!(m||S))if(o?.markedSolution?.includes(d)){let b=o.markedSolution.filter(R=>R!==d);if(b?.length===0)return _();T({...o,markedSolution:b,isSaved:!1});return}else if(n?.type==="SINGLE"){T({...o,markedSolution:[d],isSaved:!1});return}else{let b=o?.markedSolution?.length?o?.markedSolution:[];T({...o,markedSolution:[...b,d],isSaved:!1});return}},[m,S,n,o,T,_]),Q=(0,I.useCallback)(d=>{m||S||(T({...o,markedSolution:d?[d]:[],isSaved:!1}),d||_())},[m,S,o,_]),g=(0,I.useCallback)(()=>{T({...o,markedForReview:!o?.markedForReview}),p(n._id,{...o,markedForReview:!o?.markedForReview})},[p,T,o,n]),[l,a]=(0,I.useState)([]);(0,I.useEffect)(()=>{if(c?.selectedFilter){let d=r?.questions?.map((b,R)=>{if(c?.selectedFilter===k(R,s))return R})?.filter(b=>b!==void 0);a(d),d?.length&&E(s,d[0]||0)}else a([])},[c,r]);let f=(0,I.useCallback)(()=>{o?.isSaved||p(n?._id,{...o,isSaved:!0})},[o,n,p]),y=(0,I.useCallback)(()=>{if(c?.selectedFilter){let R=l?.findIndex(H=>H===u);R>=0&&l[R+1]>=0&&E(s,l[R+1]);return}let d=r?.questions[u+1]?s:t?.sections[s+1]?s+1:s,b=r?.questions[u+1]?u+1:0;E(d,b)},[c?.selectedFilter,l,u,s,r,t,E]),L=(0,I.useCallback)(()=>{if(c?.selectedFilter){let R=l?.findIndex(H=>H===u);R>=0&&l[R-1]>=0&&E(s,l[R-1]);return}let d=r?.questions[u-1]?s:t?.sections[s-1]?s-1:s,b=r?.questions[u-1]?u-1:t.sections[d]?.questions?.length-1;E(d,b)},[c?.selectedFilter,l,u,s,r,t,E]),te=(0,I.useMemo)(()=>{if(c?.selectedFilter){let d=l?.findIndex(b=>b===u);return!l[d+1]}return!t?.sections[s+1]&&!r?.questions[u+1]},[s,u,l,c?.selectedFilter,t,r]),ne=(0,I.useMemo)(()=>c?.selectedFilter?l?.findIndex(b=>b===u)<=0:s===0&&u===0,[s,u,l,c?.selectedFilter]);return{isQuizAnswer:S,handleClearResponse:_,handleSelectOption:A,handleIntegerInputChange:Q,handleMarkForReview:g,handleNext:y,handlePrevious:L,handleSaveAnswer:f,isLastQuestion:te,isFirstQuestion:ne}},X=Ie;var h=require("react"),z=O(require("react"));var _e=(0,h.forwardRef)(({test:t,isSolution:e,submitTest:n,children:r},o)=>{let u=i(a=>a.setTest),s=i(a=>a.setIsHydrated),c=i(a=>a.isHydrated),m=i(a=>a.test),E=i(a=>a.solutions),p=i(a=>a.currentQuestionIndex),T=i(a=>a.currentSectionIndex),k=i(a=>a.currentQuestionAnswer),S=i(a=>a.userSettings),_=i(a=>a.submitting),A=i(a=>a.timer),Q=i(a=>a.reset),g=z.default.useMemo(()=>({test:m,solutions:E,currentQuestionIndex:p,currentSectionIndex:T,userSettings:S,isSolution:e||!1,submitting:_,timer:A,isHydrated:c,currentQuestionAnswer:k}),[m,E,p,T,S,e,_,A,c,k]),l=()=>{console.log("[RESET]: Called"),Q(),D.removeItem(`${t?._id}-test-initiated`),D.removeItem(`test-engine-v2-store-${t?._id}`),D.removeItem("test-engine-v2-store")};return(0,h.useImperativeHandle)(o,()=>({reset:l})),(0,h.useEffect)(()=>{(async()=>{if(!(c&&t?._id===m?._id))try{if(!t?._id)return console.error("[TEST_ENGINE]: Test ID is missing. Cannot initialize store.");i.persist.setOptions({name:`test-engine-v2-store-${t?._id}`}),await i.persist.rehydrate(),D.removeItem("test-engine-v2-store"),await D.getItem(`${t?._id}-test-initiated`)?(console.log("[TEST_ENGINE]: Test already initiated, loading existing state"),u(t,!1)):(console.log("[TEST_ENGINE]: Test not initiated, initializing new state"),u(t,!0),e||D.setItem(`${t?._id}-test-initiated`,"true")),s(!0)}catch(f){console.error("Error initializing test engine store:",f),s(!0)}})()},[t?._id,c,u,s]),!c||!m?null:z.default.createElement(w.Provider,{value:[g,n]},r)}),ee=_e;0&&(module.exports={AttemptStatus,TestEngineProvider,useQuestionTimer,useQuestions,useTestActions,useTestEngine,useTestEngineV2Store,useTestTimer});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var G=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});import re,{useMemo as L}from"react";import{create as X}from"zustand";import{persist as ee,createJSONStorage as te}from"zustand/middleware";var $=()=>typeof globalThis>"u"||!globalThis.localStorage?null:(console.log("[STORAGE]: Using localStorage"),{setItem:(t,e)=>{globalThis.localStorage.setItem(t,e)},getItem:t=>globalThis.localStorage.getItem(t)??null,removeItem:t=>{globalThis.localStorage.removeItem(t)}}),Y=()=>{try{let t=G("@react-native-async-storage/async-storage").default;return console.log("[STORAGE]: Using AsyncStorage"),{setItem:async(e,n)=>{await t.setItem(e,n)},getItem:async e=>await t.getItem(e)??null,removeItem:async e=>{await t.removeItem(e)}}}catch{return console.log("[STORAGE]: AsyncStorage not available, trying MMKV Storage"),null}},j=()=>{try{let{MMKV:t}=G("react-native-mmkv"),e=new t;return console.log("[STORAGE]: Using MMKV Storage"),{setItem:(n,r)=>{e.set(n,r)},getItem:n=>e.getString(n)??null,removeItem:n=>{e.delete(n)}}}catch{return console.log("[STORAGE]: MMKV Storage not available, falling back to memory storage"),null}},P={},J=()=>({setItem:(t,e)=>{P[t]=e},getItem:t=>P[t]??null,removeItem:t=>{delete P[t]}}),Q=$()||Y()||j()||J();import ne from"react";var C={test:void 0,solutions:{},currentQuestionIndex:0,currentSectionIndex:0,currentQuestionAnswer:{},userSettings:{},isSolution:!1,submitting:!1,timer:{},isHydrated:!1},h=ne.createContext([C,()=>{}]);h.displayName="TestEngineContext";var o=X()(ee(t=>({...C,setQuestionCoordinates:(e,n)=>t(r=>{let s=r.test?.sections[e]?.questions[n]?._id,c=null;return r.isSolution||(r.solutions[s]?c={...r.solutions,[s]:{...r.solutions[s],timeTaken:r.timer[s]||0}}:c={...r.solutions,[s]:{}}),{currentSectionIndex:e,currentQuestionIndex:n,currentQuestionAnswer:c?.[s]||{},...c&&{solutions:c}}}),setTest:(e,n)=>t(()=>{if(!n)return{test:e};let r={},u={},i=0,s=0;e?.sections?.forEach((E,p)=>{E?.questions?.forEach((S,x)=>{if(S?.questionResponse&&(r={...r,[S?._id]:{markedSolution:S?.questionResponse?.markedSolution||[],markedForReview:S?.questionResponse?.markedForReview||!1,timeTaken:S?.questionResponse?.timeTaken||0,isSaved:!0}},u={...u,[S?._id]:S?.questionResponse?.timeTaken||0}),e?.status==="Paused"&&S._id===e?.lastVisitedQuestionId)i=p,s=x;else{let T=e?.sections[0]?.questions[0]?._id;r[T]||(r[T]={})}})}),e?.type==="TEST"&&(u[e?._id]=e?.timeTaken&&e?.timeTaken[e?._id]>0?+e?.timeTaken[e?._id]:+e?.duration);let c=e?.sections[i]?.questions[s]?._id,m=r[c]||{};return{test:e,solutions:r,timer:u,currentSectionIndex:i,currentQuestionIndex:s,currentQuestionAnswer:m}}),setSolution:(e,n)=>t(r=>({solutions:{...r.solutions,[e]:{...r.solutions[e],...n}},currentQuestionAnswer:{...r.solutions[e],...n}})),incrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)+1}})),decrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)-1}})),setTimer:(e,n)=>t(r=>({timer:{...r.timer,[e]:n}})),setCurrentAnswer:e=>t({currentQuestionAnswer:e}),setUserSettings:e=>t({userSettings:e}),setTestSubmitting:e=>t({submitting:e}),reset:()=>t(C),setIsHydrated:e=>t({isHydrated:e})}),{name:"test-engine-v2-store",storage:te(()=>Q)}));var se=()=>{let t=re.useContext(h);if(t===void 0)throw new Error("useTestEngineV2 must be use within TestEngineProvider");let[e,n]=t;if(!e.test)throw new Error("Please provide test data to useTestEngineV2");let r=o(T=>T.test),u=o(T=>T.setTestSubmitting),i=o(T=>T.solutions),s=o(T=>T.currentQuestionIndex),c=o(T=>T.currentSectionIndex),m=L(()=>r?.sections[c],[r,c]),E=L(()=>m?.questions[s],[m,s]),p=o(T=>T.setTimer),S=o(T=>T.timer);return{handleSubmitTest:(T=!1,I=!1)=>{u(!0);let R=[];r?.sections?.forEach(g=>{g?.questions?.forEach(l=>{i[l._id]&&R.push({questionId:l._id,markedSolution:i[l._id]?.isSaved?i[l._id]?.markedSolution:[],timeTaken:S[l._id]||i[l._id]?.timeTaken||0,markedForReview:i[l._id]?.markedForReview||!1})})});let M={submittedBy:I?"autoSubmit":"user",questionResponses:R,testMappingId:r?.testMappingId,type:T?"Pause":"Submit",testId:r?._id,...T?{lastVisitedQuestionId:E?._id}:{},...r?.type==="TEST"&&T&&S[r?._id]?{timeTaken:{[r?._id]:S[r?._id]}}:{}};return R.length||delete M.questionResponses,u(!1),n({payload:M,pause:T,autoSubmit:I}),M},currentSection:m,currentQuestion:E,...o.getState(),...e}},y=se;import{useEffect as H,useRef as oe}from"react";var ie=()=>{let{isSolution:t,handleSubmitTest:e}=y(),n=o(m=>m.test),r=o(m=>m.timer),u=o(m=>m.decrementTimer),i=o(m=>m.isHydrated),s=oe(null),c=()=>{n&&i&&u(n?._id),s.current=setTimeout(()=>{c()},1e3)};return H(()=>{if(i&&n&&typeof r[n?._id]=="number"&&r[n?._id]<=0){console.log(r[n?._id],"Timer","Test ID",n?._id),clearTimeout(s.current),e(!1,!0);return}},[r,n,i]),H(()=>{if(!(t||n?.type==="QUIZ"))return c(),()=>{s.current&&clearTimeout(s.current)}},[n,i]),{timer:r[n._id]||0}},ue=ie;import O,{useCallback as U}from"react";var V=(s=>(s.ATTEMPTED="ATTEMPTED",s.NOT_ATTEMPTED="NOT_ATTEMPTED",s.NOT_VISITED="NOT_VISITED",s.MARKED_FOR_REVIEW="MARKED_FOR_REVIEW",s.ATTEMPTED_AND_MARKED_FOR_REVIEW="ATTEMPTED_AND_MARKED_FOR_REVIEW",s.ACITVE_QUESTION="ACITVE_QUESTION",s))(V||{});var K={1:{label:"A"},2:{label:"B"},3:{label:"C"},4:{label:"D"}},ce=({includeAllSections:t}={})=>{let e=o(g=>g.test),n=o(g=>g.solutions),r=o(g=>g.isSolution),u=o(g=>g.currentSectionIndex),{currentQuestion:i,currentSection:s}=y(),c=o(g=>g.currentQuestionIndex),[m,E]=O.useState({MARKED_FOR_REVIEW:{count:0},ATTEMPTED:{count:0},ATTEMPTED_AND_MARKED_FOR_REVIEW:{count:0},NOT_ATTEMPTED:{count:0},NOT_VISITED:{count:0},ACITVE_QUESTION:{count:0}}),p=U((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?f?.markedSolution&&f?.markedSolution?.length>0&&f?.markedForReview?"ATTEMPTED_AND_MARKED_FOR_REVIEW":f?.markedSolution&&f?.markedSolution?.length>0?"ATTEMPTED":f?.markedForReview?"MARKED_FOR_REVIEW":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),S=U((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?.markedSolution?.length?T(f.markedSolution,a.solution)?"ATTEMPTED":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),x=U(()=>{let g={...m};Object.values(g).forEach(l=>l.count=0),t?e?.sections?.forEach((l,a)=>{l?.questions?.forEach((f,k)=>{let N=r||e.type==="QUIZ"?S(k,a):p(k,a);g[N].count+=1})}):e?.sections[u]?.questions.forEach((l,a)=>{let f=r||e.type==="QUIZ"?S(a,u):p(a,u);g[f].count+=1}),E(g)},[S,p,t,r,e,u,n]);O.useEffect(()=>{x()},[c,n,u]);function T(g,l){let a=g.slice().sort(),f=l.slice().sort();if(a.length!==f.length)return!1;for(let k=0;k<a.length;k++)if(a[k]!==f[k])return!1;return!0}let I=O.useMemo(()=>S(c,u)==="ATTEMPTED"?"correct":S(c,u)==="NOT_ATTEMPTED"?"incorrect":"skipped",[c,u,S]),R=O.useMemo(()=>{switch(I){case"correct":return e?.marksLevel==="TEST"?"+"+e.positiveMarks:"+"+s?.positiveMarks;case"incorrect":return e?.marksLevel==="TEST"?e.isNegativeMarkingEnabled?"-"+e.negativeMarks:0:s?.isNegativeMarkingEnabled?"-"+s?.negativeMarks:0;case"skipped":return 0}},[I]),M=O.useMemo(()=>{if(!i)return"";if(i.type==="INTEGER")return i.solution[0];if(i.type==="SINGLE"){let g=i.options.findIndex(l=>l._id===i.solution[0]);return K[g+1]?.label||""}return i.type==="MULTIPLE"?i.solution.map(l=>{let a=i.options.findIndex(f=>f._id===l);return K[a+1]?.label||""}).join(", "):""},[i]);return{getQuestionStatus:p,questionStatusMap:m,getAnsweredQuestionStatus:S,areArraysEqual:T,currentQuestionStatus:I,currentAnswerMarks:R,correctAnswer:M}},q=ce;import{useEffect as le,useRef as de}from"react";var me=()=>{let{currentQuestion:t,isSolution:e}=y(),n=o(m=>m.timer),r=o(m=>m.incrementTimer),u=o(m=>m.solutions),i=o(m=>m.isHydrated),s=de(null),c=()=>{t&&!u[t?._id]?.markedSolution?.length&&i&&r(t?._id),s.current=setTimeout(()=>{c()},1e3)};return le(()=>{if(!e)return c(),()=>{s.current&&clearTimeout(s.current)}},[t,u,i]),{timer:n[t._id]||0}},Te=me;import Se,{useCallback as D,useEffect as ge,useMemo as W,useState as fe}from"react";var Ee=()=>{let t=o(d=>d.test),e=o(d=>d.solutions),{currentQuestion:n,currentSection:r,currentQuestionAnswer:u}=y(),i=o(d=>d.currentQuestionIndex),s=o(d=>d.currentSectionIndex),c=o(d=>d.userSettings),m=o(d=>d.isSolution),E=o(d=>d.setQuestionCoordinates),p=o(d=>d.setSolution),S=o(d=>d.setCurrentAnswer),{getAnsweredQuestionStatus:x}=q(),T=Se.useMemo(()=>t?.type==="QUIZ"&&!!e[n?._id]?.markedSolution?.length,[t,e,n]),I=D(()=>{S({...u,markedSolution:[],isSaved:!1}),p(n?._id,{...u,markedSolution:[]})},[u,n,p]),R=D(d=>{if(!(m||T))if(u?.markedSolution?.includes(d)){let _=u.markedSolution.filter(b=>b!==d);if(_?.length===0)return I();S({...u,markedSolution:_,isSaved:!1});return}else if(n?.type==="SINGLE"){S({...u,markedSolution:[d],isSaved:!1});return}else{let _=u?.markedSolution?.length?u?.markedSolution:[];S({...u,markedSolution:[..._,d],isSaved:!1});return}},[m,T,n,u,S,I]),M=D(d=>{m||T||(S({...u,markedSolution:d?[d]:[],isSaved:!1}),d||I())},[m,T,u,I]),g=D(()=>{S({...u,markedForReview:!u?.markedForReview}),p(n._id,{...u,markedForReview:!u?.markedForReview})},[p,S,u,n]),[l,a]=fe([]);ge(()=>{if(c?.selectedFilter){let d=r?.questions?.map((_,b)=>{if(c?.selectedFilter===x(b,s))return b})?.filter(_=>_!==void 0);a(d),d?.length&&E(s,d[0]||0)}else a([])},[c,r]);let f=D(()=>{u?.isSaved||p(n?._id,{...u,isSaved:!0})},[u,n,p]),k=D(()=>{if(c?.selectedFilter){let b=l?.findIndex(F=>F===i);b>=0&&l[b+1]>=0&&E(s,l[b+1]);return}let d=r?.questions[i+1]?s:t?.sections[s+1]?s+1:s,_=r?.questions[i+1]?i+1:0;E(d,_)},[c?.selectedFilter,l,i,s,r,t,E]),N=D(()=>{if(c?.selectedFilter){let b=l?.findIndex(F=>F===i);b>=0&&l[b-1]>=0&&E(s,l[b-1]);return}let d=r?.questions[i-1]?s:t?.sections[s-1]?s-1:s,_=r?.questions[i-1]?i-1:t.sections[d]?.questions?.length-1;E(d,_)},[c?.selectedFilter,l,i,s,r,t,E]),Z=W(()=>{if(c?.selectedFilter){let d=l?.findIndex(_=>_===i);return!l[d+1]}return!t?.sections[s+1]&&!r?.questions[i+1]},[s,i,l,c?.selectedFilter,t,r]),B=W(()=>c?.selectedFilter?l?.findIndex(_=>_===i)<=0:s===0&&i===0,[s,i,l,c?.selectedFilter]);return{isQuizAnswer:T,handleClearResponse:I,handleSelectOption:R,handleIntegerInputChange:M,handleMarkForReview:g,handleNext:k,handlePrevious:N,handleSaveAnswer:f,isLastQuestion:Z,isFirstQuestion:B}},pe=Ee;import{useEffect as Ie,forwardRef as _e,useImperativeHandle as be}from"react";import z from"react";var Re=_e(({test:t,isSolution:e,submitTest:n,children:r},u)=>{let i=o(a=>a.setTest),s=o(a=>a.setIsHydrated),c=o(a=>a.isHydrated),m=o(a=>a.test),E=o(a=>a.solutions),p=o(a=>a.currentQuestionIndex),S=o(a=>a.currentSectionIndex),x=o(a=>a.currentQuestionAnswer),T=o(a=>a.userSettings),I=o(a=>a.submitting),R=o(a=>a.timer),M=o(a=>a.reset),g=z.useMemo(()=>({test:m,solutions:E,currentQuestionIndex:p,currentSectionIndex:S,userSettings:T,isSolution:e||!1,submitting:I,timer:R,isHydrated:c,currentQuestionAnswer:x}),[m,E,p,S,T,e,I,R,c,x]),l=()=>{console.log("[RESET]: Called"),M(),Q.removeItem(`${t?._id}-test-initiated`),Q.removeItem(`test-engine-v2-store-${t?._id}`),Q.removeItem("test-engine-v2-store")};return be(u,()=>({reset:l})),Ie(()=>{(async()=>{if(!(c&&t?._id===m?._id))try{if(!t?._id)return console.error("[TEST_ENGINE]: Test ID is missing. Cannot initialize store.");o.persist.setOptions({name:`test-engine-v2-store-${t?._id}`}),await o.persist.rehydrate(),Q.removeItem("test-engine-v2-store"),await Q.getItem(`${t?._id}-test-initiated`)?(console.log("[TEST_ENGINE]: Test already initiated, loading existing state"),i(t,!1)):(console.log("[TEST_ENGINE]: Test not initiated, initializing new state"),i(t,!0),e||Q.setItem(`${t?._id}-test-initiated`,"true")),s(!0)}catch(f){console.error("Error initializing test engine store:",f),s(!0)}})()},[t?._id,c,i,s]),!c||!m?null:z.createElement(h.Provider,{value:[g,n]},r)}),Ae=Re;export{V as AttemptStatus,Ae as TestEngineProvider,Te as useQuestionTimer,q as useQuestions,pe as useTestActions,y as useTestEngine,o as useTestEngineV2Store,ue as useTestTimer};
1
+ var G=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});import re,{useMemo as L}from"react";import{create as X}from"zustand";import{persist as ee,createJSONStorage as te}from"zustand/middleware";var $=()=>typeof globalThis>"u"||!globalThis.localStorage?null:(console.log("[STORAGE]: Using localStorage"),{setItem:(t,e)=>{globalThis.localStorage.setItem(t,e)},getItem:t=>globalThis.localStorage.getItem(t)??null,removeItem:t=>{globalThis.localStorage.removeItem(t)}}),Y=()=>{try{let t=G("@react-native-async-storage/async-storage").default;return console.log("[STORAGE]: Using AsyncStorage"),{setItem:async(e,n)=>{await t.setItem(e,n)},getItem:async e=>await t.getItem(e)??null,removeItem:async e=>{await t.removeItem(e)}}}catch{return console.log("[STORAGE]: AsyncStorage not available, trying MMKV Storage"),null}},j=()=>{try{let{MMKV:t}=G("react-native-mmkv"),e=new t;return console.log("[STORAGE]: Using MMKV Storage"),{setItem:(n,r)=>{e.set(n,r)},getItem:n=>e.getString(n)??null,removeItem:n=>{e.delete(n)}}}catch{return console.log("[STORAGE]: MMKV Storage not available, falling back to memory storage"),null}},P={},J=()=>({setItem:(t,e)=>{P[t]=e},getItem:t=>P[t]??null,removeItem:t=>{delete P[t]}}),Q=$()||Y()||j()||J();import ne from"react";var C={test:void 0,solutions:{},currentQuestionIndex:0,currentSectionIndex:0,currentQuestionAnswer:{},userSettings:{},isSolution:!1,submitting:!1,timer:{},isHydrated:!1},h=ne.createContext([C,()=>{}]);h.displayName="TestEngineContext";var o=X()(ee(t=>({...C,setQuestionCoordinates:(e,n)=>t(r=>{let s=r.test?.sections[e]?.questions[n]?._id,c=null;return r.isSolution||(r.solutions[s]?c={...r.solutions,[s]:{...r.solutions[s],timeTaken:r.timer[s]||0}}:c={...r.solutions,[s]:{}}),{currentSectionIndex:e,currentQuestionIndex:n,currentQuestionAnswer:c?.[s]||{},...c&&{solutions:c}}}),setTest:(e,n)=>t(()=>{if(!n)return{test:e};let r={},u={},i=0,s=0;e?.sections?.forEach((E,p)=>{E?.questions?.forEach((T,x)=>{T?.questionResponse&&(r={...r,[T?._id]:{markedSolution:T?.questionResponse?.markedSolution||[],markedForReview:T?.questionResponse?.markedForReview||!1,timeTaken:T?.questionResponse?.timeTaken||0,isSaved:!0}},u={...u,[T?._id]:T?.questionResponse?.timeTaken||0}),e?.status==="Paused"&&T._id===e?.lastVisitedQuestionId&&(i=p,s=x)})}),e?.type==="TEST"&&(u[e?._id]=e?.timeTaken&&e?.timeTaken[e?._id]>0?+e?.timeTaken[e?._id]:+e?.duration);let c=e?.sections[i]?.questions[s]?._id,m=r[c]||{};return r[c]||(r[c]={}),{test:e,solutions:r,timer:u,currentSectionIndex:i,currentQuestionIndex:s,currentQuestionAnswer:m}}),setSolution:(e,n)=>t(r=>({solutions:{...r.solutions,[e]:{...r.solutions[e],...n}},currentQuestionAnswer:{...r.solutions[e],...n}})),incrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)+1}})),decrementTimer:e=>t(n=>({timer:{...n.timer,[e]:(n.timer[e]||0)-1}})),setTimer:(e,n)=>t(r=>({timer:{...r.timer,[e]:n}})),setCurrentAnswer:e=>t({currentQuestionAnswer:e}),setUserSettings:e=>t({userSettings:e}),setTestSubmitting:e=>t({submitting:e}),reset:()=>t(C),setIsHydrated:e=>t({isHydrated:e})}),{name:"test-engine-v2-store",storage:te(()=>Q)}));var se=()=>{let t=re.useContext(h);if(t===void 0)throw new Error("useTestEngineV2 must be use within TestEngineProvider");let[e,n]=t;if(!e.test)throw new Error("Please provide test data to useTestEngineV2");let r=o(S=>S.test),u=o(S=>S.setTestSubmitting),i=o(S=>S.solutions),s=o(S=>S.currentQuestionIndex),c=o(S=>S.currentSectionIndex),m=L(()=>r?.sections[c],[r,c]),E=L(()=>m?.questions[s],[m,s]),p=o(S=>S.setTimer),T=o(S=>S.timer);return{handleSubmitTest:(S=!1,I=!1)=>{u(!0);let R=[];r?.sections?.forEach(g=>{g?.questions?.forEach(l=>{i[l._id]&&R.push({questionId:l._id,markedSolution:i[l._id]?.isSaved?i[l._id]?.markedSolution:[],timeTaken:T[l._id]||i[l._id]?.timeTaken||0,markedForReview:i[l._id]?.markedForReview||!1})})});let M={submittedBy:I?"autoSubmit":"user",questionResponses:R,testMappingId:r?.testMappingId,type:S?"Pause":"Submit",testId:r?._id,...S?{lastVisitedQuestionId:E?._id}:{},...r?.type==="TEST"&&S&&T[r?._id]?{timeTaken:{[r?._id]:T[r?._id]}}:{}};return R.length||delete M.questionResponses,u(!1),n({payload:M,pause:S,autoSubmit:I}),M},currentSection:m,currentQuestion:E,...o.getState(),...e}},y=se;import{useEffect as H,useRef as oe}from"react";var ie=()=>{let{isSolution:t,handleSubmitTest:e}=y(),n=o(m=>m.test),r=o(m=>m.timer),u=o(m=>m.decrementTimer),i=o(m=>m.isHydrated),s=oe(null),c=()=>{n&&i&&u(n?._id),s.current=setTimeout(()=>{c()},1e3)};return H(()=>{if(i&&n&&typeof r[n?._id]=="number"&&r[n?._id]<=0){console.log(r[n?._id],"Timer","Test ID",n?._id),clearTimeout(s.current),e(!1,!0);return}},[r,n,i]),H(()=>{if(!(t||n?.type==="QUIZ"))return c(),()=>{s.current&&clearTimeout(s.current)}},[n,i]),{timer:r[n._id]||0}},ue=ie;import O,{useCallback as U}from"react";var V=(s=>(s.ATTEMPTED="ATTEMPTED",s.NOT_ATTEMPTED="NOT_ATTEMPTED",s.NOT_VISITED="NOT_VISITED",s.MARKED_FOR_REVIEW="MARKED_FOR_REVIEW",s.ATTEMPTED_AND_MARKED_FOR_REVIEW="ATTEMPTED_AND_MARKED_FOR_REVIEW",s.ACITVE_QUESTION="ACITVE_QUESTION",s))(V||{});var K={1:{label:"A"},2:{label:"B"},3:{label:"C"},4:{label:"D"}},ce=({includeAllSections:t}={})=>{let e=o(g=>g.test),n=o(g=>g.solutions),r=o(g=>g.isSolution),u=o(g=>g.currentSectionIndex),{currentQuestion:i,currentSection:s}=y(),c=o(g=>g.currentQuestionIndex),[m,E]=O.useState({MARKED_FOR_REVIEW:{count:0},ATTEMPTED:{count:0},ATTEMPTED_AND_MARKED_FOR_REVIEW:{count:0},NOT_ATTEMPTED:{count:0},NOT_VISITED:{count:0},ACITVE_QUESTION:{count:0}}),p=U((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?f?.markedSolution&&f?.markedSolution?.length>0&&f?.markedForReview?"ATTEMPTED_AND_MARKED_FOR_REVIEW":f?.markedSolution&&f?.markedSolution?.length>0?"ATTEMPTED":f?.markedForReview?"MARKED_FOR_REVIEW":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),T=U((g,l)=>{let a=e?.sections[l]?.questions[g],f=n[a?._id];return f?.markedSolution?.length?S(f.markedSolution,a.solution)?"ATTEMPTED":"NOT_ATTEMPTED":"NOT_VISITED"},[n,e]),x=U(()=>{let g={...m};Object.values(g).forEach(l=>l.count=0),t?e?.sections?.forEach((l,a)=>{l?.questions?.forEach((f,k)=>{let N=r||e.type==="QUIZ"?T(k,a):p(k,a);g[N].count+=1})}):e?.sections[u]?.questions.forEach((l,a)=>{let f=r||e.type==="QUIZ"?T(a,u):p(a,u);g[f].count+=1}),E(g)},[T,p,t,r,e,u,n]);O.useEffect(()=>{x()},[c,n,u]);function S(g,l){let a=g.slice().sort(),f=l.slice().sort();if(a.length!==f.length)return!1;for(let k=0;k<a.length;k++)if(a[k]!==f[k])return!1;return!0}let I=O.useMemo(()=>T(c,u)==="ATTEMPTED"?"correct":T(c,u)==="NOT_ATTEMPTED"?"incorrect":"skipped",[c,u,T]),R=O.useMemo(()=>{switch(I){case"correct":return e?.marksLevel==="TEST"?"+"+e.positiveMarks:"+"+s?.positiveMarks;case"incorrect":return e?.marksLevel==="TEST"?e.isNegativeMarkingEnabled?"-"+e.negativeMarks:0:s?.isNegativeMarkingEnabled?"-"+s?.negativeMarks:0;case"skipped":return 0}},[I]),M=O.useMemo(()=>{if(!i)return"";if(i.type==="INTEGER")return i.solution[0];if(i.type==="SINGLE"){let g=i.options.findIndex(l=>l._id===i.solution[0]);return K[g+1]?.label||""}return i.type==="MULTIPLE"?i.solution.map(l=>{let a=i.options.findIndex(f=>f._id===l);return K[a+1]?.label||""}).join(", "):""},[i]);return{getQuestionStatus:p,questionStatusMap:m,getAnsweredQuestionStatus:T,areArraysEqual:S,currentQuestionStatus:I,currentAnswerMarks:R,correctAnswer:M}},q=ce;import{useEffect as le,useRef as de}from"react";var me=()=>{let{currentQuestion:t,isSolution:e}=y(),n=o(m=>m.timer),r=o(m=>m.incrementTimer),u=o(m=>m.solutions),i=o(m=>m.isHydrated),s=de(null),c=()=>{t&&!u[t?._id]?.markedSolution?.length&&i&&r(t?._id),s.current=setTimeout(()=>{c()},1e3)};return le(()=>{if(!e)return c(),()=>{s.current&&clearTimeout(s.current)}},[t,u,i]),{timer:n[t._id]||0}},Te=me;import Se,{useCallback as D,useEffect as ge,useMemo as W,useState as fe}from"react";var Ee=()=>{let t=o(d=>d.test),e=o(d=>d.solutions),{currentQuestion:n,currentSection:r,currentQuestionAnswer:u}=y(),i=o(d=>d.currentQuestionIndex),s=o(d=>d.currentSectionIndex),c=o(d=>d.userSettings),m=o(d=>d.isSolution),E=o(d=>d.setQuestionCoordinates),p=o(d=>d.setSolution),T=o(d=>d.setCurrentAnswer),{getAnsweredQuestionStatus:x}=q(),S=Se.useMemo(()=>t?.type==="QUIZ"&&!!e[n?._id]?.markedSolution?.length,[t,e,n]),I=D(()=>{T({...u,markedSolution:[],isSaved:!1}),p(n?._id,{...u,markedSolution:[]})},[u,n,p]),R=D(d=>{if(!(m||S))if(u?.markedSolution?.includes(d)){let _=u.markedSolution.filter(b=>b!==d);if(_?.length===0)return I();T({...u,markedSolution:_,isSaved:!1});return}else if(n?.type==="SINGLE"){T({...u,markedSolution:[d],isSaved:!1});return}else{let _=u?.markedSolution?.length?u?.markedSolution:[];T({...u,markedSolution:[..._,d],isSaved:!1});return}},[m,S,n,u,T,I]),M=D(d=>{m||S||(T({...u,markedSolution:d?[d]:[],isSaved:!1}),d||I())},[m,S,u,I]),g=D(()=>{T({...u,markedForReview:!u?.markedForReview}),p(n._id,{...u,markedForReview:!u?.markedForReview})},[p,T,u,n]),[l,a]=fe([]);ge(()=>{if(c?.selectedFilter){let d=r?.questions?.map((_,b)=>{if(c?.selectedFilter===x(b,s))return b})?.filter(_=>_!==void 0);a(d),d?.length&&E(s,d[0]||0)}else a([])},[c,r]);let f=D(()=>{u?.isSaved||p(n?._id,{...u,isSaved:!0})},[u,n,p]),k=D(()=>{if(c?.selectedFilter){let b=l?.findIndex(F=>F===i);b>=0&&l[b+1]>=0&&E(s,l[b+1]);return}let d=r?.questions[i+1]?s:t?.sections[s+1]?s+1:s,_=r?.questions[i+1]?i+1:0;E(d,_)},[c?.selectedFilter,l,i,s,r,t,E]),N=D(()=>{if(c?.selectedFilter){let b=l?.findIndex(F=>F===i);b>=0&&l[b-1]>=0&&E(s,l[b-1]);return}let d=r?.questions[i-1]?s:t?.sections[s-1]?s-1:s,_=r?.questions[i-1]?i-1:t.sections[d]?.questions?.length-1;E(d,_)},[c?.selectedFilter,l,i,s,r,t,E]),Z=W(()=>{if(c?.selectedFilter){let d=l?.findIndex(_=>_===i);return!l[d+1]}return!t?.sections[s+1]&&!r?.questions[i+1]},[s,i,l,c?.selectedFilter,t,r]),B=W(()=>c?.selectedFilter?l?.findIndex(_=>_===i)<=0:s===0&&i===0,[s,i,l,c?.selectedFilter]);return{isQuizAnswer:S,handleClearResponse:I,handleSelectOption:R,handleIntegerInputChange:M,handleMarkForReview:g,handleNext:k,handlePrevious:N,handleSaveAnswer:f,isLastQuestion:Z,isFirstQuestion:B}},pe=Ee;import{useEffect as Ie,forwardRef as _e,useImperativeHandle as be}from"react";import z from"react";var Re=_e(({test:t,isSolution:e,submitTest:n,children:r},u)=>{let i=o(a=>a.setTest),s=o(a=>a.setIsHydrated),c=o(a=>a.isHydrated),m=o(a=>a.test),E=o(a=>a.solutions),p=o(a=>a.currentQuestionIndex),T=o(a=>a.currentSectionIndex),x=o(a=>a.currentQuestionAnswer),S=o(a=>a.userSettings),I=o(a=>a.submitting),R=o(a=>a.timer),M=o(a=>a.reset),g=z.useMemo(()=>({test:m,solutions:E,currentQuestionIndex:p,currentSectionIndex:T,userSettings:S,isSolution:e||!1,submitting:I,timer:R,isHydrated:c,currentQuestionAnswer:x}),[m,E,p,T,S,e,I,R,c,x]),l=()=>{console.log("[RESET]: Called"),M(),Q.removeItem(`${t?._id}-test-initiated`),Q.removeItem(`test-engine-v2-store-${t?._id}`),Q.removeItem("test-engine-v2-store")};return be(u,()=>({reset:l})),Ie(()=>{(async()=>{if(!(c&&t?._id===m?._id))try{if(!t?._id)return console.error("[TEST_ENGINE]: Test ID is missing. Cannot initialize store.");o.persist.setOptions({name:`test-engine-v2-store-${t?._id}`}),await o.persist.rehydrate(),Q.removeItem("test-engine-v2-store"),await Q.getItem(`${t?._id}-test-initiated`)?(console.log("[TEST_ENGINE]: Test already initiated, loading existing state"),i(t,!1)):(console.log("[TEST_ENGINE]: Test not initiated, initializing new state"),i(t,!0),e||Q.setItem(`${t?._id}-test-initiated`,"true")),s(!0)}catch(f){console.error("Error initializing test engine store:",f),s(!0)}})()},[t?._id,c,i,s]),!c||!m?null:z.createElement(h.Provider,{value:[g,n]},r)}),Ae=Re;export{V as AttemptStatus,Ae as TestEngineProvider,Te as useQuestionTimer,q as useQuestions,pe as useTestActions,y as useTestEngine,o as useTestEngineV2Store,ue as useTestTimer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testforce-engine",
3
- "version": "1.0.0-rc-1",
3
+ "version": "1.0.0-rc-2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",