@prtcl/plonk 1.0.10 → 1.1.1

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
@@ -24,6 +24,7 @@ var index_exports = {};
24
24
  __export(index_exports, {
25
25
  Drunk: () => Drunk,
26
26
  Env: () => Env,
27
+ Fold: () => Fold,
27
28
  Frames: () => Frames,
28
29
  MS_IN_HOUR: () => MS_IN_HOUR,
29
30
  MS_IN_MINUTE: () => MS_IN_MINUTE,
@@ -35,11 +36,23 @@ __export(index_exports, {
35
36
  Scale: () => Scale,
36
37
  Sine: () => Sine,
37
38
  TimeFormat: () => TimeFormat,
39
+ Wrap: () => Wrap,
38
40
  clamp: () => clamp,
41
+ drunk: () => drunk,
42
+ env: () => env,
39
43
  expo: () => expo,
44
+ fold: () => fold,
45
+ frames: () => frames,
46
+ metro: () => metro,
40
47
  ms: () => ms,
41
48
  now: () => now,
42
- wait: () => wait
49
+ rand: () => rand,
50
+ scale: () => scale,
51
+ sigmoid: () => sigmoid,
52
+ sine: () => sine,
53
+ tanh: () => tanh,
54
+ wait: () => wait,
55
+ wrap: () => wrap
43
56
  });
44
57
  module.exports = __toCommonJS(index_exports);
45
58
 
@@ -59,7 +72,7 @@ function clamp(n, min, max) {
59
72
  return Math.min(Math.max(n, a), b);
60
73
  }
61
74
 
62
- // src/Rand.ts
75
+ // src/rand.ts
63
76
  var parseOptions = (opts) => {
64
77
  return {
65
78
  min: 0,
@@ -74,9 +87,11 @@ var Rand = class _Rand {
74
87
  this.state = { max, min, value: 0 };
75
88
  this.next();
76
89
  }
90
+ /** Returns a single random value. One-off form of `new Rand(opts).value()`. */
77
91
  static rand(opts) {
78
92
  return new _Rand(opts).value();
79
93
  }
94
+ /** Updates the range bounds, clamping the current value if needed. */
80
95
  setRange(partialOpts) {
81
96
  const { value = 0 } = this.state;
82
97
  const { min, max } = {
@@ -90,9 +105,11 @@ var Rand = class _Rand {
90
105
  value: clamp(value, min, max)
91
106
  };
92
107
  }
108
+ /** Returns the current value. */
93
109
  value() {
94
110
  return this.state.value;
95
111
  }
112
+ /** Generates a new random value within the range. */
96
113
  next() {
97
114
  const { min, max } = this.state;
98
115
  const updates = Math.random() * (max - min) + min;
@@ -100,8 +117,9 @@ var Rand = class _Rand {
100
117
  return updates;
101
118
  }
102
119
  };
120
+ var rand = Rand.rand;
103
121
 
104
- // src/Drunk.ts
122
+ // src/drunk.ts
105
123
  var DEFAULT_DRUNK_STEP = 0.1;
106
124
  var parseStepSize = (step) => typeof step !== "undefined" ? clamp(step, 0, 1) : DEFAULT_DRUNK_STEP;
107
125
  var parseOptions2 = (opts) => {
@@ -115,7 +133,7 @@ var parseOptions2 = (opts) => {
115
133
  ...restOpts
116
134
  };
117
135
  };
118
- var Drunk = class {
136
+ var Drunk = class _Drunk {
119
137
  constructor(opts) {
120
138
  __publicField(this, "state");
121
139
  __publicField(this, "_initialValue");
@@ -132,6 +150,11 @@ var Drunk = class {
132
150
  value: initialValue
133
151
  };
134
152
  }
153
+ /** Creates a new Drunk instance. Alternative form of `new Drunk(opts)`. */
154
+ static drunk(opts) {
155
+ return new _Drunk(opts);
156
+ }
157
+ /** Updates the walk bounds, clamping the current value if needed. */
135
158
  setRange(partialOpts) {
136
159
  const { max, min } = {
137
160
  min: this.state.min,
@@ -152,6 +175,7 @@ var Drunk = class {
152
175
  }
153
176
  };
154
177
  }
178
+ /** Updates the maximum step size. */
155
179
  setStepSize(partialOpts) {
156
180
  const step = parseStepSize(partialOpts?.step);
157
181
  this.state = {
@@ -159,6 +183,7 @@ var Drunk = class {
159
183
  step
160
184
  };
161
185
  }
186
+ /** Resets the walk with optional new options. */
162
187
  reset(opts) {
163
188
  const { min, max, startsAt, step } = parseOptions2(opts);
164
189
  this.setRange({ min, max });
@@ -170,9 +195,11 @@ var Drunk = class {
170
195
  value: initialValue
171
196
  };
172
197
  }
198
+ /** Returns the current value. */
173
199
  value() {
174
200
  return this.state.value;
175
201
  }
202
+ /** Advances one step and returns the new value. */
176
203
  next() {
177
204
  const { min, max, step, value } = this.state;
178
205
  const updates = clamp(value + max * this._step.next() * step, min, max);
@@ -180,8 +207,29 @@ var Drunk = class {
180
207
  return updates;
181
208
  }
182
209
  };
210
+ var drunk = Drunk.drunk;
211
+
212
+ // src/now.ts
213
+ var innerNow = (() => {
214
+ if (typeof performance !== "undefined" && "now" in performance) {
215
+ return () => performance.now();
216
+ }
217
+ if (typeof process === "object" && process.toString() === "[object process]") {
218
+ const ts = () => {
219
+ const hr = process.hrtime();
220
+ return hr[0] * 1e9 + hr[1];
221
+ };
222
+ const initialNow2 = ts();
223
+ return () => (ts() - initialNow2) / 1e6;
224
+ }
225
+ const initialNow = Date.now();
226
+ return () => Date.now() - initialNow;
227
+ })();
228
+ function now() {
229
+ return innerNow();
230
+ }
183
231
 
184
- // src/Scale.ts
232
+ // src/scale.ts
185
233
  var computeRatio = (from, to) => (to.max - to.min) / (from.max - from.min);
186
234
  var parseInitialState = (opts) => {
187
235
  const initialRange = {
@@ -225,18 +273,23 @@ var Scale = class _Scale {
225
273
  __publicField(this, "state");
226
274
  this.state = parseInitialState(opts);
227
275
  }
276
+ /** Scales a single value. One-off form of `new Scale(opts).scale(n)`. */
228
277
  static scale(n, opts) {
229
278
  return new _Scale(opts).scale(n);
230
279
  }
280
+ /** Updates input and/or output ranges, recomputing the internal ratio. */
231
281
  setRanges(opts) {
232
282
  this.state = updateStateFromOptions(opts, this.state);
233
283
  }
284
+ /** Resets with new range options. */
234
285
  reset(opts) {
235
286
  this.state = parseInitialState(opts);
236
287
  }
288
+ /** Returns the last scaled value. */
237
289
  value() {
238
290
  return this.state.value;
239
291
  }
292
+ /** Maps a value from the input range to the output range. */
240
293
  scale(n) {
241
294
  const { from, to, ratio } = this.state;
242
295
  const updates = to.min + (clamp(n, from.min, from.max) - from.min) * ratio;
@@ -244,28 +297,9 @@ var Scale = class _Scale {
244
297
  return updates;
245
298
  }
246
299
  };
300
+ var scale = Scale.scale;
247
301
 
248
- // src/now.ts
249
- var innerNow = (() => {
250
- if (typeof performance !== "undefined" && "now" in performance) {
251
- return () => performance.now();
252
- }
253
- if (typeof process === "object" && process.toString() === "[object process]") {
254
- const ts = () => {
255
- const hr = process.hrtime();
256
- return hr[0] * 1e9 + hr[1];
257
- };
258
- const initialNow2 = ts();
259
- return () => (ts() - initialNow2) / 1e6;
260
- }
261
- const initialNow = Date.now();
262
- return () => Date.now() - initialNow;
263
- })();
264
- function now() {
265
- return innerNow();
266
- }
267
-
268
- // src/Env.ts
302
+ // src/env.ts
269
303
  var parseOptions3 = (opts) => {
270
304
  return {
271
305
  duration: 0,
@@ -297,7 +331,7 @@ var updateStateFromOptions2 = (opts, prevState) => {
297
331
  totalElapsed: 0
298
332
  };
299
333
  };
300
- var Env = class {
334
+ var Env = class _Env {
301
335
  constructor(opts) {
302
336
  __publicField(this, "state");
303
337
  __publicField(this, "_interpolator");
@@ -314,6 +348,11 @@ var Env = class {
314
348
  }
315
349
  });
316
350
  }
351
+ /** Creates a new Env instance. Alternative form of `new Env(opts)`. */
352
+ static env(opts) {
353
+ return new _Env(opts);
354
+ }
355
+ /** Updates the envelope duration. */
317
356
  setDuration(duration) {
318
357
  const { to, totalElapsed } = this.state;
319
358
  this.state = {
@@ -324,6 +363,7 @@ var Env = class {
324
363
  } : { duration }
325
364
  };
326
365
  }
366
+ /** Restarts the envelope with optional new options. */
327
367
  reset(opts) {
328
368
  const updates = updateStateFromOptions2(opts, this.state);
329
369
  this.state = {
@@ -342,9 +382,11 @@ var Env = class {
342
382
  }
343
383
  });
344
384
  }
385
+ /** Returns true when the envelope has completed. */
345
386
  done() {
346
387
  return this.state.duration <= this.state.totalElapsed;
347
388
  }
389
+ /** Returns the current interpolated value. */
348
390
  value() {
349
391
  const { to, value } = this.state;
350
392
  if (this.done()) {
@@ -352,6 +394,7 @@ var Env = class {
352
394
  }
353
395
  return value;
354
396
  }
397
+ /** Advances the envelope and returns the new value. */
355
398
  next() {
356
399
  if (this.done()) {
357
400
  return this.value();
@@ -367,8 +410,73 @@ var Env = class {
367
410
  return updates;
368
411
  }
369
412
  };
413
+ var env = Env.env;
414
+
415
+ // src/fold.ts
416
+ var parseOptions4 = (opts) => {
417
+ return {
418
+ min: 0,
419
+ max: 1,
420
+ ...opts
421
+ };
422
+ };
423
+ var Fold = class _Fold {
424
+ constructor(opts) {
425
+ __publicField(this, "state");
426
+ const { min, max } = parseOptions4(opts);
427
+ this.state = { min, max, value: min };
428
+ }
429
+ /** Folds a single value. One-off form of `new Fold(opts).fold(n)`. */
430
+ static fold(n, opts) {
431
+ return new _Fold(opts).fold(n);
432
+ }
433
+ /** Updates the range bounds, folding the current value into the new range. */
434
+ setRange(partialOpts) {
435
+ const { min, max } = { ...this.state, ...partialOpts };
436
+ this.state = {
437
+ ...this.state,
438
+ min,
439
+ max,
440
+ value: transform(this.state.value, min, max)
441
+ };
442
+ }
443
+ /** Returns the last folded value. */
444
+ value() {
445
+ return this.state.value;
446
+ }
447
+ /** Folds a value into the configured range and caches the result. */
448
+ fold(n) {
449
+ const { min, max } = this.state;
450
+ const updates = transform(n, min, max);
451
+ this.state.value = updates;
452
+ return updates;
453
+ }
454
+ };
455
+ var fold = Fold.fold;
456
+ function transform(n, min, max) {
457
+ let a = 0;
458
+ let b = 1;
459
+ if (typeof min === "number") {
460
+ if (typeof max === "number") {
461
+ a = min;
462
+ b = max;
463
+ } else {
464
+ a = 0;
465
+ b = min;
466
+ }
467
+ }
468
+ const lo = Math.min(a, b);
469
+ const hi = Math.max(a, b);
470
+ const range = hi - lo;
471
+ if (range === 0) return lo;
472
+ const period = range * 2;
473
+ const offset = n - lo;
474
+ const normalized = (offset % period + period) % period;
475
+ const value = normalized <= range ? lo + normalized : lo + period - normalized;
476
+ return clamp(value, lo, hi);
477
+ }
370
478
 
371
- // src/Sine.ts
479
+ // src/sine.ts
372
480
  var SINE_PERIOD = Math.PI * 2 - 1e-4;
373
481
  var getInitialState2 = (duration) => ({
374
482
  cycle: 0,
@@ -377,7 +485,7 @@ var getInitialState2 = (duration) => ({
377
485
  totalElapsed: 0,
378
486
  value: 0
379
487
  });
380
- var Sine = class {
488
+ var Sine = class _Sine {
381
489
  constructor(opts) {
382
490
  __publicField(this, "state");
383
491
  __publicField(this, "_interpolator");
@@ -394,12 +502,18 @@ var Sine = class {
394
502
  });
395
503
  this.state = getInitialState2(duration);
396
504
  }
505
+ /** Creates a new Sine instance. Alternative form of `new Sine(opts)`. */
506
+ static sine(opts) {
507
+ return new _Sine(opts);
508
+ }
509
+ /** Updates the cycle duration. */
397
510
  setDuration(duration) {
398
511
  this.state = {
399
512
  ...this.state,
400
513
  duration
401
514
  };
402
515
  }
516
+ /** Resets the oscillator with optional new options. */
403
517
  reset(opts) {
404
518
  const { duration } = {
405
519
  ...this.state,
@@ -407,9 +521,11 @@ var Sine = class {
407
521
  };
408
522
  this.state = getInitialState2(duration);
409
523
  }
524
+ /** Returns the current oscillator value. */
410
525
  value() {
411
526
  return this.state.value;
412
527
  }
528
+ /** Advances the oscillator and returns the new value. */
413
529
  next() {
414
530
  const { cycle, duration, prev, totalElapsed: prevTotalElapsed } = this.state;
415
531
  const curr = now();
@@ -427,6 +543,70 @@ var Sine = class {
427
543
  return updates;
428
544
  }
429
545
  };
546
+ var sine = Sine.sine;
547
+
548
+ // src/wrap.ts
549
+ var parseOptions5 = (opts) => {
550
+ return {
551
+ min: 0,
552
+ max: 1,
553
+ ...opts
554
+ };
555
+ };
556
+ var Wrap = class _Wrap {
557
+ constructor(opts) {
558
+ __publicField(this, "state");
559
+ const { min, max } = parseOptions5(opts);
560
+ this.state = { min, max, value: min };
561
+ }
562
+ /** Wraps a single value. One-off form of `new Wrap(opts).wrap(n)`. */
563
+ static wrap(n, opts) {
564
+ return new _Wrap(opts).wrap(n);
565
+ }
566
+ /** Updates the range bounds, wrapping the current value into the new range. */
567
+ setRange(partialOpts) {
568
+ const { min, max } = {
569
+ ...this.state,
570
+ ...partialOpts
571
+ };
572
+ this.state = {
573
+ ...this.state,
574
+ min,
575
+ max,
576
+ value: transform2(this.state.value, min, max)
577
+ };
578
+ }
579
+ /** Returns the last wrapped value. */
580
+ value() {
581
+ return this.state.value;
582
+ }
583
+ /** Wraps a value into the configured range and caches the result. */
584
+ wrap(n) {
585
+ const { min, max } = this.state;
586
+ const updates = transform2(n, min, max);
587
+ this.state.value = updates;
588
+ return updates;
589
+ }
590
+ };
591
+ var wrap = Wrap.wrap;
592
+ function transform2(n, min, max) {
593
+ let a = 0;
594
+ let b = 1;
595
+ if (typeof min === "number") {
596
+ if (typeof max === "number") {
597
+ a = min;
598
+ b = max;
599
+ } else {
600
+ a = 0;
601
+ b = min;
602
+ }
603
+ }
604
+ const lo = Math.min(a, b);
605
+ const range = Math.max(a, b) - lo;
606
+ if (range === 0) return lo;
607
+ const offset = n - lo;
608
+ return lo + (offset % range + range) % range;
609
+ }
430
610
 
431
611
  // src/constants.ts
432
612
  var SIXTY_FPS = 1e3 / 60;
@@ -434,7 +614,7 @@ var MS_IN_SECOND = 1e3;
434
614
  var MS_IN_MINUTE = 60 * MS_IN_SECOND;
435
615
  var MS_IN_HOUR = MS_IN_MINUTE * 60;
436
616
 
437
- // src/Metro.ts
617
+ // src/metro.ts
438
618
  var getInitialState3 = (initialTime) => {
439
619
  return {
440
620
  initialTime,
@@ -468,26 +648,29 @@ var processTimerState = (state) => {
468
648
  totalElapsed: totalElapsed + tickInterval
469
649
  };
470
650
  };
471
- var parseOptions4 = (opts) => {
651
+ var parseOptions6 = (opts) => {
472
652
  return {
473
653
  time: SIXTY_FPS,
474
654
  ...opts
475
655
  };
476
656
  };
477
- var Metro = class {
657
+ var Metro = class _Metro {
478
658
  constructor(callback, opts) {
479
659
  __publicField(this, "state");
480
660
  __publicField(this, "_listeners");
661
+ /** Stops the timer and returns total elapsed time in milliseconds. */
481
662
  __publicField(this, "stop", () => {
482
663
  const { totalElapsed } = this.state;
483
664
  this.reset();
484
665
  this.clearAsyncHandler();
485
666
  return totalElapsed;
486
667
  });
668
+ /** Resets state to initial values. */
487
669
  __publicField(this, "reset", () => {
488
670
  const { initialTime } = this.state;
489
671
  this.state = getInitialState3(initialTime);
490
672
  });
673
+ /** Updates the tick interval in milliseconds. */
491
674
  __publicField(this, "setTime", (updatedTime = this.state.time) => {
492
675
  const time = Math.max(updatedTime, 0);
493
676
  this.state = {
@@ -496,6 +679,7 @@ var Metro = class {
496
679
  initialTime: time
497
680
  };
498
681
  });
682
+ /** Starts the timer loop. */
499
683
  __publicField(this, "run", () => {
500
684
  if (this.state.isRunning) {
501
685
  this.stop();
@@ -519,10 +703,14 @@ var Metro = class {
519
703
  };
520
704
  tick();
521
705
  });
522
- const { time } = parseOptions4(opts);
706
+ const { time } = parseOptions6(opts);
523
707
  this.state = getInitialState3(time);
524
708
  this._listeners = [callback];
525
709
  }
710
+ /** Creates a new Metro instance. Alternative form of `new Metro(callback, opts)`. */
711
+ static metro(callback, opts) {
712
+ return new _Metro(callback, opts);
713
+ }
526
714
  asyncHandler(callback) {
527
715
  this._timerId = setTimeout(callback, SIXTY_FPS);
528
716
  }
@@ -530,6 +718,7 @@ var Metro = class {
530
718
  clearTimeout(this._timerId);
531
719
  }
532
720
  };
721
+ var metro = Metro.metro;
533
722
 
534
723
  // src/ms.ts
535
724
  var TimeFormat = /* @__PURE__ */ ((TimeFormat2) => {
@@ -598,9 +787,9 @@ function ms(val, format) {
598
787
  return formatter(parsedValue);
599
788
  }
600
789
 
601
- // src/Frames.ts
790
+ // src/frames.ts
602
791
  var DEFAULT_FPS = 60;
603
- var parseOptions5 = (opts) => {
792
+ var parseOptions7 = (opts) => {
604
793
  const { fps } = {
605
794
  fps: DEFAULT_FPS,
606
795
  ...opts
@@ -609,13 +798,18 @@ var parseOptions5 = (opts) => {
609
798
  time: ms(fps, "fps" /* FPS */)
610
799
  };
611
800
  };
612
- var Frames = class extends Metro {
801
+ var Frames = class _Frames extends Metro {
613
802
  constructor(callback, opts) {
614
- super(() => callback(this), parseOptions5(opts));
803
+ super(() => callback(this), parseOptions7(opts));
804
+ /** Updates the target frames per second. */
615
805
  __publicField(this, "setFPS", (fps = DEFAULT_FPS) => {
616
806
  this.setTime(ms(fps, "fps" /* FPS */));
617
807
  });
618
808
  }
809
+ /** Creates a new Frames instance. Alternative form of `new Frames(callback, opts)`. */
810
+ static frames(callback, opts) {
811
+ return new _Frames(callback, opts);
812
+ }
619
813
  asyncHandler(callback) {
620
814
  if (typeof window === "undefined" || !("requestAnimationFrame" in window)) {
621
815
  super.asyncHandler(callback);
@@ -631,12 +825,31 @@ var Frames = class extends Metro {
631
825
  }
632
826
  }
633
827
  };
828
+ var frames = Frames.frames;
634
829
 
635
830
  // src/expo.ts
636
831
  function expo(n) {
637
832
  return Math.pow(clamp(n, 0, 1), Math.E);
638
833
  }
639
834
 
835
+ // src/sigmoid.ts
836
+ function logistic(v, k) {
837
+ return 1 / (1 + Math.exp(-k * (v - 0.5)));
838
+ }
839
+ function sigmoid(n, k = 5) {
840
+ const x = clamp(n, 0, 1);
841
+ if (k === 0) return x;
842
+ const f0 = logistic(0, k);
843
+ return (logistic(x, k) - f0) / (logistic(1, k) - f0);
844
+ }
845
+
846
+ // src/tanh.ts
847
+ function tanh(n, k = 5) {
848
+ const x = clamp(n, -1, 1);
849
+ if (k === 0) return x;
850
+ return Math.tanh(k * x) / Math.tanh(k);
851
+ }
852
+
640
853
  // src/wait.ts
641
854
  function wait(time) {
642
855
  return new Promise((resolve) => setTimeout(resolve, time));
@@ -645,6 +858,7 @@ function wait(time) {
645
858
  0 && (module.exports = {
646
859
  Drunk,
647
860
  Env,
861
+ Fold,
648
862
  Frames,
649
863
  MS_IN_HOUR,
650
864
  MS_IN_MINUTE,
@@ -656,10 +870,22 @@ function wait(time) {
656
870
  Scale,
657
871
  Sine,
658
872
  TimeFormat,
873
+ Wrap,
659
874
  clamp,
875
+ drunk,
876
+ env,
660
877
  expo,
878
+ fold,
879
+ frames,
880
+ metro,
661
881
  ms,
662
882
  now,
663
- wait
883
+ rand,
884
+ scale,
885
+ sigmoid,
886
+ sine,
887
+ tanh,
888
+ wait,
889
+ wrap
664
890
  });
665
891
  //# sourceMappingURL=index.cjs.map