@magmacrunch/adenosine-audio 0.2.4 → 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/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog — `@magmacrunch/adenosine-audio`
2
+
3
+ This package only. Repo-wide changes — CI, guard scripts, build tooling — live
4
+ in the [monorepo changelog](../../CHANGELOG.md), which is also where the
5
+ narrative for every release before this file existed is written up.
6
+
7
+ The seven packages version independently, so a number here means nothing about
8
+ any other package.
9
+
10
+ ## Unreleased
11
+
12
+ _Nothing yet._
13
+
14
+ ## 0.3.0 — 2026-08-29
15
+
16
+ ### Changed
17
+
18
+ - Dead `VisibilityOptions` import removed. No behaviour change.
19
+
20
+ ### Changed — packaging
21
+
22
+ - `dist/index.global.js` is now a declared export (`./global`) with `unpkg` and
23
+ `jsdelivr` fields, so the bundle the browser tools load off the CDN is named
24
+ in the manifest instead of merely existing at a known path.
25
+ - `CHANGELOG.md` now ships in the tarball.
26
+ - Dead `.d.ts.map` files are gone. They pointed at a `src/` the tarball has
27
+ never included, so an editor's go-to-definition followed them nowhere.
28
+
29
+ ## Earlier releases
30
+
31
+ `0.2.4`, `0.2.3`, `0.2.2`, `0.2.1`, `0.2.0`
32
+
33
+ Descriptions for these are in the [monorepo changelog](../../CHANGELOG.md).
34
+ They are not restated here rather than restated approximately.
package/README.md CHANGED
@@ -36,7 +36,7 @@ itself off.
36
36
  Straight from a CDN — no npm, no build step:
37
37
 
38
38
  ```html
39
- <script src="https://cdn.jsdelivr.net/npm/@magmacrunch/adenosine-audio@0.2/dist/index.global.js"></script>
39
+ <script src="https://cdn.jsdelivr.net/npm/@magmacrunch/adenosine-audio@0.3/dist/index.global.js"></script>
40
40
  ```
41
41
 
42
42
  The IIFE build exposes `window.AdAudio`. The version is pinned to a minor here on purpose:
@@ -1,4 +1,3 @@
1
1
  export declare function getCtx(): AudioContext;
2
2
  export declare function resumeCtx(): Promise<void>;
3
3
  export declare function closeCtx(): void;
4
- //# sourceMappingURL=audio-context.d.ts.map
package/dist/index.d.ts CHANGED
@@ -6,4 +6,3 @@ export declare function playMusic(fadeIn?: number): Promise<void>;
6
6
  export declare function destroy(): void;
7
7
  export { _loadMusic as loadMusic, _pauseMusic as pauseMusic, _stopMusic as stopMusic, _setMusicVolume as setMusicVolume, _setMusicMuted as setMusicMuted, _isMusicMuted as isMusicMuted, _isMusicPlaying as isMusicPlaying, _toggleMusicMute as toggleMusicMute, _loadSfx as loadSfx, _playSfx as playSfx, _setSfxVolume as setSfxVolume, _setSfxGlobalVolume as setSfxGlobalVolume, _setSfxMuted as setSfxMuted, _isSfxMuted as isSfxMuted, _toggleSfxMute as toggleSfxMute, onVisibilityChange as handleVisibility, };
