jspsych-tangram 0.0.4 → 0.0.6

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/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 =====
@@ -3155,7 +3154,9 @@ function GameBoard(props) {
3155
3154
  if (allSectorsComplete && !gameCompleted) {
3156
3155
  setGameCompleted(true);
3157
3156
  if (tracker) {
3158
- tracker.finalizeTrial("auto_complete");
3157
+ setTimeout(() => {
3158
+ tracker.finalizeTrial("auto_complete");
3159
+ }, 0);
3159
3160
  }
3160
3161
  }
3161
3162
  };
@@ -3548,33 +3549,18 @@ function startConstructionTrial(display_element, params, _jsPsych) {
3548
3549
  "medtriangle",
3549
3550
  "largetriangle"
3550
3551
  ]);
3551
- console.log("[ConstructionApp] Starting tangram conversion...");
3552
- console.log("[ConstructionApp] Received tangrams:", params.tangrams);
3553
- console.log("[ConstructionApp] Number of tangrams:", params.tangrams.length);
3552
+ const PRIMITIVE_BLUEPRINTS_ORDERED = [...PRIMITIVE_BLUEPRINTS].sort((a, b) => params.primitiveOrder.indexOf(a.kind) - params.primitiveOrder.indexOf(b.kind));
3554
3553
  const sectors = params.tangrams.map((tangramSpec, index) => {
3555
- console.log(`
3556
- [ConstructionApp] Processing tangram ${index}:`, tangramSpec);
3557
- console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
3558
- console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
3559
- console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
3560
- console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
3561
3554
  const filteredTans = tangramSpec.solutionTans.filter((tan) => {
3562
3555
  const tanName = tan.name ?? tan.kind;
3563
3556
  const isCanonical = CANON.has(tanName);
3564
- console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
3565
3557
  return isCanonical;
3566
3558
  });
3567
- console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
3568
3559
  const mask = filteredTans.map((tan, tanIndex) => {
3569
- const tanName = tan.name ?? tan.kind;
3570
3560
  const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
3571
- console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
3572
- console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
3573
3561
  return polygon;
3574
3562
  });
3575
3563
  const sectorId = `sector${index}`;
3576
- console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
3577
- console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
3578
3564
  const sector = {
3579
3565
  id: sectorId,
3580
3566
  tangramId: tangramSpec.tangramID,
@@ -3583,61 +3569,37 @@ function startConstructionTrial(display_element, params, _jsPsych) {
3583
3569
  mask
3584
3570
  }
3585
3571
  };
3586
- console.log(`[ConstructionApp] Created sector:`, sector);
3587
3572
  return sector;
3588
3573
  });
3589
- console.log("\n[ConstructionApp] Final sectors array:", sectors);
3590
- console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
3591
- console.log("\n[ConstructionApp] Processing quickstash macros...");
3592
- console.log("[ConstructionApp] quickstash_macros:", params.quickstash_macros);
3593
- console.log("[ConstructionApp] quickstash_macros count:", params.quickstash_macros?.length ?? 0);
3594
3574
  let quickstash = [];
3595
3575
  if (params.quickstash_macros && params.quickstash_macros.length > 0) {
3596
3576
  const firstMacro = params.quickstash_macros[0];
3597
- console.log("[ConstructionApp] First macro:", firstMacro);
3598
3577
  if (firstMacro && "parts" in firstMacro && firstMacro.parts && firstMacro.parts[0] && "anchorOffset" in firstMacro.parts[0]) {
3599
- console.log("[ConstructionApp] Detected anchor-based composites, converting to pixels...");
3600
3578
  const primsByKind = /* @__PURE__ */ new Map();
3601
- PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
3579
+ PRIMITIVE_BLUEPRINTS_ORDERED.forEach((p) => primsByKind.set(p.kind, p));
3602
3580
  quickstash = params.quickstash_macros.map(
3603
3581
  (anchorComposite) => convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx)
3604
3582
  // Use current CONFIG grid step
3605
3583
  );
3606
- console.log("[ConstructionApp] Converted to pixel-based blueprints:", quickstash);
3607
3584
  } else {
3608
- console.log("[ConstructionApp] Already pixel-based blueprints");
3609
3585
  quickstash = params.quickstash_macros;
3610
3586
  }
3611
- } else {
3612
- console.log("[ConstructionApp] No quickstash macros provided");
3613
3587
  }
3614
3588
  const gameBoardProps = {
3615
3589
  sectors,
3616
3590
  quickstash,
3617
- primitives: PRIMITIVE_BLUEPRINTS,
3618
- layout: params.layout || "semicircle",
3619
- target: params.target || "silhouette",
3620
- input: params.input || "drag",
3621
- timeLimitMs: params.time_limit_ms || 0,
3591
+ primitives: PRIMITIVE_BLUEPRINTS_ORDERED,
3592
+ layout: params.layout,
3593
+ target: params.target,
3594
+ input: params.input,
3595
+ timeLimitMs: params.time_limit_ms,
3622
3596
  maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
3623
3597
  mode: "construction",
3624
- // Explicit construction mode
3625
3598
  ...params.onInteraction && { onInteraction: params.onInteraction },
3626
3599
  ...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
3627
3600
  };
3628
- console.log("\n[ConstructionApp] Final GameBoard props:");
3629
- console.log("[ConstructionApp] sectors count:", gameBoardProps.sectors.length);
3630
- console.log("[ConstructionApp] quickstash count:", gameBoardProps.quickstash.length);
3631
- console.log("[ConstructionApp] primitives count:", gameBoardProps.primitives.length);
3632
- console.log("[ConstructionApp] layout:", gameBoardProps.layout);
3633
- console.log("[ConstructionApp] target:", gameBoardProps.target);
3634
- console.log("[ConstructionApp] input:", gameBoardProps.input);
3635
- console.log("[ConstructionApp] timeLimitMs:", gameBoardProps.timeLimitMs);
3636
- console.log("[ConstructionApp] mode:", gameBoardProps.mode);
3637
- console.log("[ConstructionApp] Full props:", gameBoardProps);
3638
3601
  const root = client.createRoot(display_element);
