@eatsjobs/howler-es 3.0.0-alpha.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial.js","names":[],"sources":["../../src/plugins/spatial-plugin.ts"],"sourcesContent":["import type { HowlOptions } from \"../howler.core\";\nimport {\n\ttype Howl,\n\tHowler,\n\ttype HowlerGlobal,\n\ttype Sound,\n} from \"../howler.core\";\nimport { isGainNode } from \"../types\";\nimport { globalPluginManager, HowlerPlugin, type PluginHooks } from \"./plugin\";\n\n/**\n * Extended HowlOptions with spatial audio properties.\n * Use this interface when creating a Howl instance with spatial audio capabilities.\n *\n * @example\n * ```typescript\n * const sound = new Howl({\n * src: ['sound.mp3'],\n * pos: [10, 20, 30],\n * stereo: 0.5,\n * distanceModel: 'inverse'\n * } as SpatialHowlOptions);\n * ```\n */\nexport interface SpatialHowlOptions extends HowlOptions {\n\t/** 3D position of the sound source [x, y, z]. */\n\tpos?: [number, number, number];\n\t/** Orientation vector of the sound source [x, y, z]. */\n\torientation?: [number, number, number];\n\t/** Stereo panning value from -1.0 (left) to 1.0 (right). */\n\tstereo?: number;\n\t/** Inner angle of the sound cone in degrees. Default: `360` */\n\tconeInnerAngle?: number;\n\t/** Outer angle of the sound cone in degrees. Default: `360` */\n\tconeOuterAngle?: number;\n\t/** Gain value outside the outer cone. Range: 0.0 to 1.0. Default: `0` */\n\tconeOuterGain?: number;\n\t/** Distance model algorithm: 'linear', 'inverse', or 'exponential'. Default: `'inverse'` */\n\tdistanceModel?: \"linear\" | \"inverse\" | \"exponential\";\n\t/** Maximum distance for the distance model. Default: `10000` */\n\tmaxDistance?: number;\n\t/** Panning model: 'equalpower' or 'HRTF'. Default: `'HRTF'` */\n\tpanningModel?: \"equalpower\" | \"HRTF\";\n\t/** Reference distance for the distance model. Default: `1` */\n\trefDistance?: number;\n\t/** Rolloff factor for the distance model. Default: `1` */\n\trolloffFactor?: number;\n\t/** Fires when the stereo panning changes. */\n\tonstereo?: () => void;\n\t/** Fires when the 3D position changes. */\n\tonpos?: () => void;\n\t/** Fires when the orientation changes. */\n\tonorientation?: () => void;\n}\n\n/**\n * Spatial audio state for the global Howler instance.\n * Contains the listener's position and orientation in 3D space.\n *\n * @internal\n */\nexport interface SpatialAudioState {\n\t/** Listener's 3D position [x, y, z]. */\n\t_pos: [number, number, number];\n\t/** Listener's orientation [forwardX, forwardY, forwardZ, upX, upY, upZ]. */\n\t_orientation: [number, number, number, number, number, number];\n}\n\n/**\n * Spatial audio state for a Howl instance.\n * Contains the sound source's position, orientation, and panner attributes.\n *\n * @internal\n */\nexport interface SpatialHowlState {\n\t/** Sound source's 3D position [x, y, z], or null if not set. */\n\t_pos: [number, number, number] | null;\n\t/** Sound source's orientation vector [x, y, z]. */\n\t_orientation: [number, number, number];\n\t/** Stereo panning value from -1.0 to 1.0, or null if not set. */\n\t_stereo: number | null;\n\t/** Panner node attributes for 3D audio processing. */\n\t_pannerAttr: {\n\t\t/** Inner angle of the sound cone in degrees. */\n\t\tconeInnerAngle: number;\n\t\t/** Outer angle of the sound cone in degrees. */\n\t\tconeOuterAngle: number;\n\t\t/** Gain value outside the outer cone (0.0 to 1.0). */\n\t\tconeOuterGain: number;\n\t\t/** Distance model algorithm. */\n\t\tdistanceModel: \"linear\" | \"inverse\" | \"exponential\";\n\t\t/** Maximum distance for the distance model. */\n\t\tmaxDistance: number;\n\t\t/** Panning model algorithm. */\n\t\tpanningModel: \"equalpower\" | \"HRTF\";\n\t\t/** Reference distance for the distance model. */\n\t\trefDistance: number;\n\t\t/** Rolloff factor for the distance model. */\n\t\trolloffFactor: number;\n\t};\n\t/** Event listeners for stereo panning changes. */\n\t_onstereo: Array<{ fn: () => void }>;\n\t/** Event listeners for position changes. */\n\t_onpos: Array<{ fn: () => void }>;\n\t/** Event listeners for orientation changes. */\n\t_onorientation: Array<{ fn: () => void }>;\n}\n\n/**\n * Spatial audio state for a Sound instance.\n * Contains per-sound spatial audio properties.\n *\n * @internal\n */\nexport interface SpatialSoundState {\n\t/** Sound's 3D position [x, y, z], or null if not set. */\n\t_pos: [number, number, number] | null;\n\t/** Sound's orientation vector [x, y, z]. */\n\t_orientation: [number, number, number];\n\t/** Stereo panning value from -1.0 to 1.0, or null if not set. */\n\t_stereo: number | null;\n\t/** Panner node attributes for 3D audio processing. */\n\t_pannerAttr: {\n\t\t/** Inner angle of the sound cone in degrees. */\n\t\tconeInnerAngle: number;\n\t\t/** Outer angle of the sound cone in degrees. */\n\t\tconeOuterAngle: number;\n\t\t/** Gain value outside the outer cone (0.0 to 1.0). */\n\t\tconeOuterGain: number;\n\t\t/** Distance model algorithm. */\n\t\tdistanceModel: \"linear\" | \"inverse\" | \"exponential\";\n\t\t/** Maximum distance for the distance model. */\n\t\tmaxDistance: number;\n\t\t/** Panning model algorithm. */\n\t\tpanningModel: \"equalpower\" | \"HRTF\";\n\t\t/** Reference distance for the distance model. */\n\t\trefDistance: number;\n\t\t/** Rolloff factor for the distance model. */\n\t\trolloffFactor: number;\n\t};\n}\n\n/**\n * Howler instance with spatial audio capabilities.\n * Use this type when the spatial plugin is registered to get full type safety for spatial audio methods.\n *\n * @example\n * ```typescript\n * import { Howler } from 'howler';\n * import { SpatialAudioPlugin, type SpatialHowler } from 'howler/plugins/spatial';\n *\n * Howler.addPlugin(new SpatialAudioPlugin());\n *\n * const howler: SpatialHowler = Howler as SpatialHowler;\n * howler.pos(10, 20, 30); // Set listener position\n * howler.orientation(0, 0, -1, 0, 1, 0); // Set listener orientation\n * howler.stereo(0.5); // Set stereo panning\n * ```\n */\nexport type SpatialHowler = HowlerGlobal &\n\tSpatialAudioState & {\n\t\t/**\n\t\t * Set or get the listener's 3D position.\n\t\t * @param x - X coordinate (optional)\n\t\t * @param y - Y coordinate (optional)\n\t\t * @param z - Z coordinate (optional)\n\t\t * @returns If called with no arguments, returns the current position [x, y, z]. Otherwise, returns the Howler instance for chaining.\n\t\t */\n\t\tpos(\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t): SpatialHowler | [number, number, number];\n\t\t/**\n\t\t * Set or get the listener's orientation.\n\t\t * @param x - Forward X component (optional)\n\t\t * @param y - Forward Y component (optional)\n\t\t * @param z - Forward Z component (optional)\n\t\t * @param xUp - Up X component (optional)\n\t\t * @param yUp - Up Y component (optional)\n\t\t * @param zUp - Up Z component (optional)\n\t\t * @returns If called with no arguments, returns the current orientation [forwardX, forwardY, forwardZ, upX, upY, upZ]. Otherwise, returns the Howler instance for chaining.\n\t\t */\n\t\torientation(\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t\txUp?: number,\n\t\t\tyUp?: number,\n\t\t\tzUp?: number,\n\t\t): SpatialHowler | [number, number, number, number, number, number];\n\t\t/**\n\t\t * Set or get the stereo panning value.\n\t\t * @param pan - Panning value from -1.0 (left) to 1.0 (right) (optional)\n\t\t * @returns If called with no arguments, returns the current panning value. Otherwise, returns the Howler instance for chaining.\n\t\t */\n\t\tstereo(pan?: number): SpatialHowler;\n\t};\n\n/**\n * Howl instance with spatial audio capabilities.\n * Use this type when the spatial plugin is registered to get full type safety for spatial audio methods.\n *\n * @example\n * ```typescript\n * import { Howl } from 'howler';\n * import { SpatialAudioPlugin, type SpatialHowl, type SpatialHowlOptions } from 'howler/plugins/spatial';\n *\n * Howler.addPlugin(new SpatialAudioPlugin());\n *\n * const sound: SpatialHowl = new Howl({\n * src: ['sound.mp3'],\n * pos: [10, 20, 30]\n * } as SpatialHowlOptions) as SpatialHowl;\n *\n * sound.pos(5, 10, 15); // Set sound position\n * sound.stereo(0.5); // Set stereo panning\n * sound.orientation(0, 1, 0); // Set sound orientation\n * ```\n */\nexport type SpatialHowl = Howl &\n\tSpatialHowlState & {\n\t\t/**\n\t\t * Set or get the sound's 3D position.\n\t\t * @param x - X coordinate (optional)\n\t\t * @param y - Y coordinate (optional)\n\t\t * @param z - Z coordinate (optional)\n\t\t * @param id - Sound ID to target a specific sound instance (optional)\n\t\t * @returns If called with no arguments, returns the current position [x, y, z]. Otherwise, returns the Howl instance for chaining.\n\t\t */\n\t\tpos(\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t\tid?: number,\n\t\t): SpatialHowl | [number, number, number];\n\t\t/**\n\t\t * Set or get the sound's orientation vector.\n\t\t * @param x - X component (optional)\n\t\t * @param y - Y component (optional)\n\t\t * @param z - Z component (optional)\n\t\t * @param id - Sound ID to target a specific sound instance (optional)\n\t\t * @returns If called with no arguments, returns the current orientation [x, y, z]. Otherwise, returns the Howl instance for chaining.\n\t\t */\n\t\torientation(\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t\tid?: number,\n\t\t): SpatialHowl | [number, number, number];\n\t\t/**\n\t\t * Set or get the stereo panning value.\n\t\t * @param pan - Panning value from -1.0 (left) to 1.0 (right) (optional)\n\t\t * @param id - Sound ID to target a specific sound instance (optional)\n\t\t * @returns If called with no arguments, returns the current panning value. Otherwise, returns the Howl instance for chaining.\n\t\t */\n\t\tstereo(pan?: number, id?: number): SpatialHowl | number;\n\t\t/**\n\t\t * Set or get panner node attributes.\n\t\t * @param o - Panner attributes object (optional)\n\t\t * @param id - Sound ID to target a specific sound instance (optional)\n\t\t * @returns If called with no arguments, returns the current panner attributes. Otherwise, returns the Howl instance for chaining.\n\t\t */\n\t\tpannerAttr(o?: any, id?: number): SpatialHowl | any;\n\t};\n\n/**\n * Setup a panner node for a sound\n */\nfunction setupPanner(\n\tsound: Sound & SpatialSoundState,\n\ttype: \"stereo\" | \"spatial\" = \"spatial\",\n): void {\n\tif (!Howler.ctx) {\n\t\treturn;\n\t}\n\n\t// Create the new panner node\n\tif (type === \"spatial\") {\n\t\tsound._panner = Howler.ctx.createPanner();\n\t\tconst panner = sound._panner as PannerNode;\n\t\tpanner.coneInnerAngle = sound._pannerAttr.coneInnerAngle;\n\t\tpanner.coneOuterAngle = sound._pannerAttr.coneOuterAngle;\n\t\tpanner.coneOuterGain = sound._pannerAttr.coneOuterGain;\n\t\tpanner.distanceModel = sound._pannerAttr.distanceModel;\n\t\tpanner.maxDistance = sound._pannerAttr.maxDistance;\n\t\tpanner.refDistance = sound._pannerAttr.refDistance;\n\t\tpanner.rolloffFactor = sound._pannerAttr.rolloffFactor;\n\t\tpanner.panningModel = sound._pannerAttr.panningModel;\n\n\t\tif (sound._pos) {\n\t\t\tif (typeof panner.positionX !== \"undefined\") {\n\t\t\t\tpanner.positionX.setValueAtTime(\n\t\t\t\t\tsound._pos[0],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t);\n\t\t\t\tpanner.positionY.setValueAtTime(\n\t\t\t\t\tsound._pos[1],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t);\n\t\t\t\tpanner.positionZ.setValueAtTime(\n\t\t\t\t\tsound._pos[2],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpanner.setPosition(sound._pos[0], sound._pos[1], sound._pos[2]);\n\t\t\t}\n\t\t}\n\n\t\tif (typeof panner.orientationX !== \"undefined\") {\n\t\t\tpanner.orientationX.setValueAtTime(\n\t\t\t\tsound._orientation[0],\n\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t);\n\t\t\tpanner.orientationY.setValueAtTime(\n\t\t\t\tsound._orientation[1],\n\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t);\n\t\t\tpanner.orientationZ.setValueAtTime(\n\t\t\t\tsound._orientation[2],\n\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t);\n\t\t} else {\n\t\t\tpanner.setOrientation(\n\t\t\t\tsound._orientation[0],\n\t\t\t\tsound._orientation[1],\n\t\t\t\tsound._orientation[2],\n\t\t\t);\n\t\t}\n\t} else {\n\t\tsound._panner = Howler.ctx.createStereoPanner();\n\t\tconst stereoPanner = sound._panner as StereoPannerNode;\n\t\tif (sound._stereo !== null) {\n\t\t\tstereoPanner.pan.setValueAtTime(\n\t\t\t\tsound._stereo,\n\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Connect panner to the sound's node\n\tif (sound._node && isGainNode(sound._node)) {\n\t\tsound._panner.connect(sound._node);\n\t}\n\n\t// Update connections if sound is playing\n\tif (!sound._paused) {\n\t\tsound._parent.pause(sound._id, true);\n\t\tsound._parent.play(sound._id, true);\n\t}\n}\n\n/**\n * Mixin function to add spatial audio to HowlerGlobal (listener)\n */\nfunction withSpatialListener(instance: HowlerGlobal): HowlerGlobal &\n\tSpatialAudioState & {\n\t\tpos(x?: number, y?: number, z?: number): SpatialHowler;\n\t\torientation(\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t\txUp?: number,\n\t\t\tyUp?: number,\n\t\t\tzUp?: number,\n\t\t): SpatialHowler;\n\t\tstereo(pan?: number): SpatialHowler;\n\t} {\n\tconst spatial = instance as SpatialHowler;\n\n\t// Initialize spatial properties\n\tspatial._pos = [0, 0, 0];\n\tspatial._orientation = [0, 0, -1, 0, 1, 0];\n\n\t// Add pos method to set listener position\n\tspatial.pos = function (x?: number, y?: number, z?: number) {\n\t\tif (!this.ctx || !this.ctx.listener) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Set the defaults for optional 'y' & 'z'\n\t\ty = typeof y !== \"number\" ? this._pos[1] : y;\n\t\tz = typeof z !== \"number\" ? this._pos[2] : z;\n\n\t\tif (typeof x === \"number\") {\n\t\t\tthis._pos = [x, y, z];\n\n\t\t\tif (typeof this.ctx.listener.positionX !== \"undefined\") {\n\t\t\t\tthis.ctx.listener.positionX.setTargetAtTime(\n\t\t\t\t\tthis._pos[0],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.positionY.setTargetAtTime(\n\t\t\t\t\tthis._pos[1],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.positionZ.setTargetAtTime(\n\t\t\t\t\tthis._pos[2],\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.ctx.listener.setPosition(this._pos[0], this._pos[1], this._pos[2]);\n\t\t\t}\n\t\t} else {\n\t\t\treturn this._pos;\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t// Add orientation method to set listener orientation\n\tspatial.orientation = function (\n\t\tx?: number,\n\t\ty?: number,\n\t\tz?: number,\n\t\txUp?: number,\n\t\tyUp?: number,\n\t\tzUp?: number,\n\t) {\n\t\tif (!this.ctx || !this.ctx.listener) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Set the defaults for optional parameters\n\t\tconst or = this._orientation;\n\t\ty = typeof y !== \"number\" ? or[1] : y;\n\t\tz = typeof z !== \"number\" ? or[2] : z;\n\t\txUp = typeof xUp !== \"number\" ? or[3] : xUp;\n\t\tyUp = typeof yUp !== \"number\" ? or[4] : yUp;\n\t\tzUp = typeof zUp !== \"number\" ? or[5] : zUp;\n\n\t\tif (typeof x === \"number\") {\n\t\t\tthis._orientation = [x, y, z, xUp, yUp, zUp];\n\n\t\t\tif (typeof this.ctx.listener.forwardX !== \"undefined\") {\n\t\t\t\tthis.ctx.listener.forwardX.setTargetAtTime(\n\t\t\t\t\tx,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.forwardY.setTargetAtTime(\n\t\t\t\t\ty,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.forwardZ.setTargetAtTime(\n\t\t\t\t\tz,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.upX.setTargetAtTime(\n\t\t\t\t\txUp,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.upY.setTargetAtTime(\n\t\t\t\t\tyUp,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t\tthis.ctx.listener.upZ.setTargetAtTime(\n\t\t\t\t\tzUp,\n\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t0.1,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.ctx.listener.setOrientation(x, y, z, xUp, yUp, zUp);\n\t\t\t}\n\t\t} else {\n\t\t\treturn or;\n\t\t}\n\n\t\treturn this;\n\t};\n\n\t// Add stereo method\n\tspatial.stereo = function (pan?: number) {\n\t\tif (!this.ctx || !this.ctx.listener) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Loop through all Howls and update their stereo panning\n\t\tfor (let i = this._howls.length - 1; i >= 0; i--) {\n\t\t\t(this._howls[i] as SpatialHowl).stereo?.(pan);\n\t\t}\n\n\t\treturn this;\n\t};\n\n\treturn spatial;\n}\n\n/**\n * Spatial Audio Plugin\n * Adds 3D spatial audio and stereo panning capabilities to Howler and Howl instances\n */\nexport class SpatialAudioPlugin extends HowlerPlugin {\n\treadonly name = \"spatial-audio\";\n\treadonly version = \"1.0.0\";\n\n\tgetHooks(): PluginHooks {\n\t\treturn {\n\t\t\tonHowlerInit: this.onHowlerInit.bind(this),\n\t\t\tonHowlCreate: this.onHowlCreate.bind(this),\n\t\t\tonSoundCreate: this.onSoundCreate.bind(this),\n\t\t\tonHowlLoad: this.onHowlLoad.bind(this),\n\t\t};\n\t}\n\n\t/**\n\t * Initialize spatial audio when Howler is initialized\n\t * This is called either:\n\t * - When Howler initializes (if plugin was registered before)\n\t * - Immediately during registration (if Howler is already initialized)\n\t */\n\tprivate onHowlerInit(howler: HowlerGlobal): void {\n\t\twithSpatialListener(howler);\n\t}\n\n\t/**\n\t * Extend Howl instances with spatial audio methods\n\t */\n\tprivate onHowlCreate(howl: Howl, options: HowlOptions): void {\n\t\tconst spatialOptions = options as SpatialHowlOptions;\n\t\tconst spatial = howl as SpatialHowl;\n\n\t\t// Setup user-defined default properties\n\t\tspatial._orientation = spatialOptions.orientation || [1, 0, 0];\n\t\tspatial._stereo =\n\t\t\tspatialOptions.stereo !== undefined ? spatialOptions.stereo : null;\n\t\tspatial._pos = spatialOptions.pos || null;\n\t\tspatial._pannerAttr = {\n\t\t\tconeInnerAngle:\n\t\t\t\ttypeof spatialOptions.coneInnerAngle !== \"undefined\"\n\t\t\t\t\t? spatialOptions.coneInnerAngle\n\t\t\t\t\t: 360,\n\t\t\tconeOuterAngle:\n\t\t\t\ttypeof spatialOptions.coneOuterAngle !== \"undefined\"\n\t\t\t\t\t? spatialOptions.coneOuterAngle\n\t\t\t\t\t: 360,\n\t\t\tconeOuterGain:\n\t\t\t\ttypeof spatialOptions.coneOuterGain !== \"undefined\"\n\t\t\t\t\t? spatialOptions.coneOuterGain\n\t\t\t\t\t: 0,\n\t\t\tdistanceModel:\n\t\t\t\ttypeof spatialOptions.distanceModel !== \"undefined\"\n\t\t\t\t\t? spatialOptions.distanceModel\n\t\t\t\t\t: \"inverse\",\n\t\t\tmaxDistance:\n\t\t\t\ttypeof spatialOptions.maxDistance !== \"undefined\"\n\t\t\t\t\t? spatialOptions.maxDistance\n\t\t\t\t\t: 10000,\n\t\t\tpanningModel:\n\t\t\t\ttypeof spatialOptions.panningModel !== \"undefined\"\n\t\t\t\t\t? spatialOptions.panningModel\n\t\t\t\t\t: \"HRTF\",\n\t\t\trefDistance:\n\t\t\t\ttypeof spatialOptions.refDistance !== \"undefined\"\n\t\t\t\t\t? spatialOptions.refDistance\n\t\t\t\t\t: 1,\n\t\t\trolloffFactor:\n\t\t\t\ttypeof spatialOptions.rolloffFactor !== \"undefined\"\n\t\t\t\t\t? spatialOptions.rolloffFactor\n\t\t\t\t\t: 1,\n\t\t};\n\n\t\t// Setup event listeners\n\t\tspatial._onstereo = spatialOptions.onstereo\n\t\t\t? [{ fn: spatialOptions.onstereo }]\n\t\t\t: [];\n\t\tspatial._onpos = spatialOptions.onpos ? [{ fn: spatialOptions.onpos }] : [];\n\t\tspatial._onorientation = spatialOptions.onorientation\n\t\t\t? [{ fn: spatialOptions.onorientation }]\n\t\t\t: [];\n\n\t\t// Add stereo method\n\t\tspatial.stereo = function (pan?: number, id?: number) {\n\t\t\tconst self = this as any;\n\n\t\t\t// Stop right here if not using Web Audio\n\t\t\tif (!self._webAudio) {\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// If the sound hasn't loaded, add it to the load queue\n\t\t\tif (self._state !== \"loaded\") {\n\t\t\t\tself._queue.push({\n\t\t\t\t\tevent: \"stereo\",\n\t\t\t\t\taction: () => {\n\t\t\t\t\t\tself.stereo(pan, id);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// Check for PannerStereoNode support and fallback to PannerNode if it doesn't exist\n\t\t\tconst pannerType =\n\t\t\t\ttypeof Howler.ctx?.createStereoPanner !== \"undefined\"\n\t\t\t\t\t? \"stereo\"\n\t\t\t\t\t: \"spatial\";\n\n\t\t\tconst ids = self._getSoundIds(id);\n\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\tconst sound = self._soundById(ids[i]) as Sound & SpatialSoundState;\n\t\t\t\tif (sound) {\n\t\t\t\t\tsound._stereo = pan ?? null;\n\n\t\t\t\t\t// Create a new panner node if one doesn't already exist\n\t\t\t\t\tif (!sound._panner) {\n\t\t\t\t\t\t// Make sure we have a position to setup the node with\n\t\t\t\t\t\tif (!sound._pos) {\n\t\t\t\t\t\t\tsound._pos = self._pos || [0, 0, -0.5];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetupPanner(sound, pannerType);\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tpannerType === \"stereo\" &&\n\t\t\t\t\t\tsound._panner instanceof StereoPannerNode\n\t\t\t\t\t) {\n\t\t\t\t\t\tsound._panner.pan.setValueAtTime(\n\t\t\t\t\t\t\tpan ?? 0,\n\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fire event\n\t\t\tself._emit(\"stereo\", id);\n\n\t\t\treturn self;\n\t\t};\n\n\t\t// Add pos method\n\t\tspatial.pos = function (x?: number, y?: number, z?: number, id?: number) {\n\t\t\tconst self = this as SpatialHowl;\n\n\t\t\t// Stop right here if not using Web Audio\n\t\t\tif (!self._webAudio) {\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// If the sound hasn't loaded, add it to the load queue\n\t\t\tif (self._state !== \"loaded\") {\n\t\t\t\tself._queue.push({\n\t\t\t\t\tevent: \"pos\",\n\t\t\t\t\taction: () => {\n\t\t\t\t\t\tself.pos(x, y, z, id);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// Set the defaults for optional 'y' & 'z'\n\t\t\ty = typeof y !== \"number\" ? (self._pos ? self._pos[1] : 0) : y;\n\t\t\tz = typeof z !== \"number\" ? (self._pos ? self._pos[2] : 0) : z;\n\n\t\t\tif (typeof x === \"number\") {\n\t\t\t\tconst ids = self._getSoundIds(id);\n\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\tconst sound = self._soundById(ids[i]) as Sound & SpatialSoundState;\n\t\t\t\t\tif (sound) {\n\t\t\t\t\t\tsound._pos = [x, y, z];\n\n\t\t\t\t\t\t// Create a new panner node if one doesn't already exist\n\t\t\t\t\t\tif (!sound._panner) {\n\t\t\t\t\t\t\tsetupPanner(sound, \"spatial\");\n\t\t\t\t\t\t} else if (sound._panner instanceof PannerNode) {\n\t\t\t\t\t\t\t// Update position\n\t\t\t\t\t\t\tif (typeof sound._panner.positionX !== \"undefined\") {\n\t\t\t\t\t\t\t\tsound._panner.positionX.setValueAtTime(\n\t\t\t\t\t\t\t\t\tx,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tsound._panner.positionY.setValueAtTime(\n\t\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tsound._panner.positionZ.setValueAtTime(\n\t\t\t\t\t\t\t\t\tz,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsound._panner.setPosition(x, y, z);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fire event\n\t\t\t\tself._emit(\"pos\", id);\n\n\t\t\t\treturn self;\n\t\t\t} else {\n\t\t\t\t// Return the position of the first sound or the group's position\n\t\t\t\tif (typeof id === \"number\") {\n\t\t\t\t\tconst sound = self._soundById(id) as Sound & SpatialSoundState;\n\t\t\t\t\treturn sound ? sound._pos || [0, 0, 0] : [0, 0, 0];\n\t\t\t\t}\n\t\t\t\treturn self._pos || [0, 0, 0];\n\t\t\t}\n\t\t};\n\n\t\t// Add orientation method\n\t\tspatial.orientation = function (\n\t\t\tx?: number,\n\t\t\ty?: number,\n\t\t\tz?: number,\n\t\t\tid?: number,\n\t\t) {\n\t\t\tconst self = this as SpatialHowl;\n\n\t\t\t// Stop right here if not using Web Audio\n\t\t\tif (!self._webAudio) {\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// If the sound hasn't loaded, add it to the load queue\n\t\t\tif (self._state !== \"loaded\") {\n\t\t\t\tself._queue.push({\n\t\t\t\t\tevent: \"orientation\",\n\t\t\t\t\taction: () => {\n\t\t\t\t\t\tself.orientation(x, y, z, id);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn self;\n\t\t\t}\n\n\t\t\t// Set the defaults for optional 'y' & 'z'\n\t\t\ty = typeof y !== \"number\" ? self._orientation[1] : y;\n\t\t\tz = typeof z !== \"number\" ? self._orientation[2] : z;\n\n\t\t\tif (typeof x === \"number\") {\n\t\t\t\tconst ids = self._getSoundIds(id);\n\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\tconst sound = self._soundById(ids[i]) as Sound & SpatialSoundState;\n\t\t\t\t\tif (sound) {\n\t\t\t\t\t\tsound._orientation = [x, y, z];\n\n\t\t\t\t\t\t// Create a new panner node if one doesn't already exist\n\t\t\t\t\t\tif (!sound._panner) {\n\t\t\t\t\t\t\tif (!sound._pos) {\n\t\t\t\t\t\t\t\tsound._pos = self._pos || [0, 0, -0.5];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetupPanner(sound, \"spatial\");\n\t\t\t\t\t\t} else if (sound._panner instanceof PannerNode) {\n\t\t\t\t\t\t\t// Update orientation\n\t\t\t\t\t\t\tif (typeof sound._panner.orientationX !== \"undefined\") {\n\t\t\t\t\t\t\t\tsound._panner.orientationX.setValueAtTime(\n\t\t\t\t\t\t\t\t\tx,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tsound._panner.orientationY.setValueAtTime(\n\t\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tsound._panner.orientationZ.setValueAtTime(\n\t\t\t\t\t\t\t\t\tz,\n\t\t\t\t\t\t\t\t\tHowler.ctx?.currentTime ?? 0,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsound._panner.setOrientation(x, y, z);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fire event\n\t\t\t\tself._emit(\"orientation\", id);\n\n\t\t\t\treturn self;\n\t\t\t} else {\n\t\t\t\t// Return the orientation of the first sound or the group's orientation\n\t\t\t\tif (typeof id === \"number\") {\n\t\t\t\t\tconst sound = self._soundById(id) as Sound & SpatialSoundState;\n\t\t\t\t\treturn sound ? sound._orientation : [1, 0, 0];\n\t\t\t\t}\n\t\t\t\treturn self._orientation;\n\t\t\t}\n\t\t};\n\n\t\t// Add pannerAttr method\n\t\tspatial.pannerAttr = function (o?: any, id?: number) {\n\t\t\tconst self = this as SpatialHowl;\n\t\t\tconst args = arguments;\n\t\t\tlet sound: (Sound & SpatialSoundState) | null = null;\n\n\t\t\tif (args.length === 0) {\n\t\t\t\t// Return this sound's panner attribute values\n\t\t\t\treturn self._pannerAttr;\n\t\t\t} else if (args.length === 1) {\n\t\t\t\tif (typeof args[0] === \"number\") {\n\t\t\t\t\t// Return this sound's panner attribute values\n\t\t\t\t\tsound = self._soundById(parseInt(String(args[0]), 10)) as Sound &\n\t\t\t\t\t\tSpatialSoundState;\n\t\t\t\t\treturn sound ? sound._pannerAttr : self._pannerAttr;\n\t\t\t\t} else {\n\t\t\t\t\t// Update all sounds in the group\n\t\t\t\t\to = args[0];\n\t\t\t\t}\n\t\t\t} else if (args.length === 2) {\n\t\t\t\to = args[0];\n\t\t\t\tid = parseInt(args[1] as any, 10);\n\t\t\t}\n\n\t\t\t// Update the values of the specified sounds\n\t\t\tconst ids = self._getSoundIds(id);\n\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\tsound = self._soundById(ids[i]) as any;\n\n\t\t\t\tif (sound) {\n\t\t\t\t\t// Merge the new values into the sound\n\t\t\t\t\tconst pa = sound._pannerAttr;\n\t\t\t\t\tsound._pannerAttr = {\n\t\t\t\t\t\tconeInnerAngle:\n\t\t\t\t\t\t\ttypeof o.coneInnerAngle !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.coneInnerAngle\n\t\t\t\t\t\t\t\t: pa.coneInnerAngle,\n\t\t\t\t\t\tconeOuterAngle:\n\t\t\t\t\t\t\ttypeof o.coneOuterAngle !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.coneOuterAngle\n\t\t\t\t\t\t\t\t: pa.coneOuterAngle,\n\t\t\t\t\t\tconeOuterGain:\n\t\t\t\t\t\t\ttypeof o.coneOuterGain !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.coneOuterGain\n\t\t\t\t\t\t\t\t: pa.coneOuterGain,\n\t\t\t\t\t\tdistanceModel:\n\t\t\t\t\t\t\ttypeof o.distanceModel !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.distanceModel\n\t\t\t\t\t\t\t\t: pa.distanceModel,\n\t\t\t\t\t\tmaxDistance:\n\t\t\t\t\t\t\ttypeof o.maxDistance !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.maxDistance\n\t\t\t\t\t\t\t\t: pa.maxDistance,\n\t\t\t\t\t\trefDistance:\n\t\t\t\t\t\t\ttypeof o.refDistance !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.refDistance\n\t\t\t\t\t\t\t\t: pa.refDistance,\n\t\t\t\t\t\trolloffFactor:\n\t\t\t\t\t\t\ttypeof o.rolloffFactor !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.rolloffFactor\n\t\t\t\t\t\t\t\t: pa.rolloffFactor,\n\t\t\t\t\t\tpanningModel:\n\t\t\t\t\t\t\ttypeof o.panningModel !== \"undefined\"\n\t\t\t\t\t\t\t\t? o.panningModel\n\t\t\t\t\t\t\t\t: pa.panningModel,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Create a new panner node if one doesn't already exist\n\t\t\t\t\tlet panner = sound._panner;\n\t\t\t\t\tif (!panner) {\n\t\t\t\t\t\t// Make sure we have a position to setup the node with\n\t\t\t\t\t\tif (!sound._pos) {\n\t\t\t\t\t\t\tsound._pos = self._pos || [0, 0, -0.5];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create a new panner node\n\t\t\t\t\t\tsetupPanner(sound, \"spatial\");\n\t\t\t\t\t\tpanner = sound._panner;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Update the panner values\n\t\t\t\t\tif (panner instanceof PannerNode) {\n\t\t\t\t\t\tpanner.coneInnerAngle = sound._pannerAttr.coneInnerAngle;\n\t\t\t\t\t\tpanner.coneOuterAngle = sound._pannerAttr.coneOuterAngle;\n\t\t\t\t\t\tpanner.coneOuterGain = sound._pannerAttr.coneOuterGain;\n\t\t\t\t\t\tpanner.distanceModel = sound._pannerAttr.distanceModel;\n\t\t\t\t\t\tpanner.maxDistance = sound._pannerAttr.maxDistance;\n\t\t\t\t\t\tpanner.refDistance = sound._pannerAttr.refDistance;\n\t\t\t\t\t\tpanner.rolloffFactor = sound._pannerAttr.rolloffFactor;\n\t\t\t\t\t\tpanner.panningModel = sound._pannerAttr.panningModel;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn self;\n\t\t};\n\t}\n\n\t/**\n\t * Extend Sound instances with spatial audio properties\n\t */\n\tprivate onSoundCreate(sound: Sound, parent: Howl): void {\n\t\tconst spatialParent = parent as any;\n\t\tconst spatialSound = sound as any;\n\n\t\t// Setup user-defined default properties\n\t\tspatialSound._orientation = spatialParent._orientation;\n\t\tspatialSound._stereo = spatialParent._stereo;\n\t\tspatialSound._pos = spatialParent._pos;\n\t\tspatialSound._pannerAttr = spatialParent._pannerAttr;\n\n\t\t// Wrap the reset method to handle spatial cleanup\n\t\tif (!spatialSound._originalReset) {\n\t\t\tspatialSound._originalReset = spatialSound.reset.bind(spatialSound);\n\t\t\tspatialSound.reset = function () {\n\t\t\t\tconst self = this as any;\n\t\t\t\tconst parent = self._parent as any;\n\n\t\t\t\t// Reset all spatial plugin properties on this sound\n\t\t\t\tself._orientation = parent._orientation;\n\t\t\t\tself._stereo = parent._stereo;\n\t\t\t\tself._pos = parent._pos;\n\t\t\t\tself._pannerAttr = parent._pannerAttr;\n\n\t\t\t\t// If a stereo or position was specified, set it up\n\t\t\t\tif (self._stereo !== null && self._stereo !== undefined) {\n\t\t\t\t\tparent.stereo(self._stereo, self._id);\n\t\t\t\t} else if (self._pos) {\n\t\t\t\t\tparent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);\n\t\t\t\t} else if (self._panner) {\n\t\t\t\t\t// Disconnect the panner\n\t\t\t\t\tself._panner.disconnect(0);\n\t\t\t\t\tself._panner = undefined;\n\t\t\t\t\tparent._refreshBuffer(self);\n\t\t\t\t}\n\n\t\t\t\t// Complete resetting of the sound\n\t\t\t\treturn self._originalReset();\n\t\t\t};\n\t\t}\n\n\t\t// If a stereo or position was specified, set it up\n\t\tif (spatialSound._stereo !== null && spatialSound._stereo !== undefined) {\n\t\t\tspatialParent.stereo(spatialSound._stereo, spatialSound._id);\n\t\t} else if (spatialSound._pos) {\n\t\t\tspatialParent.pos(\n\t\t\t\tspatialSound._pos[0],\n\t\t\t\tspatialSound._pos[1],\n\t\t\t\tspatialSound._pos[2],\n\t\t\t\tspatialSound._id,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Handle load queue for spatial audio\n\t */\n\tprivate onHowlLoad(howl: Howl): void {\n\t\tconst spatial = howl as any;\n\n\t\t// Process any queued spatial audio actions\n\t\tif (spatial._queue) {\n\t\t\tfor (let i = 0; i < spatial._queue.length; i++) {\n\t\t\t\tconst task = spatial._queue[i];\n\t\t\t\tif (\n\t\t\t\t\ttask.event === \"stereo\" ||\n\t\t\t\t\ttask.event === \"pos\" ||\n\t\t\t\t\ttask.event === \"orientation\"\n\t\t\t\t) {\n\t\t\t\t\ttask.action();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tonUnregister(): void {\n\t\tconst howler = globalPluginManager.getHowlerInstance();\n\t\tif (!howler) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up Howler instance\n\t\tdelete (howler as any)._pos;\n\t\tdelete (howler as any)._orientation;\n\t\tdelete (howler as any).pos;\n\t\tdelete (howler as any).orientation;\n\t\tdelete (howler as any).stereo;\n\n\t\t// Clean up all Howl instances\n\t\tfor (let i = 0; i < howler._howls.length; i++) {\n\t\t\tconst howl = howler._howls[i] as any;\n\n\t\t\t// Remove spatial methods from Howl\n\t\t\tdelete howl.stereo;\n\t\t\tdelete howl.pos;\n\t\t\tdelete howl.orientation;\n\t\t\tdelete howl.pannerAttr;\n\n\t\t\t// Remove spatial properties from Howl\n\t\t\tdelete howl._pos;\n\t\t\tdelete howl._orientation;\n\t\t\tdelete howl._stereo;\n\t\t\tdelete howl._pannerAttr;\n\t\t\tdelete howl._onstereo;\n\t\t\tdelete howl._onpos;\n\t\t\tdelete howl._onorientation;\n\n\t\t\t// Clean up all Sound instances in this Howl\n\t\t\tif (howl._sounds) {\n\t\t\t\tfor (let j = 0; j < howl._sounds.length; j++) {\n\t\t\t\t\tconst sound = howl._sounds[j] as any;\n\n\t\t\t\t\t// Disconnect and remove panner nodes\n\t\t\t\t\tif (sound._panner) {\n\t\t\t\t\t\tconst wasPlaying = !sound._paused;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Disconnect panner from the audio graph\n\t\t\t\t\t\t\tsound._panner.disconnect(0);\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t// Panner may already be disconnected\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Remove panner reference\n\t\t\t\t\t\tsound._panner = undefined;\n\n\t\t\t\t\t\t// If the sound was playing, we need to stop it and clean up the buffer source\n\t\t\t\t\t\t// The user will need to call play() again to resume without spatial audio\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\twasPlaying &&\n\t\t\t\t\t\t\thowl._webAudio &&\n\t\t\t\t\t\t\tsound._node &&\n\t\t\t\t\t\t\tsound._node.bufferSource\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Stop the current buffer source\n\t\t\t\t\t\t\t\tsound._node.bufferSource.stop(0);\n\t\t\t\t\t\t\t\tsound._node.bufferSource.disconnect(0);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t// Buffer source may already be stopped or disconnected\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Mark as paused so the audio graph can be reconnected on next play\n\t\t\t\t\t\t\tsound._paused = true;\n\n\t\t\t\t\t\t\t// Clean up the buffer source - it will be recreated on next play\n\t\t\t\t\t\t\thowl._cleanBuffer(sound._node);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove spatial properties from Sound\n\t\t\t\t\tdelete sound._pos;\n\t\t\t\t\tdelete sound._orientation;\n\t\t\t\t\tdelete sound._stereo;\n\t\t\t\t\tdelete sound._pannerAttr;\n\n\t\t\t\t\t// Restore original reset method if it was wrapped\n\t\t\t\t\tif (sound._originalReset) {\n\t\t\t\t\t\tsound.reset = sound._originalReset;\n\t\t\t\t\t\tdelete sound._originalReset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove spatial-related queue items\n\t\t\tif (howl._queue) {\n\t\t\t\thowl._queue = howl._queue.filter((item: any) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\titem.event !== \"stereo\" &&\n\t\t\t\t\t\titem.event !== \"pos\" &&\n\t\t\t\t\t\titem.event !== \"orientation\"\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@eatsjobs/howler-es",
3
+ "version": "3.0.0-alpha.1",
4
+ "description": "Javascript audio library for the modern web.",
5
+ "homepage": "https://howlerjs.com",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "keywords": [
9
+ "howler",
10
+ "howler.js",
11
+ "howler.es",
12
+ "howler-es",
13
+ "howler-esm",
14
+ "audio",
15
+ "sound",
16
+ "web audio",
17
+ "webaudio",
18
+ "browser",
19
+ "html5",
20
+ "html5 audio",
21
+ "audio sprite",
22
+ "audiosprite"
23
+ ],
24
+ "author": "James Simpson <james@goldfirestudios.com> (http://goldfirestudios.com)",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/eatsjobs/howler.es.git"
28
+ },
29
+ "scripts": {
30
+ "serve-tests": "npx serve .",
31
+ "build": "tsdown",
32
+ "size": "node scripts/check-size.js",
33
+ "preversion": "npm run lint && npm run build",
34
+ "postversion": "git push --follow-tags",
35
+ "lint": "biome check",
36
+ "lint:fix": "biome check --write"
37
+ },
38
+ "devDependencies": {
39
+ "@arethetypeswrong/core": "~0.18.2",
40
+ "@biomejs/biome": "2.4.5",
41
+ "publint": "~0.3.18",
42
+ "serve": "^14.2.5",
43
+ "tsdown": "~0.20.3",
44
+ "typescript": "~5.9.3"
45
+ },
46
+ "main": "dist/index.js",
47
+ "module": "dist/index.js",
48
+ "types": "dist/index.d.ts",
49
+ "exports": {
50
+ ".": {
51
+ "types": "./dist/index.d.ts",
52
+ "import": "./dist/index.js"
53
+ },
54
+ "./plugins/spatial": {
55
+ "types": "./dist/plugins/spatial.d.ts",
56
+ "import": "./dist/plugins/spatial.js"
57
+ }
58
+ },
59
+ "license": "MIT",
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "files": [
64
+ "dist",
65
+ "LICENSE.md",
66
+ "README.md"
67
+ ]
68
+ }