jspsych-tangram 0.0.15 → 0.0.17

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 (44) hide show
  1. package/dist/afc/index.browser.js +3897 -4514
  2. package/dist/afc/index.browser.js.map +1 -1
  3. package/dist/afc/index.browser.min.js +12 -12
  4. package/dist/afc/index.browser.min.js.map +1 -1
  5. package/dist/afc/index.cjs +39 -4
  6. package/dist/afc/index.cjs.map +1 -1
  7. package/dist/afc/index.js +39 -4
  8. package/dist/afc/index.js.map +1 -1
  9. package/dist/construct/index.browser.js +3892 -4522
  10. package/dist/construct/index.browser.js.map +1 -1
  11. package/dist/construct/index.browser.min.js +13 -13
  12. package/dist/construct/index.browser.min.js.map +1 -1
  13. package/dist/construct/index.cjs +31 -9
  14. package/dist/construct/index.cjs.map +1 -1
  15. package/dist/construct/index.js +31 -9
  16. package/dist/construct/index.js.map +1 -1
  17. package/dist/index.cjs +31 -9
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.js +31 -9
  20. package/dist/index.js.map +1 -1
  21. package/dist/nback/index.browser.js +3897 -4514
  22. package/dist/nback/index.browser.js.map +1 -1
  23. package/dist/nback/index.browser.min.js +12 -12
  24. package/dist/nback/index.browser.min.js.map +1 -1
  25. package/dist/nback/index.cjs +39 -4
  26. package/dist/nback/index.cjs.map +1 -1
  27. package/dist/nback/index.js +39 -4
  28. package/dist/nback/index.js.map +1 -1
  29. package/dist/prep/index.browser.js +3163 -3791
  30. package/dist/prep/index.browser.js.map +1 -1
  31. package/dist/prep/index.browser.min.js +13 -13
  32. package/dist/prep/index.browser.min.js.map +1 -1
  33. package/dist/prep/index.cjs +34 -10
  34. package/dist/prep/index.cjs.map +1 -1
  35. package/dist/prep/index.js +34 -10
  36. package/dist/prep/index.js.map +1 -1
  37. package/package.json +9 -3
  38. package/src/core/components/board/GameBoard.tsx +12 -0
  39. package/src/core/io/InteractionTracker.ts +19 -7
  40. package/src/core/io/data-tracking.ts +5 -0
  41. package/tangram-afc.min.js +42 -0
  42. package/tangram-construct.min.js +13 -13
  43. package/tangram-nback.min.js +12 -12
  44. package/tangram-prep.min.js +13 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspsych-tangram",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Tangram tasks for jsPsych: prep and construct.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -27,6 +27,11 @@
27
27
  "types": "./dist/nback/index.d.ts",
28
28
  "import": "./dist/nback/index.js",
29
29
  "require": "./dist/nback/index.cjs"
30
+ },
31
+ "./afc": {
32
+ "types": "./dist/afc/index.d.ts",
33
+ "import": "./dist/afc/index.js",
34
+ "require": "./dist/afc/index.cjs"
30
35
  }
31
36
  },
32
37
  "files": [
@@ -34,12 +39,13 @@
34
39
  "dist",
35
40
  "tangram-prep.min.js",
36
41
  "tangram-construct.min.js",
37
- "tangram-nback.min.js"
42
+ "tangram-nback.min.js",
43
+ "tangram-afc.min.js"
38
44
  ],
39
45
  "source": "src/index.ts",
40
46
  "scripts": {
41
47
  "build": "rollup --config",
42
- "postbuild": "cp dist/prep/index.browser.min.js tangram-prep.min.js && cp dist/construct/index.browser.min.js tangram-construct.min.js && cp dist/nback/index.browser.min.js tangram-nback.min.js",
48
+ "postbuild": "cp dist/prep/index.browser.min.js tangram-prep.min.js && cp dist/construct/index.browser.min.js tangram-construct.min.js && cp dist/nback/index.browser.min.js tangram-nback.min.js && cp dist/afc/index.browser.min.js tangram-afc.min.js",
43
49
  "build:watch": "npm run build -- --watch",
44
50
  "dev": "vite",
45
51
  "test": "jest",
@@ -378,6 +378,18 @@ export default function GameBoard(props: GameBoardProps) {
378
378
  };
379
379
  }, [sectors, layoutMode, target, maxQuickstashSlots, primitives.length]);
