jspsych-tangram 0.0.3 → 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.
Files changed (35) hide show
  1. package/dist/construct/index.browser.js +23 -63
  2. package/dist/construct/index.browser.js.map +1 -1
  3. package/dist/construct/index.browser.min.js +11 -15
  4. package/dist/construct/index.browser.min.js.map +1 -1
  5. package/dist/construct/index.cjs +23 -63
  6. package/dist/construct/index.cjs.map +1 -1
  7. package/dist/construct/index.js +23 -63
  8. package/dist/construct/index.js.map +1 -1
  9. package/dist/index.cjs +26 -64
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.js +26 -64
  12. package/dist/index.js.map +1 -1
  13. package/dist/prep/index.browser.js +16 -14
  14. package/dist/prep/index.browser.js.map +1 -1
  15. package/dist/prep/index.browser.min.js +1 -1
  16. package/dist/prep/index.browser.min.js.map +1 -1
  17. package/dist/prep/index.cjs +16 -14
  18. package/dist/prep/index.cjs.map +1 -1
  19. package/dist/prep/index.js +16 -14
  20. package/dist/prep/index.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/core/components/board/GameBoard.tsx +4 -1
  23. package/src/core/domain/primitives.ts +9 -10
  24. package/src/core/domain/types.ts +4 -3
  25. package/src/core/engine/state/BaseGameController.ts +0 -1
  26. package/src/core/io/InteractionTracker.ts +1 -1
  27. package/src/core/io/quickstash.ts +3 -29
  28. package/src/core/types/plugin-interfaces.ts +1 -1
  29. package/src/plugins/tangram-construct/ConstructionApp.tsx +13 -58
  30. package/src/plugins/tangram-construct/index.ts +1 -1
  31. package/src/plugins/tangram-prep/PrepApp.tsx +1 -0
  32. package/src/plugins/tangram-prep/index.ts +1 -1
  33. package/tangram-construct.min.js +11 -15
  34. package/tangram-prep.min.js +1 -1
  35. package/src/core/io/stims.ts +0 -107
package/dist/index.cjs CHANGED
@@ -187,7 +187,6 @@ class BaseGameController {
187
187
  const allDone = Object.values(this.state.sectors).every((s) => !!s.completedAt);
188
188
  if (allDone && !this.state.endedAt) {
189
189
  this.state.endedAt = NOW();
190
- console.log("[BaseGameController] all sectors complete");
191
190
  }
192
191
  }
193
192
  // ===== Piece Operations =====
@@ -2928,8 +2927,7 @@ class InteractionTracker {
2928
2927
  }
2929
2928
  const sectorTangramMap = this.controller.state.cfg.sectors.map((s) => ({
2930
2929
  sectorId: s.id,
2931
- tangramId: s.id
2932
- // In our system, sector ID == tangram ID
2930
+ tangramId: s.tangramId
2933
2931
  }));
2934
2932
  const blueprintOrder = {
2935
2933
  primitives: this.controller.state.primitives.map((bp) => bp.id),
@@ -3156,7 +3154,9 @@ function GameBoard(props) {
3156
3154
  if (allSectorsComplete && !gameCompleted) {
3157
3155
  setGameCompleted(true);
3158
3156
  if (tracker) {
3159
- tracker.finalizeTrial("auto_complete");
3157
+ setTimeout(() => {
3158
+ tracker.finalizeTrial("auto_complete");
3159
+ }, 0);
3160
3160
  }
3161
3161
  }
3162
3162
  };
@@ -3434,10 +3434,10 @@ function constructFromSpec(sideLens, angles, firstEdgeUnits) {
3434
3434
  return pts;
3435
3435
  }
3436
3436
  const FIRST_EDGES_UNITS = {
3437
- "small-triangle": [P(0, 0), P(0.5, 0.5)],
3437
+ "smalltriangle": [P(0, 0), P(0.5, 0.5)],
3438
3438
  "parallelogram": [P(0, 0), P(0.5, 0)],
3439
- "large-triangle": [P(0, 0), P(0.5, -0.5)],
3440
- "med-triangle": [P(0, 0), P(0.5, 0)],
3439
+ "largetriangle": [P(0, 0), P(0.5, -0.5)],
3440
+ "medtriangle": [P(0, 0), P(0.5, 0)],
3441
3441
  "square": [P(0, 0), P(0.5, 0)]
3442
3442
  };
3443
3443
  const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
@@ -3450,8 +3450,8 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
3450
3450
  color: "#f43f5e"
3451
3451
  },
