@adriansteffan/reactive 0.0.37 → 0.0.40

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.
@@ -1,4 +1,4 @@
1
- import { W as e } from "./mod-B9pn3CIt.js";
1
+ import { W as e } from "./mod-atv0jMSt.js";
2
2
  class s extends e {
3
3
  async enable() {
4
4
  console.log("Immersive mode is only available on Android");
@@ -1,4 +1,4 @@
1
- import { W as P, b as x, E } from "./mod-B9pn3CIt.js";
1
+ import { W as P, b as x, E } from "./mod-atv0jMSt.js";
2
2
  function m(w) {
3
3
  const e = w.split("/").filter((t) => t !== "."), r = [];
4
4
  return e.forEach((t) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adriansteffan/reactive",
3
- "version": "0.0.37",
3
+ "version": "0.0.40",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -108,27 +108,80 @@ function combineTrialsToCsv(
108
108
  data: any[],
109
109
  filename: string,
110
110
  names: string[],
111
- flatteningFunctions: Record<string, (item: any) => any[]>,
111
+ flatteningFunctions: Record<string, (item: any) => any[] | Record<string, any[]>>,
112
112
  fun?: (obj: any) => any,
113
- ) {
114
-
115
- const processedData = names
116
- .flatMap((name) => {
117
- const matchingItems = data.filter((d) => d.name === name);
118
-
119
- return matchingItems.flatMap((item) => {
120
- const flattener = item.type && flatteningFunctions[item.type];
121
-
122
- return flattener ? flattener(item) : transform(item);
113
+ ): FileUpload | FileUpload[] {
114
+
115
+ // Collect all flattener results first
116
+ const allResults: (any[] | Record<string, any[]>)[] = names.flatMap((name) => {
117
+ const matchingItems = data.filter((d) => d.name === name);
118
+
119
+ return matchingItems.map((item) => {
120
+ const flattener = item.type && flatteningFunctions[item.type];
121
+ return flattener ? flattener(item) : [transform(item)];
122
+ });
123
+ });
124
+
125
+ // Check if any result is a multi-table object (has string keys with array values)
126
+ const hasMultiTable = allResults.some((result) =>
127
+ result &&
128
+ typeof result === 'object' &&
129
+ !Array.isArray(result) &&
130
+ Object.keys(result).some(key => Array.isArray(result[key]))
131
+ );
132
+
133
+ if (!hasMultiTable) {
134
+ // Original behavior: all results are arrays, combine them into one CSV
135
+ const processedData = allResults
136
+ .flatMap((result) => Array.isArray(result) ? result : [])
137
+ .map((x) => (fun ? fun(x) : x));
138
+
139
+ return {
140
+ filename,
141
+ encoding: 'utf8' as const,
142
+ content: convertArrayOfObjectsToCSV(processedData),
143
+ };
144
+ }
145
+
146
+ // New behavior: handle multi-table results
147
+ // Collect all table keys from all results
148
+ const allTableKeys = new Set<string>();
149
+ allResults.forEach((result) => {
150
+ if (result && typeof result === 'object' && !Array.isArray(result)) {
151
+ Object.keys(result).forEach(key => {
152
+ if (Array.isArray(result[key])) {
153
+ allTableKeys.add(key);
154
+ }
123
155
  });
124
- })
125
- .map((x) => (fun ? fun(x) : x));
156
+ }
157
+ });
126
158
 
127
- return {
128
- filename,
129
- encoding: 'utf8' as const,
130
- content: convertArrayOfObjectsToCSV(processedData),
131
- };
159
+ // Create separate CSV files for each table key
160
+ const files: FileUpload[] = [];
161
+
162
+ for (const tableKey of allTableKeys) {
163
+ const tableData = allResults.flatMap((result) => {
164
+ if (Array.isArray(result)) {
165
+ // If this result is a simple array, include it in all tables for backward compatibility
166
+ return result;
167
+ } else if (result && typeof result === 'object' && result[tableKey]) {
168
+ // If this result has data for this table key, include it
169
+ return result[tableKey];
170
+ }
171
+ return [];
172
+ }).map((x) => (fun ? fun(x) : x));
173
+
174
+ // Remove file extension from filename and add table key
175
+ const baseFilename = filename.replace(/\.csv$/, '');
176
+
177
+ files.push({
178
+ filename: `${baseFilename}_${tableKey}.csv`,
179
+ encoding: 'utf8' as const,
180
+ content: convertArrayOfObjectsToCSV(tableData),
181
+ });
182
+ }
183
+
184
+ return files.length === 1 ? files[0] : files;
132
185
  }
133
186
 
134
187
  interface FileBackend {
@@ -281,7 +334,7 @@ export default function Upload({
281
334
  sessionID?: string | null;
282
335
  generateFiles: (sessionID: string, data: TrialData[], store?: Store) => FileUpload[];
283
336
  sessionCSVBuilder: CSVBuilder;
284
- trialCSVBuilder: {flatteners: Record<string, ((item: TrialData) => Record<string, any>[])>, builders: CSVBuilder[]};
337
+ trialCSVBuilder: {flatteners: Record<string, ((item: TrialData) => Record<string, any>[] | Record<string, Record<string, any>[]>)>, builders: CSVBuilder[]};
285
338
  uploadRaw: boolean;
286
339
  autoUpload: boolean;
287
340
  androidFolderName?: string;
@@ -415,15 +468,19 @@ export default function Upload({
415
468
 
416
469
  if (trialCSVBuilder) {
417
470
  for (const builder of trialCSVBuilder.builders) {
418
- files.push(
419
- combineTrialsToCsv(
420
- data,
421
- `${sessionIDUpload}${builder.filename}.csv`,
422
- builder.trials ?? [],
423
- {...defaultFlatteningFunctions, ...trialCSVBuilder.flatteners},
424
- builder.fun,
425
- ),
471
+ const result = combineTrialsToCsv(
472
+ data,
473
+ `${sessionIDUpload}${builder.filename}.csv`,
474
+ builder.trials ?? [],
475
+ {...defaultFlatteningFunctions, ...trialCSVBuilder.flatteners},
476
+ builder.fun,
426
477
  );
478
+
479
+ if (Array.isArray(result)) {
480
+ files.push(...result);
481
+ } else {
482
+ files.push(result);
483
+ }
427
484
  }
428
485
  }
429
486
 
@@ -5,4 +5,7 @@
5
5
  @theme {
6
6
  --font-*: initial;
7
7
  --font-atkinson: Atkinson Hyperlegible, sans-serif;
8
- }
8
+ }
9
+
10
+ @source '../node_modules/@adriansteffan/reactive/dist/**/*.{js,jsx,ts,tsx}';
11
+ @source '../node_modules/@adriansteffan/reactive/src/**/*.{js,jsx,ts,tsx}';