@gentomiyano/optimized-web-audio-player 0.1.0 → 0.2.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.
Files changed (47) hide show
  1. package/README.md +177 -159
  2. package/dist/config/index.d.ts +1 -1
  3. package/dist/config/index.js +1 -0
  4. package/dist/config/index.js.map +1 -1
  5. package/dist/consumer/index.d.ts +1 -1
  6. package/dist/consumer/index.js.map +1 -1
  7. package/dist/contracts/index.d.ts +2 -2
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +1 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/media-delivery/index.d.ts +1 -1
  12. package/dist/media-delivery/index.js.map +1 -1
  13. package/dist/{media-element-C9dis4aG.d.ts → media-element-DyMO-PhK.d.ts} +1 -1
  14. package/dist/{player-DE9Vqztu.d.ts → player-BxNFzRq4.d.ts} +53 -1
  15. package/dist/ports/index.d.ts +2 -2
  16. package/dist/react/index.d.ts +14 -3
  17. package/dist/react/index.js +193 -12
  18. package/dist/react/index.js.map +1 -1
  19. package/dist/testing/index.d.ts +1 -1
  20. package/dist/testing/index.js +1 -0
  21. package/dist/testing/index.js.map +1 -1
  22. package/dist/ui/index.d.ts +10 -2
  23. package/dist/ui/index.js +227 -56
  24. package/dist/ui/index.js.map +1 -1
  25. package/dist/ui/player-tokens.css +572 -572
  26. package/dist/ui/player-views.css +713 -654
  27. package/dist/ui/styles.css +2 -2
  28. package/package.json +12 -2
  29. package/dist/consumer-smoke/node_modules/.modules.yaml +0 -30
  30. package/dist/consumer-smoke/node_modules/.package-map.json +0 -1
  31. package/dist/consumer-smoke/node_modules/.pnpm/lock.yaml +0 -57
  32. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/LICENSE +0 -21
  33. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/README.md +0 -9
  34. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +0 -414
  35. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_mock.production.js +0 -406
  36. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js +0 -150
  37. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_post_task.production.js +0 -140
  38. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.development.js +0 -364
  39. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.native.development.js +0 -350
  40. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.native.production.js +0 -330
  41. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.production.js +0 -340
  42. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/index.js +0 -7
  43. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/index.native.js +0 -7
  44. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/package.json +0 -27
  45. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/unstable_mock.js +0 -7
  46. package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/unstable_post_task.js +0 -7
  47. package/dist/consumer-smoke/node_modules/.pnpm-workspace-state-v1.json +0 -29
@@ -1,4 +1,4 @@
1
- import { q as PlayerMediaAdapter, r as PlayerMediaItem, Q as QueueItem, j as PlayerError, u as PlayerState, l as PlayerExperienceConfig } from '../player-DE9Vqztu.js';
1
+ import { u as PlayerMediaAdapter, v as PlayerMediaItem, Q as QueueItem, n as PlayerError, y as PlayerState, p as PlayerExperienceConfig } from '../player-BxNFzRq4.js';
2
2
 
3
3
  type MockPlayerScenario = "success" | "loading" | "duration-unknown" | "missing-waveform" | "recoverable-error" | "fatal-error";