3639
3602
  root.render(React.createElement(GameBoard, gameBoardProps));
3640
- console.log("[ConstructionApp] GameBoard rendered successfully");
3641
3603
  return { root, display_element, jsPsych: _jsPsych };
3642
3604
  }
3643
3605
 
@@ -3657,6 +3619,12 @@ const info$1 = {
3657
3619
  default: [],
3658
3620
  description: "Array of MacroSpec objects created in prep trial"
3659
3621
  },
3622
+ /** Array of primitive names in the order they should be displayed */
3623
+ primitive_order: {
3624
+ type: jspsych.ParameterType.OBJECT,
3625
+ default: ["square", "smalltriangle", "parallelogram", "medtriangle", "largetriangle"],
3626
+ description: "Array of primitive names in the order they should be displayed"
3627
+ },
3660
3628
  /** Whether to place pieces in workspace or directly on silhouette */
3661
3629
  target: {
3662
3630
  type: jspsych.ParameterType.SELECT,
@@ -3758,10 +3726,11 @@ class TangramConstructPlugin {
3758
3726
  const params = {
3759
3727
  tangrams: trial.tangrams,
3760
3728
  quickstash_macros: trial.quickstash_macros,
3729
+ primitiveOrder: trial.primitive_order,
3761
3730
  target: trial.target,
3762
3731
  input: trial.input,
3763
3732
  layout: trial.layout,
3764
- time_limit_ms: trial.time_limit_ms || 0,
3733
+ time_limit_ms: trial.time_limit_ms,
3765
3734
  onInteraction: trial.onInteraction,
3766
3735
  onTrialEnd: wrappedOnTrialEnd
3767
3736
  };
@@ -3779,9 +3748,11 @@ function startPrepTrial(display_element, params, jsPsych) {
3779
3748
  layoutMode,
3780
3749
  requireAllSlots,
3781
3750
  quickstashMacros,
3751
+ primitiveOrder,
3782
3752
  onInteraction,
3783
3753
  onTrialEnd
3784
3754
  } = params;
3755
+ const PRIMITIVE_BLUEPRINTS_ORDERED = [...PRIMITIVE_BLUEPRINTS].sort((a, b) => primitiveOrder.indexOf(a.kind) - primitiveOrder.indexOf(b.kind));
3785
3756
  const prepSectors = Array.from({ length: numQuickstashSlots }, (_, i) => ({
3786
3757
  id: `prep-sector-${i}`,
3787
3758
  tangramId: `prep-sector-${i}`,
@@ -3795,7 +3766,7 @@ function startPrepTrial(display_element, params, jsPsych) {
3795
3766
  const handleControllerReady = (controller, layout, force) => {
3796
3767
  if (quickstashMacros && quickstashMacros.length > 0 && layout) {
3797
3768
  const primsByKind = /* @__PURE__ */ new Map();
3798
- PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
3769
+ PRIMITIVE_BLUEPRINTS_ORDERED.forEach((p) => primsByKind.set(p.kind, p));
3799
3770
  quickstashMacros.forEach((anchorComposite, macroIndex) => {
3800
3771
  const sectorId = `prep-sector-${macroIndex}`;
3801
3772
  const compositeBlueprint = convertAnchorCompositeToPixels(
@@ -3852,7 +3823,7 @@ function startPrepTrial(display_element, params, jsPsych) {
3852
3823
  sectors: prepSectors,
3853
3824
  quickstash: [],
3854
3825
  // No pre-made macros
3855
- primitives: PRIMITIVE_BLUEPRINTS,
3826
+ primitives: PRIMITIVE_BLUEPRINTS_ORDERED,
3856
3827
  layout: layoutMode,
3857
3828
  target: "workspace",
3858
3829
  // Pieces go in sectors
@@ -3913,6 +3884,12 @@ const info = {
3913
3884
  default: [],
3914
3885
  description: "Array of AnchorComposite objects to edit as primitive pieces"
3915
3886
  },
3887
+ /** Array of primitive names in the order they should be displayed */
3888
+ primitive_order: {
3889
+ type: jspsych.ParameterType.OBJECT,
3890
+ default: ["square", "smalltriangle", "parallelogram", "medtriangle", "largetriangle"],
3891
+ description: "Array of primitive names in the order they should be displayed"
3892
+ },
3916
3893
  /** Callback fired after each interaction (optional analytics hook) */
3917
3894
  onInteraction: {
3918
3895
  type: jspsych.ParameterType.FUNCTION,
@@ -3956,13 +3933,14 @@ class TangramPrepPlugin {
3956
3933
  this.jsPsych.finishTrial(data);
3957
3934
  };
3958
3935
  const params = {
3959
- numQuickstashSlots: trial.num_quickstash_slots || 4,
3936
+ numQuickstashSlots: trial.num_quickstash_slots,
3960
3937
  maxPiecesPerMacro: trial.max_pieces_per_macro,
3961
3938
  minPiecesPerMacro: trial.min_pieces_per_macro,
3962
3939
  inputMode: trial.input,
3963
3940
  layoutMode: trial.layout,
3964
3941
  requireAllSlots: trial.require_all_slots,
3965
3942
  quickstashMacros: trial.quickstash_macros,
3943
+ primitiveOrder: trial.primitive_order,
3966
3944
  onInteraction: trial.onInteraction,
3967
3945
  onTrialEnd: wrappedOnTrialEnd
3968
3946
  };