@adriansteffan/reactive 0.0.24 → 0.0.27

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.
Files changed (36) hide show
  1. package/dist/{mod-DFT88PVZ.js → mod-CbGhKi2f.js} +11270 -9987
  2. package/dist/mod.d.ts +188 -48
  3. package/dist/reactive.es.js +26 -15
  4. package/dist/reactive.umd.js +37 -39
  5. package/dist/style.css +1 -1
  6. package/dist/{web-BkxeXT_o.js → web-BFGLx41c.js} +1 -1
  7. package/dist/{web-DLRbsabT.js → web-DOFokKz7.js} +1 -1
  8. package/package.json +7 -2
  9. package/src/components/canvasblock.tsx +519 -0
  10. package/src/components/checkdevice.tsx +158 -0
  11. package/src/components/enterfullscreen.tsx +114 -31
  12. package/src/components/exitfullscreen.tsx +98 -21
  13. package/src/components/experimentprovider.tsx +34 -20
  14. package/src/components/experimentrunner.tsx +387 -0
  15. package/src/components/index.ts +13 -0
  16. package/src/components/mobilefilepermission.tsx +63 -0
  17. package/src/components/plaininput.tsx +7 -8
  18. package/src/components/prolificending.tsx +10 -4
  19. package/src/components/quest.tsx +27 -31
  20. package/src/components/settingsscreen.tsx +770 -0
  21. package/src/components/text.tsx +48 -3
  22. package/src/components/upload.tsx +218 -47
  23. package/src/mod.tsx +3 -11
  24. package/src/types/array.d.ts +6 -0
  25. package/src/utils/array.ts +79 -0
  26. package/src/utils/bytecode.ts +178 -0
  27. package/src/utils/common.ts +170 -39
  28. package/template/.env.template +2 -1
  29. package/template/README.md +20 -5
  30. package/template/package.json +1 -0
  31. package/template/shared.vite.config.js +18 -0
  32. package/template/src/{App.tsx → Experiment.tsx} +4 -4
  33. package/template/src/main.tsx +4 -4
  34. package/template/tsconfig.json +4 -2
  35. package/tsconfig.json +1 -0
  36. package/src/components/experiment.tsx +0 -369
package/dist/mod.d.ts CHANGED
@@ -1,14 +1,56 @@
1
1
  import { ComponentType } from 'react';
2
+ import { default as default_2 } from 'react';
2
3
  import { JSX as JSX_2 } from 'react/jsx-runtime';
3
4
  import { ReactNode } from 'react';
4
5
 
5
6
  export declare interface BaseComponentProps {
6
- next: (data: object) => void;
7
+ next: (data?: object, actualStartTime?: number, actualStopTime?: number) => void;
7
8
  data: TrialData[];
8
9
  store?: Store;
9
10
  updateStore: (mergeIn: Store) => void;
10
11
  }
11
12
 
