@lookit/lookit-initjspsych
Version:
This package overloads jsPsych's init function.
197 lines (189 loc) • 6.45 kB
JavaScript
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