4
4
  interface MockMediaRecord {
@@ -314,6 +314,7 @@ function createInitialPlayerState(experienceConfig) {
314
314
  shuffleEnabled: resolved.value.initialShuffleEnabled,
315
315
  repeatMode: resolved.value.initialRepeatMode,
316
316
  queue: Object.freeze([]),
317
+ activeContext: null,
317
318
  currentQueueIndex: null,
318
319
  canSeek: false,
319
320
  canGoPrevious: false,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/mock/mock-player-adapter.ts","../../src/config/defaults.ts","../../src/config/validation.ts","../../src/config/initial-state.ts","../../src/testing/fixtures.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n PlayerError,\n PlayerMediaAdapter,\n PlayerMediaItem,\n QueueItem,\n} from \"../../contracts/player\";\n\nexport type MockPlayerScenario =\n | \"success\"\n | \"loading\"\n | \"duration-unknown\"\n | \"missing-waveform\"\n | \"recoverable-error\"\n | \"fatal-error\";\n\nexport interface MockMediaRecord {\n readonly id: string;\n readonly playable: boolean;\n readonly title: string;\n readonly creatorName?: string;\n readonly collectionTitle?: string;\n readonly sourceUrl?: string;\n readonly durationHintSec?: number;\n readonly waveformPeaks?: readonly number[];\n}\n\nexport interface MockPlayerAdapterOptions {\n readonly scenario?: MockPlayerScenario;\n readonly delayMs?: number;\n}\n\nexport interface MockPlayerScenarioResult {\n readonly scenario: MockPlayerScenario;\n readonly queue: readonly QueueItem[];\n readonly initialError: PlayerError | null;\n readonly remainsLoading: boolean;\n}\n\nconst MOCK_RECORDS: readonly MockMediaRecord[] = Object.freeze([\n Object.freeze({\n id: \"sample-track-alpha\",\n playable: true,\n title: \"Sample Track Alpha\",\n creatorName: \"Sample Creator\",\n collectionTitle: \"Sample Collection\",\n sourceUrl: \"/mock-audio/sample-track-alpha.mp3\",\n durationHintSec: 185,\n waveformPeaks: Object.freeze([0.18, 0.42, 0.7, 0.54, 0.82, 0.33]),\n }),\n Object.freeze({\n id: \"sample-track-beta\",\n playable: true,\n title: \"Sample Track Beta\",\n creatorName: \"Sample Creator\",\n collectionTitle: \"Sample Collection\",\n sourceUrl: \"/mock-audio/sample-track-beta.mp3\",\n durationHintSec: 212,\n waveformPeaks: Object.freeze([0.28, 0.5, 0.36, 0.76, 0.61, 0.24]),\n }),\n]);\n\nconst RECOVERABLE_ERROR: PlayerError = Object.freeze({\n code: \"network\",\n recoverable: true,\n messageKey: \"player.error.network\",\n});\n\nconst FATAL_ERROR: PlayerError = Object.freeze({\n code: \"unsupported\",\n recoverable: false,\n messageKey: \"player.error.unsupported\",\n});\n\nconst MOCK_PLAYER_SCENARIOS = new Set<MockPlayerScenario>([\n \"success\",\n \"loading\",\n \"duration-unknown\",\n \"missing-waveform\",\n \"recoverable-error\",\n \"fatal-error\",\n]);\n\nfunction wait(delayMs: number): Promise<void> {\n if (delayMs <= 0) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n setTimeout(resolve, delayMs);\n });\n}\n\nexport class MockPlayerAdapter\n implements PlayerMediaAdapter<MockMediaRecord>\n{\n readonly #scenario: MockPlayerScenario;\n readonly #delayMs: number;\n\n constructor(options: MockPlayerAdapterOptions = {}) {\n this.#scenario = options.scenario ?? \"success\";\n this.#delayMs = options.delayMs ?? 0;\n\n if (!MOCK_PLAYER_SCENARIOS.has(this.#scenario)) {\n throw new TypeError(\"Mock scenario is not supported.\");\n }\n\n if (\n !Number.isFinite(this.#delayMs) ||\n this.#delayMs < 0 ||\n this.#delayMs > 30_000\n ) {\n throw new RangeError(\"Mock delayMs must be between 0 and 30000.\");\n }\n }\n\n toPlayerMediaItem(source: MockMediaRecord): PlayerMediaItem | null {\n if (\n !source.playable ||\n typeof source.sourceUrl !== \"string\" ||\n source.sourceUrl.length === 0\n ) {\n return null;\n }\n\n const base: PlayerMediaItem = {\n id: source.id,\n kind: \"track\",\n title: source.title,\n source: {\n url: source.sourceUrl,\n crossOrigin: \"anonymous\",\n mimeType: \"audio/mpeg\",\n },\n ...(source.creatorName === undefined\n ? {}\n : { creatorName: source.creatorName }),\n ...(source.collectionTitle === undefined\n ? {}\n : { collectionTitle: source.collectionTitle }),\n ...(this.#scenario === \"duration-unknown\" ||\n source.durationHintSec === undefined\n ? {}\n : { durationHintSec: source.durationHintSec }),\n };\n\n return {\n ...base,\n ...(this.#scenario === \"missing-waveform\" ||\n source.waveformPeaks === undefined\n ? {}\n : {\n waveform: {\n version: 1,\n peaks: source.waveformPeaks,\n },\n }),\n };\n }\n\n async loadScenario(): Promise<MockPlayerScenarioResult> {\n await wait(this.#delayMs);\n\n const queue = MOCK_RECORDS.flatMap((record, index) => {\n const item = this.toPlayerMediaItem(record);\n return item === null\n ? []\n : [{ queueItemId: `sample-queue-${String(index + 1)}`, item }];\n });\n\n return Object.freeze({\n scenario: this.#scenario,\n queue: Object.freeze(queue),\n initialError:\n this.#scenario === \"recoverable-error\"\n ? RECOVERABLE_ERROR\n : this.#scenario === \"fatal-error\"\n ? FATAL_ERROR\n : null,\n remainsLoading: this.#scenario === \"loading\",\n });\n }\n}\n\nexport const mockMediaRecords = MOCK_RECORDS;\n","import type { PlayerExperienceConfig } from \"../contracts/player\";\n\nexport const PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION = 2 as const;\n\nexport const PLAYER_EXPERIENCE_CONFIG_LIMITS = Object.freeze({\n fadeMs: Object.freeze({ min: 0, max: 10_000 }),\n previousRestartThresholdSec: Object.freeze({ min: 0, max: 60 }),\n waveformOpacity: Object.freeze({ min: 0, max: 1 }),\n initialVolume: Object.freeze({ min: 0, max: 1 }),\n podcastSkipSec: Object.freeze({ minExclusive: 0, max: 3_600 }),\n});\n\nexport const PREVIEW_PLAYER_EXPERIENCE_CONFIG: Readonly<PlayerExperienceConfig> =\n Object.freeze({\n playFadeInMs: 300,\n pauseFadeOutMs: 600,\n trackChangeFadeOutMs: 300,\n trackChangeFadeInMs: 300,\n seekFadeMs: 120,\n fadeCurve: \"ease-out\",\n previousRestartThresholdSec: 3,\n seekCommitMode: \"on-release\",\n waveformPlayedStateEnabled: true,\n waveformOpacity: 0.72,\n initialShuffleEnabled: false,\n initialRepeatMode: \"off\",\n initialVolume: 0.8,\n persistMode: \"none\",\n podcastBackSec: 15,\n podcastForwardSec: 30,\n podcastPreviousMode: \"previous-episode\",\n });\n","import type {\n FadeCurve,\n PersistMode,\n PlayerExperienceConfig,\n PodcastPreviousMode,\n RepeatMode,\n SeekCommitMode,\n} from \"../contracts/player\";\nimport type { PlayerExperienceConfigValidationResult } from \"../contracts/config\";\nimport {\n PLAYER_EXPERIENCE_CONFIG_LIMITS,\n PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION,\n PREVIEW_PLAYER_EXPERIENCE_CONFIG,\n} from \"./defaults\";\n\nconst CONFIG_KEYS = [\n \"playFadeInMs\",\n \"pauseFadeOutMs\",\n \"trackChangeFadeOutMs\",\n \"trackChangeFadeInMs\",\n \"seekFadeMs\",\n \"fadeCurve\",\n \"previousRestartThresholdSec\",\n \"seekCommitMode\",\n \"waveformPlayedStateEnabled\",\n \"waveformOpacity\",\n \"initialShuffleEnabled\",\n \"initialRepeatMode\",\n \"initialVolume\",\n \"persistMode\",\n \"podcastBackSec\",\n \"podcastForwardSec\",\n \"podcastPreviousMode\",\n] as const satisfies readonly (keyof PlayerExperienceConfig)[];\n\nconst FADE_CURVES = new Set<FadeCurve>([\n \"linear\",\n \"ease-in\",\n \"ease-out\",\n \"equal-power\",\n]);\nconst SEEK_COMMIT_MODES = new Set<SeekCommitMode>([\"live\", \"on-release\"]);\nconst REPEAT_MODES = new Set<RepeatMode>([\"off\", \"all\", \"one\"]);\nconst PERSIST_MODES = new Set<PersistMode>([\"none\", \"session\", \"local\"]);\nconst PODCAST_PREVIOUS_MODES = new Set<PodcastPreviousMode>([\n \"previous-episode\",\n \"restart-episode\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction validateFiniteRange(\n value: unknown,\n path: string,\n min: number,\n max: number,\n errors: string[],\n): value is number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < min ||\n value > max\n ) {\n errors.push(\n `${path} must be a finite number between ${String(min)} and ${String(max)}.`,\n );\n return false;\n }\n return true;\n}\n\nfunction validateBoolean(\n value: unknown,\n path: string,\n errors: string[],\n): value is boolean {\n if (typeof value !== \"boolean\") {\n errors.push(`${path} must be a boolean.`);\n return false;\n }\n return true;\n}\n\nfunction validateConfigRecord(\n value: unknown,\n options: { readonly partial: boolean },\n): PlayerExperienceConfigValidationResult {\n if (!isRecord(value)) {\n return { ok: false, errors: [\"config must be an object.\"] };\n }\n\n const errors: string[] = [];\n const allowedKeys = new Set<string>(CONFIG_KEYS);\n\n for (const key of Object.keys(value)) {\n if (!allowedKeys.has(key)) {\n errors.push(`config.${key} is not supported.`);\n }\n }\n\n if (!options.partial) {\n for (const key of CONFIG_KEYS) {\n if (!Object.hasOwn(value, key)) {\n errors.push(`config.${key} is required.`);\n }\n }\n }\n\n const has = (key: keyof PlayerExperienceConfig): boolean =>\n Object.hasOwn(value, key);\n const fadeLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.fadeMs;\n\n for (const key of [\n \"playFadeInMs\",\n \"pauseFadeOutMs\",\n \"trackChangeFadeOutMs\",\n \"trackChangeFadeInMs\",\n \"seekFadeMs\",\n ] as const) {\n if (has(key)) {\n validateFiniteRange(value[key], `config.${key}`, fadeLimits.min, fadeLimits.max, errors);\n }\n }\n\n const thresholdLimits =\n PLAYER_EXPERIENCE_CONFIG_LIMITS.previousRestartThresholdSec;\n if (has(\"previousRestartThresholdSec\")) {\n validateFiniteRange(\n value.previousRestartThresholdSec,\n \"config.previousRestartThresholdSec\",\n thresholdLimits.min,\n thresholdLimits.max,\n errors,\n );\n }\n\n const volumeLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.initialVolume;\n if (has(\"initialVolume\")) {\n validateFiniteRange(\n value.initialVolume,\n \"config.initialVolume\",\n volumeLimits.min,\n volumeLimits.max,\n errors,\n );\n }\n\n const waveformOpacityLimits =\n PLAYER_EXPERIENCE_CONFIG_LIMITS.waveformOpacity;\n if (has(\"waveformOpacity\")) {\n validateFiniteRange(\n value.waveformOpacity,\n \"config.waveformOpacity\",\n waveformOpacityLimits.min,\n waveformOpacityLimits.max,\n errors,\n );\n }\n\n for (const key of [\n \"waveformPlayedStateEnabled\",\n \"initialShuffleEnabled\",\n ] as const) {\n if (has(key)) {\n validateBoolean(value[key], `config.${key}`, errors);\n }\n }\n\n const skipLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.podcastSkipSec;\n for (const key of [\"podcastBackSec\", \"podcastForwardSec\"] as const) {\n if (has(key)) {\n const candidate = value[key];\n const valid = validateFiniteRange(\n candidate,\n `config.${key}`,\n skipLimits.minExclusive,\n skipLimits.max,\n errors,\n );\n if (valid && candidate <= skipLimits.minExclusive) {\n errors.push(`config.${key} must be greater than 0.`);\n }\n }\n }\n\n if (has(\"fadeCurve\") && !FADE_CURVES.has(value.fadeCurve as FadeCurve)) {\n errors.push(\"config.fadeCurve is not supported.\");\n }\n if (\n has(\"seekCommitMode\") &&\n !SEEK_COMMIT_MODES.has(value.seekCommitMode as SeekCommitMode)\n ) {\n errors.push(\"config.seekCommitMode is not supported.\");\n }\n if (\n has(\"initialRepeatMode\") &&\n !REPEAT_MODES.has(value.initialRepeatMode as RepeatMode)\n ) {\n errors.push(\"config.initialRepeatMode is not supported.\");\n }\n if (has(\"persistMode\") && !PERSIST_MODES.has(value.persistMode as PersistMode)) {\n errors.push(\"config.persistMode is not supported.\");\n }\n if (\n has(\"podcastPreviousMode\") &&\n !PODCAST_PREVIOUS_MODES.has(\n value.podcastPreviousMode as PodcastPreviousMode,\n )\n ) {\n errors.push(\"config.podcastPreviousMode is not supported.\");\n }\n\n if (errors.length > 0) {\n return { ok: false, errors: Object.freeze(errors) };\n }\n\n const merged = options.partial\n ? { ...PREVIEW_PLAYER_EXPERIENCE_CONFIG, ...value }\n : value;\n\n return {\n ok: true,\n errors: [],\n value: Object.freeze({ ...merged }) as Readonly<PlayerExperienceConfig>,\n };\n}\n\nexport function validatePlayerExperienceConfig(\n value: unknown,\n): PlayerExperienceConfigValidationResult {\n return validateConfigRecord(value, { partial: false });\n}\n\nexport function validatePlayerExperienceConfigOverride(\n value: unknown,\n): PlayerExperienceConfigValidationResult {\n return validateConfigRecord(value, { partial: true });\n}\n\nexport function resolvePlayerExperienceConfig(\n override?: Partial<PlayerExperienceConfig>,\n): PlayerExperienceConfigValidationResult {\n return validatePlayerExperienceConfigOverride(override ?? {});\n}\n\nexport function parsePlayerExperienceConfigJson(\n json: string,\n): PlayerExperienceConfigValidationResult {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(json) as unknown;\n } catch {\n return { ok: false, errors: [\"Config JSON is not valid JSON.\"] };\n }\n\n if (!isRecord(parsed)) {\n return { ok: false, errors: [\"Config JSON envelope must be an object.\"] };\n }\n\n const envelopeKeys = Object.keys(parsed);\n const errors: string[] = [];\n\n for (const key of envelopeKeys) {\n if (key !== \"schemaVersion\" && key !== \"config\") {\n errors.push(`envelope.${key} is not supported.`);\n }\n }\n if (!Object.hasOwn(parsed, \"schemaVersion\")) {\n errors.push(\"envelope.schemaVersion is required.\");\n } else if (\n parsed.schemaVersion !== PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION\n ) {\n errors.push(\"envelope.schemaVersion is not supported.\");\n }\n if (!Object.hasOwn(parsed, \"config\")) {\n errors.push(\"envelope.config is required.\");\n }\n\n if (errors.length > 0) {\n return { ok: false, errors: Object.freeze(errors) };\n }\n\n return validatePlayerExperienceConfig(parsed.config);\n}\n\nexport function serializePlayerExperienceConfig(\n config: PlayerExperienceConfig,\n): string {\n const result = validatePlayerExperienceConfig(config);\n\n if (!result.ok) {\n throw new TypeError(result.errors.join(\" \"));\n }\n\n return JSON.stringify(\n {\n schemaVersion: PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION,\n config: result.value,\n },\n null,\n 2,\n );\n}\n","import type {\n PlayerExperienceConfig,\n PlayerState,\n} from \"../contracts/player\";\nimport { resolvePlayerExperienceConfig } from \"./validation\";\n\nexport function createInitialPlayerState(\n experienceConfig?: Partial<PlayerExperienceConfig>,\n): Readonly<PlayerState> {\n const resolved = resolvePlayerExperienceConfig(experienceConfig);\n\n if (!resolved.ok) {\n throw new TypeError(resolved.errors.join(\" \"));\n }\n\n return Object.freeze({\n currentItem: null,\n currentItemId: null,\n currentQueueItemId: null,\n mediaKind: null,\n status: \"idle\",\n currentTimeSec: 0,\n durationSec: null,\n volume: resolved.value.initialVolume,\n muted: false,\n shuffleEnabled: resolved.value.initialShuffleEnabled,\n repeatMode: resolved.value.initialRepeatMode,\n queue: Object.freeze([]),\n currentQueueIndex: null,\n canSeek: false,\n canGoPrevious: false,\n canGoNext: false,\n needsUserGesture: false,\n lastTransitionCause: null,\n error: null,\n experienceConfig: resolved.value,\n });\n}\n","import type {\n PlayerExperienceConfig,\n PlayerMediaItem,\n PlayerState,\n QueueItem,\n} from \"../contracts/player\";\nimport { createInitialPlayerState } from \"../config/initial-state\";\n\nexport function createPlayerMediaItemFixture(\n overrides: Partial<PlayerMediaItem> = {},\n): PlayerMediaItem {\n return {\n id: \"fixture-track\",\n kind: \"track\",\n title: \"Fixture Track\",\n creatorName: \"Fixture Creator\",\n source: {\n url: \"/mock-audio/fixture-track.mp3\",\n mimeType: \"audio/mpeg\",\n crossOrigin: \"anonymous\",\n },\n durationHintSec: 180,\n waveform: {\n version: 1,\n peaks: [0.2, 0.6, 0.4, 0.8],\n },\n ...overrides,\n };\n}\n\nexport function createQueueItemFixture(\n overrides: Partial<QueueItem> = {},\n): QueueItem {\n return {\n queueItemId: \"fixture-queue-item\",\n item: createPlayerMediaItemFixture(),\n ...overrides,\n };\n}\n\nexport function createPlayerStateFixture(\n overrides: Partial<PlayerState> = {},\n experienceConfig?: Partial<PlayerExperienceConfig>,\n): Readonly<PlayerState> {\n const initial = createInitialPlayerState(experienceConfig);\n return Object.freeze({\n ...initial,\n ...overrides,\n });\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/mock/mock-player-adapter.ts","../../src/config/defaults.ts","../../src/config/validation.ts","../../src/config/initial-state.ts","../../src/testing/fixtures.ts"],"names":[],"mappings":";AAsCA,IAAM,YAAA,GAA2C,OAAO,MAAA,CAAO;AAAA,EAC7D,OAAO,MAAA,CAAO;AAAA,IACZ,EAAA,EAAI,oBAAA;AAAA,IACJ,QAAA,EAAU,IAAA;AAAA,IACV,KAAA,EAAO,oBAAA;AAAA,IACP,WAAA,EAAa,gBAAA;AAAA,IACb,eAAA,EAAiB,mBAAA;AAAA,IACjB,SAAA,EAAW,oCAAA;AAAA,IACX,eAAA,EAAiB,GAAA;AAAA,IACjB,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,CAAC,IAAA,EAAM,MAAM,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,IAAI,CAAC;AAAA,GACjE,CAAA;AAAA,EACD,OAAO,MAAA,CAAO;AAAA,IACZ,EAAA,EAAI,mBAAA;AAAA,IACJ,QAAA,EAAU,IAAA;AAAA,IACV,KAAA,EAAO,mBAAA;AAAA,IACP,WAAA,EAAa,gBAAA;AAAA,IACb,eAAA,EAAiB,mBAAA;AAAA,IACjB,SAAA,EAAW,mCAAA;AAAA,IACX,eAAA,EAAiB,GAAA;AAAA,IACjB,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,CAAC,IAAA,EAAM,KAAK,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAC;AAAA,GACjE;AACH,CAAC,CAAA;AAED,IAAM,iBAAA,GAAiC,OAAO,MAAA,CAAO;AAAA,EACnD,IAAA,EAAM,SAAA;AAAA,EACN,WAAA,EAAa,IAAA;AAAA,EACb,UAAA,EAAY;AACd,CAAC,CAAA;AAED,IAAM,WAAA,GAA2B,OAAO,MAAA,CAAO;AAAA,EAC7C,IAAA,EAAM,aAAA;AAAA,EACN,WAAA,EAAa,KAAA;AAAA,EACb,UAAA,EAAY;AACd,CAAC,CAAA;AAED,IAAM,qBAAA,uBAA4B,GAAA,CAAwB;AAAA,EACxD,SAAA;AAAA,EACA,SAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,KAAK,OAAA,EAAgC;AAC5C,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,EACzB;AAEA,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,UAAA,CAAW,SAAS,OAAO,CAAA;AAAA,EAC7B,CAAC,CAAA;AACH;AAEO,IAAM,oBAAN,MAEP;AAAA,EACW,SAAA;AAAA,EACA,QAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,QAAA,IAAY,SAAA;AACrC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,OAAA,IAAW,CAAA;AAEnC,IAAA,IAAI,CAAC,qBAAA,CAAsB,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AAC9C,MAAA,MAAM,IAAI,UAAU,iCAAiC,CAAA;AAAA,IACvD;AAEA,IAAA,IACE,CAAC,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA,IAC9B,IAAA,CAAK,QAAA,GAAW,CAAA,IAChB,IAAA,CAAK,QAAA,GAAW,GAAA,EAChB;AACA,MAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,kBAAkB,MAAA,EAAiD;AACjE,IAAA,IACE,CAAC,MAAA,CAAO,QAAA,IACR,OAAO,MAAA,CAAO,cAAc,QAAA,IAC5B,MAAA,CAAO,SAAA,CAAU,MAAA,KAAW,CAAA,EAC5B;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAwB;AAAA,MAC5B,IAAI,MAAA,CAAO,EAAA;AAAA,MACX,IAAA,EAAM,OAAA;AAAA,MACN,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,MAAA,EAAQ;AAAA,QACN,KAAK,MAAA,CAAO,SAAA;AAAA,QACZ,WAAA,EAAa,WAAA;AAAA,QACb,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,GAAI,OAAO,WAAA,KAAgB,MAAA,GACvB,EAAC,GACD,EAAE,WAAA,EAAa,MAAA,CAAO,WAAA,EAAY;AAAA,MACtC,GAAI,OAAO,eAAA,KAAoB,MAAA,GAC3B,EAAC,GACD,EAAE,eAAA,EAAiB,MAAA,CAAO,eAAA,EAAgB;AAAA,MAC9C,GAAI,IAAA,CAAK,SAAA,KAAc,kBAAA,IACvB,MAAA,CAAO,eAAA,KAAoB,MAAA,GACvB,EAAC,GACD,EAAE,eAAA,EAAiB,MAAA,CAAO,eAAA;AAAgB,KAChD;AAEA,IAAA,OAAO;AAAA,MACL,GAAG,IAAA;AAAA,MACH,GAAI,KAAK,SAAA,KAAc,kBAAA,IACvB,OAAO,aAAA,KAAkB,MAAA,GACrB,EAAC,GACD;AAAA,QACE,QAAA,EAAU;AAAA,UACR,OAAA,EAAS,CAAA;AAAA,UACT,OAAO,MAAA,CAAO;AAAA;AAChB;AACF,KACN;AAAA,EACF;AAAA,EAEA,MAAM,YAAA,GAAkD;AACtD,IAAA,MAAM,IAAA,CAAK,KAAK,QAAQ,CAAA;AAExB,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,CAAC,QAAQ,KAAA,KAAU;AACpD,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,iBAAA,CAAkB,MAAM,CAAA;AAC1C,MAAA,OAAO,IAAA,KAAS,IAAA,GACZ,EAAC,GACD,CAAC,EAAE,WAAA,EAAa,CAAA,aAAA,EAAgB,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,IACjE,CAAC,CAAA;AAED,IAAA,OAAO,OAAO,MAAA,CAAO;AAAA,MACnB,UAAU,IAAA,CAAK,SAAA;AAAA,MACf,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,MAC1B,YAAA,EACE,KAAK,SAAA,KAAc,mBAAA,GACf,oBACA,IAAA,CAAK,SAAA,KAAc,gBACjB,WAAA,GACA,IAAA;AAAA,MACR,cAAA,EAAgB,KAAK,SAAA,KAAc;AAAA,KACpC,CAAA;AAAA,EACH;AACF;AAEO,IAAM,gBAAA,GAAmB;;;ACnLzB,IAAM,+BAAA,GAAkC,OAAO,MAAA,CAAO;AAAA,EAC3D,MAAA,EAAQ,OAAO,MAAA,CAAO,EAAE,KAAK,CAAA,EAAG,GAAA,EAAK,KAAQ,CAAA;AAAA,EAC7C,2BAAA,EAA6B,OAAO,MAAA,CAAO,EAAE,KAAK,CAAA,EAAG,GAAA,EAAK,IAAI,CAAA;AAAA,EAC9D,eAAA,EAAiB,OAAO,MAAA,CAAO,EAAE,KAAK,CAAA,EAAG,GAAA,EAAK,GAAG,CAAA;AAAA,EACjD,aAAA,EAAe,OAAO,MAAA,CAAO,EAAE,KAAK,CAAA,EAAG,GAAA,EAAK,GAAG,CAAA;AAAA,EAC/C,cAAA,EAAgB,OAAO,MAAA,CAAO,EAAE,cAAc,CAAA,EAAG,GAAA,EAAK,MAAO;AAC/D,CAAC,CAAA;AAEM,IAAM,gCAAA,GACX,OAAO,MAAA,CAAO;AAAA,EACZ,YAAA,EAAc,GAAA;AAAA,EACd,cAAA,EAAgB,GAAA;AAAA,EAChB,oBAAA,EAAsB,GAAA;AAAA,EACtB,mBAAA,EAAqB,GAAA;AAAA,EACrB,UAAA,EAAY,GAAA;AAAA,EACZ,SAAA,EAAW,UAAA;AAAA,EACX,2BAAA,EAA6B,CAAA;AAAA,EAC7B,cAAA,EAAgB,YAAA;AAAA,EAChB,0BAAA,EAA4B,IAAA;AAAA,EAC5B,eAAA,EAAiB,IAAA;AAAA,EACjB,qBAAA,EAAuB,KAAA;AAAA,EACvB,iBAAA,EAAmB,KAAA;AAAA,EACnB,aAAA,EAAe,GAAA;AAAA,EACf,WAAA,EAAa,MAAA;AAAA,EACb,cAAA,EAAgB,EAAA;AAAA,EAChB,iBAAA,EAAmB,EAAA;AAAA,EACnB,mBAAA,EAAqB;AACvB,CAAC,CAAA;;;AChBH,IAAM,WAAA,GAAc;AAAA,EAClB,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,sBAAA;AAAA,EACA,qBAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,6BAAA;AAAA,EACA,gBAAA;AAAA,EACA,4BAAA;AAAA,EACA,iBAAA;AAAA,EACA,uBAAA;AAAA,EACA,mBAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,WAAA,uBAAkB,GAAA,CAAe;AAAA,EACrC,QAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,IAAM,oCAAoB,IAAI,GAAA,CAAoB,CAAC,MAAA,EAAQ,YAAY,CAAC,CAAA;AACxE,IAAM,+BAAe,IAAI,GAAA,CAAgB,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC,CAAA;AAC9D,IAAM,gCAAgB,IAAI,GAAA,CAAiB,CAAC,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAC,CAAA;AACvE,IAAM,sBAAA,uBAA6B,GAAA,CAAyB;AAAA,EAC1D,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAEA,SAAS,mBAAA,CACP,KAAA,EACA,IAAA,EACA,GAAA,EACA,KACA,MAAA,EACiB;AACjB,EAAA,IACE,OAAO,KAAA,KAAU,QAAA,IACjB,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IACtB,KAAA,GAAQ,GAAA,IACR,KAAA,GAAQ,GAAA,EACR;AACA,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,EAAG,IAAI,CAAA,iCAAA,EAAoC,MAAA,CAAO,GAAG,CAAC,CAAA,KAAA,EAAQ,MAAA,CAAO,GAAG,CAAC,CAAA,CAAA;AAAA,KAC3E;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,eAAA,CACP,KAAA,EACA,IAAA,EACA,MAAA,EACkB;AAClB,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,IAAI,CAAA,mBAAA,CAAqB,CAAA;AACxC,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,oBAAA,CACP,OACA,OAAA,EACwC;AACxC,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG;AACpB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,CAAC,2BAA2B,CAAA,EAAE;AAAA,EAC5D;AAEA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAY,WAAW,CAAA;AAE/C,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACpC,IAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA,EAAG;AACzB,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,OAAA,EAAU,GAAG,CAAA,kBAAA,CAAoB,CAAA;AAAA,IAC/C;AAAA,EACF;AAUA,EAAA,MAAM,MAAM,CAAC,GAAA,KACX,MAAA,CAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B,EAAA,MAAM,aAAa,+BAAA,CAAgC,MAAA;AAEnD,EAAA,KAAA,MAAW,GAAA,IAAO;AAAA,IAChB,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,sBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACF,EAAY;AACV,IAAA,IAAI,GAAA,CAAI,GAAG,CAAA,EAAG;AACZ,MAAA,mBAAA,CAAoB,KAAA,CAAM,GAAG,CAAA,EAAG,CAAA,OAAA,EAAU,GAAG,IAAI,UAAA,CAAW,GAAA,EAAK,UAAA,CAAW,GAAA,EAAK,MAAM,CAAA;AAAA,IACzF;AAAA,EACF;AAEA,EAAA,MAAM,kBACJ,+BAAA,CAAgC,2BAAA;AAClC,EAAA,IAAI,GAAA,CAAI,6BAA6B,CAAA,EAAG;AACtC,IAAA,mBAAA;AAAA,MACE,KAAA,CAAM,2BAAA;AAAA,MACN,oCAAA;AAAA,MACA,eAAA,CAAgB,GAAA;AAAA,MAChB,eAAA,CAAgB,GAAA;AAAA,MAChB;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,eAAe,+BAAA,CAAgC,aAAA;AACrD,EAAA,IAAI,GAAA,CAAI,eAAe,CAAA,EAAG;AACxB,IAAA,mBAAA;AAAA,MACE,KAAA,CAAM,aAAA;AAAA,MACN,sBAAA;AAAA,MACA,YAAA,CAAa,GAAA;AAAA,MACb,YAAA,CAAa,GAAA;AAAA,MACb;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,wBACJ,+BAAA,CAAgC,eAAA;AAClC,EAAA,IAAI,GAAA,CAAI,iBAAiB,CAAA,EAAG;AAC1B,IAAA,mBAAA;AAAA,MACE,KAAA,CAAM,eAAA;AAAA,MACN,wBAAA;AAAA,MACA,qBAAA,CAAsB,GAAA;AAAA,MACtB,qBAAA,CAAsB,GAAA;AAAA,MACtB;AAAA,KACF;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,GAAA,IAAO;AAAA,IAChB,4BAAA;AAAA,IACA;AAAA,GACF,EAAY;AACV,IAAA,IAAI,GAAA,CAAI,GAAG,CAAA,EAAG;AACZ,MAAA,eAAA,CAAgB,MAAM,GAAG,CAAA,EAAG,CAAA,OAAA,EAAU,GAAG,IAAI,MAAM,CAAA;AAAA,IACrD;AAAA,EACF;AAEA,EAAA,MAAM,aAAa,+BAAA,CAAgC,cAAA;AACnD,EAAA,KAAA,MAAW,GAAA,IAAO,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,EAAY;AAClE,IAAA,IAAI,GAAA,CAAI,GAAG,CAAA,EAAG;AACZ,MAAA,MAAM,SAAA,GAAY,MAAM,GAAG,CAAA;AAC3B,MAAA,MAAM,KAAA,GAAQ,mBAAA;AAAA,QACZ,SAAA;AAAA,QACA,UAAU,GAAG,CAAA,CAAA;AAAA,QACb,UAAA,CAAW,YAAA;AAAA,QACX,UAAA,CAAW,GAAA;AAAA,QACX;AAAA,OACF;AACA,MAAA,IAAI,KAAA,IAAS,SAAA,IAAa,UAAA,CAAW,YAAA,EAAc;AACjD,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,OAAA,EAAU,GAAG,CAAA,wBAAA,CAA0B,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,IAAK,CAAC,YAAY,GAAA,CAAI,KAAA,CAAM,SAAsB,CAAA,EAAG;AACtE,IAAA,MAAA,CAAO,KAAK,oCAAoC,CAAA;AAAA,EAClD;AACA,EAAA,IACE,GAAA,CAAI,gBAAgB,CAAA,IACpB,CAAC,kBAAkB,GAAA,CAAI,KAAA,CAAM,cAAgC,CAAA,EAC7D;AACA,IAAA,MAAA,CAAO,KAAK,yCAAyC,CAAA;AAAA,EACvD;AACA,EAAA,IACE,GAAA,CAAI,mBAAmB,CAAA,IACvB,CAAC,aAAa,GAAA,CAAI,KAAA,CAAM,iBAA+B,CAAA,EACvD;AACA,IAAA,MAAA,CAAO,KAAK,4CAA4C,CAAA;AAAA,EAC1D;AACA,EAAA,IAAI,GAAA,CAAI,aAAa,CAAA,IAAK,CAAC,cAAc,GAAA,CAAI,KAAA,CAAM,WAA0B,CAAA,EAAG;AAC9E,IAAA,MAAA,CAAO,KAAK,sCAAsC,CAAA;AAAA,EACpD;AACA,EAAA,IACE,GAAA,CAAI,qBAAqB,CAAA,IACzB,CAAC,sBAAA,CAAuB,GAAA;AAAA,IACtB,KAAA,CAAM;AAAA,GACR,EACA;AACA,IAAA,MAAA,CAAO,KAAK,8CAA8C,CAAA;AAAA,EAC5D;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,EAAE;AAAA,EACpD;AAEA,EAAA,MAAM,MAAA,GACF,EAAE,GAAG,gCAAA,EAAkC,GAAG,OAAM,CAChD;AAEJ,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,QAAQ,EAAC;AAAA,IACT,OAAO,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,QAAQ;AAAA,GACpC;AACF;AAQO,SAAS,uCACd,KAAA,EACwC;AACxC,EAAA,OAAO,oBAAA,CAAqB,KAAwB,CAAA;AACtD;AAEO,SAAS,8BACd,QAAA,EACwC;AACxC,EAAA,OAAO,sCAAA,CAAuC,QAAA,IAAY,EAAE,CAAA;AAC9D;;;AChPO,SAAS,yBACd,gBAAA,EACuB;AACvB,EAAA,MAAM,QAAA,GAAW,8BAA8B,gBAAgB,CAAA;AAE/D,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,SAAA,CAAU,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,IAAA;AAAA,IACf,kBAAA,EAAoB,IAAA;AAAA,IACpB,SAAA,EAAW,IAAA;AAAA,IACX,MAAA,EAAQ,MAAA;AAAA,IACR,cAAA,EAAgB,CAAA;AAAA,IAChB,WAAA,EAAa,IAAA;AAAA,IACb,MAAA,EAAQ,SAAS,KAAA,CAAM,aAAA;AAAA,IACvB,KAAA,EAAO,KAAA;AAAA,IACP,cAAA,EAAgB,SAAS,KAAA,CAAM,qBAAA;AAAA,IAC/B,UAAA,EAAY,SAAS,KAAA,CAAM,iBAAA;AAAA,IAC3B,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAAA,IACvB,aAAA,EAAe,IAAA;AAAA,IACf,iBAAA,EAAmB,IAAA;AAAA,IACnB,OAAA,EAAS,KAAA;AAAA,IACT,aAAA,EAAe,KAAA;AAAA,IACf,SAAA,EAAW,KAAA;AAAA,IACX,gBAAA,EAAkB,KAAA;AAAA,IAClB,mBAAA,EAAqB,IAAA;AAAA,IACrB,KAAA,EAAO,IAAA;AAAA,IACP,kBAAkB,QAAA,CAAS;AAAA,GAC5B,CAAA;AACH;;;AC9BO,SAAS,4BAAA,CACd,SAAA,GAAsC,EAAC,EACtB;AACjB,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,eAAA;AAAA,IACJ,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,eAAA;AAAA,IACP,WAAA,EAAa,iBAAA;AAAA,IACb,MAAA,EAAQ;AAAA,MACN,GAAA,EAAK,+BAAA;AAAA,MACL,QAAA,EAAU,YAAA;AAAA,MACV,WAAA,EAAa;AAAA,KACf;AAAA,IACA,eAAA,EAAiB,GAAA;AAAA,IACjB,QAAA,EAAU;AAAA,MACR,OAAA,EAAS,CAAA;AAAA,MACT,KAAA,EAAO,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,GAAG;AAAA,KAC5B;AAAA,IACA,GAAG;AAAA,GACL;AACF;AAEO,SAAS,sBAAA,CACd,SAAA,GAAgC,EAAC,EACtB;AACX,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,oBAAA;AAAA,IACb,MAAM,4BAAA,EAA6B;AAAA,IACnC,GAAG;AAAA,GACL;AACF;AAEO,SAAS,wBAAA,CACd,SAAA,GAAkC,EAAC,EACnC,gBAAA,EACuB;AACvB,EAAA,MAAM,OAAA,GAAU,yBAAyB,gBAAgB,CAAA;AACzD,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,GAAG,OAAA;AAAA,IACH,GAAG;AAAA,GACJ,CAAA;AACH","file":"index.js","sourcesContent":["import type {\r\n PlayerError,\r\n PlayerMediaAdapter,\r\n PlayerMediaItem,\r\n QueueItem,\r\n} from \"../../contracts/player\";\r\n\r\nexport type MockPlayerScenario =\r\n | \"success\"\r\n | \"loading\"\r\n | \"duration-unknown\"\r\n | \"missing-waveform\"\r\n | \"recoverable-error\"\r\n | \"fatal-error\";\r\n\r\nexport interface MockMediaRecord {\r\n readonly id: string;\r\n readonly playable: boolean;\r\n readonly title: string;\r\n readonly creatorName?: string;\r\n readonly collectionTitle?: string;\r\n readonly sourceUrl?: string;\r\n readonly durationHintSec?: number;\r\n readonly waveformPeaks?: readonly number[];\r\n}\r\n\r\nexport interface MockPlayerAdapterOptions {\r\n readonly scenario?: MockPlayerScenario;\r\n readonly delayMs?: number;\r\n}\r\n\r\nexport interface MockPlayerScenarioResult {\r\n readonly scenario: MockPlayerScenario;\r\n readonly queue: readonly QueueItem[];\r\n readonly initialError: PlayerError | null;\r\n readonly remainsLoading: boolean;\r\n}\r\n\r\nconst MOCK_RECORDS: readonly MockMediaRecord[] = Object.freeze([\r\n Object.freeze({\r\n id: \"sample-track-alpha\",\r\n playable: true,\r\n title: \"Sample Track Alpha\",\r\n creatorName: \"Sample Creator\",\r\n collectionTitle: \"Sample Collection\",\r\n sourceUrl: \"/mock-audio/sample-track-alpha.mp3\",\r\n durationHintSec: 185,\r\n waveformPeaks: Object.freeze([0.18, 0.42, 0.7, 0.54, 0.82, 0.33]),\r\n }),\r\n Object.freeze({\r\n id: \"sample-track-beta\",\r\n playable: true,\r\n title: \"Sample Track Beta\",\r\n creatorName: \"Sample Creator\",\r\n collectionTitle: \"Sample Collection\",\r\n sourceUrl: \"/mock-audio/sample-track-beta.mp3\",\r\n durationHintSec: 212,\r\n waveformPeaks: Object.freeze([0.28, 0.5, 0.36, 0.76, 0.61, 0.24]),\r\n }),\r\n]);\r\n\r\nconst RECOVERABLE_ERROR: PlayerError = Object.freeze({\r\n code: \"network\",\r\n recoverable: true,\r\n messageKey: \"player.error.network\",\r\n});\r\n\r\nconst FATAL_ERROR: PlayerError = Object.freeze({\r\n code: \"unsupported\",\r\n recoverable: false,\r\n messageKey: \"player.error.unsupported\",\r\n});\r\n\r\nconst MOCK_PLAYER_SCENARIOS = new Set<MockPlayerScenario>([\r\n \"success\",\r\n \"loading\",\r\n \"duration-unknown\",\r\n \"missing-waveform\",\r\n \"recoverable-error\",\r\n \"fatal-error\",\r\n]);\r\n\r\nfunction wait(delayMs: number): Promise<void> {\r\n if (delayMs <= 0) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise((resolve) => {\r\n setTimeout(resolve, delayMs);\r\n });\r\n}\r\n\r\nexport class MockPlayerAdapter\r\n implements PlayerMediaAdapter<MockMediaRecord>\r\n{\r\n readonly #scenario: MockPlayerScenario;\r\n readonly #delayMs: number;\r\n\r\n constructor(options: MockPlayerAdapterOptions = {}) {\r\n this.#scenario = options.scenario ?? \"success\";\r\n this.#delayMs = options.delayMs ?? 0;\r\n\r\n if (!MOCK_PLAYER_SCENARIOS.has(this.#scenario)) {\r\n throw new TypeError(\"Mock scenario is not supported.\");\r\n }\r\n\r\n if (\r\n !Number.isFinite(this.#delayMs) ||\r\n this.#delayMs < 0 ||\r\n this.#delayMs > 30_000\r\n ) {\r\n throw new RangeError(\"Mock delayMs must be between 0 and 30000.\");\r\n }\r\n }\r\n\r\n toPlayerMediaItem(source: MockMediaRecord): PlayerMediaItem | null {\r\n if (\r\n !source.playable ||\r\n typeof source.sourceUrl !== \"string\" ||\r\n source.sourceUrl.length === 0\r\n ) {\r\n return null;\r\n }\r\n\r\n const base: PlayerMediaItem = {\r\n id: source.id,\r\n kind: \"track\",\r\n title: source.title,\r\n source: {\r\n url: source.sourceUrl,\r\n crossOrigin: \"anonymous\",\r\n mimeType: \"audio/mpeg\",\r\n },\r\n ...(source.creatorName === undefined\r\n ? {}\r\n : { creatorName: source.creatorName }),\r\n ...(source.collectionTitle === undefined\r\n ? {}\r\n : { collectionTitle: source.collectionTitle }),\r\n ...(this.#scenario === \"duration-unknown\" ||\r\n source.durationHintSec === undefined\r\n ? {}\r\n : { durationHintSec: source.durationHintSec }),\r\n };\r\n\r\n return {\r\n ...base,\r\n ...(this.#scenario === \"missing-waveform\" ||\r\n source.waveformPeaks === undefined\r\n ? {}\r\n : {\r\n waveform: {\r\n version: 1,\r\n peaks: source.waveformPeaks,\r\n },\r\n }),\r\n };\r\n }\r\n\r\n async loadScenario(): Promise<MockPlayerScenarioResult> {\r\n await wait(this.#delayMs);\r\n\r\n const queue = MOCK_RECORDS.flatMap((record, index) => {\r\n const item = this.toPlayerMediaItem(record);\r\n return item === null\r\n ? []\r\n : [{ queueItemId: `sample-queue-${String(index + 1)}`, item }];\r\n });\r\n\r\n return Object.freeze({\r\n scenario: this.#scenario,\r\n queue: Object.freeze(queue),\r\n initialError:\r\n this.#scenario === \"recoverable-error\"\r\n ? RECOVERABLE_ERROR\r\n : this.#scenario === \"fatal-error\"\r\n ? FATAL_ERROR\r\n : null,\r\n remainsLoading: this.#scenario === \"loading\",\r\n });\r\n }\r\n}\r\n\r\nexport const mockMediaRecords = MOCK_RECORDS;\r\n","import type { PlayerExperienceConfig } from \"../contracts/player\";\r\n\r\nexport const PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION = 2 as const;\r\n\r\nexport const PLAYER_EXPERIENCE_CONFIG_LIMITS = Object.freeze({\r\n fadeMs: Object.freeze({ min: 0, max: 10_000 }),\r\n previousRestartThresholdSec: Object.freeze({ min: 0, max: 60 }),\r\n waveformOpacity: Object.freeze({ min: 0, max: 1 }),\r\n initialVolume: Object.freeze({ min: 0, max: 1 }),\r\n podcastSkipSec: Object.freeze({ minExclusive: 0, max: 3_600 }),\r\n});\r\n\r\nexport const PREVIEW_PLAYER_EXPERIENCE_CONFIG: Readonly<PlayerExperienceConfig> =\r\n Object.freeze({\r\n playFadeInMs: 300,\r\n pauseFadeOutMs: 600,\r\n trackChangeFadeOutMs: 300,\r\n trackChangeFadeInMs: 300,\r\n seekFadeMs: 120,\r\n fadeCurve: \"ease-out\",\r\n previousRestartThresholdSec: 3,\r\n seekCommitMode: \"on-release\",\r\n waveformPlayedStateEnabled: true,\r\n waveformOpacity: 0.72,\r\n initialShuffleEnabled: false,\r\n initialRepeatMode: \"off\",\r\n initialVolume: 0.8,\r\n persistMode: \"none\",\r\n podcastBackSec: 15,\r\n podcastForwardSec: 30,\r\n podcastPreviousMode: \"previous-episode\",\r\n });\r\n","import type {\r\n FadeCurve,\r\n PersistMode,\r\n PlayerExperienceConfig,\r\n PodcastPreviousMode,\r\n RepeatMode,\r\n SeekCommitMode,\r\n} from \"../contracts/player\";\r\nimport type { PlayerExperienceConfigValidationResult } from \"../contracts/config\";\r\nimport {\r\n PLAYER_EXPERIENCE_CONFIG_LIMITS,\r\n PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION,\r\n PREVIEW_PLAYER_EXPERIENCE_CONFIG,\r\n} from \"./defaults\";\r\n\r\nconst CONFIG_KEYS = [\r\n \"playFadeInMs\",\r\n \"pauseFadeOutMs\",\r\n \"trackChangeFadeOutMs\",\r\n \"trackChangeFadeInMs\",\r\n \"seekFadeMs\",\r\n \"fadeCurve\",\r\n \"previousRestartThresholdSec\",\r\n \"seekCommitMode\",\r\n \"waveformPlayedStateEnabled\",\r\n \"waveformOpacity\",\r\n \"initialShuffleEnabled\",\r\n \"initialRepeatMode\",\r\n \"initialVolume\",\r\n \"persistMode\",\r\n \"podcastBackSec\",\r\n \"podcastForwardSec\",\r\n \"podcastPreviousMode\",\r\n] as const satisfies readonly (keyof PlayerExperienceConfig)[];\r\n\r\nconst FADE_CURVES = new Set<FadeCurve>([\r\n \"linear\",\r\n \"ease-in\",\r\n \"ease-out\",\r\n \"equal-power\",\r\n]);\r\nconst SEEK_COMMIT_MODES = new Set<SeekCommitMode>([\"live\", \"on-release\"]);\r\nconst REPEAT_MODES = new Set<RepeatMode>([\"off\", \"all\", \"one\"]);\r\nconst PERSIST_MODES = new Set<PersistMode>([\"none\", \"session\", \"local\"]);\r\nconst PODCAST_PREVIOUS_MODES = new Set<PodcastPreviousMode>([\r\n \"previous-episode\",\r\n \"restart-episode\",\r\n]);\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction validateFiniteRange(\r\n value: unknown,\r\n path: string,\r\n min: number,\r\n max: number,\r\n errors: string[],\r\n): value is number {\r\n if (\r\n typeof value !== \"number\" ||\r\n !Number.isFinite(value) ||\r\n value < min ||\r\n value > max\r\n ) {\r\n errors.push(\r\n `${path} must be a finite number between ${String(min)} and ${String(max)}.`,\r\n );\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nfunction validateBoolean(\r\n value: unknown,\r\n path: string,\r\n errors: string[],\r\n): value is boolean {\r\n if (typeof value !== \"boolean\") {\r\n errors.push(`${path} must be a boolean.`);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nfunction validateConfigRecord(\r\n value: unknown,\r\n options: { readonly partial: boolean },\r\n): PlayerExperienceConfigValidationResult {\r\n if (!isRecord(value)) {\r\n return { ok: false, errors: [\"config must be an object.\"] };\r\n }\r\n\r\n const errors: string[] = [];\r\n const allowedKeys = new Set<string>(CONFIG_KEYS);\r\n\r\n for (const key of Object.keys(value)) {\r\n if (!allowedKeys.has(key)) {\r\n errors.push(`config.${key} is not supported.`);\r\n }\r\n }\r\n\r\n if (!options.partial) {\r\n for (const key of CONFIG_KEYS) {\r\n if (!Object.hasOwn(value, key)) {\r\n errors.push(`config.${key} is required.`);\r\n }\r\n }\r\n }\r\n\r\n const has = (key: keyof PlayerExperienceConfig): boolean =>\r\n Object.hasOwn(value, key);\r\n const fadeLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.fadeMs;\r\n\r\n for (const key of [\r\n \"playFadeInMs\",\r\n \"pauseFadeOutMs\",\r\n \"trackChangeFadeOutMs\",\r\n \"trackChangeFadeInMs\",\r\n \"seekFadeMs\",\r\n ] as const) {\r\n if (has(key)) {\r\n validateFiniteRange(value[key], `config.${key}`, fadeLimits.min, fadeLimits.max, errors);\r\n }\r\n }\r\n\r\n const thresholdLimits =\r\n PLAYER_EXPERIENCE_CONFIG_LIMITS.previousRestartThresholdSec;\r\n if (has(\"previousRestartThresholdSec\")) {\r\n validateFiniteRange(\r\n value.previousRestartThresholdSec,\r\n \"config.previousRestartThresholdSec\",\r\n thresholdLimits.min,\r\n thresholdLimits.max,\r\n errors,\r\n );\r\n }\r\n\r\n const volumeLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.initialVolume;\r\n if (has(\"initialVolume\")) {\r\n validateFiniteRange(\r\n value.initialVolume,\r\n \"config.initialVolume\",\r\n volumeLimits.min,\r\n volumeLimits.max,\r\n errors,\r\n );\r\n }\r\n\r\n const waveformOpacityLimits =\r\n PLAYER_EXPERIENCE_CONFIG_LIMITS.waveformOpacity;\r\n if (has(\"waveformOpacity\")) {\r\n validateFiniteRange(\r\n value.waveformOpacity,\r\n \"config.waveformOpacity\",\r\n waveformOpacityLimits.min,\r\n waveformOpacityLimits.max,\r\n errors,\r\n );\r\n }\r\n\r\n for (const key of [\r\n \"waveformPlayedStateEnabled\",\r\n \"initialShuffleEnabled\",\r\n ] as const) {\r\n if (has(key)) {\r\n validateBoolean(value[key], `config.${key}`, errors);\r\n }\r\n }\r\n\r\n const skipLimits = PLAYER_EXPERIENCE_CONFIG_LIMITS.podcastSkipSec;\r\n for (const key of [\"podcastBackSec\", \"podcastForwardSec\"] as const) {\r\n if (has(key)) {\r\n const candidate = value[key];\r\n const valid = validateFiniteRange(\r\n candidate,\r\n `config.${key}`,\r\n skipLimits.minExclusive,\r\n skipLimits.max,\r\n errors,\r\n );\r\n if (valid && candidate <= skipLimits.minExclusive) {\r\n errors.push(`config.${key} must be greater than 0.`);\r\n }\r\n }\r\n }\r\n\r\n if (has(\"fadeCurve\") && !FADE_CURVES.has(value.fadeCurve as FadeCurve)) {\r\n errors.push(\"config.fadeCurve is not supported.\");\r\n }\r\n if (\r\n has(\"seekCommitMode\") &&\r\n !SEEK_COMMIT_MODES.has(value.seekCommitMode as SeekCommitMode)\r\n ) {\r\n errors.push(\"config.seekCommitMode is not supported.\");\r\n }\r\n if (\r\n has(\"initialRepeatMode\") &&\r\n !REPEAT_MODES.has(value.initialRepeatMode as RepeatMode)\r\n ) {\r\n errors.push(\"config.initialRepeatMode is not supported.\");\r\n }\r\n if (has(\"persistMode\") && !PERSIST_MODES.has(value.persistMode as PersistMode)) {\r\n errors.push(\"config.persistMode is not supported.\");\r\n }\r\n if (\r\n has(\"podcastPreviousMode\") &&\r\n !PODCAST_PREVIOUS_MODES.has(\r\n value.podcastPreviousMode as PodcastPreviousMode,\r\n )\r\n ) {\r\n errors.push(\"config.podcastPreviousMode is not supported.\");\r\n }\r\n\r\n if (errors.length > 0) {\r\n return { ok: false, errors: Object.freeze(errors) };\r\n }\r\n\r\n const merged = options.partial\r\n ? { ...PREVIEW_PLAYER_EXPERIENCE_CONFIG, ...value }\r\n : value;\r\n\r\n return {\r\n ok: true,\r\n errors: [],\r\n value: Object.freeze({ ...merged }) as Readonly<PlayerExperienceConfig>,\r\n };\r\n}\r\n\r\nexport function validatePlayerExperienceConfig(\r\n value: unknown,\r\n): PlayerExperienceConfigValidationResult {\r\n return validateConfigRecord(value, { partial: false });\r\n}\r\n\r\nexport function validatePlayerExperienceConfigOverride(\r\n value: unknown,\r\n): PlayerExperienceConfigValidationResult {\r\n return validateConfigRecord(value, { partial: true });\r\n}\r\n\r\nexport function resolvePlayerExperienceConfig(\r\n override?: Partial<PlayerExperienceConfig>,\r\n): PlayerExperienceConfigValidationResult {\r\n return validatePlayerExperienceConfigOverride(override ?? {});\r\n}\r\n\r\nexport function parsePlayerExperienceConfigJson(\r\n json: string,\r\n): PlayerExperienceConfigValidationResult {\r\n let parsed: unknown;\r\n\r\n try {\r\n parsed = JSON.parse(json) as unknown;\r\n } catch {\r\n return { ok: false, errors: [\"Config JSON is not valid JSON.\"] };\r\n }\r\n\r\n if (!isRecord(parsed)) {\r\n return { ok: false, errors: [\"Config JSON envelope must be an object.\"] };\r\n }\r\n\r\n const envelopeKeys = Object.keys(parsed);\r\n const errors: string[] = [];\r\n\r\n for (const key of envelopeKeys) {\r\n if (key !== \"schemaVersion\" && key !== \"config\") {\r\n errors.push(`envelope.${key} is not supported.`);\r\n }\r\n }\r\n if (!Object.hasOwn(parsed, \"schemaVersion\")) {\r\n errors.push(\"envelope.schemaVersion is required.\");\r\n } else if (\r\n parsed.schemaVersion !== PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION\r\n ) {\r\n errors.push(\"envelope.schemaVersion is not supported.\");\r\n }\r\n if (!Object.hasOwn(parsed, \"config\")) {\r\n errors.push(\"envelope.config is required.\");\r\n }\r\n\r\n if (errors.length > 0) {\r\n return { ok: false, errors: Object.freeze(errors) };\r\n }\r\n\r\n return validatePlayerExperienceConfig(parsed.config);\r\n}\r\n\r\nexport function serializePlayerExperienceConfig(\r\n config: PlayerExperienceConfig,\r\n): string {\r\n const result = validatePlayerExperienceConfig(config);\r\n\r\n if (!result.ok) {\r\n throw new TypeError(result.errors.join(\" \"));\r\n }\r\n\r\n return JSON.stringify(\r\n {\r\n schemaVersion: PLAYER_EXPERIENCE_CONFIG_SCHEMA_VERSION,\r\n config: result.value,\r\n },\r\n null,\r\n 2,\r\n );\r\n}\r\n","import type {\r\n PlayerExperienceConfig,\r\n PlayerState,\r\n} from \"../contracts/player\";\r\nimport { resolvePlayerExperienceConfig } from \"./validation\";\r\n\r\nexport function createInitialPlayerState(\r\n experienceConfig?: Partial<PlayerExperienceConfig>,\r\n): Readonly<PlayerState> {\r\n const resolved = resolvePlayerExperienceConfig(experienceConfig);\r\n\r\n if (!resolved.ok) {\r\n throw new TypeError(resolved.errors.join(\" \"));\r\n }\r\n\r\n return Object.freeze({\r\n currentItem: null,\r\n currentItemId: null,\r\n currentQueueItemId: null,\r\n mediaKind: null,\r\n status: \"idle\",\r\n currentTimeSec: 0,\r\n durationSec: null,\r\n volume: resolved.value.initialVolume,\r\n muted: false,\r\n shuffleEnabled: resolved.value.initialShuffleEnabled,\r\n repeatMode: resolved.value.initialRepeatMode,\r\n queue: Object.freeze([]),\r\n activeContext: null,\r\n currentQueueIndex: null,\r\n canSeek: false,\r\n canGoPrevious: false,\r\n canGoNext: false,\r\n needsUserGesture: false,\r\n lastTransitionCause: null,\r\n error: null,\r\n experienceConfig: resolved.value,\r\n });\r\n}\r\n","import type {\r\n PlayerExperienceConfig,\r\n PlayerMediaItem,\r\n PlayerState,\r\n QueueItem,\r\n} from \"../contracts/player\";\r\nimport { createInitialPlayerState } from \"../config/initial-state\";\r\n\r\nexport function createPlayerMediaItemFixture(\r\n overrides: Partial<PlayerMediaItem> = {},\r\n): PlayerMediaItem {\r\n return {\r\n id: \"fixture-track\",\r\n kind: \"track\",\r\n title: \"Fixture Track\",\r\n creatorName: \"Fixture Creator\",\r\n source: {\r\n url: \"/mock-audio/fixture-track.mp3\",\r\n mimeType: \"audio/mpeg\",\r\n crossOrigin: \"anonymous\",\r\n },\r\n durationHintSec: 180,\r\n waveform: {\r\n version: 1,\r\n peaks: [0.2, 0.6, 0.4, 0.8],\r\n },\r\n ...overrides,\r\n };\r\n}\r\n\r\nexport function createQueueItemFixture(\r\n overrides: Partial<QueueItem> = {},\r\n): QueueItem {\r\n return {\r\n queueItemId: \"fixture-queue-item\",\r\n item: createPlayerMediaItemFixture(),\r\n ...overrides,\r\n };\r\n}\r\n\r\nexport function createPlayerStateFixture(\r\n overrides: Partial<PlayerState> = {},\r\n experienceConfig?: Partial<PlayerExperienceConfig>,\r\n): Readonly<PlayerState> {\r\n const initial = createInitialPlayerState(experienceConfig);\r\n return Object.freeze({\r\n ...initial,\r\n ...overrides,\r\n });\r\n}\r\n"]}
