Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions packages/jspsych/src/ExtensionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ import { JsPsychExtension, JsPsychExtensionInfo } from "./modules/extensions";
import { TrialExtensionsConfiguration } from "./timeline";

export type GlobalExtensionsConfiguration = Array<{
type: Class<JsPsychExtension>;
type: Class<JsPsychExtension> & { info: JsPsychExtensionInfo };
params?: Record<string, any>;
}>;

export interface ExtensionManagerDependencies {
/**
* Given an extension class, create a new instance of it and return it.
*/
instantiateExtension(extensionClass: Class<JsPsychExtension>): JsPsychExtension;
instantiateExtension(
extensionClass: Class<JsPsychExtension> & { info: JsPsychExtensionInfo }
): JsPsychExtension;
}

export class ExtensionManager {
private static getExtensionNameByClass(extensionClass: Class<JsPsychExtension>) {
return (extensionClass["info"] as JsPsychExtensionInfo).name;
private static getExtensionNameByClass(
extensionClass: Class<JsPsychExtension> & { info: JsPsychExtensionInfo }
) {
return extensionClass.info.name;
}

public readonly extensions: Record<string, JsPsychExtension>;
Expand All @@ -34,7 +38,9 @@ export class ExtensionManager {
);
}

private getExtensionInstanceByClass(extensionClass: Class<JsPsychExtension>) {
private getExtensionInstanceByClass(
extensionClass: Class<JsPsychExtension> & { info: JsPsychExtensionInfo }
) {
return this.extensions[ExtensionManager.getExtensionNameByClass(extensionClass)];
}

Expand All @@ -43,7 +49,7 @@ export class ExtensionManager {
this.extensionsConfiguration.map(({ type, params = {} }) => {
this.getExtensionInstanceByClass(type).initialize(params);

const extensionInfo = type["info"] as JsPsychExtensionInfo;
const extensionInfo = type.info;

if (!("version" in extensionInfo) && !("data" in extensionInfo)) {
console.warn(
Expand Down Expand Up @@ -88,8 +94,10 @@ export class ExtensionManager {

const extensionInfos = trialExtensionsConfiguration.length
? {
extension_type: trialExtensionsConfiguration.map(({ type }) => type["info"].name),
extension_version: trialExtensionsConfiguration.map(({ type }) => type["info"].version),
extension_type: trialExtensionsConfiguration.map(({ type }) => type.info.name),
extension_version: trialExtensionsConfiguration.map(
({ type }) => type.info.version ?? ""
),
}
: {};

Expand Down
2 changes: 2 additions & 0 deletions packages/jspsych/src/modules/extensions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Class } from "type-fest";

import { ParameterInfos } from "./plugins";

export interface JsPsychExtensionInfo {
Expand Down
10 changes: 8 additions & 2 deletions packages/jspsych/src/timeline/Trial.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,11 @@ describe("Trial", () => {
it("invokes extension callbacks and includes extension results", async () => {
dependencies.runOnFinishExtensionCallbacks.mockResolvedValue({ extension: "result" });

const mockExtensionClass = jest.fn() as any;
mockExtensionClass.info = { name: "test-extension", version: "1.0.0" };

const extensionsConfig: TrialExtensionsConfiguration = [
{ type: jest.fn(), params: { my: "option" } },
{ type: mockExtensionClass, params: { my: "option" } },
];

const trial = createTrial({
Expand Down Expand Up @@ -654,9 +657,12 @@ describe("Trial", () => {
);
}

const mockExtensionClass2 = jest.fn() as any;
mockExtensionClass2.info = { name: "test-extension-2", version: "1.0.0" };

const trial = createTrial({
type: TestPlugin,
extensions: [{ type: jest.fn(), params: { my: "option" } }],
extensions: [{ type: mockExtensionClass2, params: { my: "option" } }],
on_start: createInvocationOrderCallback("on_start"),
on_load: createInvocationOrderCallback("on_load"),
on_finish: createInvocationOrderCallback("on_finish"),
Expand Down
4 changes: 2 additions & 2 deletions packages/jspsych/src/timeline/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Class } from "type-fest";

import { JsPsychExtension } from "../modules/extensions";
import { JsPsychExtension, JsPsychExtensionInfo } from "../modules/extensions";
import { JsPsychPlugin, PluginInfo } from "../modules/plugins";
import { Trial } from "./Trial";
import { PromiseWrapper } from "./util";
Expand All @@ -12,7 +12,7 @@ export class TimelineVariable {
export type Parameter<T> = T | (() => T) | TimelineVariable;

export type TrialExtensionsConfiguration = Array<{
type: Class<JsPsychExtension>;
type: Class<JsPsychExtension> & { info: JsPsychExtensionInfo };
params?: Record<string, any>;
}>;

Expand Down