380
380
 
381
+ // Update tracker with sector centers whenever layout changes
382
+ React.useEffect(() => {
383
+ if (tracker && layout) {
384
+ const centers: { [sectorId: string]: { x: number; y: number } } = {};
385
+ layout.sectors.forEach(s => {
386
+ const rect = rectForBand(layout, s, "silhouette", 1.0);
387
+ centers[s.id] = { x: rect.cx, y: rect.cy };
388
+ });
389
+ tracker.setSectorCenters(centers);
390
+ }
391
+ }, [tracker, layout]);
392
+
381
393
  // Force re-render utility
382
394
  const [, force] = React.useReducer((x) => x + 1, 0);
383
395
 
@@ -99,7 +99,10 @@ export class InteractionTracker {
99
99
 
100
100
  // Trial timing
101
101
  private trialStartTime: number;
102
- private readonly gridStep: number = CONFIG.layout.grid.stepPx;
102
+ private completionTimes: Array<{ sectorId: string; completedAt: number }> = [];
103
+
104
+ // Sector centers (set by GameBoard after layout computation)
105
+ private sectorCenters: { [sectorId: string]: { x: number; y: number } } = {};
103
106
 
104
107
  // Interaction state
105
108
  private interactionIndex: number = 0;
@@ -113,21 +116,22 @@ export class InteractionTracker {
113
116
  // Interaction history (for TrialEndData)
114
117
  private interactions: InteractionEvent[] = [];
115
118
 
116
- // Construction-specific tracking
117
- private completionTimes: Array<{ sectorId: string; completedAt: number }> = [];
118
-
119
119
  // Prep-specific tracking
120
120
  private createdMacros: MacroSnapshot[] = [];
121
121
 
122
+ // Grid step for coordinate conversion
123
+ private gridStep: number;
124
+
122
125
  constructor(
123
126
  controller: BaseGameController,
124
127
  callbacks: DataTrackingCallbacks,
125
- trialParams?: any
128
+ trialParams: any
126
129
  ) {
127
130
  this.controller = controller;
128
131
  this.callbacks = callbacks;
129
132
  this.trialParams = trialParams;
130
133
  this.trialStartTime = Date.now();
134
+ this.gridStep = CONFIG.layout.grid.stepPx;
131
135
 
132
136
  // Register tracking callbacks with controller
133
137
  this.controller.setTrackingCallbacks({
@@ -325,7 +329,14 @@ export class InteractionTracker {
325
329
  }
326
330
 
327
331
  /**
328
- * Record sector completion
332
+ * Set sector centers (for anchor alignment)
333
+ */
334
+ setSectorCenters(centers: { [sectorId: string]: { x: number; y: number } }): void {
335
+ this.sectorCenters = centers;
336
+ }
337
+
338
+ /**
339
+ * Record a sector completion event
329
340
  */
330
341
  recordSectorCompletion(sectorId: string): void {
331
342
  this.completionTimes.push({
@@ -557,7 +568,8 @@ export class InteractionTracker {
557
568
  sectorId: sector.id,
558
569
  completed,
559
570
  pieceCount: pieces.length,
560
- pieces
571
+ pieces,
572
+ center: this.sectorCenters[sector.id] ? this.toAnchorPoint(this.sectorCenters[sector.id]) : undefined
561
573
  };
562
574
 
563
575
  if (sectorState?.completedAt !== undefined) {
@@ -146,6 +146,10 @@ export interface ConstructionTrialData extends BaseTrialData {
146
146
  completedAt: number; // timestamp in ms (Date.now())
147
147
  }>;
148
148
 
149
+ // Sector centers (computed layout positions)
150
+ // Removed in favor of SectorSnapshot.center
151
+ // sectorCenters?: { [sectorId: string]: { x: number; y: number } };
152
+
149
153
  // Final blueprint state (usage counts + definitions)
150
154
  finalBlueprintState: Array<{
151
155
  blueprintId: string;
@@ -212,6 +216,7 @@ export interface SectorSnapshot {
212
216
  completedAt?: number; // timestamp in ms (Date.now()) (undefined if not completed)
213
217
  pieceCount: number;
214
218
  pieces: PieceSnapshot[];
219
+ center?: { x: number; y: number }; // Center of sector in anchor coordinates
215
220
  }
216
221
 
217
222
  /**