@@ -1,12 +1,20 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { w as PlayerViewProps, r as PlayerMediaItem, u as PlayerState, f as PlayerCommands, d as PlayerAppearance, j as PlayerError, R as RepeatMode, b as PlaybackStatus, S as SeekCommitMode, x as PlayerWaveform } from '../player-DE9Vqztu.js';
3
+ import { C as PlayerViewProps, h as PlayerAppearance, c as PlaybackContextInput, Q as QueueItem, v as PlayerMediaItem, y as PlayerState, j as PlayerCommands, n as PlayerError, R as RepeatMode, f as PlaybackStatus, S as SeekCommitMode, D as PlayerWaveform } from '../player-BxNFzRq4.js';
4
4
 
5
5
  interface CompactPlayerProps extends PlayerViewProps {
6
6
  readonly className?: string;
7
7
  }
8
8
  declare function CompactPlayer({ appearance, className, commands, state, }: CompactPlayerProps): react.JSX.Element;
9
9
 
10
+ interface BoundCompactPlayerProps {
11
+ readonly appearance: PlayerAppearance;
12
+ readonly context: PlaybackContextInput;
13
+ readonly queueItem: QueueItem;
14
+ readonly className?: string;
15
+ }
16
+ declare function BoundCompactPlayer({ appearance, className, context, queueItem, }: BoundCompactPlayerProps): react.JSX.Element;
17
+
10
18
  interface DetailedPlayerProps extends PlayerViewProps {
11
19
  readonly className?: string;
12
20
  readonly queueLimit?: number;
@@ -140,4 +148,4 @@ interface WidePlayerProps extends PlayerViewProps {
140
148
  }
141
149
  declare function WidePlayer({ appearance, className, commands, state, }: WidePlayerProps): react.JSX.Element;
142
150
 
143
- export { Artwork, type ArtworkProps, CompactPlayer, type CompactPlayerProps, DetailedPlayer, type DetailedPlayerProps, IconButton, type IconButtonProps, MiniPlayer, type MiniPlayerProps, PlayerErrorNotice, type PlayerErrorNoticeProps, PlayerStatus, type PlayerStatusProps, PlayerSurface, type PlayerSurfaceProps, PodcastPlayer, type PodcastPlayerProps, PopoverVolumeControl, type PopoverVolumeControlProps, PrimaryPlaybackButton, type PrimaryPlaybackButtonProps, QueuePanel, type QueuePanelProps, QueueToggle, type QueueToggleProps, SeekBar, type SeekBarProps, TimeReadout, type TimeReadoutProps, TrackMetadata, type TrackMetadataProps, TransportControls, type TransportControlsProps, VolumeControl, type VolumeControlProps, Waveform, type WaveformProps, WidePlayer, type WidePlayerProps, clamp, formatTime, formatTimeAria, getErrorMessage, getNextRepeatMode, getRepeatLabel, getStatusLabel };
151
+ export { Artwork, type ArtworkProps, BoundCompactPlayer, type BoundCompactPlayerProps, CompactPlayer, type CompactPlayerProps, DetailedPlayer, type DetailedPlayerProps, IconButton, type IconButtonProps, MiniPlayer, type MiniPlayerProps, PlayerErrorNotice, type PlayerErrorNoticeProps, PlayerStatus, type PlayerStatusProps, PlayerSurface, type PlayerSurfaceProps, PodcastPlayer, type PodcastPlayerProps, PopoverVolumeControl, type PopoverVolumeControlProps, PrimaryPlaybackButton, type PrimaryPlaybackButtonProps, QueuePanel, type QueuePanelProps, QueueToggle, type QueueToggleProps, SeekBar, type SeekBarProps, TimeReadout, type TimeReadoutProps, TrackMetadata, type TrackMetadataProps, TransportControls, type TransportControlsProps, VolumeControl, type VolumeControlProps, Waveform, type WaveformProps, WidePlayer, type WidePlayerProps, clamp, formatTime, formatTimeAria, getErrorMessage, getNextRepeatMode, getRepeatLabel, getStatusLabel };
package/dist/ui/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useState, useRef, useId, useEffect } from 'react';
1
+ import { createContext, useState, useRef, useId, useEffect, useMemo, useSyncExternalStore, useContext } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
 
