@hapticjs/core 0.2.1 → 0.3.0

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
@@ -1,4 +1,4 @@
1
- export { accessibility, gaming, notifications, presets, system, ui } from './presets/index.js';
1
+ export { accessibility, emotions, gaming, notifications, presets, system, ui } from './presets/index.js';
2
2
 
3
3
  /** A single step in a haptic sequence */
4
4
  interface HapticStep {
@@ -267,6 +267,270 @@ declare class FallbackManager {
267
267
  */
268
268
  declare function detectAdapter(): HapticAdapter;
269
269
 
270
+ /** Options for SoundEngine construction */
271
+ interface SoundEngineOptions {
272
+ enabled?: boolean;
273
+ volume?: number;
274
+ muted?: boolean;
275
+ }
276
+ /** Options for the click sound */
277
+ interface ClickOptions {
278
+ pitch?: 'low' | 'mid' | 'high';
279
+ volume?: number;
280
+ }
281
+ /** Options for the generic tone player */
282
+ interface ToneOptions {
283
+ waveform?: OscillatorType;
284
+ volume?: number;
285
+ decay?: boolean;
286
+ }
287
+ /**
288
+ * Lightweight audio feedback engine using Web Audio API.
289
+ * Produces tiny UI sounds synced with haptics — all procedurally generated.
290
+ */
291
+ declare class SoundEngine {
292
+ private ctx;
293
+ private masterVolume;
294
+ private _muted;
295
+ private _enabled;
296
+ constructor(options?: SoundEngineOptions);
297
+ /** Short click sound */
298
+ click(options?: ClickOptions): Promise<void>;
299
+ /** Ultra-short tick sound */
300
+ tick(): Promise<void>;
301
+ /** Bubbly pop sound — quick frequency sweep high to low */
302
+ pop(): Promise<void>;
303
+ /** Swipe/swoosh sound — noise with quick fade */
304
+ whoosh(): Promise<void>;
305
+ /** Musical chime */
306
+ chime(note?: 'C4' | 'E4' | 'G4' | 'C5'): Promise<void>;
307
+ /** Low buzzer/error tone — two descending tones */
308
+ error(): Promise<void>;
309
+ /** Ascending two-tone success sound */
310
+ success(): Promise<void>;
311
+ /** Subtle tap sound */
312
+ tap(): Promise<void>;
313
+ /** Toggle sound — ascending for on, descending for off */
314
+ toggle(on: boolean): Promise<void>;
315
+ /** Generic tone player */
316
+ playTone(frequency: number, duration: number, options?: ToneOptions): Promise<void>;
317
+ /** Set master volume (0-1) */
318
+ setVolume(volume: number): void;
319
+ /** Mute all sounds */
320
+ mute(): void;
321
+ /** Unmute sounds */
322
+ unmute(): void;
323
+ /** Whether sounds are currently muted */
324
+ get muted(): boolean;
325
+ /** Current master volume */
326
+ get volume(): number;
327
+ /** Whether the engine is enabled */
328
+ get enabled(): boolean;
329
+ /** Close AudioContext and release resources */
330
+ dispose(): void;
331
+ /** Lazily create and return AudioContext, handling autoplay policy */
332
+ private _getContext;
333
+ /** Compute effective volume from master + per-sound volume */
334
+ private _effectiveVolume;
335
+ /** Schedule a tone at a specific AudioContext time */
336
+ private _scheduleTone;
337
+ }
338
+
339
+ /** Options for VisualEngine construction */
340
+ interface VisualEngineOptions {
341
+ enabled?: boolean;
342
+ target?: HTMLElement;
343
+ intensity?: number;
344
+ }
345
+ interface FlashOptions {
346
+ color?: string;
347
+ duration?: number;
348
+ opacity?: number;
349
+ }
350
+ interface ShakeOptions {
351
+ intensity?: number;
352
+ duration?: number;
353
+ }
354
+ interface PulseOptions {
355
+ scale?: number;
356
+ duration?: number;
357
+ }
358
+ interface RippleOptions {
359
+ color?: string;
360
+ size?: number;
361
+ duration?: number;
362
+ }
363
+ interface GlowOptions {
364
+ color?: string;
365
+ duration?: number;
366
+ size?: number;
367
+ }
368
+ interface BounceOptions$1 {
369
+ height?: number;
370
+ duration?: number;
371
+ }
372
+ interface JelloOptions {
373
+ intensity?: number;
374
+ duration?: number;
375
+ }
376
+ interface RubberOptions {
377
+ scaleX?: number;
378
+ scaleY?: number;
379
+ duration?: number;
380
+ }
381
+ interface HighlightOptions {
382
+ color?: string;
383
+ duration?: number;
384
+ }
385
+ /**
386
+ * CSS-based visual feedback effects that complement haptic patterns.
387
+ * Works everywhere including desktop/iOS where vibration is unavailable.
388
+ */
389
+ declare class VisualEngine {
390
+ private _enabled;
391
+ private _target;
392
+ private _intensity;
393
+ private _styleInjected;
394
+ private _cleanups;
395
+ constructor(options?: VisualEngineOptions);
396
+ /** Quick screen flash overlay */
397
+ flash(options?: FlashOptions): void;
398
+ /** CSS shake animation on target */
399
+ shake(options?: ShakeOptions): void;
400
+ /** Scale pulse animation */
401
+ pulse(options?: PulseOptions): void;
402
+ /** Material Design style ripple at coordinates */
403
+ ripple(x: number, y: number, options?: RippleOptions): void;
404
+ /** Box shadow glow effect */
405
+ glow(options?: GlowOptions): void;
406
+ /** Bounce animation on target */
407
+ bounce(options?: BounceOptions$1): void;
408
+ /** Jello/wobble animation */
409
+ jello(options?: JelloOptions): void;
410
+ /** Rubber band scale effect */
411
+ rubber(options?: RubberOptions): void;
412
+ /** Brief background color highlight */
413
+ highlight(options?: HighlightOptions): void;
414
+ /** Change the target element for animations */
415
+ setTarget(element: HTMLElement): void;
416
+ /** Whether the engine is enabled */
417
+ get enabled(): boolean;
418
+ /** Current intensity multiplier */
419
+ get intensity(): number;
420
+ /** Remove all active animations and clean up */
421
+ dispose(): void;
422
+ private _canRun;
423
+ private _getTarget;
424
+ /** Inject a <style> tag for keyframes on first use */
425
+ private _injectStyles;
426
+ /** Ensure a @keyframes rule exists in our style tag */
427
+ private _ensureKeyframes;
428
+ /** Apply a CSS animation to an element and clean up after */
429
+ private _applyAnimation;
430
+ private _removeCleanup;
431
+ }
432
+
433
+ /** Multi-sensory theme preset — configures haptic, sound, and visual behavior */
434
+ interface ThemePreset {
435
+ name: string;
436
+ hapticIntensity: number;
437
+ soundEnabled: boolean;
438
+ soundVolume: number;
439
+ visualEnabled: boolean;
440
+ visualStyle: 'flash' | 'ripple' | 'shake' | 'glow' | 'pulse';
441
+ colors: {
442
+ primary: string;
443
+ success: string;
444
+ error: string;
445
+ warning: string;
446
+ };
447
+ }
448
+ /** Built-in theme presets */
449
+ declare const themes: Record<string, ThemePreset>;
450
+ /**
451
+ * Manages multi-sensory themes that configure haptic, sound, and visual behavior.
452
+ */
453
+ declare class ThemeManager {
454
+ private _current;
455
+ private _registry;
456
+ constructor();
457
+ /** Apply a theme by name or provide a custom preset */
458
+ setTheme(name: string | ThemePreset): void;
459
+ /** Get the current theme preset */
460
+ getTheme(): ThemePreset;
461
+ /** Current theme name */
462
+ get current(): string;
463
+ /** List all available theme names */
464
+ listThemes(): string[];
465
+ /** Register a custom theme preset */
466
+ registerTheme(preset: ThemePreset): void;
467
+ }
468
+
469
+ /** Options for the SensoryEngine */
470
+ interface SensoryEngineOptions {
471
+ haptic?: Partial<HapticConfig>;
472
+ sound?: {
473
+ enabled?: boolean;
474
+ volume?: number;
475
+ muted?: boolean;
476
+ };
477
+ visual?: {
478
+ enabled?: boolean;
479
+ target?: HTMLElement;
480
+ intensity?: number;
481
+ };
482
+ theme?: string | ThemePreset;
483
+ }
484
+ /**
485
+ * Higher-level engine that combines haptic + sound + visual feedback.
486
+ * Ties HapticEngine, SoundEngine, VisualEngine, and ThemeManager together.
487
+ *
488
+ * Usage:
489
+ * const engine = SensoryEngine.create();
490
+ * engine.tap();
491
+ * engine.success();
492
+ * engine.setTheme('gaming');
493
+ */
494
+ declare class SensoryEngine {
495
+ private _haptic;
496
+ private _sound;
497
+ private _visual;
498
+ private _themes;
499
+ constructor(options?: SensoryEngineOptions);
500
+ /** Factory method */
501
+ static create(options?: SensoryEngineOptions): SensoryEngine;
502
+ /** Tap: vibrate + click sound + pulse visual */
503
+ tap(): Promise<void>;
504
+ /** Success: haptic success + success sound + green glow */
505
+ success(): Promise<void>;
506
+ /** Error: haptic error + error sound + red flash */
507
+ error(): Promise<void>;
508
+ /** Warning: haptic warning + warning sound + yellow flash */
509
+ warning(): Promise<void>;
510
+ /** Selection: haptic selection + tick sound + subtle pulse */
511
+ selection(): Promise<void>;
512
+ /** Toggle: haptic toggle + toggle sound + pulse */
513
+ toggle(on: boolean): Promise<void>;
514
+ /** Play a haptic pattern (sound/visual auto-mapped from theme) */
515
+ play(pattern: string | HapticPattern | HapticStep[]): Promise<void>;
516
+ /** Apply a theme by name or preset */
517
+ setTheme(name: string | ThemePreset): void;
518
+ /** Access the underlying HapticEngine */
519
+ get haptic(): HapticEngine;
520
+ /** Access the SoundEngine */
521
+ get sound(): SoundEngine;
522
+ /** Access the VisualEngine */
523
+ get visual(): VisualEngine;
524
+ /** Access the ThemeManager */
525
+ get themes(): ThemeManager;
526
+ /** Configure all engines */
527
+ configure(options: SensoryEngineOptions): void;
528
+ /** Clean up all engines */
529
+ dispose(): void;
530
+ /** Run the appropriate visual effect based on theme style */
531
+ private _runVisual;
532
+ }
533
+
270
534
  /**
271
535
  * No-op adapter — used in SSR, Node, or when no haptic hardware is available.
272
536
  * Silently accepts all calls without doing anything.
@@ -436,6 +700,155 @@ declare function patternToDataURL(input: ExportInput, options?: ExportOptions):
436
700
  */
437
701
  declare function patternFromDataURL(url: string): HapticPattern;
438
702
 
703
+ /** A single recorded tap event */
704
+ interface RecordedTap {
705
+ /** Timestamp in ms relative to recording start */
706
+ time: number;
707
+ /** Intensity from 0.0 to 1.0 */
708
+ intensity: number;
709
+ }
710
+ /** Callback invoked on each tap during recording */
711
+ type TapCallback = (tap: RecordedTap, index: number) => void;
712
+ /**
713
+ * Records tap rhythms and converts them to HPL pattern strings or HapticSteps.
714
+ *
715
+ * Usage:
716
+ * const recorder = new PatternRecorder();
717
+ * recorder.start();
718
+ * recorder.tap(); // user taps...
719
+ * recorder.tap(0.9); // heavy tap
720
+ * recorder.stop();
721
+ * console.log(recorder.toHPL()); // '##..@@'
722
+ */
723
+ declare class PatternRecorder {
724
+ private taps;
725
+ private recording;
726
+ private startTime;
727
+ private stopTime;
728
+ private tapCallbacks;
729
+ private nowFn;
730
+ constructor(options?: {
731
+ now?: () => number;
732
+ });
733
+ /** Whether the recorder is currently recording */
734
+ get isRecording(): boolean;
735
+ /** Total duration of the recording in ms */
736
+ get duration(): number;
737
+ /** Number of taps recorded */
738
+ get tapCount(): number;
739
+ /** Begin recording. Records timestamps of tap events. */
740
+ start(): void;
741
+ /** Register a tap at current time. */
742
+ tap(intensity?: number): void;
743
+ /** Stop recording, return the recorded taps. */
744
+ stop(): RecordedTap[];
745
+ /** Register a callback for each tap (for visual feedback during recording). */
746
+ onTap(callback: TapCallback): void;
747
+ /** Reset the recorder. */
748
+ clear(): void;
749
+ /**
750
+ * Snap taps to a grid for cleaner patterns.
751
+ * @param gridMs Grid size in ms (default 50ms)
752
+ */
753
+ quantize(gridMs?: number): void;
754
+ /**
755
+ * Convert recorded taps to an HPL string.
756
+ *
757
+ * Maps gaps between taps to `.` characters (each 50ms),
758
+ * and tap intensities to `~` (light), `#` (medium), `@` (heavy).
759
+ */
760
+ toHPL(): string;
761
+ /** Convert recorded taps to HapticStep[]. */
762
+ toSteps(): HapticStep[];
763
+ /** Convert recorded taps to a HapticPattern. */
764
+ toPattern(name?: string): HapticPattern;
765
+ }
766
+
767
+ interface SpringOptions {
768
+ /** Spring stiffness 0.5-1.0 */
769
+ stiffness?: number;
770
+ /** Damping factor 0.1-0.9 */
771
+ damping?: number;
772
+ /** Total duration in ms */
773
+ duration?: number;
774
+ }
775
+ interface BounceOptions {
776
+ /** Initial height 0.5-1.0 */
777
+ height?: number;
778
+ /** Bounciness factor 0.3-0.9 */
779
+ bounciness?: number;
780
+ /** Number of bounces */
781
+ bounces?: number;
782
+ }
783
+ interface FrictionOptions {
784
+ /** Surface roughness 0.1-1.0 */
785
+ roughness?: number;
786
+ /** Sliding speed 0.1-1.0 */
787
+ speed?: number;
788
+ /** Total duration in ms */
789
+ duration?: number;
790
+ }
791
+ interface ImpactOptions {
792
+ /** Object mass 0.1-1.0 */
793
+ mass?: number;
794
+ /** Surface hardness 0.1-1.0 */
795
+ hardness?: number;
796
+ }
797
+ interface GravityOptions {
798
+ /** Fall distance 0.3-1.0 */
799
+ distance?: number;
800
+ /** Total duration in ms */
801
+ duration?: number;
802
+ }
803
+ interface ElasticOptions {
804
+ /** Stretch amount 0.3-1.0 */
805
+ stretch?: number;
806
+ /** Snap-back speed 0.3-1.0 */
807
+ snapSpeed?: number;
808
+ }
809
+ interface WaveOptions {
810
+ /** Wave amplitude 0.3-1.0 */
811
+ amplitude?: number;
812
+ /** Wave frequency 0.5-2.0 */
813
+ frequency?: number;
814
+ /** Number of full cycles */
815
+ cycles?: number;
816
+ }
817
+ interface PendulumOptions {
818
+ /** Swing energy 0.3-1.0 */
819
+ energy?: number;
820
+ /** Number of swings */
821
+ swings?: number;
822
+ }
823
+ /** Bouncy spring oscillation — starts heavy, bounces with decreasing intensity */
824
+ declare function spring(options?: SpringOptions): HapticPattern;
825
+ /** Ball bouncing — each bounce is shorter and lighter */
826
+ declare function bounce(options?: BounceOptions): HapticPattern;
827
+ /** Rough surface sliding — continuous but slightly irregular vibration */
828
+ declare function friction(options?: FrictionOptions): HapticPattern;
829
+ /** Collision with surface — sharp initial hit followed by resonance */
830
+ declare function impact(options?: ImpactOptions): HapticPattern;
831
+ /** Falling sensation — accelerating intensity */
832
+ declare function gravity(options?: GravityOptions): HapticPattern;
833
+ /** Rubber band snap — stretch and snap back */
834
+ declare function elastic(options?: ElasticOptions): HapticPattern;
835
+ /** Ocean wave motion — smooth sine-wave-like intensity */
836
+ declare function wave(options?: WaveOptions): HapticPattern;
837
+ /** Swinging motion — intensity peaks at ends, quiet in middle */
838
+ declare function pendulum(options?: PendulumOptions): HapticPattern;
839
+
840
+ /** All physics-based haptic pattern generators */
841
+ declare const physics: {
842
+ readonly spring: typeof spring;
843
+ readonly bounce: typeof bounce;
844
+ readonly friction: typeof friction;
845
+ readonly impact: typeof impact;
846
+ readonly gravity: typeof gravity;
847
+ readonly elastic: typeof elastic;
848
+ readonly wave: typeof wave;
849
+ readonly pendulum: typeof pendulum;
850
+ };
851
+
439
852
  /** Platform detection utilities */
440
853
  interface PlatformInfo {
441
854
  isWeb: boolean;
@@ -460,4 +873,4 @@ declare function detectPlatform(): PlatformInfo;
460
873
  */
461
874
  declare const haptic: HapticEngine;
462
875
 
463
- export { type AdapterCapabilities, AdaptiveEngine, type EasingFunction, type ExportOptions, type FallbackConfig, FallbackManager, type HPLNode, type HPLNodeType, HPLParser, HPLParserError, type HPLToken, type HPLTokenType, HPLTokenizerError, type HapticAdapter, type HapticConfig, HapticEngine, type HapticPattern, type HapticPatternExport, type HapticStep, type ImpactStyle, IoSAudioAdapter, NoopAdapter, type NotificationType, PatternComposer, type PlatformInfo, type SemanticEffect, type ValidationResult, type VisualFallbackStyle, WebVibrationAdapter, compile, detectAdapter, detectPlatform, exportPattern, haptic, importPattern, optimizeSteps, parseHPL, patternFromDataURL, patternFromJSON, patternToDataURL, patternToJSON, tokenize, validateHPL };
876
+ export { type AdapterCapabilities, AdaptiveEngine, type BounceOptions, type ClickOptions, type EasingFunction, type ElasticOptions, type ExportOptions, type FallbackConfig, FallbackManager, type FlashOptions, type FrictionOptions, type GlowOptions, type GravityOptions, type HPLNode, type HPLNodeType, HPLParser, HPLParserError, type HPLToken, type HPLTokenType, HPLTokenizerError, type HapticAdapter, type HapticConfig, HapticEngine, type HapticPattern, type HapticPatternExport, type HapticStep, type HighlightOptions, type ImpactOptions, type ImpactStyle, IoSAudioAdapter, type JelloOptions, NoopAdapter, type NotificationType, PatternComposer, PatternRecorder, type PendulumOptions, type PlatformInfo, type PulseOptions, type RippleOptions, type RubberOptions, type SemanticEffect, SensoryEngine, type SensoryEngineOptions, type ShakeOptions, SoundEngine, type SoundEngineOptions, type SpringOptions, ThemeManager, type ThemePreset, type ToneOptions, type ValidationResult, type BounceOptions$1 as VisualBounceOptions, VisualEngine, type VisualEngineOptions, type VisualFallbackStyle, type WaveOptions, WebVibrationAdapter, bounce, compile, detectAdapter, detectPlatform, elastic, exportPattern, friction, gravity, haptic, impact, importPattern, optimizeSteps, parseHPL, patternFromDataURL, patternFromJSON, patternToDataURL, patternToJSON, pendulum, physics, spring, themes, tokenize, validateHPL, wave };