jspsych 7.1.1 → 7.2.1

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.
@@ -36,6 +36,7 @@ export declare class DataCollection {
36
36
  addToLast(properties: any): this;
37
37
  filter(filters: any): DataCollection;
38
38
  filterCustom(fn: any): DataCollection;
39
+ filterColumns(columns: Array<string>): DataCollection;
39
40
  select(column: any): DataColumn;
40
41
  ignore(columns: any): DataCollection;
41
42
  uniqueNames(): any[];
@@ -113,6 +113,13 @@ export declare const universalPluginParameters: {
113
113
  readonly pretty_name: "Custom CSS classes";
114
114
  readonly default: any;
115
115
  };
116
+ /**
117
+ * Options to control simulation mode for the trial.
118
+ */
119
+ readonly simulation_options: {
120
+ readonly type: ParameterType.COMPLEX;
121
+ readonly default: any;
122
+ };
116
123
  };
117
124
  export declare type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;
118
125
  export interface PluginInfo {
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Uses the `seedrandom` package to replace Math.random() with a seedable PRNG.
3
+ *
4
+ * @param seed An optional seed. If none is given, a random seed will be generated.
5
+ * @returns The seed value.
6
+ */
7
+ export declare function setSeed(seed?: string): string;
1
8
  export declare function repeat(array: any, repetitions: any, unpack?: boolean): any;
2
9
  export declare function shuffle(array: Array<any>): any[];
3
10
  export declare function shuffleNoRepeats(arr: Array<any>, equalityTest: (a: any, b: any) => boolean): any[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspsych",
3
- "version": "7.1.1",
3
+ "version": "7.2.1",
4
4
  "description": "Behavioral experiments in a browser",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -23,8 +23,10 @@
23
23
  "test": "jest",
24
24
  "test:watch": "npm test -- --watch",
25
25
  "tsc": "tsc",
26
- "build": "rollup --config",
27
- "build:watch": "npm run build -- --watch",
26
+ "build:js": "rollup --config",
27
+ "build:styles": "webpack-cli",
28
+ "build": "run-p build:js build:styles",
29
+ "build:watch": "run-p \"build:js -- --watch\" \"build:styles watch\"",
28
30
  "prepack": "cp ../../README.md ."
29
31
  },
30
32
  "repository": {
@@ -40,11 +42,22 @@
40
42
  "homepage": "https://www.jspsych.org",
41
43
  "dependencies": {
42
44
  "auto-bind": "^4.0.0",
43
- "random-words": "^1.1.1"
45
+ "random-words": "^1.1.1",
46
+ "seedrandom": "^3.0.5"
44
47
  },
45
48
  "devDependencies": {
46
- "@jspsych/config": "^1.1.0",
47
- "@jspsych/test-utils": "^1.1.1",
48
- "@types/dom-mediacapture-record": "^1.0.11"
49
+ "@fontsource/open-sans": "4.5.3",
50
+ "@jspsych/config": "^1.2.0",
51
+ "@types/dom-mediacapture-record": "^1.0.11",
52
+ "base64-inline-loader": "^2.0.1",
53
+ "css-loader": "^6.6.0",
54
+ "mini-css-extract-plugin": "^2.5.3",
55
+ "npm-run-all": "^4.1.5",
56
+ "sass": "^1.43.5",
57
+ "sass-loader": "^12.4.0",
58
+ "webpack": "^5.68.0",
59
+ "webpack-cli": "^4.9.2",
60
+ "webpack-remove-empty-scripts": "^0.7.2",
61
+ "replace-in-file-webpack-plugin": "^1.0.6"
49
62
  }
50
63
  }
package/src/JsPsych.ts CHANGED
@@ -302,7 +302,9 @@ export class JsPsych {
302
302
  this.internal.call_immediate = false;
303
303
 
304
304
  // wait for iti
305
- if (
305
+ if (this.simulation_mode === "data-only") {
306
+ this.nextTrial();
307
+ } else if (
306
308
  typeof current_trial.post_trial_gap === null ||
307
309
  typeof current_trial.post_trial_gap === "undefined"
308
310
  ) {
package/src/index.scss ADDED
@@ -0,0 +1,209 @@
1
+ /*
2
+ * CSS for jsPsych experiments.
3
+ *
4
+ * This stylesheet provides minimal styling to make jsPsych
5
+ * experiments look polished without any additional styles.
6
+ */
7
+
8
+ @import "@fontsource/open-sans/400-italic.css";
9
+ @import "@fontsource/open-sans/700-italic.css";
10
+ @import "@fontsource/open-sans/400.css";
11
+ @import "@fontsource/open-sans/700.css";
12
+
13
+ /* Container holding jsPsych content */
14
+
15
+ .jspsych-display-element {
16
+ display: flex;
17
+ flex-direction: column;
18
+ overflow-y: auto;
19
+ }
20
+
21
+ .jspsych-display-element:focus {
22
+ outline: none;
23
+ }
24
+
25
+ .jspsych-content-wrapper {
26
+ display: flex;
27
+ margin: auto;
28
+ flex: 1 1 100%;
29
+ width: 100%;
30
+ }
31
+
32
+ .jspsych-content {
33
+ max-width: 95%; /* this is mainly an IE 10-11 fix */
34
+ text-align: center;
35
+ margin: auto; /* this is for overflowing content */
36
+ }
37
+
38
+ .jspsych-top {
39
+ align-items: flex-start;
40
+ }
41
+
42
+ .jspsych-middle {
43
+ align-items: center;
44
+ }
45
+
46
+ /* fonts and type */
47
+
48
+ .jspsych-display-element {
49
+ font-family: "Open Sans", "Arial", sans-serif;
50
+ font-size: 18px;
51
+ line-height: 1.6em;
52
+ }
53
+
54
+ /* Form elements like input fields and buttons */
55
+
56
+ .jspsych-display-element input[type="text"] {
57
+ font-family: "Open Sans", "Arial", sans-serif;
58
+ font-size: 14px;
59
+ }
60
+
61
+ /* borrowing Bootstrap style for btn elements, but combining styles a bit */
62
+ .jspsych-btn {
63
+ display: inline-block;
64
+ padding: 6px 12px;
65
+ margin: 0px;
66
+ font-size: 14px;
67
+ font-weight: 400;
68
+ font-family: "Open Sans", "Arial", sans-serif;
69
+ cursor: pointer;
70
+ line-height: 1.4;
71
+ text-align: center;
72
+ white-space: nowrap;
73
+ vertical-align: middle;
74
+ background-image: none;
75
+ border: 1px solid transparent;
76
+ border-radius: 4px;
77
+ color: #333;
78
+ background-color: #fff;
79
+ border-color: #ccc;
80
+ }
81
+
82
+ /* only apply the hover style on devices with a mouse/pointer that can hover - issue #977 */
83
+ @media (hover: hover) {
84
+ .jspsych-btn:hover {
85
+ background-color: #ddd;
86
+ border-color: #aaa;
87
+ }
88
+ }
89
+
90
+ .jspsych-btn:active {
91
+ background-color: #ddd;
92
+ border-color: #000000;
93
+ }
94
+
95
+ .jspsych-btn:disabled {
96
+ background-color: #eee;
97
+ color: #aaa;
98
+ border-color: #ccc;
99
+ cursor: not-allowed;
100
+ }
101
+
102
+ /* custom style for input[type="range] (slider) to improve alignment between positions and labels */
103
+
104
+ .jspsych-slider {
105
+ appearance: none;
106
+ -webkit-appearance: none;
107
+ -moz-appearance: none;
108
+ width: 100%;
109
+ background: transparent;
110
+ }
111
+ .jspsych-slider:focus {
112
+ outline: none;
113
+ }
114
+ /* track */
115
+ .jspsych-slider::-webkit-slider-runnable-track {
116
+ appearance: none;
117
+ -webkit-appearance: none;
118
+ width: 100%;
119
+ height: 8px;
120
+ cursor: pointer;
121
+ background: #eee;
122
+ box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
123
+ border-radius: 2px;
124
+ border: 1px solid #aaa;
125
+ }
126
+ .jspsych-slider::-moz-range-track {
127
+ appearance: none;
128
+ width: 100%;
129
+ height: 8px;
130
+ cursor: pointer;
131
+ background: #eee;
132
+ box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
133
+ border-radius: 2px;
134
+ border: 1px solid #aaa;
135
+ }
136
+ .jspsych-slider::-ms-track {
137
+ appearance: none;
138
+ width: 99%;
139
+ height: 14px;
140
+ cursor: pointer;
141
+ background: #eee;
142
+ box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
143
+ border-radius: 2px;
144
+ border: 1px solid #aaa;
145
+ }
146
+ /* thumb */
147
+ .jspsych-slider::-webkit-slider-thumb {
148
+ border: 1px solid #666;
149
+ height: 24px;
150
+ width: 15px;
151
+ border-radius: 5px;
152
+ background: #ffffff;
153
+ cursor: pointer;
154
+ -webkit-appearance: none;
155
+ margin-top: -9px;
156
+ }
157
+ .jspsych-slider::-moz-range-thumb {
158
+ border: 1px solid #666;
159
+ height: 24px;
160
+ width: 15px;
161
+ border-radius: 5px;
162
+ background: #ffffff;
163
+ cursor: pointer;
164
+ }
165
+ .jspsych-slider::-ms-thumb {
166
+ border: 1px solid #666;
167
+ height: 20px;
168
+ width: 15px;
169
+ border-radius: 5px;
170
+ background: #ffffff;
171
+ cursor: pointer;
172
+ margin-top: -2px;
173
+ }
174
+
175
+ /* jsPsych progress bar */
176
+
177
+ #jspsych-progressbar-container {
178
+ color: #555;
179
+ border-bottom: 1px solid #dedede;
180
+ background-color: #f9f9f9;
181
+ margin-bottom: 1em;
182
+ text-align: center;
183
+ padding: 8px 0px;
184
+ width: 100%;
185
+ line-height: 1em;
186
+ }
187
+ #jspsych-progressbar-container span {
188
+ font-size: 14px;
189
+ padding-right: 14px;
190
+ }
191
+ #jspsych-progressbar-outer {
192
+ background-color: #eee;
193
+ width: 50%;
194
+ margin: auto;
195
+ height: 14px;
196
+ display: inline-block;
197
+ vertical-align: middle;
198
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
199
+ }
200
+ #jspsych-progressbar-inner {
201
+ background-color: #aaa;
202
+ width: 0%;
203
+ height: 100%;
204
+ }
205
+
206
+ /* Control appearance of jsPsych.data.displayData() */
207
+ #jspsych-data-display {
208
+ text-align: left;
209
+ }
@@ -134,6 +134,14 @@ export class DataCollection {
134
134
  return new DataCollection(this.trials.filter(fn));
135
135
  }
