jspsych-tangram 0.0.4 → 0.0.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspsych-tangram",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Tangram tasks for jsPsych: prep and construct.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -357,8 +357,11 @@ export default function GameBoard(props: GameBoardProps) {
357
357
  setGameCompleted(true);
358
358
 
359
359
  // Finalize trial data tracking (which calls onTrialEnd)
360
+ // Defer to avoid unmounting React while still in commit phase
360
361
  if (tracker) {
361
- tracker.finalizeTrial('auto_complete');
362
+ setTimeout(() => {
363
+ tracker.finalizeTrial('auto_complete');
364
+ }, 0);
362
365
  }
363
366
  }
364
367
  };
@@ -196,7 +196,6 @@ export class BaseGameController {
196
196
  const allDone = Object.values(this.state.sectors).every((s: SectorState) => !!s.completedAt);
197
197
  if (allDone && !this.state.endedAt) {
198
198
  this.state.endedAt = NOW();
199
- console.log("[BaseGameController] all sectors complete");
200
199
  }
201
200
  }
202
201
 
@@ -58,42 +58,24 @@ export function startConstructionTrial(
58
58
  ]);
59
59
 
60
60
  // Convert JSON plugin parameters to internal Sector[] format
61
- console.log('[ConstructionApp] Starting tangram conversion...');
62
- console.log('[ConstructionApp] Received tangrams:', params.tangrams);
63
- console.log('[ConstructionApp] Number of tangrams:', params.tangrams.length);
64
-
65
- const sectors: Sector[] = params.tangrams.map((tangramSpec, index) => {
66
- console.log(`\n[ConstructionApp] Processing tangram ${index}:`, tangramSpec);
67
- console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
68
- console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
69
- console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
70
- console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
71
-
61
+ const sectors: Sector[] = params.tangrams.map((tangramSpec, index) => {
62
+
72
63
  // Filter to canonical pieces only and convert vertices to polygon format
73
64
  const filteredTans = tangramSpec.solutionTans.filter((tan: any) => {
74
65
  // Support both "name" and "kind" fields (different JSON formats)
75
66
  const tanName = tan.name ?? tan.kind;
76
67
  const isCanonical = CANON.has(tanName);
77
- console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
78
68
  return isCanonical;
79
69
  });
80
70
 
81
- console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
82
-
83
71
  const mask = filteredTans.map((tan: any, tanIndex: number) => {
84
- const tanName = tan.name ?? tan.kind;
85
72
  const polygon = tan.vertices.map(([x, y]: number[]) => ({ x: x ?? 0, y: -(y ?? 0) }));
86
- console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
87
- console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
88
73
  return polygon;
89
74
  });
90
75
 
91
76
  // Assign sector ID from alphabetical sequence
92
77
  const sectorId = `sector${index}`;
93
78
 
94
- console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
95
- console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
96
-
97
79
  const sector = {
98
80
  id: sectorId,
99
81
  tangramId: tangramSpec.tangramID,
@@ -103,27 +85,17 @@ export function startConstructionTrial(
103
85
  },
104
86
  };
105
87
 
106
- console.log(`[ConstructionApp] Created sector:`, sector);
107
88
  return sector;
108
89
  });
109
90
 
110
- console.log('\n[ConstructionApp] Final sectors array:', sectors);
111
- console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
112
-
113
91
  // Convert quickstash_macros to Blueprint[] format
114
92
  // Handle both anchor-based composites and pre-converted blueprints
115
- console.log('\n[ConstructionApp] Processing quickstash macros...');
116
- console.log('[ConstructionApp] quickstash_macros:', params.quickstash_macros);
117
- console.log('[ConstructionApp] quickstash_macros count:', params.quickstash_macros?.length ?? 0);
118
-
119
93
  let quickstash: Blueprint[] = [];
120
94
 
121
95
  if (params.quickstash_macros && params.quickstash_macros.length > 0) {
122
96
  // Check if the first item has anchorOffset (anchor-based) or offset (pixel-based)
123
97
  const firstMacro = params.quickstash_macros[0];
124
- console.log('[ConstructionApp] First macro:', firstMacro);
125
98
  if (firstMacro && 'parts' in firstMacro && firstMacro.parts && firstMacro.parts[0] && 'anchorOffset' in firstMacro.parts[0]) {
126
- console.log('[ConstructionApp] Detected anchor-based composites, converting to pixels...');
127
99
 
128
100
  // Create primitive map for conversion
129
101
  const primsByKind = new Map<TanKind, PrimitiveBlueprint>();
@@ -133,14 +105,11 @@ export function startConstructionTrial(
133
105
  quickstash = (params.quickstash_macros as AnchorComposite[]).map(anchorComposite =>
134
106
  convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx) // Use current CONFIG grid step
135
107
  );
136
- console.log('[ConstructionApp] Converted to pixel-based blueprints:', quickstash);
137
108
  } else {
138
- console.log('[ConstructionApp] Already pixel-based blueprints');
139
109
  // Already pixel-based blueprints
140
110
  quickstash = params.quickstash_macros as Blueprint[];
141
111
  }
142
112
  } else {
143
- console.log('[ConstructionApp] No quickstash macros provided');
144
113
  }
145
114
 
146
115
  // Create React root and render GameBoard
@@ -148,31 +117,18 @@ export function startConstructionTrial(
148
117
  sectors,
149
118
  quickstash,
150
119
  primitives: PRIMITIVE_BLUEPRINTS,
151
- layout: (params.layout || "semicircle") as LayoutMode,
152
- target: (params.target || "silhouette") as PlacementTarget,
153
- input: (params.input || "drag") as InputMode,
154
- timeLimitMs: params.time_limit_ms || 0,
120
+ layout: params.layout as LayoutMode,
121
+ target: params.target as PlacementTarget,
122
+ input: params.input as InputMode,
123
+ timeLimitMs: params.time_limit_ms,
155
124
  maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
156
- mode: 'construction' as const, // Explicit construction mode
125
+ mode: 'construction' as const,
157
126
  ...(params.onInteraction && { onInteraction: params.onInteraction }),
158
127
  ...(params.onTrialEnd && { onTrialEnd: params.onTrialEnd })
159
128
  };
160
129
 
161
- console.log('\n[ConstructionApp] Final GameBoard props:');
162
- console.log('[ConstructionApp] sectors count:', gameBoardProps.sectors.length);
163
- console.log('[ConstructionApp] quickstash count:', gameBoardProps.quickstash.length);
164
- console.log('[ConstructionApp] primitives count:', gameBoardProps.primitives.length);
165
- console.log('[ConstructionApp] layout:', gameBoardProps.layout);
166
- console.log('[ConstructionApp] target:', gameBoardProps.target);
167
- console.log('[ConstructionApp] input:', gameBoardProps.input);
168
- console.log('[ConstructionApp] timeLimitMs:', gameBoardProps.timeLimitMs);
169
- console.log('[ConstructionApp] mode:', gameBoardProps.mode);
170
- console.log('[ConstructionApp] Full props:', gameBoardProps);
171
-
172
130
  const root = createRoot(display_element);
173
131
  root.render(React.createElement(GameBoard, gameBoardProps));
174
132
 
175
- console.log('[ConstructionApp] GameBoard rendered successfully');
176
-
177
133
  return { root, display_element, jsPsych: _jsPsych };
178
134
  }
@@ -140,7 +140,7 @@ class TangramConstructPlugin implements JsPsychPlugin<Info> {
140
140
  target: trial.target,
141
141
  input: trial.input,
142
142
  layout: trial.layout,
143
- time_limit_ms: trial.time_limit_ms || 0,
143
+ time_limit_ms: trial.time_limit_ms,
144
144
  onInteraction: trial.onInteraction,
145
145
  onTrialEnd: wrappedOnTrialEnd
146
146
  };
@@ -101,7 +101,7 @@ class TangramPrepPlugin implements JsPsychPlugin<Info> {
101
101
  };
102
102
 
103
103
  const params: StartPrepTrialParams = {
104
- numQuickstashSlots: trial.num_quickstash_slots || 4,
104
+ numQuickstashSlots: trial.num_quickstash_slots,
105
105
  maxPiecesPerMacro: trial.max_pieces_per_macro,
106
106
  minPiecesPerMacro: trial.min_pieces_per_macro,
107
107
  inputMode: trial.input as "click" | "drag",