ts-fsrs 5.2.1 → 5.2.3

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.d.ts CHANGED
@@ -387,7 +387,7 @@ declare const FSRS5_DEFAULT_DECAY = 0.5;
387
387
  declare const FSRS6_DEFAULT_DECAY = 0.1542;
388
388
  declare const default_w: readonly number[];
389
389
  declare const W17_W18_Ceiling = 2;
390
- declare const CLAMP_PARAMETERS: (w17_w18_ceiling: number) => number[][];
390
+ declare const CLAMP_PARAMETERS: (w17_w18_ceiling: number, enable_short_term?: boolean) => number[][];
391
391
 
392
392
  declare class TypeConvert {
393
393
  static card<T extends Card | CardInput>(card: T): Card;
@@ -397,7 +397,7 @@ declare class TypeConvert {
397
397
  static review_log(log: ReviewLogInput | ReviewLog): ReviewLog;
398
398
  }
399
399
 
400
- declare const clipParameters: (parameters: number[], numRelearningSteps: number) => number[];
400
+ declare const clipParameters: (parameters: number[], numRelearningSteps: number, enableShortTerm?: boolean) => number[];
401
401
  /**
402
402
  * @returns The input if the parameters are valid, throws if they are invalid
403
403
  * @example
@@ -410,7 +410,7 @@ declare const clipParameters: (parameters: number[], numRelearningSteps: number)
410
410
  * }
411
411
  */
412
412
  declare const checkParameters: (parameters: number[] | readonly number[]) => number[] | readonly number[];
413
- declare const migrateParameters: (parameters?: number[] | readonly number[]) => number[];
413
+ declare const migrateParameters: (parameters?: number[] | readonly number[], numRelearningSteps?: number, enableShortTerm?: boolean) => number[];
414
414
  declare const generatorParameters: (props?: Partial<FSRSParameters>) => FSRSParameters;
415
415
  /**
416
416
  * Create an empty card
package/dist/index.mjs CHANGED
@@ -52,8 +52,9 @@ class TypeConvert {
52
52
  throw new Error(`Invalid state:[${value}]`);
53
53
  }
54
54
  static time(value) {
55
- if (typeof value === "object" && value instanceof Date) {
56
- return value;
55
+ const date = new Date(value);
56
+ if (typeof value === "object" && value !== null && !Number.isNaN(Date.parse(value) || +date)) {
57
+ return date;
57
58
  } else if (typeof value === "string") {
58
59
  const timestamp = Date.parse(value);
59
60
  if (!Number.isNaN(timestamp)) {
@@ -466,7 +467,7 @@ function alea(seed) {
466
467
  return prng;
467
468
  }
468
469
 
469
- const version="5.2.1";
470
+ const version="5.2.3";
470
471
 
471
472
  const default_request_retention = 0.9;
472
473
  const default_maximum_interval = 36500;
@@ -509,7 +510,7 @@ const default_w = Object.freeze([
509
510
  FSRS6_DEFAULT_DECAY
510
511
  ]);
511
512
  const W17_W18_Ceiling = 2;
512
- const CLAMP_PARAMETERS = (w17_w18_ceiling) => [
513
+ const CLAMP_PARAMETERS = (w17_w18_ceiling, enable_short_term = default_enable_short_term) => [
513
514
  [S_MIN, INIT_S_MAX],
514
515
  [S_MIN, INIT_S_MAX],
515
516
  [S_MIN, INIT_S_MAX],
@@ -529,18 +530,26 @@ const CLAMP_PARAMETERS = (w17_w18_ceiling) => [
529
530
  [1, 6],
530
531
  [0, w17_w18_ceiling],
531
532
  [0, w17_w18_ceiling],
532
- [0, 0.8],
533
+ [
534
+ enable_short_term ? 0.01 : 0,
535
+ 0.8
536
+ ],
533
537
  [0.1, 0.8]
534
538
  ];
535
539
 
536
- const clipParameters = (parameters, numRelearningSteps) => {
540
+ const clipParameters = (parameters, numRelearningSteps, enableShortTerm = default_enable_short_term) => {
537
541
  let w17_w18_ceiling = W17_W18_Ceiling;
538
542
  if (Math.max(0, numRelearningSteps) > 1) {
539
543
  const value = -(Math.log(parameters[11]) + Math.log(Math.pow(2, parameters[13]) - 1) + parameters[14] * 0.3) / numRelearningSteps;
540
544
  w17_w18_ceiling = clamp(+value.toFixed(8), 0.01, 2);
541
545
  }
542
- const clip = CLAMP_PARAMETERS(w17_w18_ceiling);
543
- return clip.map(([min, max], index) => clamp(parameters[index], min, max));
546
+ const clip = CLAMP_PARAMETERS(w17_w18_ceiling, enableShortTerm).slice(
547
+ 0,
548
+ parameters.length
549
+ );
550
+ return clip.map(
551
+ ([min, max], index) => clamp(parameters[index] || 0, min, max)
552
+ );
544
553
  };
545
554
  const checkParameters = (parameters) => {
546
555
  const invalid = parameters.find(
@@ -555,18 +564,30 @@ const checkParameters = (parameters) => {
555
564
  }
556
565
  return parameters;
557
566
  };
558
- const migrateParameters = (parameters) => {
567
+ const migrateParameters = (parameters, numRelearningSteps = 0, enableShortTerm = default_enable_short_term) => {
559
568
  if (parameters === void 0) {
560
569
  return [...default_w];
561
570
  }
562
571
  switch (parameters.length) {
563
572
  case 21:
564
- return [...parameters];
573
+ return clipParameters(
574
+ Array.from(parameters),
575
+ numRelearningSteps,
576
+ enableShortTerm
577
+ );
565
578
  case 19:
566
579
  console.debug("[FSRS-6]auto fill w from 19 to 21 length");
567
- return [...parameters, 0, FSRS5_DEFAULT_DECAY];
580
+ return clipParameters(
581
+ Array.from(parameters),
582
+ numRelearningSteps,
583
+ enableShortTerm
584
+ ).concat([0, FSRS5_DEFAULT_DECAY]);
568
585
  case 17: {
569
- const w = [...parameters];
586
+ const w = clipParameters(
587
+ Array.from(parameters),
588
+ numRelearningSteps,
589
+ enableShortTerm
590
+ );
570
591
  w[4] = +(w[5] * 2 + w[4]).toFixed(8);
571
592
  w[5] = +(Math.log(w[5] * 3 + 1) / 3).toFixed(8);
572
593
  w[6] = +(w[6] + 0.5).toFixed(8);
@@ -581,13 +602,18 @@ const migrateParameters = (parameters) => {
581
602
  const generatorParameters = (props) => {
582
603
  const learning_steps = Array.isArray(props?.learning_steps) ? props.learning_steps : default_learning_steps;
583
604
  const relearning_steps = Array.isArray(props?.relearning_steps) ? props.relearning_steps : default_relearning_steps;
584
- const w = clipParameters(migrateParameters(props?.w), relearning_steps.length);
605
+ const enable_short_term = props?.enable_short_term ?? default_enable_short_term;
606
+ const w = migrateParameters(
607
+ props?.w,
608
+ relearning_steps.length,
609
+ enable_short_term
610
+ );
585
611
  return {
586
612
  request_retention: props?.request_retention || default_request_retention,
587
613
  maximum_interval: props?.maximum_interval || default_maximum_interval,
588
614
  w,
589
615
  enable_fuzz: props?.enable_fuzz ?? default_enable_fuzz,
590
- enable_short_term: props?.enable_short_term ?? default_enable_short_term,
616
+ enable_short_term,
591
617
  learning_steps,
592
618
  relearning_steps
593
619
  };
@@ -677,9 +703,10 @@ class FSRSAlgorithm {
677
703
  Number(value)
678
704
  );
679
705
  } else if (prop === "w") {
680
- value = clipParameters(
681
- migrateParameters(value),
682
- target.relearning_steps.length
706
+ value = migrateParameters(
707
+ value,
708
+ target.relearning_steps.length,
709
+ target.enable_short_term
683
710
  );
684
711
  _this.forgetting_curve = forgetting_curve.bind(this, value);
685
712
  _this.intervalModifier = _this.calculate_interval_modifier(
@@ -1492,9 +1519,10 @@ class FSRS extends FSRSAlgorithm {
1492
1519
  } else if (prop === "enable_short_term") {
1493
1520
  _this.Scheduler = value === true ? BasicScheduler : LongTermScheduler;
1494
1521
  } else if (prop === "w") {
1495
- value = clipParameters(
1496
- migrateParameters(value),
1497
- target.relearning_steps.length
1522
+ value = migrateParameters(
1523
+ value,
1524
+ target.relearning_steps.length,
1525
+ target.enable_short_term
1498
1526
  );
1499
1527
  _this.forgetting_curve = forgetting_curve.bind(this, value);
1500
1528
  _this.intervalModifier = _this.calculate_interval_modifier(