136
136
 
137
+ filterColumns(columns: Array<string>) {
138
+ return new DataCollection(
139
+ this.trials.map((trial) =>
140
+ Object.fromEntries(columns.filter((key) => key in trial).map((key) => [key, trial[key]]))
141
+ )
142
+ );
143
+ }
144
+
137
145
  select(column) {
138
146
  const values = [];
139
147
  for (const trial of this.trials) {
@@ -133,6 +133,13 @@ export const universalPluginParameters = <const>{
133
133
  pretty_name: "Custom CSS classes",
134
134
  default: null,
135
135
  },
136
+ /**
137
+ * Options to control simulation mode for the trial.
138
+ */
139
+ simulation_options: {
140
+ type: ParameterType.COMPLEX,
141
+ default: null,
142
+ },
136
143
  };
137
144
 
138
145
  export type UniversalPluginParameters = InferredParameters<typeof universalPluginParameters>;
@@ -1,4 +1,16 @@
1
1
  import rw from "random-words";
2
+ import seedrandom from "seedrandom/lib/alea";
3
+
4
+ /**
5
+ * Uses the `seedrandom` package to replace Math.random() with a seedable PRNG.
6
+ *
7
+ * @param seed An optional seed. If none is given, a random seed will be generated.
8
+ * @returns The seed value.
9
+ */
10
+ export function setSeed(seed: string = Math.random().toString()) {
11
+ Math.random = seedrandom(seed);
12
+ return seed;
13
+ }
2
14
 
3
15
  export function repeat(array, repetitions, unpack = false) {
4
16
  const arr_isArray = Array.isArray(array);