3452
3452
  {
3453
- id: "prim:small",
3454
- kind: "small-triangle",
3453
+ id: "prim:smalltriangle",
3454
+ kind: "smalltriangle",
3455
3455
  sideLens: [HALFDIAGONAL, HALFDIAGONAL, HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT],
3456
3456
  angles: [180, 45, 180, 90, 180, 45],
3457
3457
  color: "#f59e0b"
@@ -3464,15 +3464,15 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
3464
3464
  color: "#10b981"
3465
3465
  },
3466
3466
  {
3467
- id: "prim:med",
3468
- kind: "med-triangle",
3467
+ id: "prim:medtriangle",
3468
+ kind: "medtriangle",
3469
3469
  sideLens: [HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL],
3470
3470
  angles: [180, 180, 180, 45, 180, 90, 180, 45],
3471
3471
  color: "#3b82f6"
3472
3472
  },
3473
3473
  {
3474
- id: "prim:large",
3475
- kind: "large-triangle",
3474
+ id: "prim:largetriangle",
3475
+ kind: "largetriangle",
3476
3476
  sideLens: [
3477
3477
  HALFDIAGONAL,
3478
3478
  HALFDIAGONAL,
@@ -3544,101 +3544,61 @@ function convertAnchorCompositeToPixels(anchorComposite, primsByKind, gridStepPx
3544
3544
  function startConstructionTrial(display_element, params, _jsPsych) {
3545
3545
  const CANON = /* @__PURE__ */ new Set([
3546
3546
  "square",
3547
- "small-triangle",
3547
+ "smalltriangle",
3548
3548
  "parallelogram",
3549
- "med-triangle",
3550
- "large-triangle"
3549
+ "medtriangle",
3550
+ "largetriangle"
3551
3551
  ]);
3552
- const SECTOR_IDS = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"];
3553
- console.log("[ConstructionApp] Starting tangram conversion...");
3554
- console.log("[ConstructionApp] Received tangrams:", params.tangrams);
3555
- console.log("[ConstructionApp] Number of tangrams:", params.tangrams.length);
3556
3552
  const sectors = params.tangrams.map((tangramSpec, index) => {
3557
- console.log(`
3558
- [ConstructionApp] Processing tangram ${index}:`, tangramSpec);
3559
- console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
3560
- console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
3561
- console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
3562
- console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
3563
3553
  const filteredTans = tangramSpec.solutionTans.filter((tan) => {
3564
3554
  const tanName = tan.name ?? tan.kind;
3565
3555
  const isCanonical = CANON.has(tanName);
3566
- console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
3567
3556
  return isCanonical;
3568
3557
  });
3569
- console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
3570
3558
  const mask = filteredTans.map((tan, tanIndex) => {
3571
- const tanName = tan.name ?? tan.kind;
3572
3559
  const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
3573
- console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
3574
- console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
3575
3560
  return polygon;
3576
3561
  });
3577
- const sectorId = SECTOR_IDS[index] ?? `S${index}`;
3578
- console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
3579
- console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
3562
+ const sectorId = `sector${index}`;
3580
3563
  const sector = {
3581
3564
  id: sectorId,
3565
+ tangramId: tangramSpec.tangramID,
3582
3566
  silhouette: {
3583
3567
  id: sectorId,
3584
3568
  mask
3585
3569
  }
3586
3570
  };
3587
- console.log(`[ConstructionApp] Created sector:`, sector);
3588
3571
  return sector;
3589
3572
  });
3590
- console.log("\n[ConstructionApp] Final sectors array:", sectors);
3591
- console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
3592
- console.log("\n[ConstructionApp] Processing quickstash macros...");
3593
- console.log("[ConstructionApp] quickstash_macros:", params.quickstash_macros);
3594
- console.log("[ConstructionApp] quickstash_macros count:", params.quickstash_macros?.length ?? 0);
3595
3573
  let quickstash = [];
3596
3574
  if (params.quickstash_macros && params.quickstash_macros.length > 0) {
3597
3575
  const firstMacro = params.quickstash_macros[0];
3598
- console.log("[ConstructionApp] First macro:", firstMacro);
3599
3576
  if (firstMacro && "parts" in firstMacro && firstMacro.parts && firstMacro.parts[0] && "anchorOffset" in firstMacro.parts[0]) {
3600
- console.log("[ConstructionApp] Detected anchor-based composites, converting to pixels...");
3601
3577
  const primsByKind = /* @__PURE__ */ new Map();
3602
3578
  PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
3603
3579
  quickstash = params.quickstash_macros.map(
3604
3580
  (anchorComposite) => convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx)
3605
3581
  // Use current CONFIG grid step
3606
3582
  );
3607
- console.log("[ConstructionApp] Converted to pixel-based blueprints:", quickstash);
3608
3583
  } else {
3609
- console.log("[ConstructionApp] Already pixel-based blueprints");
3610
3584
  quickstash = params.quickstash_macros;
3611
3585
  }
3612
- } else {
3613
- console.log("[ConstructionApp] No quickstash macros provided");
3614
3586
  }
3615
3587
  const gameBoardProps = {
3616
3588
  sectors,
3617
3589
  quickstash,
3618
3590
  primitives: PRIMITIVE_BLUEPRINTS,
3619
- layout: params.layout || "semicircle",
3620
- target: params.target || "silhouette",
3621
- input: params.input || "drag",
3622
- timeLimitMs: params.time_limit_ms || 0,
3591
+ layout: params.layout,
3592
+ target: params.target,
3593
+ input: params.input,
3594
+ timeLimitMs: params.time_limit_ms,
3623
3595
  maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
3624
3596
  mode: "construction",
3625
- // Explicit construction mode
3626
3597
  ...params.onInteraction && { onInteraction: params.onInteraction },
3627
3598
  ...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
3628
3599
  };
3629
- console.log("\n[ConstructionApp] Final GameBoard props:");
3630
- console.log("[ConstructionApp] sectors count:", gameBoardProps.sectors.length);
3631
- console.log("[ConstructionApp] quickstash count:", gameBoardProps.quickstash.length);
3632
- console.log("[ConstructionApp] primitives count:", gameBoardProps.primitives.length);
3633
- console.log("[ConstructionApp] layout:", gameBoardProps.layout);
3634
- console.log("[ConstructionApp] target:", gameBoardProps.target);
3635
- console.log("[ConstructionApp] input:", gameBoardProps.input);
3636
- console.log("[ConstructionApp] timeLimitMs:", gameBoardProps.timeLimitMs);
3637
- console.log("[ConstructionApp] mode:", gameBoardProps.mode);
3638
- console.log("[ConstructionApp] Full props:", gameBoardProps);
3639
3600
  const root = client.createRoot(display_element);
3640
3601
  root.render(React.createElement(GameBoard, gameBoardProps));
3641
- console.log("[ConstructionApp] GameBoard rendered successfully");
3642
3602
  return { root, display_element, jsPsych: _jsPsych };
3643
3603
  }
3644
3604
 
@@ -3762,7 +3722,7 @@ class TangramConstructPlugin {
3762
3722
  target: trial.target,
3763
3723
  input: trial.input,
3764
3724
  layout: trial.layout,
3765
- time_limit_ms: trial.time_limit_ms || 0,
3725
+ time_limit_ms: trial.time_limit_ms,
3766
3726
  onInteraction: trial.onInteraction,
3767
3727
  onTrialEnd: wrappedOnTrialEnd
3768
3728
  };
@@ -3785,6 +3745,8 @@ function startPrepTrial(display_element, params, jsPsych) {
3785
3745
  } = params;
3786
3746
  const prepSectors = Array.from({ length: numQuickstashSlots }, (_, i) => ({
3787
3747
  id: `prep-sector-${i}`,
3748
+ tangramId: `prep-sector-${i}`,
3749
+ // dummy value since prep mode doesn't have tangrams
3788
3750
  silhouette: {
3789
3751
  id: `prep-silhouette-${i}`,
3790
3752
  mask: []
@@ -3955,7 +3917,7 @@ class TangramPrepPlugin {
3955
3917
  this.jsPsych.finishTrial(data);
3956
3918
  };
3957
3919
  const params = {
3958
- numQuickstashSlots: trial.num_quickstash_slots || 4,
3920
+ numQuickstashSlots: trial.num_quickstash_slots,
3959
3921
  maxPiecesPerMacro: trial.max_pieces_per_macro,
3960
3922
  minPiecesPerMacro: trial.min_pieces_per_macro,
3961
3923
  inputMode: trial.input,