8
8
  export type { AudioManifest, MusicConfig, SfxConfig, VisibilityOptions } from './types.js';
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/audio-context.ts","../src/music.ts","../src/sfx.ts"],"sourcesContent":["import type { AudioManifest, VisibilityOptions } from './types.js';\nimport {\n loadMusic as _loadMusic,\n playMusic as _playMusic,\n pauseMusic as _pauseMusic,\n stopMusic as _stopMusic,\n setMusicVolume as _setMusicVolume,\n setMusicMuted as _setMusicMuted,\n isMusicMuted as _isMusicMuted,\n isMusicPlaying as _isMusicPlaying,\n toggleMusicMute as _toggleMusicMute,\n onVisibilityChange,\n destroyMusic,\n} from './music.js';\nimport {\n loadSfx as _loadSfx,\n playSfx as _playSfx,\n setSfxVolume as _setSfxVolume,\n setSfxGlobalVolume as _setSfxGlobalVolume,\n setSfxMuted as _setSfxMuted,\n isSfxMuted as _isSfxMuted,\n toggleSfxMute as _toggleSfxMute,\n destroySfx,\n} from './sfx.js';\nimport { closeCtx } from './audio-context.js';\n\nlet musicFadeIn = 2.0;\n\nexport async function init(manifest: AudioManifest): Promise<void> {\n if (manifest.music) {\n await _loadMusic(manifest.music.url, {\n volume: manifest.music.volume,\n fadeIn: manifest.music.fadeIn,\n });\n musicFadeIn = manifest.music.fadeIn ?? 2.0;\n }\n\n if (manifest.sfx) {\n const entries = Object.entries(manifest.sfx);\n await Promise.all(\n entries.map(([name, cfg]) => _loadSfx(name, cfg.url, { volume: cfg.volume, pool: cfg.pool }))\n );\n }\n\n if (manifest.autoVisibility !== false) {\n onVisibilityChange(true);\n }\n}\n\nexport async function playMusic(fadeIn?: number): Promise<void> {\n await _playMusic(fadeIn ?? musicFadeIn);\n}\n\nexport function destroy(): void {\n destroyMusic();\n destroySfx();\n closeCtx();\n}\n\nexport {\n _loadMusic as loadMusic,\n _pauseMusic as pauseMusic,\n _stopMusic as stopMusic,\n _setMusicVolume as setMusicVolume,\n _setMusicMuted as setMusicMuted,\n _isMusicMuted as isMusicMuted,\n _isMusicPlaying as isMusicPlaying,\n _toggleMusicMute as toggleMusicMute,\n _loadSfx as loadSfx,\n _playSfx as playSfx,\n _setSfxVolume as setSfxVolume,\n _setSfxGlobalVolume as setSfxGlobalVolume,\n _setSfxMuted as setSfxMuted,\n _isSfxMuted as isSfxMuted,\n _toggleSfxMute as toggleSfxMute,\n onVisibilityChange as handleVisibility,\n};\n\nexport type { AudioManifest, MusicConfig, SfxConfig, VisibilityOptions } from './types.js';\n","let ctx: AudioContext | null = null;\n\nexport function getCtx(): AudioContext {\n if (!ctx) {\n ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n }\n return ctx;\n}\n\nexport async function resumeCtx(): Promise<void> {\n const c = getCtx();\n if (c.state === 'suspended') {\n await c.resume();\n }\n}\n\nexport function closeCtx(): void {\n if (ctx && ctx.state !== 'closed') {\n ctx.close();\n }\n ctx = null;\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\nlet musicBuffer: AudioBuffer | null = null;\nlet musicSource: AudioBufferSourceNode | null = null;\nlet musicGain: GainNode | null = null;\nlet musicStarted = false;\nlet musicMuted = false;\nlet musicVolume = 0.3;\nlet visibilityHandler: (() => void) | null = null;\n\nexport async function loadMusic(url: string, opts?: { volume?: number; fadeIn?: number }): Promise<void> {\n musicVolume = opts?.volume ?? 0.3;\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n musicBuffer = await getCtx().decodeAudioData(arrayBuf);\n}\n\nexport async function playMusic(fadeIn = 2.0): Promise<void> {\n if (!musicBuffer || musicStarted) return;\n await resumeCtx();\n\n const ctx = getCtx();\n musicGain = ctx.createGain();\n musicGain.connect(ctx.destination);\n musicGain.gain.setValueAtTime(0, ctx.currentTime);\n\n musicSource = ctx.createBufferSource();\n musicSource.buffer = musicBuffer;\n musicSource.loop = true;\n musicSource.connect(musicGain);\n musicSource.start(0);\n\n const target = musicMuted ? 0 : musicVolume;\n musicGain.gain.linearRampToValueAtTime(target, ctx.currentTime + fadeIn);\n musicStarted = true;\n}\n\nexport function pauseMusic(): void {\n if (musicSource) {\n musicSource.onended = null;\n musicSource.stop();\n musicSource = null;\n }\n musicStarted = false;\n}\n\nexport function stopMusic(): void {\n pauseMusic();\n if (musicGain) {\n musicGain.disconnect();\n musicGain = null;\n }\n}\n\nexport function setMusicVolume(volume: number, rampTime = 0.5): void {\n musicVolume = volume;\n if (musicGain && !musicMuted) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(volume, ctx.currentTime + rampTime);\n }\n}\n\nexport function setMusicMuted(muted: boolean, rampTime = 0.5): void {\n musicMuted = muted;\n if (musicGain) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n if (rampTime <= 0) {\n musicGain.gain.setValueAtTime(muted ? 0 : musicVolume, ctx.currentTime);\n } else {\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(muted ? 0 : musicVolume, ctx.currentTime + rampTime);\n }\n }\n}\n\nexport function isMusicMuted(): boolean {\n return musicMuted;\n}\n\nexport function toggleMusicMute(): boolean {\n setMusicMuted(!musicMuted);\n return musicMuted;\n}\n\nexport function isMusicPlaying(): boolean {\n return musicStarted;\n}\n\nexport function onVisibilityChange(pause: boolean): void {\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n visibilityHandler = () => {\n if (document.hidden && pause && musicStarted) {\n pauseMusic();\n } else if (!document.hidden && pause && musicBuffer) {\n playMusic(0);\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n}\n\nexport function destroyMusic(): void {\n stopMusic();\n musicBuffer = null;\n musicStarted = false;\n musicMuted = false;\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n visibilityHandler = null;\n }\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\ninterface SfxEntry {\n buffer: AudioBuffer;\n volume: number;\n pool: AudioBufferSourceNode[];\n poolSize: number;\n}\n\nconst sfxMap = new Map<string, SfxEntry>();\nlet sfxMuted = false;\nlet sfxGlobalVolume = 1.0;\n\nexport async function loadSfx(name: string, url: string, opts?: { volume?: number; pool?: number }): Promise<void> {\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n const buffer = await getCtx().decodeAudioData(arrayBuf);\n sfxMap.set(name, {\n buffer,\n volume: opts?.volume ?? 0.5,\n pool: [],\n poolSize: opts?.pool ?? 1,\n });\n}\n\nexport async function playSfx(name: string, opts?: { volume?: number }): Promise<void> {\n if (sfxMuted) return;\n const entry = sfxMap.get(name);\n if (!entry) return;\n await resumeCtx();\n\n const ctx = getCtx();\n const gain = ctx.createGain();\n const vol = (opts?.volume ?? entry.volume) * sfxGlobalVolume;\n gain.gain.setValueAtTime(vol, ctx.currentTime);\n gain.connect(ctx.destination);\n\n const source = ctx.createBufferSource();\n source.buffer = entry.buffer;\n source.connect(gain);\n source.start(0);\n\n source.onended = () => {\n gain.disconnect();\n const idx = entry.pool.indexOf(source);\n if (idx !== -1) entry.pool.splice(idx, 1);\n };\n\n if (entry.pool.length < entry.poolSize) {\n entry.pool.push(source);\n }\n}\n\nexport function setSfxVolume(name: string, volume: number): void {\n const entry = sfxMap.get(name);\n if (entry) entry.volume = volume;\n}\n\nexport function setSfxGlobalVolume(volume: number): void {\n sfxGlobalVolume = volume;\n}\n\nexport function setSfxMuted(muted: boolean): void {\n sfxMuted = muted;\n}\n\nexport function isSfxMuted(): boolean {\n return sfxMuted;\n}\n\nexport function toggleSfxMute(): boolean {\n sfxMuted = !sfxMuted;\n return sfxMuted;\n}\n\nexport function destroySfx(): void {\n sfxMap.clear();\n sfxMuted = false;\n sfxGlobalVolume = 1.0;\n}\n"],"mappings":"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","names":["playMusic","ctx","ctx","playMusic"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/audio-context.ts","../src/music.ts","../src/sfx.ts"],"sourcesContent":["import type { AudioManifest } from './types.js';\nimport {\n loadMusic as _loadMusic,\n playMusic as _playMusic,\n pauseMusic as _pauseMusic,\n stopMusic as _stopMusic,\n setMusicVolume as _setMusicVolume,\n setMusicMuted as _setMusicMuted,\n isMusicMuted as _isMusicMuted,\n isMusicPlaying as _isMusicPlaying,\n toggleMusicMute as _toggleMusicMute,\n onVisibilityChange,\n destroyMusic,\n} from './music.js';\nimport {\n loadSfx as _loadSfx,\n playSfx as _playSfx,\n setSfxVolume as _setSfxVolume,\n setSfxGlobalVolume as _setSfxGlobalVolume,\n setSfxMuted as _setSfxMuted,\n isSfxMuted as _isSfxMuted,\n toggleSfxMute as _toggleSfxMute,\n destroySfx,\n} from './sfx.js';\nimport { closeCtx } from './audio-context.js';\n\nlet musicFadeIn = 2.0;\n\nexport async function init(manifest: AudioManifest): Promise<void> {\n if (manifest.music) {\n await _loadMusic(manifest.music.url, {\n volume: manifest.music.volume,\n fadeIn: manifest.music.fadeIn,\n });\n musicFadeIn = manifest.music.fadeIn ?? 2.0;\n }\n\n if (manifest.sfx) {\n const entries = Object.entries(manifest.sfx);\n await Promise.all(\n entries.map(([name, cfg]) => _loadSfx(name, cfg.url, { volume: cfg.volume, pool: cfg.pool }))\n );\n }\n\n if (manifest.autoVisibility !== false) {\n onVisibilityChange(true);\n }\n}\n\nexport async function playMusic(fadeIn?: number): Promise<void> {\n await _playMusic(fadeIn ?? musicFadeIn);\n}\n\nexport function destroy(): void {\n destroyMusic();\n destroySfx();\n closeCtx();\n}\n\nexport {\n _loadMusic as loadMusic,\n _pauseMusic as pauseMusic,\n _stopMusic as stopMusic,\n _setMusicVolume as setMusicVolume,\n _setMusicMuted as setMusicMuted,\n _isMusicMuted as isMusicMuted,\n _isMusicPlaying as isMusicPlaying,\n _toggleMusicMute as toggleMusicMute,\n _loadSfx as loadSfx,\n _playSfx as playSfx,\n _setSfxVolume as setSfxVolume,\n _setSfxGlobalVolume as setSfxGlobalVolume,\n _setSfxMuted as setSfxMuted,\n _isSfxMuted as isSfxMuted,\n _toggleSfxMute as toggleSfxMute,\n onVisibilityChange as handleVisibility,\n};\n\nexport type { AudioManifest, MusicConfig, SfxConfig, VisibilityOptions } from './types.js';\n","let ctx: AudioContext | null = null;\n\nexport function getCtx(): AudioContext {\n if (!ctx) {\n ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n }\n return ctx;\n}\n\nexport async function resumeCtx(): Promise<void> {\n const c = getCtx();\n if (c.state === 'suspended') {\n await c.resume();\n }\n}\n\nexport function closeCtx(): void {\n if (ctx && ctx.state !== 'closed') {\n ctx.close();\n }\n ctx = null;\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\nlet musicBuffer: AudioBuffer | null = null;\nlet musicSource: AudioBufferSourceNode | null = null;\nlet musicGain: GainNode | null = null;\nlet musicStarted = false;\nlet musicMuted = false;\nlet musicVolume = 0.3;\nlet visibilityHandler: (() => void) | null = null;\n\nexport async function loadMusic(url: string, opts?: { volume?: number; fadeIn?: number }): Promise<void> {\n musicVolume = opts?.volume ?? 0.3;\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n musicBuffer = await getCtx().decodeAudioData(arrayBuf);\n}\n\nexport async function playMusic(fadeIn = 2.0): Promise<void> {\n if (!musicBuffer || musicStarted) return;\n await resumeCtx();\n\n const ctx = getCtx();\n musicGain = ctx.createGain();\n musicGain.connect(ctx.destination);\n musicGain.gain.setValueAtTime(0, ctx.currentTime);\n\n musicSource = ctx.createBufferSource();\n musicSource.buffer = musicBuffer;\n musicSource.loop = true;\n musicSource.connect(musicGain);\n musicSource.start(0);\n\n const target = musicMuted ? 0 : musicVolume;\n musicGain.gain.linearRampToValueAtTime(target, ctx.currentTime + fadeIn);\n musicStarted = true;\n}\n\nexport function pauseMusic(): void {\n if (musicSource) {\n musicSource.onended = null;\n musicSource.stop();\n musicSource = null;\n }\n musicStarted = false;\n}\n\nexport function stopMusic(): void {\n pauseMusic();\n if (musicGain) {\n musicGain.disconnect();\n musicGain = null;\n }\n}\n\nexport function setMusicVolume(volume: number, rampTime = 0.5): void {\n musicVolume = volume;\n if (musicGain && !musicMuted) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(volume, ctx.currentTime + rampTime);\n }\n}\n\nexport function setMusicMuted(muted: boolean, rampTime = 0.5): void {\n musicMuted = muted;\n if (musicGain) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n if (rampTime <= 0) {\n musicGain.gain.setValueAtTime(muted ? 0 : musicVolume, ctx.currentTime);\n } else {\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(muted ? 0 : musicVolume, ctx.currentTime + rampTime);\n }\n }\n}\n\nexport function isMusicMuted(): boolean {\n return musicMuted;\n}\n\nexport function toggleMusicMute(): boolean {\n setMusicMuted(!musicMuted);\n return musicMuted;\n}\n\nexport function isMusicPlaying(): boolean {\n return musicStarted;\n}\n\nexport function onVisibilityChange(pause: boolean): void {\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n visibilityHandler = () => {\n if (document.hidden && pause && musicStarted) {\n pauseMusic();\n } else if (!document.hidden && pause && musicBuffer) {\n playMusic(0);\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n}\n\nexport function destroyMusic(): void {\n stopMusic();\n musicBuffer = null;\n musicStarted = false;\n musicMuted = false;\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n visibilityHandler = null;\n }\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\ninterface SfxEntry {\n buffer: AudioBuffer;\n volume: number;\n pool: AudioBufferSourceNode[];\n poolSize: number;\n}\n\nconst sfxMap = new Map<string, SfxEntry>();\nlet sfxMuted = false;\nlet sfxGlobalVolume = 1.0;\n\nexport async function loadSfx(name: string, url: string, opts?: { volume?: number; pool?: number }): Promise<void> {\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n const buffer = await getCtx().decodeAudioData(arrayBuf);\n sfxMap.set(name, {\n buffer,\n volume: opts?.volume ?? 0.5,\n pool: [],\n poolSize: opts?.pool ?? 1,\n });\n}\n\nexport async function playSfx(name: string, opts?: { volume?: number }): Promise<void> {\n if (sfxMuted) return;\n const entry = sfxMap.get(name);\n if (!entry) return;\n await resumeCtx();\n\n const ctx = getCtx();\n const gain = ctx.createGain();\n const vol = (opts?.volume ?? entry.volume) * sfxGlobalVolume;\n gain.gain.setValueAtTime(vol, ctx.currentTime);\n gain.connect(ctx.destination);\n\n const source = ctx.createBufferSource();\n source.buffer = entry.buffer;\n source.connect(gain);\n source.start(0);\n\n source.onended = () => {\n gain.disconnect();\n const idx = entry.pool.indexOf(source);\n if (idx !== -1) entry.pool.splice(idx, 1);\n };\n\n if (entry.pool.length < entry.poolSize) {\n entry.pool.push(source);\n }\n}\n\nexport function setSfxVolume(name: string, volume: number): void {\n const entry = sfxMap.get(name);\n if (entry) entry.volume = volume;\n}\n\nexport function setSfxGlobalVolume(volume: number): void {\n sfxGlobalVolume = volume;\n}\n\nexport function setSfxMuted(muted: boolean): void {\n sfxMuted = muted;\n}\n\nexport function isSfxMuted(): boolean {\n return sfxMuted;\n}\n\nexport function toggleSfxMute(): boolean {\n sfxMuted = !sfxMuted;\n return sfxMuted;\n}\n\nexport function destroySfx(): void {\n sfxMap.clear();\n sfxMuted = false;\n sfxGlobalVolume = 1.0;\n}\n"],"mappings":"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","names":["playMusic","ctx","ctx","playMusic"]}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/audio-context.ts","../src/music.ts","../src/sfx.ts","../src/index.ts"],"sourcesContent":["let ctx: AudioContext | null = null;\n\nexport function getCtx(): AudioContext {\n if (!ctx) {\n ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n }\n return ctx;\n}\n\nexport async function resumeCtx(): Promise<void> {\n const c = getCtx();\n if (c.state === 'suspended') {\n await c.resume();\n }\n}\n\nexport function closeCtx(): void {\n if (ctx && ctx.state !== 'closed') {\n ctx.close();\n }\n ctx = null;\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\nlet musicBuffer: AudioBuffer | null = null;\nlet musicSource: AudioBufferSourceNode | null = null;\nlet musicGain: GainNode | null = null;\nlet musicStarted = false;\nlet musicMuted = false;\nlet musicVolume = 0.3;\nlet visibilityHandler: (() => void) | null = null;\n\nexport async function loadMusic(url: string, opts?: { volume?: number; fadeIn?: number }): Promise<void> {\n musicVolume = opts?.volume ?? 0.3;\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n musicBuffer = await getCtx().decodeAudioData(arrayBuf);\n}\n\nexport async function playMusic(fadeIn = 2.0): Promise<void> {\n if (!musicBuffer || musicStarted) return;\n await resumeCtx();\n\n const ctx = getCtx();\n musicGain = ctx.createGain();\n musicGain.connect(ctx.destination);\n musicGain.gain.setValueAtTime(0, ctx.currentTime);\n\n musicSource = ctx.createBufferSource();\n musicSource.buffer = musicBuffer;\n musicSource.loop = true;\n musicSource.connect(musicGain);\n musicSource.start(0);\n\n const target = musicMuted ? 0 : musicVolume;\n musicGain.gain.linearRampToValueAtTime(target, ctx.currentTime + fadeIn);\n musicStarted = true;\n}\n\nexport function pauseMusic(): void {\n if (musicSource) {\n musicSource.onended = null;\n musicSource.stop();\n musicSource = null;\n }\n musicStarted = false;\n}\n\nexport function stopMusic(): void {\n pauseMusic();\n if (musicGain) {\n musicGain.disconnect();\n musicGain = null;\n }\n}\n\nexport function setMusicVolume(volume: number, rampTime = 0.5): void {\n musicVolume = volume;\n if (musicGain && !musicMuted) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(volume, ctx.currentTime + rampTime);\n }\n}\n\nexport function setMusicMuted(muted: boolean, rampTime = 0.5): void {\n musicMuted = muted;\n if (musicGain) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n if (rampTime <= 0) {\n musicGain.gain.setValueAtTime(muted ? 0 : musicVolume, ctx.currentTime);\n } else {\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(muted ? 0 : musicVolume, ctx.currentTime + rampTime);\n }\n }\n}\n\nexport function isMusicMuted(): boolean {\n return musicMuted;\n}\n\nexport function toggleMusicMute(): boolean {\n setMusicMuted(!musicMuted);\n return musicMuted;\n}\n\nexport function isMusicPlaying(): boolean {\n return musicStarted;\n}\n\nexport function onVisibilityChange(pause: boolean): void {\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n visibilityHandler = () => {\n if (document.hidden && pause && musicStarted) {\n pauseMusic();\n } else if (!document.hidden && pause && musicBuffer) {\n playMusic(0);\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n}\n\nexport function destroyMusic(): void {\n stopMusic();\n musicBuffer = null;\n musicStarted = false;\n musicMuted = false;\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n visibilityHandler = null;\n }\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\ninterface SfxEntry {\n buffer: AudioBuffer;\n volume: number;\n pool: AudioBufferSourceNode[];\n poolSize: number;\n}\n\nconst sfxMap = new Map<string, SfxEntry>();\nlet sfxMuted = false;\nlet sfxGlobalVolume = 1.0;\n\nexport async function loadSfx(name: string, url: string, opts?: { volume?: number; pool?: number }): Promise<void> {\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n const buffer = await getCtx().decodeAudioData(arrayBuf);\n sfxMap.set(name, {\n buffer,\n volume: opts?.volume ?? 0.5,\n pool: [],\n poolSize: opts?.pool ?? 1,\n });\n}\n\nexport async function playSfx(name: string, opts?: { volume?: number }): Promise<void> {\n if (sfxMuted) return;\n const entry = sfxMap.get(name);\n if (!entry) return;\n await resumeCtx();\n\n const ctx = getCtx();\n const gain = ctx.createGain();\n const vol = (opts?.volume ?? entry.volume) * sfxGlobalVolume;\n gain.gain.setValueAtTime(vol, ctx.currentTime);\n gain.connect(ctx.destination);\n\n const source = ctx.createBufferSource();\n source.buffer = entry.buffer;\n source.connect(gain);\n source.start(0);\n\n source.onended = () => {\n gain.disconnect();\n const idx = entry.pool.indexOf(source);\n if (idx !== -1) entry.pool.splice(idx, 1);\n };\n\n if (entry.pool.length < entry.poolSize) {\n entry.pool.push(source);\n }\n}\n\nexport function setSfxVolume(name: string, volume: number): void {\n const entry = sfxMap.get(name);\n if (entry) entry.volume = volume;\n}\n\nexport function setSfxGlobalVolume(volume: number): void {\n sfxGlobalVolume = volume;\n}\n\nexport function setSfxMuted(muted: boolean): void {\n sfxMuted = muted;\n}\n\nexport function isSfxMuted(): boolean {\n return sfxMuted;\n}\n\nexport function toggleSfxMute(): boolean {\n sfxMuted = !sfxMuted;\n return sfxMuted;\n}\n\nexport function destroySfx(): void {\n sfxMap.clear();\n sfxMuted = false;\n sfxGlobalVolume = 1.0;\n}\n","import type { AudioManifest, VisibilityOptions } from './types.js';\nimport {\n loadMusic as _loadMusic,\n playMusic as _playMusic,\n pauseMusic as _pauseMusic,\n stopMusic as _stopMusic,\n setMusicVolume as _setMusicVolume,\n setMusicMuted as _setMusicMuted,\n isMusicMuted as _isMusicMuted,\n isMusicPlaying as _isMusicPlaying,\n toggleMusicMute as _toggleMusicMute,\n onVisibilityChange,\n destroyMusic,\n} from './music.js';\nimport {\n loadSfx as _loadSfx,\n playSfx as _playSfx,\n setSfxVolume as _setSfxVolume,\n setSfxGlobalVolume as _setSfxGlobalVolume,\n setSfxMuted as _setSfxMuted,\n isSfxMuted as _isSfxMuted,\n toggleSfxMute as _toggleSfxMute,\n destroySfx,\n} from './sfx.js';\nimport { closeCtx } from './audio-context.js';\n\nlet musicFadeIn = 2.0;\n\nexport async function init(manifest: AudioManifest): Promise<void> {\n if (manifest.music) {\n await _loadMusic(manifest.music.url, {\n volume: manifest.music.volume,\n fadeIn: manifest.music.fadeIn,\n });\n musicFadeIn = manifest.music.fadeIn ?? 2.0;\n }\n\n if (manifest.sfx) {\n const entries = Object.entries(manifest.sfx);\n await Promise.all(\n entries.map(([name, cfg]) => _loadSfx(name, cfg.url, { volume: cfg.volume, pool: cfg.pool }))\n );\n }\n\n if (manifest.autoVisibility !== false) {\n onVisibilityChange(true);\n }\n}\n\nexport async function playMusic(fadeIn?: number): Promise<void> {\n await _playMusic(fadeIn ?? musicFadeIn);\n}\n\nexport function destroy(): void {\n destroyMusic();\n destroySfx();\n closeCtx();\n}\n\nexport {\n _loadMusic as loadMusic,\n _pauseMusic as pauseMusic,\n _stopMusic as stopMusic,\n _setMusicVolume as setMusicVolume,\n _setMusicMuted as setMusicMuted,\n _isMusicMuted as isMusicMuted,\n _isMusicPlaying as isMusicPlaying,\n _toggleMusicMute as toggleMusicMute,\n _loadSfx as loadSfx,\n _playSfx as playSfx,\n _setSfxVolume as setSfxVolume,\n _setSfxGlobalVolume as setSfxGlobalVolume,\n _setSfxMuted as setSfxMuted,\n _isSfxMuted as isSfxMuted,\n _toggleSfxMute as toggleSfxMute,\n onVisibilityChange as handleVisibility,\n};\n\nexport type { AudioManifest, MusicConfig, SfxConfig, VisibilityOptions } from './types.js';\n"],"mappings":"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","names":["ctx","ctx","playMusic"]}
1
+ {"version":3,"sources":["../src/audio-context.ts","../src/music.ts","../src/sfx.ts","../src/index.ts"],"sourcesContent":["let ctx: AudioContext | null = null;\n\nexport function getCtx(): AudioContext {\n if (!ctx) {\n ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n }\n return ctx;\n}\n\nexport async function resumeCtx(): Promise<void> {\n const c = getCtx();\n if (c.state === 'suspended') {\n await c.resume();\n }\n}\n\nexport function closeCtx(): void {\n if (ctx && ctx.state !== 'closed') {\n ctx.close();\n }\n ctx = null;\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\nlet musicBuffer: AudioBuffer | null = null;\nlet musicSource: AudioBufferSourceNode | null = null;\nlet musicGain: GainNode | null = null;\nlet musicStarted = false;\nlet musicMuted = false;\nlet musicVolume = 0.3;\nlet visibilityHandler: (() => void) | null = null;\n\nexport async function loadMusic(url: string, opts?: { volume?: number; fadeIn?: number }): Promise<void> {\n musicVolume = opts?.volume ?? 0.3;\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n musicBuffer = await getCtx().decodeAudioData(arrayBuf);\n}\n\nexport async function playMusic(fadeIn = 2.0): Promise<void> {\n if (!musicBuffer || musicStarted) return;\n await resumeCtx();\n\n const ctx = getCtx();\n musicGain = ctx.createGain();\n musicGain.connect(ctx.destination);\n musicGain.gain.setValueAtTime(0, ctx.currentTime);\n\n musicSource = ctx.createBufferSource();\n musicSource.buffer = musicBuffer;\n musicSource.loop = true;\n musicSource.connect(musicGain);\n musicSource.start(0);\n\n const target = musicMuted ? 0 : musicVolume;\n musicGain.gain.linearRampToValueAtTime(target, ctx.currentTime + fadeIn);\n musicStarted = true;\n}\n\nexport function pauseMusic(): void {\n if (musicSource) {\n musicSource.onended = null;\n musicSource.stop();\n musicSource = null;\n }\n musicStarted = false;\n}\n\nexport function stopMusic(): void {\n pauseMusic();\n if (musicGain) {\n musicGain.disconnect();\n musicGain = null;\n }\n}\n\nexport function setMusicVolume(volume: number, rampTime = 0.5): void {\n musicVolume = volume;\n if (musicGain && !musicMuted) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(volume, ctx.currentTime + rampTime);\n }\n}\n\nexport function setMusicMuted(muted: boolean, rampTime = 0.5): void {\n musicMuted = muted;\n if (musicGain) {\n const ctx = getCtx();\n musicGain.gain.cancelScheduledValues(ctx.currentTime);\n if (rampTime <= 0) {\n musicGain.gain.setValueAtTime(muted ? 0 : musicVolume, ctx.currentTime);\n } else {\n musicGain.gain.setValueAtTime(musicGain.gain.value, ctx.currentTime);\n musicGain.gain.linearRampToValueAtTime(muted ? 0 : musicVolume, ctx.currentTime + rampTime);\n }\n }\n}\n\nexport function isMusicMuted(): boolean {\n return musicMuted;\n}\n\nexport function toggleMusicMute(): boolean {\n setMusicMuted(!musicMuted);\n return musicMuted;\n}\n\nexport function isMusicPlaying(): boolean {\n return musicStarted;\n}\n\nexport function onVisibilityChange(pause: boolean): void {\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n }\n visibilityHandler = () => {\n if (document.hidden && pause && musicStarted) {\n pauseMusic();\n } else if (!document.hidden && pause && musicBuffer) {\n playMusic(0);\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n}\n\nexport function destroyMusic(): void {\n stopMusic();\n musicBuffer = null;\n musicStarted = false;\n musicMuted = false;\n if (visibilityHandler) {\n document.removeEventListener('visibilitychange', visibilityHandler);\n visibilityHandler = null;\n }\n}\n","import { getCtx, resumeCtx } from './audio-context.js';\n\ninterface SfxEntry {\n buffer: AudioBuffer;\n volume: number;\n pool: AudioBufferSourceNode[];\n poolSize: number;\n}\n\nconst sfxMap = new Map<string, SfxEntry>();\nlet sfxMuted = false;\nlet sfxGlobalVolume = 1.0;\n\nexport async function loadSfx(name: string, url: string, opts?: { volume?: number; pool?: number }): Promise<void> {\n const res = await fetch(url);\n const arrayBuf = await res.arrayBuffer();\n const buffer = await getCtx().decodeAudioData(arrayBuf);\n sfxMap.set(name, {\n buffer,\n volume: opts?.volume ?? 0.5,\n pool: [],\n poolSize: opts?.pool ?? 1,\n });\n}\n\nexport async function playSfx(name: string, opts?: { volume?: number }): Promise<void> {\n if (sfxMuted) return;\n const entry = sfxMap.get(name);\n if (!entry) return;\n await resumeCtx();\n\n const ctx = getCtx();\n const gain = ctx.createGain();\n const vol = (opts?.volume ?? entry.volume) * sfxGlobalVolume;\n gain.gain.setValueAtTime(vol, ctx.currentTime);\n gain.connect(ctx.destination);\n\n const source = ctx.createBufferSource();\n source.buffer = entry.buffer;\n source.connect(gain);\n source.start(0);\n\n source.onended = () => {\n gain.disconnect();\n const idx = entry.pool.indexOf(source);\n if (idx !== -1) entry.pool.splice(idx, 1);\n };\n\n if (entry.pool.length < entry.poolSize) {\n entry.pool.push(source);\n }\n}\n\nexport function setSfxVolume(name: string, volume: number): void {\n const entry = sfxMap.get(name);\n if (entry) entry.volume = volume;\n}\n\nexport function setSfxGlobalVolume(volume: number): void {\n sfxGlobalVolume = volume;\n}\n\nexport function setSfxMuted(muted: boolean): void {\n sfxMuted = muted;\n}\n\nexport function isSfxMuted(): boolean {\n return sfxMuted;\n}\n\nexport function toggleSfxMute(): boolean {\n sfxMuted = !sfxMuted;\n return sfxMuted;\n}\n\nexport function destroySfx(): void {\n sfxMap.clear();\n sfxMuted = false;\n sfxGlobalVolume = 1.0;\n}\n","import type { AudioManifest } from './types.js';\nimport {\n loadMusic as _loadMusic,\n playMusic as _playMusic,\n pauseMusic as _pauseMusic,\n stopMusic as _stopMusic,\n setMusicVolume as _setMusicVolume,\n setMusicMuted as _setMusicMuted,\n isMusicMuted as _isMusicMuted,\n isMusicPlaying as _isMusicPlaying,\n toggleMusicMute as _toggleMusicMute,\n onVisibilityChange,\n destroyMusic,\n} from './music.js';\nimport {\n loadSfx as _loadSfx,\n playSfx as _playSfx,\n setSfxVolume as _setSfxVolume,\n setSfxGlobalVolume as _setSfxGlobalVolume,\n setSfxMuted as _setSfxMuted,\n isSfxMuted as _isSfxMuted,\n toggleSfxMute as _toggleSfxMute,\n destroySfx,\n} from './sfx.js';\nimport { closeCtx } from './audio-context.js';\n\nlet musicFadeIn = 2.0;\n\nexport async function init(manifest: AudioManifest): Promise<void> {\n if (manifest.music) {\n await _loadMusic(manifest.music.url, {\n volume: manifest.music.volume,\n fadeIn: manifest.music.fadeIn,\n });\n musicFadeIn = manifest.music.fadeIn ?? 2.0;\n }\n\n if (manifest.sfx) {\n const entries = Object.entries(manifest.sfx);\n await Promise.all(\n entries.map(([name, cfg]) => _loadSfx(name, cfg.url, { volume: cfg.volume, pool: cfg.pool }))\n );\n }\n\n if (manifest.autoVisibility !== false) {\n onVisibilityChange(true);\n }\n}\n\nexport async function playMusic(fadeIn?: number): Promise<void> {\n await _playMusic(fadeIn ?? musicFadeIn);\n}\n\nexport function destroy(): void {\n destroyMusic();\n destroySfx();\n closeCtx();\n}\n\nexport {\n _loadMusic as loadMusic,\n _pauseMusic as pauseMusic,\n _stopMusic as stopMusic,\n _setMusicVolume as setMusicVolume,\n _setMusicMuted as setMusicMuted,\n _isMusicMuted as isMusicMuted,\n _isMusicPlaying as isMusicPlaying,\n _toggleMusicMute as toggleMusicMute,\n _loadSfx as loadSfx,\n _playSfx as playSfx,\n _setSfxVolume as setSfxVolume,\n _setSfxGlobalVolume as setSfxGlobalVolume,\n _setSfxMuted as setSfxMuted,\n _isSfxMuted as isSfxMuted,\n _toggleSfxMute as toggleSfxMute,\n onVisibilityChange as handleVisibility,\n};\n\nexport type { AudioManifest, MusicConfig, SfxConfig, VisibilityOptions } from './types.js';\n"],"mappings":"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","names":["ctx","ctx","playMusic"]}
package/dist/music.d.ts CHANGED
@@ -12,4 +12,3 @@ export declare function toggleMusicMute(): boolean;
12
12
  export declare function isMusicPlaying(): boolean;
13
13
  export declare function onVisibilityChange(pause: boolean): void;
14
14
  export declare function destroyMusic(): void;
15
- //# sourceMappingURL=music.d.ts.map
package/dist/sfx.d.ts CHANGED
@@ -11,4 +11,3 @@ export declare function setSfxMuted(muted: boolean): void;
11
11
  export declare function isSfxMuted(): boolean;
12
12
  export declare function toggleSfxMute(): boolean;
13
13
  export declare function destroySfx(): void;
14
- //# sourceMappingURL=sfx.d.ts.map
package/dist/types.d.ts CHANGED
@@ -17,4 +17,3 @@ export interface VisibilityOptions {
17
17
  pauseMusic?: boolean;
18
18
  muteSfxOnHidden?: boolean;
19
19
  }
20
- //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magmacrunch/adenosine-audio",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Web Audio API engine for game music and sound effects",
6
6
  "license": "Apache-2.0",
@@ -17,23 +17,27 @@
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/magmacrunchmedia/adenosine",
20
+ "url": "git+https://github.com/magmacrunchmedia/adenosine.git",
21
21
  "directory": "packages/audio"
22
22
  },
23
23
  "author": "magmacrunch media",
24
- "homepage": "https://github.com/magmacrunchmedia/adenosine#readme",
24
+ "homepage": "https://magmacrunch.com/ware/adenosine/",
25
25
  "main": "dist/index.js",
26
+ "unpkg": "dist/index.global.js",
27
+ "jsdelivr": "dist/index.global.js",
26
28
  "types": "dist/index.d.ts",
27
29
  "exports": {
28
30
  ".": {
29
31
  "types": "./dist/index.d.ts",
30
32
  "import": "./dist/index.js"
31
- }
33
+ },
34
+ "./global": "./dist/index.global.js"
32
35
  },