4
4
  // src/ui/player-primitives.tsx
@@ -399,6 +399,7 @@ function TransportControls({
399
399
  showModes ? /* @__PURE__ */ jsx(
400
400
  IconButton,
401
401
  {
402
+ disabled: state.activeContext?.mode === "manual-history",
402
403
  label: state.shuffleEnabled ? "Shuffle on" : "Shuffle off",
403
404
  onClick: () => {
404
405
  commands.setShuffle(!state.shuffleEnabled);
@@ -435,7 +436,9 @@ function TransportControls({
435
436
  {
436
437
  label: getRepeatLabel(state.repeatMode),
437
438
  onClick: () => {
438
- commands.setRepeatMode(getNextRepeatMode(state.repeatMode));
439
+ commands.setRepeatMode(
440
+ state.activeContext?.mode === "manual-history" ? state.repeatMode === "one" ? "off" : "one" : getNextRepeatMode(state.repeatMode)
441
+ );
439
442
  },
440
443
  pressed: state.repeatMode !== "off",
441
444
  children: /* @__PURE__ */ jsx(RepeatModeIcon, {})
@@ -778,6 +781,79 @@ function CompactPlayer({
778
781
  }
779
782
  );
780
783
  }
784
+ var PlayerRuntimeContext = createContext(null);
785
+ function usePlayerRuntimeContext() {
786
+ const context = useContext(PlayerRuntimeContext);
787
+ if (context === null) {
788
+ throw new Error("usePlayer must be used inside PlayerProvider.");
789
+ }
790
+ return context;
791
+ }
792
+ function usePlayer() {
793
+ const context = usePlayerRuntimeContext();
794
+ const state = useSyncExternalStore(
795
+ (listener) => context.store.subscribe(listener),
796
+ () => context.store.getState(),
797
+ () => context.store.getState()
798
+ );
799
+ return {
800
+ state,
801
+ commands: context.commands,
802
+ experience: context.experience,
803
+ audioContextState: context.audioContextState,
804
+ audioMode: context.audioMode,
805
+ mediaSessionSupported: context.mediaSessionSupported,
806
+ mediaSessionActionsEnabled: context.mediaSessionActionsEnabled
807
+ };
808
+ }
809
+ function deriveBoundPlayerViewState(playerState, contextId, queueItem) {
810
+ const isActive = playerState.activeContext?.id === contextId && playerState.currentQueueItemId === queueItem.queueItemId;
811
+ return Object.freeze({
812
+ queueItemId: queueItem.queueItemId,
813
+ item: isActive ? playerState.currentItem ?? queueItem.item : queueItem.item,
814
+ isActive,
815
+ status: isActive ? playerState.status : "paused",
816
+ currentTimeSec: isActive ? playerState.currentTimeSec : 0,
817
+ durationSec: isActive ? playerState.durationSec : queueItem.item.durationHintSec ?? null,
818
+ canSeek: isActive && playerState.canSeek,
819
+ isPlaying: isActive && playerState.status === "playing"
820
+ });
821
+ }
822
+ function useBoundPlayer({
823
+ context,
824
+ queueItem
825
+ }) {
826
+ const player = usePlayer();
827
+ const state = useMemo(
828
+ () => deriveBoundPlayerViewState(player.state, context.id, queueItem),
829
+ [context.id, player.state, queueItem]
830
+ );
831
+ const commands = useMemo(() => {
832
+ const play = () => player.commands.activateContext({
833
+ contextId: context.id,
834
+ mode: context.mode,
835
+ ...context.label === void 0 ? {} : { label: context.label },
836
+ queue: context.mode === "manual-history" ? [queueItem] : context.queue,
837
+ startQueueItemId: queueItem.queueItemId,
838
+ autoplay: true
839
+ });
840
+ return Object.freeze({
841
+ play,
842
+ togglePlayback() {
843
+ if (player.state.activeContext?.id === context.id && player.state.currentQueueItemId === queueItem.queueItemId) {
844
+ return player.commands.togglePlayback();
845
+ }
846
+ return play();
847
+ },
848
+ seekTo(seconds) {
849
+ if (player.state.activeContext?.id === context.id && player.state.currentQueueItemId === queueItem.queueItemId && player.state.canSeek) {
850
+ player.commands.seekTo(seconds);
851
+ }
852
+ }
853
+ });
854
+ }, [context, player.commands, player.state, queueItem]);
855
+ return { state, commands };
856
+ }
781
857
  function SeekBar({
782
858
  canSeek,
783
859
  className,
@@ -872,6 +948,93 @@ function SeekBar({
872
948
  }
873
949
  );
874
950
  }
951
+ function BoundCompactPlayer({
952
+ appearance,
953
+ className,
954
+ context,
955
+ queueItem
956
+ }) {
957
+ const bound = useBoundPlayer({ context, queueItem });
958
+ const player = usePlayer();
959
+ const progress = bound.state.durationSec === null || bound.state.durationSec <= 0 ? 0 : bound.state.currentTimeSec / bound.state.durationSec;
960
+ return /* @__PURE__ */ jsx(
961
+ PlayerSurface,
962
+ {
963
+ appearance,
964
+ className: ["player-bound-compact", className].filter(Boolean).join(" "),
965
+ label: `Inline player: ${queueItem.item.title}`,
966
+ children: /* @__PURE__ */ jsxs(
967
+ "div",
968
+ {
969
+ className: "player-bound-compact__main",
970
+ "data-active": bound.state.isActive ? "true" : "false",
971
+ "data-playback-context-id": context.id,
972
+ "data-playback-context-mode": context.mode,
973
+ "data-queue-item-id": queueItem.queueItemId,
974
+ children: [
975
+ /* @__PURE__ */ jsx(
976
+ IconButton,
977
+ {
978
+ className: "player-play-button",
979
+ label: bound.state.isPlaying ? "Pause" : "Play",
980
+ onClick: () => {
981
+ void bound.commands.togglePlayback();
982
+ },
983
+ children: bound.state.isPlaying ? /* @__PURE__ */ jsx(PauseIcon, { size: 22 }) : /* @__PURE__ */ jsx(PlayIcon, { size: 22 })
984
+ }
985
+ ),
986
+ /* @__PURE__ */ jsx(
987
+ Artwork,
988
+ {
989
+ className: "player-bound-compact__artwork",
990
+ item: bound.state.item
991
+ }
992
+ ),
993
+ /* @__PURE__ */ jsx(
994
+ TrackMetadata,
995
+ {
996
+ item: bound.state.item,
997
+ scrollTitle: bound.state.isPlaying
998
+ }
999
+ ),
1000
+ /* @__PURE__ */ jsxs("div", { className: "player-bound-compact__signal", children: [
1001
+ /* @__PURE__ */ jsx(
1002
+ Waveform,
1003
+ {
1004
+ opacity: player.state.experienceConfig.waveformOpacity,
1005
+ playedStateEnabled: player.state.experienceConfig.waveformPlayedStateEnabled,
1006
+ progress,
1007
+ waveform: bound.state.item.waveform
1008
+ }
1009
+ ),
1010
+ /* @__PURE__ */ jsx(
1011
+ TimeReadout,
1012
+ {
1013
+ currentTimeSec: bound.state.currentTimeSec,
1014
+ durationSec: bound.state.durationSec
1015
+ }
1016
+ )
1017
+ ] }),
1018
+ /* @__PURE__ */ jsx(
1019
+ SeekBar,
1020
+ {
1021
+ canSeek: bound.state.canSeek,
1022
+ commitMode: player.state.experienceConfig.seekCommitMode,
1023
+ currentTimeSec: bound.state.currentTimeSec,
1024
+ durationSec: bound.state.durationSec,
1025
+ label: `Seek in ${queueItem.item.title}`,
1026
+ onSeek: (seconds) => {
1027
+ bound.commands.seekTo(seconds);
1028
+ },
1029
+ status: bound.state.status
1030
+ }
1031
+ )
1032
+ ]
1033
+ }
1034
+ )
1035
+ }
1036
+ );
1037
+ }
875
1038
  function QueueRow({
876
1039
  commands,
877
1040
  index,
@@ -1021,59 +1184,67 @@ function MiniPlayer({
1021
1184
  className: ["player-mini", className].filter(Boolean).join(" "),
1022
1185
  label: "Mini music player",
1023
1186
  children: [
1024
- /* @__PURE__ */ jsxs("div", { className: "player-mini__main", children: [
1025
- /* @__PURE__ */ jsx(Artwork, { className: "player-mini__artwork", item: state.currentItem }),
1026
- /* @__PURE__ */ jsx(
1027
- TrackMetadata,
1028
- {
1029
- item: state.currentItem,
1030
- scrollTitle: state.status === "playing"
1031
- }
1032
- ),
1033
- /* @__PURE__ */ jsx(PlayerStatus, { state }),
1034
- /* @__PURE__ */ jsxs("div", { className: "player-mini__controls", children: [
1035
- /* @__PURE__ */ jsx(
1036
- TransportControls,
1037
- {
1038
- commands,
1039
- compact: true,
1040
- showModes: false,
1041
- state
1042
- }
1043
- ),
1044
- /* @__PURE__ */ jsx(
1045
- PopoverVolumeControl,
1046
- {
1047
- commands,
1048
- label: "Mini volume",
1049
- state
1050
- }
1051
- )
1052
- ] }),
1053
- /* @__PURE__ */ jsxs("div", { className: "player-mini__timeline", children: [
1054
- /* @__PURE__ */ jsx(
1055
- SeekBar,
1056
- {
1057
- canSeek: state.canSeek,
1058
- commitMode: state.experienceConfig.seekCommitMode,
1059
- currentTimeSec: state.currentTimeSec,
1060
- durationSec: state.durationSec,
1061
- label: "Seek in mini player",
1062
- onSeek: (seconds) => {
1063
- commands.seekTo(seconds);
1064
- },
1065
- status: state.status
1066
- }
1067
- ),
1068
- /* @__PURE__ */ jsx(
1069
- TimeReadout,
1070
- {
1071
- currentTimeSec: state.currentTimeSec,
1072
- durationSec: state.durationSec
1073
- }
1074
- )
1075
- ] })
1076
- ] }),
1187
+ /* @__PURE__ */ jsxs(
1188
+ "div",
1189
+ {
1190
+ className: "player-mini__main",
1191
+ "data-playback-context-id": state.activeContext?.id,
1192
+ "data-playback-context-mode": state.activeContext?.mode,
1193
+ children: [
1194
+ /* @__PURE__ */ jsx(Artwork, { className: "player-mini__artwork", item: state.currentItem }),
1195
+ /* @__PURE__ */ jsx(
1196
+ TrackMetadata,
1197
+ {
1198
+ item: state.currentItem,
1199
+ scrollTitle: state.status === "playing"
1200
+ }
1201
+ ),
1202
+ /* @__PURE__ */ jsx(PlayerStatus, { state }),
1203
+ /* @__PURE__ */ jsxs("div", { className: "player-mini__controls", children: [
1204
+ /* @__PURE__ */ jsx(
1205
+ TransportControls,
1206
+ {
1207
+ commands,
1208
+ compact: true,
1209
+ showModes: false,
1210
+ state
1211
+ }
1212
+ ),
1213
+ /* @__PURE__ */ jsx(
1214
+ PopoverVolumeControl,
1215
+ {
1216
+ commands,
1217
+ label: "Mini volume",
1218
+ state
1219
+ }
1220
+ )
1221
+ ] }),
1222
+ /* @__PURE__ */ jsxs("div", { className: "player-mini__timeline", children: [
1223
+ /* @__PURE__ */ jsx(
1224
+ SeekBar,
1225
+ {
1226
+ canSeek: state.canSeek,
1227
+ commitMode: state.experienceConfig.seekCommitMode,
1228
+ currentTimeSec: state.currentTimeSec,
1229
+ durationSec: state.durationSec,
1230
+ label: "Seek in mini player",
1231
+ onSeek: (seconds) => {
1232
+ commands.seekTo(seconds);
1233
+ },
1234
+ status: state.status
1235
+ }
1236
+ ),
1237
+ /* @__PURE__ */ jsx(
1238
+ TimeReadout,
1239
+ {
1240
+ currentTimeSec: state.currentTimeSec,
1241
+ durationSec: state.durationSec
1242
+ }
1243
+ )
1244
+ ] })
1245
+ ]
1246
+ }
1247
+ ),
1077
1248
  /* @__PURE__ */ jsx(PlayerErrorNotice, { commands, state })
1078
1249
  ]
1079
1250
  }
@@ -1339,6 +1510,6 @@ function WidePlayer({
1339
1510
  );
1340
1511
  }
1341
1512
 
1342
- export { Artwork, CompactPlayer, DetailedPlayer, IconButton, MiniPlayer, PlayerErrorNotice, PlayerStatus, PlayerSurface, PodcastPlayer, PopoverVolumeControl, PrimaryPlaybackButton, QueuePanel, QueueToggle, SeekBar, TimeReadout, TrackMetadata, TransportControls, VolumeControl, Waveform, WidePlayer, clamp, formatTime, formatTimeAria, getErrorMessage, getNextRepeatMode, getRepeatLabel, getStatusLabel };
1513
+ export { Artwork, BoundCompactPlayer, CompactPlayer, DetailedPlayer, IconButton, MiniPlayer, PlayerErrorNotice, PlayerStatus, PlayerSurface, PodcastPlayer, PopoverVolumeControl, PrimaryPlaybackButton, QueuePanel, QueueToggle, SeekBar, TimeReadout, TrackMetadata, TransportControls, VolumeControl, Waveform, WidePlayer, clamp, formatTime, formatTimeAria, getErrorMessage, getNextRepeatMode, getRepeatLabel, getStatusLabel };
1343
1514
  //# sourceMappingURL=index.js.map
1344
1515
  //# sourceMappingURL=index.js.map