UNPKG

@lookit/lookit-initjspsych

Version:

This package overloads jsPsych's init function.

197 lines (189 loc) 6.45 kB
var chsInitJsPsych = (function (jspsychModule, Api, chsTemplates) { 'use strict'; function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var jspsychModule__namespace = /*#__PURE__*/_interopNamespaceDefault(jspsychModule); class UndefinedTypeError extends Error { constructor(object) { super( `A trial object in the timeline has an undefined type. Maybe the type name is misspelled, or the plugin you want to use is not supported. Object: ${JSON.stringify(object)}.` ); } } class UndefinedTimelineError extends Error { constructor(el) { super( `An element in the timeline is not structured correctly or is missing required information. It may be a timeline node with a timeline array that is the wrong type or missing/undefined, or a trial object with a missing type. Element: ${JSON.stringify(el)}` ); } } class NoJsPsychInstanceError extends Error { constructor() { super("No jsPsych instance available for on_data_update."); this.name = "NoJsPsychInstanceError"; } } const on_data_update = (jsPsychInstance, responseUuid, userFunc) => { return async function(data) { if (!jsPsychInstance || !jsPsychInstance.data) { throw new NoJsPsychInstanceError(); } await Api.updateResponse(responseUuid, { exp_data: jsPsychInstance.data.get().values() }); await Api.finish(); if (typeof userFunc === "function") { userFunc(data); } }; }; const on_finish = (jsPsychInstance, responseUuid, userFunc) => { return async function(data) { if (!jsPsychInstance || !jsPsychInstance.getDisplayElement) { throw new NoJsPsychInstanceError(); } jsPsychInstance.getDisplayElement().innerHTML = chsTemplates.loadingAnimation(); const exp_data = data.values(); const { exit_url } = window.chs.study.attributes; if (typeof userFunc === "function") { userFunc(data); } try { await Api.updateResponse(responseUuid, { exp_data, completed: true }); await Api.finish(); if (window.chs.pendingUploads) { await Promise.allSettled( window.chs.pendingUploads.map((u) => u.promise) ); } if (exit_url) { let url; try { url = new URL(exit_url); } catch { try { url = new URL(`https://${exit_url}`); } catch { url = new URL(window.location.origin); } } const hash_child_id = window.chs.response.attributes.hash_child_id; if (hash_child_id) url.searchParams.set("child", hash_child_id); url.searchParams.set("response", window.chs.response.id); window.location.replace(url.toString()); } } catch (err) { console.error( "Error while finishing the experiment and saving data/video: ", err ); } }; }; const isTimelineNodeArray = (description) => { return (Boolean(description.timeline) || Array.isArray(description)) && !description.type; }; const isTrialWithType = (description) => { return typeof description === "object" && !isTimelineNodeArray( description ); }; const lookitInitJsPsych = (responseUuid) => { return function(opts) { const { on_data_update: userOnDataUpdate, on_finish: userOnFinish, ...otherOpts } = opts || {}; let jsPsychInstance = null; const onDataUpdate = (...args) => { return on_data_update( jsPsychInstance, responseUuid, userOnDataUpdate )(...args); }; const onFinish = (...args) => { return on_finish(jsPsychInstance, responseUuid, userOnFinish)(...args); }; const jsPsych = jspsychModule__namespace.initJsPsych({ ...otherOpts, on_data_update: onDataUpdate, on_finish: onFinish }); jsPsychInstance = jsPsych; const origJsPsychRun = jsPsych.run; const lookitJsPsych = jsPsych; lookitJsPsych.run = async function(timeline) { const handleTrialTypes = (timeline2, callback) => { return timeline2.map( (el) => { if (isTimelineNodeArray( el )) { if (Array.isArray(el)) { return handleTrialTypes(el, callback); } else if ("timeline" in el && Array.isArray(el.timeline)) { const chsTimelineDescription = { ...el, timeline: handleTrialTypes( el.timeline, callback ) }; return chsTimelineDescription; } else { throw new UndefinedTimelineError(el); } } else if (isTrialWithType( el )) { if (el !== null && "type" in el && el.type !== null && el.type !== void 0) { const chsTrialDescription = el; callback(chsTrialDescription); return chsTrialDescription; } else { throw new UndefinedTypeError(el); } } else { throw new UndefinedTimelineError(el); } } ); }; const modifiedTimeline = handleTrialTypes( timeline, (trial) => { if ("type" in trial) { if (trial.type?.chsData) { trial.data = { ...trial.data, ...trial.type.chsData() }; } } } ); return await origJsPsychRun(modifiedTimeline); }; return lookitJsPsych; }; }; return lookitInitJsPsych; })(jsPsychModule, chsData, chsTemplates); //# sourceMappingURL=https://unpkg.com/@lookit/lookit-initjspsych@3.1.0/dist/index.browser.js.map