33
36
  "files": [
34
37
  "dist",
35
38
  "NOTICE",
36
- "API.md"
39
+ "API.md",
40
+ "CHANGELOG.md"
37
41
  ],
38
42
  "publishConfig": {
39
43
  "access": "public"
@@ -41,12 +45,13 @@
41
45
  "scripts": {
42
46
  "build": "tsup && tsc --emitDeclarationOnly --declaration --outDir dist",
43
47
  "typecheck": "tsc --noEmit",
44
- "test": "vitest run --passWithNoTests"
48
+ "test": "vitest run --passWithNoTests",
49
+ "test:coverage": "vitest run --coverage"
45
50
  },
46
51
  "devDependencies": {
47
52
  "tsup": "^8.5.1",
48
53
  "typescript": "^7.0.2",
49
- "vitest": "^3.2.1"
54
+ "vitest": "^4.1.11"
50
55
  },
51
56
  "sideEffects": false
52
57
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"audio-context.d.ts","sourceRoot":"","sources":["../src/audio-context.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,IAAI,YAAY,CAKrC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAK/C;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAK/B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,SAAS,IAAI,UAAU,EAEvB,UAAU,IAAI,WAAW,EACzB,SAAS,IAAI,UAAU,EACvB,cAAc,IAAI,eAAe,EACjC,aAAa,IAAI,cAAc,EAC/B,YAAY,IAAI,aAAa,EAC7B,cAAc,IAAI,eAAe,EACjC,eAAe,IAAI,gBAAgB,EACnC,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,OAAO,IAAI,QAAQ,EACnB,OAAO,IAAI,QAAQ,EACnB,YAAY,IAAI,aAAa,EAC7B,kBAAkB,IAAI,mBAAmB,EACzC,WAAW,IAAI,YAAY,EAC3B,UAAU,IAAI,WAAW,EACzB,aAAa,IAAI,cAAc,EAEhC,MAAM,UAAU,CAAC;AAKlB,wBAAsB,IAAI,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBjE;AAED,wBAAsB,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAgB,OAAO,IAAI,IAAI,CAI9B;AAED,OAAO,EACL,UAAU,IAAI,SAAS,EACvB,WAAW,IAAI,UAAU,EACzB,UAAU,IAAI,SAAS,EACvB,eAAe,IAAI,cAAc,EACjC,cAAc,IAAI,aAAa,EAC/B,aAAa,IAAI,YAAY,EAC7B,eAAe,IAAI,cAAc,EACjC,gBAAgB,IAAI,eAAe,EACnC,QAAQ,IAAI,OAAO,EACnB,QAAQ,IAAI,OAAO,EACnB,aAAa,IAAI,YAAY,EAC7B,mBAAmB,IAAI,kBAAkB,EACzC,YAAY,IAAI,WAAW,EAC3B,WAAW,IAAI,UAAU,EACzB,cAAc,IAAI,aAAa,EAC/B,kBAAkB,IAAI,gBAAgB,GACvC,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"music.d.ts","sourceRoot":"","sources":["../src/music.ts"],"names":[],"mappings":"AAUA,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAKvG;AAED,wBAAsB,SAAS,CAAC,MAAM,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3D;AAED,wBAAgB,UAAU,IAAI,IAAI,CAOjC;AAED,wBAAgB,SAAS,IAAI,IAAI,CAMhC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAM,GAAG,IAAI,CAQnE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAM,GAAG,IAAI,CAYlE;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAYvD;AAED,wBAAgB,YAAY,IAAI,IAAI,CASnC"}
package/dist/sfx.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sfx.d.ts","sourceRoot":"","sources":["../src/sfx.ts"],"names":[],"mappings":"AAaA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjH;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BrF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAG/D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEhD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,aAAa,IAAI,OAAO,CAGvC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B"}