13
+ declare type BaseTrialData = {
14
+ index: number;
15
+ trialNumber: number;
16
+ start: number;
17
+ end: number;
18
+ duration: number;
19
+ };
20
+
21
+ export declare function CanvasBlock({ next, updateStore, timeline, width, height, store, styleCanvas, initCanvas, }: CanvasBlockProps): JSX_2.Element;
22
+
23
+ declare type CanvasBlockProps = {
24
+ timeline: TimelineItem[];
25
+ width?: number | string;
26
+ height?: number | string;
27
+ styleCanvas?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
28
+ initCanvas?: (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
29
+ } & BaseComponentProps;
30
+
31
+ export declare function canvasCountdown(seconds: number): {
32
+ draw: (ctx: CanvasRenderingContext2D, w: number, h: number) => void;
33
+ displayDuration: number;
34
+ ignoreData: boolean;
35
+ }[];
36
+
37
+ declare type CanvasResultData = BaseTrialData & {
38
+ metadata?: Record<string, any>;
39
+ key: string | null;
40
+ reactionTime: number | null;
41
+ };
42
+
43
+ export declare function CheckDevice({ check, content, data, store, updateStore, next, }: {
44
+ check: (deviceInfo: DeviceInfo, data: any, store: any) => boolean;
45
+ content?: React.ReactNode;
46
+ } & BaseComponentProps): JSX_2.Element | null;
47
+
48
+ declare type ComponentResultData = BaseTrialData & {
49
+ type: string;
50
+ name: string;
51
+ responseData?: any;
52
+ };
53
+
12
54
  declare type ComponentsMap = {
13
55
  [key: string]: ComponentType<any>;
14
56
  };
@@ -17,63 +59,86 @@ declare type ComponentsMap_2 = {
17
59
  [key: string]: ComponentType<any>;
18
60
  };
19
61
 
20
- declare interface ComponentTrial {
21
- name: string;
22
- type: string;
23
- props?: Record<string, any> | ((store: Store, data: TrialData[]) => Record<string, any>);
62
+ declare type ConditionalFunction = (data?: RefinedTrialData[], store?: Store_2) => boolean;
63
+
64
+ declare type ControlFlowItem = MarkerItem | IfGotoItem | UpdateStoreItem | IfBlockItem | WhileBlockItem;
65
+
66
+ declare type CSVBuilder = {
67
+ filename?: string;
68
+ trials?: string[];
69
+ fun?: (row: Record<string, any>) => Record<string, any>;
70
+ };
71
+
72
+ declare interface DeviceInfo {
73
+ windowWidth: number;
74
+ windowHeight: number;
75
+ screenWidth: number;
76
+ screenHeight: number;
77
+ browser: string;
78
+ browserVersion: string;
79
+ isMobile: boolean;
80
+ operatingSystem: string;
81
+ hasWebAudio: boolean;
82
+ hasFullscreen: boolean;
83
+ hasWebcam: boolean;
84
+ hasMicrophone: boolean;
24
85
  }
25
86
 
26
- export declare function EnterFullscreen({ content, buttonText, next, }: {
87
+ export declare function EnterFullscreen({ content, buttonText, next, data, updateStore, delayMs, }: {
27
88
  prolificCode?: string;
28
- content?: React.ReactNode;
89
+ content?: default_2.ReactNode;
29
90
  buttonText?: string;
30
- } & BaseComponentProps): JSX_2.Element;
91
+ delayMs?: number;
92
+ } & BaseComponentProps): JSX_2.Element | null;
31
93
 
32
- export declare function ExitFullscreen({ next }: BaseComponentProps): JSX_2.Element;
33
-
34
- export declare function Experiment({ timeline, config, components, questions, }: {
35
- timeline: ExperimentTrial[];
36
- config?: ExperimentConfig;
37
- components?: ComponentsMap_2;
38
- questions?: ComponentsMap_2;
39
- }): JSX_2.Element;
94
+ export declare function ExitFullscreen({ next, delayMs, }: {
95
+ delayMs?: number;
96
+ } & BaseComponentProps): null;
40
97
 
41
98
  export declare interface ExperimentConfig {
42
99
  showProgressBar: boolean;
43
100
  }
44
101
 
45
- export declare function ExperimentProvider({ children }: {
102
+ export declare function ExperimentProvider({ children, disableSettings }: {
46
103
  children: ReactNode;
104
+ disableSettings?: boolean;
47
105
  }): JSX_2.Element;
48
106
 
49
- declare type ExperimentTrial = MarkerTrial | IfGotoTrial | UpdateStoreTrial | IfBlockTrial | WhileBlockTrial | ComponentTrial;
107
+ export declare function ExperimentRunner({ timeline, config, components, questions, }: {
108
+ timeline: TimelineItem[];
109
+ config?: ExperimentConfig;
110
+ components?: ComponentsMap_2;
111
+ questions?: ComponentsMap_2;
112
+ }): JSX_2.Element;
50
113
 
51
114
  export declare interface FileUpload {
52
115
  filename: string;
53
116
  content: string;
54
- encoding: 'base64' | 'utf8';
117
+ encoding?: 'base64' | 'utf8';
55
118
  }
56
119
 
57
- export declare function getParam<T extends ParamType>(name: string, defaultValue: ParamValue<T> | undefined, type?: T): ParamValue<T> | undefined;
120
+ export declare function getParam<T extends ParamType>(name: string, defaultValue: ParamValue<T>, type?: T, description?: string): ParamValue<T>;
58
121
 
59
122
  export declare const getPlatform: () => Platform;
60
123
 
61
- declare interface IfBlockTrial {
62
- type: 'IF_BLOCK' | string;
63
- cond: (store: Store, data: TrialData[]) => boolean;
64
- timeline: ExperimentTrial[];
124
+ declare interface IfBlockItem {
125
+ type: 'IF_BLOCK';
126
+ cond: ConditionalFunction;
127
+ timeline: TimelineItem[];
65
128
  }
66
129
 
67
- declare interface IfGotoTrial {
68
- type: 'IF_GOTO' | string;
69
- cond: (store: Store, data: TrialData[]) => boolean;
130
+ declare interface IfGotoItem {
131
+ type: 'IF_GOTO';
132
+ cond: ConditionalFunction;
70
133
  marker: string;
71
134
  }
72
135
 
73
136
  export declare function isDesktop(): boolean;
74
137
 
75
- declare interface MarkerTrial {
76
- type: 'MARKER' | string;
138
+ export declare function isFullscreen(): boolean;
139
+
140
+ declare interface MarkerItem {
141
+ type: 'MARKER';
77
142
  id: string;
78
143
  }
79
144
 
@@ -83,12 +148,19 @@ export declare const MicCheck: ({ next }: {
83
148
 
84
149
  export declare function now(): number;
85
150
 
151
+ export declare class Param {
152
+ static getRegistry(): any[];
153
+ static getTimelineRepresentation(): {
154
+ type: string;
155
+ name?: string;
156
+ }[];
157
+ }
158
+
86
159
  declare type ParamType = 'string' | 'number' | 'boolean' | 'array' | 'json';
87
160
 
88
- declare type ParamValue<T extends ParamType> = T extends 'number' ? number | undefined : T extends 'boolean' ? boolean | undefined : T extends 'array' | 'json' ? any | undefined : string | undefined;
161
+ declare type ParamValue<T extends ParamType> = T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'array' | 'json' ? any : string;
89
162
 
90
- export declare function PlainInput({ content, buttonText, className, next, updateStore, animate, storeupdate, // user defined function
91
- placeholder, }: BaseComponentProps & {
163
+ export declare function PlainInput({ content, buttonText, className, next, updateStore, animate, storeupdate, placeholder, }: BaseComponentProps & {
92
164
  content: React.ReactNode;
93
165
  buttonText?: string;
94
166
  onButtonClick?: () => void;
@@ -102,60 +174,128 @@ export declare function PlainInput({ content, buttonText, className, next, updat
102
174
 
103
175
  export declare type Platform = 'desktop' | 'mobile' | 'web';
104
176
 
105
- export declare function ProlificEnding({ prolificCode, }: {
177
+ export declare function ProlificEnding({ prolificCode, data, updateStore }: {
106
178
  prolificCode?: string;
107
179
  } & BaseComponentProps): JSX_2.Element;
108
180
 
109
- export declare function Quest({ next, surveyJson, customQuestions }: {
181
+ export declare function Quest({ next, surveyJson, customQuestions, }: {
110
182
  next: (data: object) => void;
111
183
  surveyJson: object;
112
184
  customQuestions?: ComponentsMap;
113
185
  }): JSX_2.Element;
114
186
 
115
- export declare function shuffle(array: any[]): any[];
187
+ declare type RefinedTrialData = ComponentResultData | CanvasResultData;
188
+
189
+ /**
190
+ * Registers array methods on the Array prototype.
191
+ * Call this function once to make array methods available globally.
192
+ *
193
+ * Example:
194
+ * ```
195
+ * import { registerArrayExtensions } from '@adriansteffan/reactive/array';
196
+ * registerArrayExtensions();
197
+ *
198
+ * // Now you can use the methods
199
+ * const myArray = [1, 2, 3, 4, 5];
200
+ * myArray.shuffle();
201
+ * ```
202
+ */
203
+ export declare function registerArrayExtensions(): void;
204
+
205
+ export declare function registerComponentParams(type: string, params: {
206
+ name: string;
207
+ defaultValue: any;
208
+ type: string;
209
+ description?: string;
210
+ }[]): void;
211
+
212
+ export declare function registerExperimentParams(experiment: any[]): void;
213
+
214
+ export declare function RequestFilePermission({ next }: BaseComponentProps): JSX_2.Element | null;
215
+
216
+ /**
217
+ * Returns random elements from an array
218
+ * @param array The source array
219
+ * @param n Number of random elements to return (defaults to 1)
220
+ * @returns Array of randomly selected elements
221
+ */
222
+ export declare function sample<T>(array: T[], n?: number): T[];
223
+
224
+ /**
225
+ * Shuffles array elements using Fisher-Yates algorithm
226
+ * @param array The source array
227
+ * @returns A new shuffled array
228
+ */
229
+ export declare function shuffle<T>(array: T[]): T[];
116
230
 
117
231
  export declare interface Store {
118
232
  [key: string]: any;
119
233
  }
120
234
 
121
- declare function Text_2({ content, buttonText, className, next, animate, }: {
122
- content: React.ReactNode;
235
+ declare type Store_2 = Record<string, any>;
236
+
237
+ declare type StoreUpdateFunction = (data?: RefinedTrialData[], store?: Store_2) => Record<string, any>;
238
+
239
+ export declare function subsetExperimentByParam(experiment: any[]): any[];
240
+
241
+ declare function Text_2({ content, buttonText, className, next, animate, allowedKeys, }: {
242
+ content: default_2.ReactNode;
123
243
  buttonText?: string;
124
244
  onButtonClick?: () => void;
125
245
  className?: string;
126
- next: (newData: object) => void;
127
246
  animate?: boolean;
128
- }): JSX_2.Element;
247
+ allowedKeys?: string[] | boolean;
248
+ } & BaseComponentProps): JSX_2.Element;
129
249
  export { Text_2 as Text }
130
250
 
251
+ declare type TimelineItem = ControlFlowItem | any;
252
+
131
253
  export declare interface TrialData {
132
254
  index: number;
133
255
  trialNumber: number;
134
256
  type: string;
135
257
  name: string;
136
- data: any;
258
+ responseData: any;
137
259
  start: number;
138
260
  end: number;
139
261
  duration: number;
140
262
  }
141
263
 
142
- declare interface UpdateStoreTrial {
143
- type: 'UPDATE_STORE' | string;
144
- fun: (store: Store, data: TrialData[]) => Store;
264
+ declare interface UpdateStoreItem {
265
+ type: 'UPDATE_STORE';
266
+ fun: StoreUpdateFunction;
145
267
  }
146
268
 
147
- export declare function Upload({ data, next, store, sessionID, generateFiles, uploadRaw, autoUpload, androidFolderName, }: BaseComponentProps & {
269
+ export declare function Upload({ data, next, store, sessionID, generateFiles, sessionCSVBuilder, trialCSVBuilders, uploadRaw, autoUpload, androidFolderName, }: BaseComponentProps & {
148
270
  sessionID?: string | null;
149
271
  generateFiles: (sessionID: string, data: TrialData[], store?: Store) => FileUpload[];
272
+ sessionCSVBuilder: CSVBuilder;
273
+ trialCSVBuilders: CSVBuilder[];
150
274
  uploadRaw: boolean;
151
275
  autoUpload: boolean;
152
276
  androidFolderName?: string;
153
277
  }): JSX_2.Element;
154
278
 
155
- declare interface WhileBlockTrial {
156
- type: 'WHILE_BLOCK' | string;
157
- cond: (store: Store, data: TrialData[]) => boolean;
158
- timeline: ExperimentTrial[];
279
+ declare interface WhileBlockItem {
280
+ type: 'WHILE_BLOCK';
281
+ cond: ConditionalFunction;
282
+ timeline: TimelineItem[];
159
283
  }
160
284
 
161
285
  export { }
286
+
287
+ declare global {
288
+ interface Array<T> {
289
+ /**
290
+ * Returns random elements from the array
291
+ * @param n Number of random elements to return (defaults to 1)
292
+ * @returns Array of randomly selected elements
293
+ */
294
+ sample(n?: number): Array<T>;
295
+ /**
296
+ * Shuffles array elements using Fisher-Yates algorithm
297
+ * @returns A new shuffled array
298
+ */
299
+ shuffle(): Array<T>;
300
+ }
301
+ }
@@ -1,18 +1,29 @@
1
- import { a as e, c as r, d as t, e as i, M as n, f as l, P as o, Q as c, T as f, U as p, g as P, h as m, i as u, n as x, s as E } from "./mod-DFT88PVZ.js";
1
+ import { C as e, t as r, m as n, o as t, p as i, q as o, M as l, P as m, k as c, l as p, Q as P, R as u, T as x, U as E, j as g, g as f, d as C, c as d, i as k, n as h, r as v, f as F, e as R, s as q, a as w, h as y } from "./mod-CbGhKi2f.js";
2
2
  export {
3
- e as EnterFullscreen,
4
- r as ExitFullscreen,
5
- t as Experiment,
3
+ e as CanvasBlock,
4
+ r as CheckDevice,
5
+ n as EnterFullscreen,
6
+ t as ExitFullscreen,
6
7
  i as ExperimentProvider,
7
- n as MicCheck,
8
- l as PlainInput,
9
- o as ProlificEnding,
10
- c as Quest,
11
- f as Text,
12
- p as Upload,
13
- P as getParam,
14
- m as getPlatform,
15
- u as isDesktop,
16
- x as now,
17
- E as shuffle
8
+ o as ExperimentRunner,
9
+ l as MicCheck,
10
+ m as Param,
11
+ c as PlainInput,
12
+ p as ProlificEnding,
13
+ P as Quest,
14
+ u as RequestFilePermission,
15
+ x as Text,
16
+ E as Upload,
17
+ g as canvasCountdown,
18
+ f as getParam,
19
+ C as getPlatform,
20
+ d as isDesktop,
21
+ k as isFullscreen,
22
+ h as now,
23
+ v as registerArrayExtensions,
24
+ F as registerComponentParams,
25
+ R as registerExperimentParams,
26
+ q as sample,
27
+ w as shuffle,
28
+ y as subsetExperimentByParam
18
29
  };