@wwdrew/expo-spotify-sdk 2.0.0 → 2.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 (126) hide show
  1. package/README.md +94 -346
  2. package/android/build.gradle +4 -5
  3. package/android/libs/SETUP.md +9 -24
  4. package/android/spotify-native-sdk.gradle +118 -0
  5. package/android/src/main/java/expo/modules/spotifysdk/ExpoSpotifySDKModule.kt +14 -5
  6. package/android/src/main/java/expo/modules/spotifysdk/SpotifyAppRemoteCoordinator.kt +38 -64
  7. package/android/src/main/java/expo/modules/spotifysdk/SpotifyAppRemoteErrorMapping.kt +106 -0
  8. package/android/src/main/java/expo/modules/spotifysdk/SpotifyTokenSwapClient.kt +2 -7
  9. package/build/app-remote/index.d.ts +34 -0
  10. package/build/app-remote/index.d.ts.map +1 -1
  11. package/build/app-remote/index.js +47 -24
  12. package/build/app-remote/index.js.map +1 -1
  13. package/build/auth/index.d.ts.map +1 -1
  14. package/build/auth/index.js +17 -34
  15. package/build/auth/index.js.map +1 -1
  16. package/build/content/index.d.ts.map +1 -1
  17. package/build/content/index.js +12 -25
  18. package/build/content/index.js.map +1 -1
  19. package/build/hooks/index.d.ts +1 -1
  20. package/build/hooks/index.d.ts.map +1 -1
  21. package/build/hooks/index.js +38 -115
  22. package/build/hooks/index.js.map +1 -1
  23. package/build/images/index.d.ts +2 -2
  24. package/build/images/index.d.ts.map +1 -1
  25. package/build/images/index.js +12 -25
  26. package/build/images/index.js.map +1 -1
  27. package/build/index.d.ts +0 -18
  28. package/build/index.d.ts.map +1 -1
  29. package/build/index.js +0 -27
  30. package/build/index.js.map +1 -1
  31. package/build/internal/native-errors.d.ts +14 -0
  32. package/build/internal/native-errors.d.ts.map +1 -0
  33. package/build/internal/native-errors.js +29 -0
  34. package/build/internal/native-errors.js.map +1 -0
  35. package/build/internal/sync-external-store.d.ts +14 -0
  36. package/build/internal/sync-external-store.d.ts.map +1 -0
  37. package/build/internal/sync-external-store.js +36 -0
  38. package/build/internal/sync-external-store.js.map +1 -0
  39. package/build/player/index.d.ts.map +1 -1
  40. package/build/player/index.js +14 -27
  41. package/build/player/index.js.map +1 -1
  42. package/build/user/index.d.ts +2 -2
  43. package/build/user/index.d.ts.map +1 -1
  44. package/build/user/index.js +16 -26
  45. package/build/user/index.js.map +1 -1
  46. package/ios/ExpoSpotifyAppDelegate.swift +8 -1
  47. package/ios/ExpoSpotifySDK.podspec +26 -2
  48. package/ios/ExpoSpotifySDKModule.swift +16 -1
  49. package/ios/SpotifyAppRemoteCoordinator.swift +137 -404
  50. package/ios/SpotifyAppRemoteErrorMapping.swift +110 -0
  51. package/ios/SpotifyAppRemoteErrors.swift +221 -0
  52. package/ios/SpotifyAppRemoteMappers.swift +88 -0
  53. package/ios/spotify-native-sdk-versions.json +12 -0
  54. package/package.json +13 -5
  55. package/plugin/index.d.ts +2 -0
  56. package/plugin/index.js +1 -0
  57. package/ios/SpotifySDK/Licenses/MPMessagePack-LICENSE.md +0 -20
  58. package/ios/SpotifySDK/SpotifyiOS.xcframework/Info.plist +0 -40
  59. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemote.h +0 -287
  60. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteAlbum.h +0 -18
  61. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteArtist.h +0 -18
  62. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteCommon.h +0 -37
  63. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteConnectionParams.h +0 -65
  64. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteConnectivityAPI.h +0 -55
  65. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteConnectivityState.h +0 -15
  66. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteContentAPI.h +0 -78
  67. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteContentItem.h +0 -49
  68. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteCrossfadeState.h +0 -18
  69. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteImageAPI.h +0 -25
  70. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteImageRepresentable.h +0 -16
  71. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteLibraryState.h +0 -19
  72. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemotePlaybackOptions.h +0 -32
  73. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemotePlaybackRestrictions.h +0 -32
  74. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemotePlayerAPI.h +0 -267
  75. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemotePlayerState.h +0 -40
  76. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemotePodcastPlaybackSpeed.h +0 -15
  77. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteTrack.h +0 -52
  78. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteUserAPI.h +0 -102
  79. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTAppRemoteUserCapabilities.h +0 -15
  80. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTConfiguration.h +0 -66
  81. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTError.h +0 -31
  82. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTLogin.h +0 -10
  83. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTMacros.h +0 -125
  84. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTScope.h +0 -75
  85. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTSession.h +0 -33
  86. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTSessionManager.h +0 -170
  87. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SpotifyAppRemote.h +0 -28
  88. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SpotifyiOS.h +0 -7
  89. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Info.plist +0 -0
  90. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Modules/module.modulemap +0 -5
  91. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/PrivacyInfo.xcprivacy +0 -14
  92. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/SpotifyiOS +0 -0
  93. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemote.h +0 -287
  94. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteAlbum.h +0 -18
  95. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteArtist.h +0 -18
  96. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteCommon.h +0 -37
  97. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteConnectionParams.h +0 -65
  98. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteConnectivityAPI.h +0 -55
  99. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteConnectivityState.h +0 -15
  100. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteContentAPI.h +0 -78
  101. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteContentItem.h +0 -49
  102. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteCrossfadeState.h +0 -18
  103. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteImageAPI.h +0 -25
  104. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteImageRepresentable.h +0 -16
  105. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteLibraryState.h +0 -19
  106. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemotePlaybackOptions.h +0 -32
  107. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemotePlaybackRestrictions.h +0 -32
  108. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemotePlayerAPI.h +0 -267
  109. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemotePlayerState.h +0 -40
  110. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemotePodcastPlaybackSpeed.h +0 -15
  111. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteTrack.h +0 -52
  112. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteUserAPI.h +0 -102
  113. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTAppRemoteUserCapabilities.h +0 -15
  114. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTConfiguration.h +0 -66
  115. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTError.h +0 -31
  116. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTLogin.h +0 -10
  117. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTMacros.h +0 -125
  118. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTScope.h +0 -75
  119. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTSession.h +0 -33
  120. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTSessionManager.h +0 -170
  121. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SpotifyAppRemote.h +0 -28
  122. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SpotifyiOS.h +0 -7
  123. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Info.plist +0 -0
  124. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Modules/module.modulemap +0 -5
  125. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/PrivacyInfo.xcprivacy +0 -14
  126. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/SpotifyiOS +0 -0
@@ -1,33 +1,20 @@
1
- export { ImagesError } from "./error";
2
1
  // ---------------------------------------------------------------------------
3
2
  // Types
4
3
  // ---------------------------------------------------------------------------
5
4
  import ExpoSpotifySDKModule from "../ExpoSpotifySDKModule";
5
+ import { createNativeErrorRethrow } from "../internal/native-errors";
6
6
  import { ImagesError } from "./error";
7
- const VALID_IMAGE_CODES = new Set([
8
- "NOT_CONNECTED",
9
- "INVALID_URI",
10
- "IMAGE_LOAD_FAILED",
11
- "UNKNOWN",
12
- ]);
13
- const CAUSE_SEPARATOR = "→ Caused by: ";
14
- function unwrapReason(message) {
15
- const idx = message.lastIndexOf(CAUSE_SEPARATOR);
16
- return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);
17
- }
18
- function rethrowAsImagesError(err) {
19
- if (err instanceof ImagesError)
20
- throw err;
21
- if (err instanceof Error) {
22
- const reason = unwrapReason(err.message);
23
- const maybeCode = err.code;
24
- if (maybeCode && VALID_IMAGE_CODES.has(maybeCode)) {
25
- throw new ImagesError(maybeCode, reason);
26
- }
27
- throw new ImagesError("UNKNOWN", reason);
28
- }
29
- throw new ImagesError("UNKNOWN", String(err));
30
- }
7
+ export { ImagesError } from "./error";
8
+ const rethrowAsImagesError = createNativeErrorRethrow({
9
+ ErrorClass: ImagesError,
10
+ unknownCode: "UNKNOWN",
11
+ validCodes: new Set([
12
+ "NOT_CONNECTED",
13
+ "INVALID_URI",
14
+ "IMAGE_LOAD_FAILED",
15
+ "UNKNOWN",
16
+ ]),
17
+ });
31
18
  function getImageIdentifier(item) {
32
19
  const value = item?.imageIdentifier;
33
20
  if (!value || !value.trim()) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/images/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAE9E,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAwB,MAAM,SAAS,CAAC;AAoB5D,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAkB;IACjD,eAAe;IACf,aAAa;IACb,mBAAmB;IACnB,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,eAAe,CAAC;AAExC,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IACjD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAY;IACxC,IAAI,GAAG,YAAY,WAAW;QAAE,MAAM,GAAG,CAAC;IAC1C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,SAAS,GAAI,GAAiC,CAAC,IAAI,CAAC;QAC1D,IAAI,SAAS,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAA4B,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,WAAW,CAAC,SAA4B,EAAE,MAAM,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAwB;IAClD,MAAM,KAAK,GAAG,IAAI,EAAE,eAAe,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,WAAW,CACnB,aAAa,EACb,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB;;OAEG;IACH,IAAI,CAAC,IAAwB,EAAE,IAAe;QAC5C,MAAM,eAAe,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,oBAAoB,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,KAAK,CACjE,oBAAoB,CACrB,CAAC;IACJ,CAAC;CACO,CAAC","sourcesContent":["export type { ImagesErrorCode } from \"./error\";\nexport { ImagesError } from \"./error\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport type { ContentItem } from \"../content\";\nimport type { Track } from \"../player\";\nimport { ImagesError, type ImagesErrorCode } from \"./error\";\n\nexport type ImageSize = \"small\" | \"medium\" | \"large\";\n\nexport interface ImageResult {\n uri: string;\n}\n\n/** Minimal shape required to fetch an image by identifier. */\ninterface HasImageIdentifier {\n imageIdentifier?: string | null;\n}\n\n/** Minimal album/artist representation for image loading. */\ninterface BasicImageEntity {\n imageIdentifier?: string | null;\n}\n\nexport type ImageRepresentable = Track | ContentItem | BasicImageEntity | HasImageIdentifier;\n\nconst VALID_IMAGE_CODES = new Set<ImagesErrorCode>([\n \"NOT_CONNECTED\",\n \"INVALID_URI\",\n \"IMAGE_LOAD_FAILED\",\n \"UNKNOWN\",\n]);\n\nconst CAUSE_SEPARATOR = \"→ Caused by: \";\n\nfunction unwrapReason(message: string): string {\n const idx = message.lastIndexOf(CAUSE_SEPARATOR);\n return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);\n}\n\nfunction rethrowAsImagesError(err: unknown): never {\n if (err instanceof ImagesError) throw err;\n if (err instanceof Error) {\n const reason = unwrapReason(err.message);\n const maybeCode = (err as Error & { code?: string }).code;\n if (maybeCode && VALID_IMAGE_CODES.has(maybeCode as ImagesErrorCode)) {\n throw new ImagesError(maybeCode as ImagesErrorCode, reason);\n }\n throw new ImagesError(\"UNKNOWN\", reason);\n }\n throw new ImagesError(\"UNKNOWN\", String(err));\n}\n\nfunction getImageIdentifier(item: ImageRepresentable): string {\n const value = item?.imageIdentifier;\n if (!value || !value.trim()) {\n throw new ImagesError(\n \"INVALID_URI\",\n \"Images.load(): item does not contain a valid imageIdentifier\",\n );\n }\n return value;\n}\n\n/**\n * Spotify Images namespace. Fetches cover art for tracks, albums, artists,\n * and content items via the App Remote SDK, writing the bitmap to a temp file\n * and returning its local URI. Requires `AppRemote.connect()` to be resolved.\n *\n * @example\n * ```ts\n * import { Images } from \"@wwdrew/expo-spotify-sdk\";\n *\n * const { uri } = await Images.load(track, \"large\");\n * ```\n */\nexport const Images = {\n /**\n * Loads a Spotify image and returns a local file URI.\n */\n load(item: ImageRepresentable, size: ImageSize): Promise<ImageResult> {\n const imageIdentifier = getImageIdentifier(item);\n return ExpoSpotifySDKModule.imagesLoad(imageIdentifier, size).catch(\n rethrowAsImagesError,\n );\n },\n} as const;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/images/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAE9E,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,WAAW,EAAwB,MAAM,SAAS,CAAC;AAG5D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwBtC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;IACpD,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE,IAAI,GAAG,CAAkB;QACnC,eAAe;QACf,aAAa;QACb,mBAAmB;QACnB,SAAS;KACV,CAAC;CACH,CAAC,CAAC;AAEH,SAAS,kBAAkB,CAAC,IAAwB;IAClD,MAAM,KAAK,GAAG,IAAI,EAAE,eAAe,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,WAAW,CACnB,aAAa,EACb,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB;;OAEG;IACH,IAAI,CAAC,IAAwB,EAAE,IAAe;QAC5C,MAAM,eAAe,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,oBAAoB,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,KAAK,CACjE,oBAAoB,CACrB,CAAC;IACJ,CAAC;CACO,CAAC","sourcesContent":["// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport type { ContentItem } from \"../content\";\nimport { createNativeErrorRethrow } from \"../internal/native-errors\";\nimport type { Track } from \"../player\";\nimport { ImagesError, type ImagesErrorCode } from \"./error\";\n\nexport type { ImagesErrorCode } from \"./error\";\nexport { ImagesError } from \"./error\";\n\nexport type ImageSize = \"small\" | \"medium\" | \"large\";\n\nexport interface ImageResult {\n uri: string;\n}\n\n/** Minimal shape required to fetch an image by identifier. */\ninterface HasImageIdentifier {\n imageIdentifier?: string | null;\n}\n\n/** Minimal album/artist representation for image loading. */\ninterface BasicImageEntity {\n imageIdentifier?: string | null;\n}\n\nexport type ImageRepresentable =\n | Track\n | ContentItem\n | BasicImageEntity\n | HasImageIdentifier;\n\nconst rethrowAsImagesError = createNativeErrorRethrow({\n ErrorClass: ImagesError,\n unknownCode: \"UNKNOWN\",\n validCodes: new Set<ImagesErrorCode>([\n \"NOT_CONNECTED\",\n \"INVALID_URI\",\n \"IMAGE_LOAD_FAILED\",\n \"UNKNOWN\",\n ]),\n});\n\nfunction getImageIdentifier(item: ImageRepresentable): string {\n const value = item?.imageIdentifier;\n if (!value || !value.trim()) {\n throw new ImagesError(\n \"INVALID_URI\",\n \"Images.load(): item does not contain a valid imageIdentifier\",\n );\n }\n return value;\n}\n\n/**\n * Spotify Images namespace. Fetches cover art for tracks, albums, artists,\n * and content items via the App Remote SDK, writing the bitmap to a temp file\n * and returning its local URI. Requires `AppRemote.connect()` to be resolved.\n *\n * @example\n * ```ts\n * import { Images } from \"@wwdrew/expo-spotify-sdk\";\n *\n * const { uri } = await Images.load(track, \"large\");\n * ```\n */\nexport const Images = {\n /**\n * Loads a Spotify image and returns a local file URI.\n */\n load(item: ImageRepresentable, size: ImageSize): Promise<ImageResult> {\n const imageIdentifier = getImageIdentifier(item);\n return ExpoSpotifySDKModule.imagesLoad(imageIdentifier, size).catch(\n rethrowAsImagesError,\n );\n },\n} as const;\n"]}
package/build/index.d.ts CHANGED
@@ -26,22 +26,4 @@ export type { RepeatMode, PodcastPlaybackSpeed, Artist, Album, Track, PlaybackOp
26
26
  export type { Capabilities, LibraryState } from "./user";
27
27
  export type { ContentType, ContentItem } from "./content";
28
28
  export type { ImageSize, ImageResult, ImageRepresentable } from "./images";
29
- import { Auth } from "./auth";
30
- import type { AuthenticateConfig as SpotifyConfig, RefreshConfig as SpotifyRefreshConfig } from "./auth";
31
- /** @deprecated Use `Auth.isAvailable()` */
32
- export declare function isAvailable(): boolean;
33
- /** @deprecated Use `Auth.authenticate(config)` */
34
- export declare function authenticateAsync(config: SpotifyConfig): Promise<import("./auth").SpotifySession>;
35
- /** @deprecated Use `Auth.cancelPending()` */
36
- export declare function cancelPendingAuthAsync(): Promise<void>;
37
- /** @deprecated Use `Auth.refresh(config)` */
38
- export declare function refreshSessionAsync(config: SpotifyRefreshConfig): Promise<import("./auth").SpotifySession>;
39
- /** @deprecated Use `Auth.addListener("sessionChange", cb)` */
40
- export declare function addSessionChangeListener(listener: Parameters<typeof Auth.addListener>[1]): import("expo-modules-core").EventSubscription;
41
- export type { SpotifyConfig, SpotifyRefreshConfig };
42
- /**
43
- * @deprecated `SpotifyErrorCode` is now `AuthErrorCode`. Import via:
44
- * `import type { AuthErrorCode } from "@wwdrew/expo-spotify-sdk"`
45
- */
46
- export type { AuthErrorCode as SpotifyErrorCode } from "./auth";
47
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,YAAY,EAAE,mBAAmB,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,OAAO,CAAC;AAM/E,YAAY,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAMhB,YAAY,EACV,eAAe,EACf,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAMtB,YAAY,EACV,UAAU,EACV,oBAAoB,EACpB,MAAM,EACN,KAAK,EACL,KAAK,EACL,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,cAAc,GACf,MAAM,UAAU,CAAC;AAMlB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMzD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAM1D,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAS3E,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,KAAK,EACV,kBAAkB,IAAI,aAAa,EACnC,aAAa,IAAI,oBAAoB,EACtC,MAAM,QAAQ,CAAC;AAEhB,2CAA2C;AAC3C,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,kDAAkD;AAClD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,4CAEtD;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,kBAErC;AAED,6CAA6C;AAC7C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,4CAE/D;AAED,8DAA8D;AAC9D,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,iDAGjD;AAID,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,CAAC;AAEpD;;;GAGG;AACH,YAAY,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,YAAY,EAAE,mBAAmB,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,OAAO,CAAC;AAM/E,YAAY,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAMhB,YAAY,EACV,eAAe,EACf,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAMtB,YAAY,EACV,UAAU,EACV,oBAAoB,EACpB,MAAM,EACN,KAAK,EACL,KAAK,EACL,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,cAAc,GACf,MAAM,UAAU,CAAC;AAMlB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMzD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAM1D,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
package/build/index.js CHANGED
@@ -25,31 +25,4 @@ export { ImagesError } from "./images";
25
25
  // URI helpers
26
26
  // ---------------------------------------------------------------------------
27
27
  export { SpotifyURI } from "./uri";
28
- // ---------------------------------------------------------------------------
29
- // v0.x backward-compatible exports (deprecated — remove at v2.0.0)
30
- //
31
- // These shims let existing callers continue to compile after upgrading to v1.
32
- // Migrate to the namespaced API: see docs/V1_PLAN.md §8 (Migration).
33
- // ---------------------------------------------------------------------------
34
- import { Auth } from "./auth";
35
- /** @deprecated Use `Auth.isAvailable()` */
36
- export function isAvailable() {
37
- return Auth.isAvailable();
38
- }
39
- /** @deprecated Use `Auth.authenticate(config)` */
40
- export function authenticateAsync(config) {
41
- return Auth.authenticate(config);
42
- }
43
- /** @deprecated Use `Auth.cancelPending()` */
44
- export function cancelPendingAuthAsync() {
45
- return Auth.cancelPending();
46
- }
47
- /** @deprecated Use `Auth.refresh(config)` */
48
- export function refreshSessionAsync(config) {
49
- return Auth.refresh(config);
50
- }
51
- /** @deprecated Use `Auth.addListener("sessionChange", cb)` */
52
- export function addSessionChangeListener(listener) {
53
- return Auth.addListener("sessionChange", listener);
54
- }
55
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAavC,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA2DnC,8EAA8E;AAC9E,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAE9E,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAM9B,2CAA2C;AAC3C,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,iBAAiB,CAAC,MAAqB;IACrD,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;AAC9B,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,mBAAmB,CAAC,MAA4B;IAC9D,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,wBAAwB,CACtC,QAAgD;IAEhD,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC","sourcesContent":["// ---------------------------------------------------------------------------\n// Hooks (v1 public API)\n// ---------------------------------------------------------------------------\n\nexport {\n useSession,\n useConnectionState,\n usePlayerState,\n useCurrentTrack,\n useIsPlaying,\n usePlaybackPosition,\n useCapabilities,\n useLibraryState,\n} from \"./hooks\";\n\n// ---------------------------------------------------------------------------\n// Namespaces (v1 public API)\n// ---------------------------------------------------------------------------\n\nexport { Auth } from \"./auth\";\nexport { AppRemote } from \"./app-remote\";\nexport { Player } from \"./player\";\nexport { User } from \"./user\";\nexport { Content } from \"./content\";\nexport { Images } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// Error hierarchy\n// ---------------------------------------------------------------------------\n\nexport { SpotifyError } from \"./error\";\nexport { AuthError } from \"./auth\";\nexport { AppRemoteError } from \"./app-remote\";\nexport { PlayerError } from \"./player\";\nexport { UserError } from \"./user\";\nexport { ContentError } from \"./content\";\nexport { ImagesError } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// Error code types\n// ---------------------------------------------------------------------------\n\nexport type { AuthErrorCode } from \"./auth\";\nexport type { AppRemoteErrorCode } from \"./app-remote\";\nexport type { PlayerErrorCode } from \"./player\";\nexport type { UserErrorCode } from \"./user\";\nexport type { ContentErrorCode } from \"./content\";\nexport type { ImagesErrorCode } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// URI helpers\n// ---------------------------------------------------------------------------\n\nexport { SpotifyURI } from \"./uri\";\nexport type { SpotifyResourceType, SpotifyURI as SpotifyURIType } from \"./uri\";\n\n// ---------------------------------------------------------------------------\n// Auth types\n// ---------------------------------------------------------------------------\n\nexport type {\n SpotifySession,\n SpotifyScope,\n AuthenticateConfig,\n RefreshConfig,\n SessionChangeEvent,\n} from \"./auth\";\n\n// ---------------------------------------------------------------------------\n// App Remote types\n// ---------------------------------------------------------------------------\n\nexport type {\n ConnectionState,\n ConnectionStateChangeEvent,\n ConnectionErrorEvent,\n} from \"./app-remote\";\n\n// ---------------------------------------------------------------------------\n// Player types\n// ---------------------------------------------------------------------------\n\nexport type {\n RepeatMode,\n PodcastPlaybackSpeed,\n Artist,\n Album,\n Track,\n PlaybackOptions,\n PlaybackRestrictions,\n PlayerState,\n CrossfadeState,\n} from \"./player\";\n\n// ---------------------------------------------------------------------------\n// User types\n// ---------------------------------------------------------------------------\n\nexport type { Capabilities, LibraryState } from \"./user\";\n\n// ---------------------------------------------------------------------------\n// Content types\n// ---------------------------------------------------------------------------\n\nexport type { ContentType, ContentItem } from \"./content\";\n\n// ---------------------------------------------------------------------------\n// Images types\n// ---------------------------------------------------------------------------\n\nexport type { ImageSize, ImageResult, ImageRepresentable } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// v0.x backward-compatible exports (deprecated — remove at v2.0.0)\n//\n// These shims let existing callers continue to compile after upgrading to v1.\n// Migrate to the namespaced API: see docs/V1_PLAN.md §8 (Migration).\n// ---------------------------------------------------------------------------\n\nimport { Auth } from \"./auth\";\nimport type {\n AuthenticateConfig as SpotifyConfig,\n RefreshConfig as SpotifyRefreshConfig,\n} from \"./auth\";\n\n/** @deprecated Use `Auth.isAvailable()` */\nexport function isAvailable(): boolean {\n return Auth.isAvailable();\n}\n\n/** @deprecated Use `Auth.authenticate(config)` */\nexport function authenticateAsync(config: SpotifyConfig) {\n return Auth.authenticate(config);\n}\n\n/** @deprecated Use `Auth.cancelPending()` */\nexport function cancelPendingAuthAsync() {\n return Auth.cancelPending();\n}\n\n/** @deprecated Use `Auth.refresh(config)` */\nexport function refreshSessionAsync(config: SpotifyRefreshConfig) {\n return Auth.refresh(config);\n}\n\n/** @deprecated Use `Auth.addListener(\"sessionChange\", cb)` */\nexport function addSessionChangeListener(\n listener: Parameters<typeof Auth.addListener>[1],\n) {\n return Auth.addListener(\"sessionChange\", listener);\n}\n\n// Re-export legacy type aliases so existing `import type { SpotifyConfig }`\n// consumers don't break.\nexport type { SpotifyConfig, SpotifyRefreshConfig };\n\n/**\n * @deprecated `SpotifyErrorCode` is now `AuthErrorCode`. Import via:\n * `import type { AuthErrorCode } from \"@wwdrew/expo-spotify-sdk\"`\n */\nexport type { AuthErrorCode as SpotifyErrorCode } from \"./auth\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAavC,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC","sourcesContent":["// ---------------------------------------------------------------------------\n// Hooks (v1 public API)\n// ---------------------------------------------------------------------------\n\nexport {\n useSession,\n useConnectionState,\n usePlayerState,\n useCurrentTrack,\n useIsPlaying,\n usePlaybackPosition,\n useCapabilities,\n useLibraryState,\n} from \"./hooks\";\n\n// ---------------------------------------------------------------------------\n// Namespaces (v1 public API)\n// ---------------------------------------------------------------------------\n\nexport { Auth } from \"./auth\";\nexport { AppRemote } from \"./app-remote\";\nexport { Player } from \"./player\";\nexport { User } from \"./user\";\nexport { Content } from \"./content\";\nexport { Images } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// Error hierarchy\n// ---------------------------------------------------------------------------\n\nexport { SpotifyError } from \"./error\";\nexport { AuthError } from \"./auth\";\nexport { AppRemoteError } from \"./app-remote\";\nexport { PlayerError } from \"./player\";\nexport { UserError } from \"./user\";\nexport { ContentError } from \"./content\";\nexport { ImagesError } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// Error code types\n// ---------------------------------------------------------------------------\n\nexport type { AuthErrorCode } from \"./auth\";\nexport type { AppRemoteErrorCode } from \"./app-remote\";\nexport type { PlayerErrorCode } from \"./player\";\nexport type { UserErrorCode } from \"./user\";\nexport type { ContentErrorCode } from \"./content\";\nexport type { ImagesErrorCode } from \"./images\";\n\n// ---------------------------------------------------------------------------\n// URI helpers\n// ---------------------------------------------------------------------------\n\nexport { SpotifyURI } from \"./uri\";\nexport type { SpotifyResourceType, SpotifyURI as SpotifyURIType } from \"./uri\";\n\n// ---------------------------------------------------------------------------\n// Auth types\n// ---------------------------------------------------------------------------\n\nexport type {\n SpotifySession,\n SpotifyScope,\n AuthenticateConfig,\n RefreshConfig,\n SessionChangeEvent,\n} from \"./auth\";\n\n// ---------------------------------------------------------------------------\n// App Remote types\n// ---------------------------------------------------------------------------\n\nexport type {\n ConnectionState,\n ConnectionStateChangeEvent,\n ConnectionErrorEvent,\n} from \"./app-remote\";\n\n// ---------------------------------------------------------------------------\n// Player types\n// ---------------------------------------------------------------------------\n\nexport type {\n RepeatMode,\n PodcastPlaybackSpeed,\n Artist,\n Album,\n Track,\n PlaybackOptions,\n PlaybackRestrictions,\n PlayerState,\n CrossfadeState,\n} from \"./player\";\n\n// ---------------------------------------------------------------------------\n// User types\n// ---------------------------------------------------------------------------\n\nexport type { Capabilities, LibraryState } from \"./user\";\n\n// ---------------------------------------------------------------------------\n// Content types\n// ---------------------------------------------------------------------------\n\nexport type { ContentType, ContentItem } from \"./content\";\n\n// ---------------------------------------------------------------------------\n// Images types\n// ---------------------------------------------------------------------------\n\nexport type { ImageSize, ImageResult, ImageRepresentable } from \"./images\";\n"]}
@@ -0,0 +1,14 @@
1
+ import type { SpotifyError } from "../error";
2
+ export interface NativeErrorRethrowOptions<C extends string, E extends SpotifyError & {
3
+ code: C;
4
+ }> {
5
+ ErrorClass: new (code: C, message: string) => E;
6
+ validCodes: ReadonlySet<C>;
7
+ /** Parse legacy `"CODE: message"` prefixes embedded in native error reasons. */
8
+ legacyCodePrefix?: boolean;
9
+ unknownCode: C;
10
+ }
11
+ export declare function createNativeErrorRethrow<C extends string, E extends SpotifyError & {
12
+ code: C;
13
+ }>(options: NativeErrorRethrowOptions<C, E>): (err: unknown) => never;
14
+ //# sourceMappingURL=native-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-errors.d.ts","sourceRoot":"","sources":["../../src/internal/native-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAU7C,MAAM,WAAW,yBAAyB,CACxC,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,YAAY,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE;IAEpC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC;IAChD,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAC3B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,CAAC,CAAC;CAChB;AAED,wBAAgB,wBAAwB,CACtC,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,YAAY,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,EACpC,OAAO,EAAE,yBAAyB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,CAqBnE"}
@@ -0,0 +1,29 @@
1
+ const CAUSE_SEPARATOR = "→ Caused by: ";
2
+ const LEGACY_CODE_PREFIX_RE = /^([A-Z_][A-Z0-9_]*):\s*(.*)$/s;
3
+ function unwrapReason(message) {
4
+ const idx = message.lastIndexOf(CAUSE_SEPARATOR);
5
+ return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);
6
+ }
7
+ export function createNativeErrorRethrow(options) {
8
+ const { ErrorClass, validCodes, legacyCodePrefix, unknownCode } = options;
9
+ return function rethrowNativeError(err) {
10
+ if (err instanceof ErrorClass)
11
+ throw err;
12
+ if (err instanceof Error) {
13
+ const reason = unwrapReason(err.message);
14
+ const maybeCode = err.code;
15
+ if (maybeCode && validCodes.has(maybeCode)) {
16
+ throw new ErrorClass(maybeCode, reason);
17
+ }
18
+ if (legacyCodePrefix) {
19
+ const match = reason.match(LEGACY_CODE_PREFIX_RE);
20
+ if (match && validCodes.has(match[1])) {
21
+ throw new ErrorClass(match[1], match[2]);
22
+ }
23
+ }
24
+ throw new ErrorClass(unknownCode, reason);
25
+ }
26
+ throw new ErrorClass(unknownCode, String(err));
27
+ };
28
+ }
29
+ //# sourceMappingURL=native-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-errors.js","sourceRoot":"","sources":["../../src/internal/native-errors.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,eAAe,CAAC;AACxC,MAAM,qBAAqB,GAAG,+BAA+B,CAAC;AAE9D,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IACjD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC;AAaD,MAAM,UAAU,wBAAwB,CAGtC,OAAwC;IACxC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE1E,OAAO,SAAS,kBAAkB,CAAC,GAAY;QAC7C,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAC;QACzC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzC,MAAM,SAAS,GAAI,GAAiC,CAAC,IAAI,CAAC;YAC1D,IAAI,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,SAAc,CAAC,EAAE,CAAC;gBAChD,MAAM,IAAI,UAAU,CAAC,SAAc,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBAClD,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC,EAAE,CAAC;oBAC3C,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { SpotifyError } from \"../error\";\n\nconst CAUSE_SEPARATOR = \"→ Caused by: \";\nconst LEGACY_CODE_PREFIX_RE = /^([A-Z_][A-Z0-9_]*):\\s*(.*)$/s;\n\nfunction unwrapReason(message: string): string {\n const idx = message.lastIndexOf(CAUSE_SEPARATOR);\n return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);\n}\n\nexport interface NativeErrorRethrowOptions<\n C extends string,\n E extends SpotifyError & { code: C },\n> {\n ErrorClass: new (code: C, message: string) => E;\n validCodes: ReadonlySet<C>;\n /** Parse legacy `\"CODE: message\"` prefixes embedded in native error reasons. */\n legacyCodePrefix?: boolean;\n unknownCode: C;\n}\n\nexport function createNativeErrorRethrow<\n C extends string,\n E extends SpotifyError & { code: C },\n>(options: NativeErrorRethrowOptions<C, E>): (err: unknown) => never {\n const { ErrorClass, validCodes, legacyCodePrefix, unknownCode } = options;\n\n return function rethrowNativeError(err: unknown): never {\n if (err instanceof ErrorClass) throw err;\n if (err instanceof Error) {\n const reason = unwrapReason(err.message);\n const maybeCode = (err as Error & { code?: string }).code;\n if (maybeCode && validCodes.has(maybeCode as C)) {\n throw new ErrorClass(maybeCode as C, reason);\n }\n if (legacyCodePrefix) {\n const match = reason.match(LEGACY_CODE_PREFIX_RE);\n if (match && validCodes.has(match[1] as C)) {\n throw new ErrorClass(match[1] as C, match[2]!);\n }\n }\n throw new ErrorClass(unknownCode, reason);\n }\n throw new ErrorClass(unknownCode, String(err));\n };\n}\n"]}
@@ -0,0 +1,14 @@
1
+ type StoreListener = () => void;
2
+ export interface SyncExternalStore<T> {
3
+ subscribe: (listener: StoreListener) => () => void;
4
+ getSnapshot: () => T;
5
+ getState: () => T;
6
+ update: (next: T | ((prev: T) => T)) => void;
7
+ }
8
+ /**
9
+ * Module-level store backing `useSyncExternalStore` hooks. Initialises lazily on
10
+ * first subscription and notifies subscribers when `update` changes the snapshot.
11
+ */
12
+ export declare function createSyncExternalStore<T>(initialState: T, init: (store: SyncExternalStore<T>) => void): SyncExternalStore<T>;
13
+ export {};
14
+ //# sourceMappingURL=sync-external-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-external-store.d.ts","sourceRoot":"","sources":["../../src/internal/sync-external-store.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG,MAAM,IAAI,CAAC;AAEhC,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,SAAS,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,IAAI,CAAC;IACnD,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,YAAY,EAAE,CAAC,EACf,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAC1C,iBAAiB,CAAC,CAAC,CAAC,CA+BtB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Module-level store backing `useSyncExternalStore` hooks. Initialises lazily on
3
+ * first subscription and notifies subscribers when `update` changes the snapshot.
4
+ */
5
+ export function createSyncExternalStore(initialState, init) {
6
+ let state = initialState;
7
+ const listeners = new Set();
8
+ let initialised = false;
9
+ const store = {
10
+ getState: () => state,
11
+ getSnapshot: () => state,
12
+ update(next) {
13
+ const resolved = typeof next === "function" ? next(state) : next;
14
+ if (Object.is(resolved, state))
15
+ return;
16
+ state = resolved;
17
+ listeners.forEach((listener) => listener());
18
+ },
19
+ subscribe(listener) {
20
+ if (!initialised) {
21
+ initialised = true;
22
+ try {
23
+ init(store);
24
+ }
25
+ catch (error) {
26
+ initialised = false;
27
+ throw error;
28
+ }
29
+ }
30
+ listeners.add(listener);
31
+ return () => listeners.delete(listener);
32
+ },
33
+ };
34
+ return store;
35
+ }
36
+ //# sourceMappingURL=sync-external-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-external-store.js","sourceRoot":"","sources":["../../src/internal/sync-external-store.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAe,EACf,IAA2C;IAE3C,IAAI,KAAK,GAAG,YAAY,CAAC;IACzB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC3C,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,KAAK,GAAyB;QAClC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK;QACrB,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK;QACxB,MAAM,CAAC,IAAI;YACT,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtE,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;gBAAE,OAAO;YACvC,KAAK,GAAG,QAAQ,CAAC;YACjB,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,SAAS,CAAC,QAAQ;YAChB,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,WAAW,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC;oBACH,IAAI,CAAC,KAAK,CAAC,CAAC;gBACd,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,WAAW,GAAG,KAAK,CAAC;oBACpB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["type StoreListener = () => void;\n\nexport interface SyncExternalStore<T> {\n subscribe: (listener: StoreListener) => () => void;\n getSnapshot: () => T;\n getState: () => T;\n update: (next: T | ((prev: T) => T)) => void;\n}\n\n/**\n * Module-level store backing `useSyncExternalStore` hooks. Initialises lazily on\n * first subscription and notifies subscribers when `update` changes the snapshot.\n */\nexport function createSyncExternalStore<T>(\n initialState: T,\n init: (store: SyncExternalStore<T>) => void,\n): SyncExternalStore<T> {\n let state = initialState;\n const listeners = new Set<StoreListener>();\n let initialised = false;\n\n const store: SyncExternalStore<T> = {\n getState: () => state,\n getSnapshot: () => state,\n update(next) {\n const resolved =\n typeof next === \"function\" ? (next as (prev: T) => T)(state) : next;\n if (Object.is(resolved, state)) return;\n state = resolved;\n listeners.forEach((listener) => listener());\n },\n subscribe(listener) {\n if (!initialised) {\n initialised = true;\n try {\n init(store);\n } catch (error) {\n initialised = false;\n throw error;\n }\n }\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n\n return store;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/player/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMtC,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAClB,CAAC,CAAC,UAAU,GACZ,CAAC,CAAC,2BAA2B,GAC7B,CAAC,CAAC,CAAC,6BAA6B;AAEpC,gDAAgD;AAChD,MAAM,MAAM,oBAAoB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE3E,wBAAwB;AACxB,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,uBAAuB;AACvB,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,sDAAsD;AACtD,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,iDAAiD;IACjD,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,eAAe,CAAC;IACjC,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwCD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM;IACjB;;;;OAIG;yBACO,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,uBAAuB;0BACd,OAAO,CAAC,IAAI,CAAC;IAItB,+BAA+B;2BACrB,OAAO,CAAC,IAAI,CAAC;IAIvB,uDAAuD;6BAC3C,OAAO,CAAC,IAAI,CAAC;IAIzB,mCAAmC;iCACnB,OAAO,CAAC,IAAI,CAAC;IAI7B;;;OAGG;kCACgB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,mCAAmC;mCACf,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC;IAI3C;;;OAGG;mCACiB,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC;IAI9C;;;OAGG;8CAC4B,oBAAoB,KAAG,OAAO,CAAC,IAAI,CAAC;IAMnE,iEAAiE;0BACtD,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,kEAAkE;mCAChD,OAAO,CAAC,WAAW,CAAC;IAItC,qEAAqE;sCAChD,OAAO,CAAC,cAAc,CAAC;IAI5C;;;;;;;;;;;;;;;OAeG;kCAEM,mBAAmB,YAChB,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KACrC,iBAAiB;CAMZ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/player/index.ts"],"names":[],"mappings":"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"}
@@ -1,37 +1,24 @@
1
1
  import ExpoSpotifySDKModule from "../ExpoSpotifySDKModule";
2
+ import { createNativeErrorRethrow } from "../internal/native-errors";
2
3
  import { SpotifyURI } from "../uri";
3
4
  import { PlayerError } from "./error";
4
5
  export { PlayerError } from "./error";
5
6
  // ---------------------------------------------------------------------------
6
7
  // Internal helpers
7
8
  // ---------------------------------------------------------------------------
8
- const VALID_PLAYER_CODES = new Set([
9
- "NOT_CONNECTED",
10
- "CONNECTION_LOST",
11
- "PREMIUM_REQUIRED",
12
- "INVALID_URI",
13
- "INVALID_PARAMETER",
14
- "OPERATION_NOT_ALLOWED",
15
- "UNKNOWN",
16
- ]);
17
- const CAUSE_SEPARATOR = "→ Caused by: ";
18
- function unwrapReason(message) {
19
- const idx = message.lastIndexOf(CAUSE_SEPARATOR);
20
- return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);
21
- }
22
- function rethrowAsPlayerError(err) {
23
- if (err instanceof PlayerError)
24
- throw err;
25
- if (err instanceof Error) {
26
- const reason = unwrapReason(err.message);
27
- const maybeCode = err.code;
28
- if (maybeCode && VALID_PLAYER_CODES.has(maybeCode)) {
29
- throw new PlayerError(maybeCode, reason);
30
- }
31
- throw new PlayerError("UNKNOWN", reason);
32
- }
33
- throw new PlayerError("UNKNOWN", String(err));
34
- }
9
+ const rethrowAsPlayerError = createNativeErrorRethrow({
10
+ ErrorClass: PlayerError,
11
+ unknownCode: "UNKNOWN",
12
+ validCodes: new Set([
13
+ "NOT_CONNECTED",
14
+ "CONNECTION_LOST",
15
+ "PREMIUM_REQUIRED",
16
+ "INVALID_URI",
17
+ "INVALID_PARAMETER",
18
+ "OPERATION_NOT_ALLOWED",
19
+ "UNKNOWN",
20
+ ]),
21
+ });
35
22
  // ---------------------------------------------------------------------------
36
23
  // Player namespace
37
24
  // ---------------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/player/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EventSubscription } from \"expo-modules-core\";\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport { SpotifyURI } from \"../uri\";\nimport { PlayerError, type PlayerErrorCode } from \"./error\";\n\nexport type { PlayerErrorCode } from \"./error\";\nexport { PlayerError } from \"./error\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Repeat mode for the Spotify player. */\nexport type RepeatMode =\n | 0 /** off */\n | 1 /** repeat current track */\n | 2; /** repeat current context */\n\n/** Valid podcast playback speed multipliers. */\nexport type PodcastPlaybackSpeed = 0.5 | 0.8 | 1.0 | 1.2 | 1.5 | 2.0 | 3.0;\n\n/** A Spotify artist. */\nexport interface Artist {\n name: string;\n uri: string;\n}\n\n/** A Spotify album. */\nexport interface Album {\n name: string;\n uri: string;\n}\n\n/** A track currently loaded in the Spotify player. */\nexport interface Track {\n uri: string;\n name: string;\n /** Identifier used by `Images.load(...)`. */\n imageIdentifier?: string;\n /** Duration in milliseconds. */\n duration: number;\n artist: Artist;\n album: Album;\n isSaved: boolean;\n isEpisode: boolean;\n isPodcast: boolean;\n isAdvertisement: boolean;\n}\n\n/** Current playback options (shuffle / repeat). */\nexport interface PlaybackOptions {\n isShuffling: boolean;\n /** 0 = off, 1 = repeat track, 2 = repeat context. */\n repeatMode: RepeatMode;\n}\n\n/** Actions currently permitted by Spotify (gate UI buttons on these). */\nexport interface PlaybackRestrictions {\n canSkipNext: boolean;\n canSkipPrevious: boolean;\n canRepeatTrack: boolean;\n canRepeatContext: boolean;\n canToggleShuffle: boolean;\n canSeek: boolean;\n}\n\n/** Full snapshot of the Spotify player at a point in time. */\nexport interface PlayerState {\n track: Track;\n /** Current playback position in milliseconds. */\n playbackPosition: number;\n playbackSpeed: number;\n isPaused: boolean;\n playbackOptions: PlaybackOptions;\n playbackRestrictions: PlaybackRestrictions;\n contextTitle: string;\n contextUri: string;\n}\n\n/** Crossfade configuration from the Spotify app. */\nexport interface CrossfadeState {\n isEnabled: boolean;\n /** Crossfade duration in milliseconds (only meaningful when enabled). */\n duration: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_PLAYER_CODES = new Set<PlayerErrorCode>([\n \"NOT_CONNECTED\",\n \"CONNECTION_LOST\",\n \"PREMIUM_REQUIRED\",\n \"INVALID_URI\",\n \"INVALID_PARAMETER\",\n \"OPERATION_NOT_ALLOWED\",\n \"UNKNOWN\",\n]);\n\nconst CAUSE_SEPARATOR = \"→ Caused by: \";\n\nfunction unwrapReason(message: string): string {\n const idx = message.lastIndexOf(CAUSE_SEPARATOR);\n return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);\n}\n\nfunction rethrowAsPlayerError(err: unknown): never {\n if (err instanceof PlayerError) throw err;\n if (err instanceof Error) {\n const reason = unwrapReason(err.message);\n const maybeCode = (err as Error & { code?: string }).code;\n if (maybeCode && VALID_PLAYER_CODES.has(maybeCode as PlayerErrorCode)) {\n throw new PlayerError(maybeCode as PlayerErrorCode, reason);\n }\n throw new PlayerError(\"UNKNOWN\", reason);\n }\n throw new PlayerError(\"UNKNOWN\", String(err));\n}\n\n// ---------------------------------------------------------------------------\n// Player namespace\n// ---------------------------------------------------------------------------\n\n/**\n * Spotify Player namespace. Transport controls, queue management, and\n * player-state subscriptions. Requires `AppRemote.connect()` to be resolved\n * before any call.\n *\n * @example\n * ```ts\n * import { Player, SpotifyURI } from \"@wwdrew/expo-spotify-sdk\";\n *\n * await Player.play(SpotifyURI.from(\"spotify:track:4uLU6hMCjMI75M1A2tKUQC\"));\n * const state = await Player.getPlayerState();\n *\n * const sub = Player.addListener(\"playerStateChange\", (state) => {\n * console.log(\"now playing:\", state.track.name, \"paused:\", state.isPaused);\n * });\n * ```\n */\nexport const Player = {\n /**\n * Asks Spotify to play the entity identified by the given URI.\n * Requires Spotify Premium for on-demand track playback; throws\n * `PlayerError(\"PREMIUM_REQUIRED\", ...)` for Free users.\n */\n play(uri: SpotifyURI): Promise<void> {\n return ExpoSpotifySDKModule.playerPlay(uri).catch(rethrowAsPlayerError);\n },\n\n /** Pauses playback. */\n pause(): Promise<void> {\n return ExpoSpotifySDKModule.playerPause().catch(rethrowAsPlayerError);\n },\n\n /** Resumes paused playback. */\n resume(): Promise<void> {\n return ExpoSpotifySDKModule.playerResume().catch(rethrowAsPlayerError);\n },\n\n /** Skips to the next track in the queue or context. */\n skipNext(): Promise<void> {\n return ExpoSpotifySDKModule.playerSkipNext().catch(rethrowAsPlayerError);\n },\n\n /** Skips to the previous track. */\n skipPrevious(): Promise<void> {\n return ExpoSpotifySDKModule.playerSkipPrevious().catch(rethrowAsPlayerError);\n },\n\n /**\n * Seeks to the given position in milliseconds.\n * Only valid when `PlaybackRestrictions.canSeek` is `true`.\n */\n seekTo(positionMs: number): Promise<void> {\n return ExpoSpotifySDKModule.playerSeekTo(positionMs).catch(rethrowAsPlayerError);\n },\n\n /** Enables or disables shuffle. */\n setShuffle(enabled: boolean): Promise<void> {\n return ExpoSpotifySDKModule.playerSetShuffle(enabled).catch(rethrowAsPlayerError);\n },\n\n /**\n * Sets the repeat mode.\n * @param mode 0 = off, 1 = repeat track, 2 = repeat context.\n */\n setRepeatMode(mode: RepeatMode): Promise<void> {\n return ExpoSpotifySDKModule.playerSetRepeatMode(mode).catch(rethrowAsPlayerError);\n },\n\n /**\n * Sets the podcast playback speed. Only takes effect when a podcast episode\n * is playing; valid speeds are `0.5 | 0.8 | 1.0 | 1.2 | 1.5 | 2.0 | 3.0`.\n */\n setPodcastPlaybackSpeed(speed: PodcastPlaybackSpeed): Promise<void> {\n return ExpoSpotifySDKModule.playerSetPodcastPlaybackSpeed(speed).catch(\n rethrowAsPlayerError,\n );\n },\n\n /** Adds a track URI to the end of the current playback queue. */\n queue(uri: SpotifyURI): Promise<void> {\n return ExpoSpotifySDKModule.playerQueue(uri).catch(rethrowAsPlayerError);\n },\n\n /** Returns the current {@link PlayerState} as a one-shot pull. */\n getPlayerState(): Promise<PlayerState> {\n return ExpoSpotifySDKModule.playerGetPlayerState().catch(rethrowAsPlayerError);\n },\n\n /** Returns the current {@link CrossfadeState} as a one-shot pull. */\n getCrossfadeState(): Promise<CrossfadeState> {\n return ExpoSpotifySDKModule.playerGetCrossfadeState().catch(rethrowAsPlayerError);\n },\n\n /**\n * Subscribes to player state changes. The callback fires whenever the\n * Spotify app reports a state update (track change, pause/resume, seek,\n * shuffle/repeat change, etc.).\n *\n * Returns a `Subscription` — call `.remove()` to unsubscribe.\n *\n * @example\n * ```ts\n * const sub = Player.addListener(\"playerStateChange\", (state) => {\n * console.log(\"track:\", state.track.name, \"paused:\", state.isPaused);\n * });\n * // ...later:\n * sub.remove();\n * ```\n */\n addListener(\n event: \"playerStateChange\",\n listener: (state: PlayerState) => void,\n ): EventSubscription {\n return ExpoSpotifySDKModule.addListener(\n \"onPlayerStateChange\",\n listener as (event: unknown) => void,\n ) as EventSubscription;\n },\n} as const;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/player/index.ts"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAwB,MAAM,SAAS,CAAC;AAG5D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAgFtC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;IACpD,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE,IAAI,GAAG,CAAkB;QACnC,eAAe;QACf,iBAAiB;QACjB,kBAAkB;QAClB,aAAa;QACb,mBAAmB;QACnB,uBAAuB;QACvB,SAAS;KACV,CAAC;CACH,CAAC,CAAC;AAEH,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB;;;;OAIG;IACH,IAAI,CAAC,GAAe;QAClB,OAAO,oBAAoB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1E,CAAC;IAED,uBAAuB;IACvB,KAAK;QACH,OAAO,oBAAoB,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxE,CAAC;IAED,+BAA+B;IAC/B,MAAM;QACJ,OAAO,oBAAoB,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACzE,CAAC;IAED,uDAAuD;IACvD,QAAQ;QACN,OAAO,oBAAoB,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC3E,CAAC;IAED,mCAAmC;IACnC,YAAY;QACV,OAAO,oBAAoB,CAAC,kBAAkB,EAAE,CAAC,KAAK,CACpD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,UAAkB;QACvB,OAAO,oBAAoB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,CACxD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED,mCAAmC;IACnC,UAAU,CAAC,OAAgB;QACzB,OAAO,oBAAoB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,CACzD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,IAAgB;QAC5B,OAAO,oBAAoB,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,KAAK,CACzD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,uBAAuB,CAAC,KAA2B;QACjD,OAAO,oBAAoB,CAAC,6BAA6B,CAAC,KAAK,CAAC,CAAC,KAAK,CACpE,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,KAAK,CAAC,GAAe;QACnB,OAAO,oBAAoB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC3E,CAAC;IAED,kEAAkE;IAClE,cAAc;QACZ,OAAO,oBAAoB,CAAC,oBAAoB,EAAE,CAAC,KAAK,CACtD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,iBAAiB;QACf,OAAO,oBAAoB,CAAC,uBAAuB,EAAE,CAAC,KAAK,CACzD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACT,KAA0B,EAC1B,QAAsC;QAEtC,OAAO,oBAAoB,CAAC,WAAW,CACrC,qBAAqB,EACrB,QAAoC,CAChB,CAAC;IACzB,CAAC;CACO,CAAC","sourcesContent":["import type { EventSubscription } from \"expo-modules-core\";\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport { createNativeErrorRethrow } from \"../internal/native-errors\";\nimport { SpotifyURI } from \"../uri\";\nimport { PlayerError, type PlayerErrorCode } from \"./error\";\n\nexport type { PlayerErrorCode } from \"./error\";\nexport { PlayerError } from \"./error\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Repeat mode for the Spotify player. */\nexport type RepeatMode =\n | 0 /** off */\n | 1 /** repeat current track */\n | 2; /** repeat current context */\n\n/** Valid podcast playback speed multipliers. */\nexport type PodcastPlaybackSpeed = 0.5 | 0.8 | 1.0 | 1.2 | 1.5 | 2.0 | 3.0;\n\n/** A Spotify artist. */\nexport interface Artist {\n name: string;\n uri: string;\n}\n\n/** A Spotify album. */\nexport interface Album {\n name: string;\n uri: string;\n}\n\n/** A track currently loaded in the Spotify player. */\nexport interface Track {\n uri: string;\n name: string;\n /** Identifier used by `Images.load(...)`. */\n imageIdentifier?: string;\n /** Duration in milliseconds. */\n duration: number;\n artist: Artist;\n album: Album;\n isSaved: boolean;\n isEpisode: boolean;\n isPodcast: boolean;\n isAdvertisement: boolean;\n}\n\n/** Current playback options (shuffle / repeat). */\nexport interface PlaybackOptions {\n isShuffling: boolean;\n /** 0 = off, 1 = repeat track, 2 = repeat context. */\n repeatMode: RepeatMode;\n}\n\n/** Actions currently permitted by Spotify (gate UI buttons on these). */\nexport interface PlaybackRestrictions {\n canSkipNext: boolean;\n canSkipPrevious: boolean;\n canRepeatTrack: boolean;\n canRepeatContext: boolean;\n canToggleShuffle: boolean;\n canSeek: boolean;\n}\n\n/** Full snapshot of the Spotify player at a point in time. */\nexport interface PlayerState {\n track: Track;\n /** Current playback position in milliseconds. */\n playbackPosition: number;\n playbackSpeed: number;\n isPaused: boolean;\n playbackOptions: PlaybackOptions;\n playbackRestrictions: PlaybackRestrictions;\n contextTitle: string;\n contextUri: string;\n}\n\n/** Crossfade configuration from the Spotify app. */\nexport interface CrossfadeState {\n isEnabled: boolean;\n /** Crossfade duration in milliseconds (only meaningful when enabled). */\n duration: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst rethrowAsPlayerError = createNativeErrorRethrow({\n ErrorClass: PlayerError,\n unknownCode: \"UNKNOWN\",\n validCodes: new Set<PlayerErrorCode>([\n \"NOT_CONNECTED\",\n \"CONNECTION_LOST\",\n \"PREMIUM_REQUIRED\",\n \"INVALID_URI\",\n \"INVALID_PARAMETER\",\n \"OPERATION_NOT_ALLOWED\",\n \"UNKNOWN\",\n ]),\n});\n\n// ---------------------------------------------------------------------------\n// Player namespace\n// ---------------------------------------------------------------------------\n\n/**\n * Spotify Player namespace. Transport controls, queue management, and\n * player-state subscriptions. Requires `AppRemote.connect()` to be resolved\n * before any call.\n *\n * @example\n * ```ts\n * import { Player, SpotifyURI } from \"@wwdrew/expo-spotify-sdk\";\n *\n * await Player.play(SpotifyURI.from(\"spotify:track:4uLU6hMCjMI75M1A2tKUQC\"));\n * const state = await Player.getPlayerState();\n *\n * const sub = Player.addListener(\"playerStateChange\", (state) => {\n * console.log(\"now playing:\", state.track.name, \"paused:\", state.isPaused);\n * });\n * ```\n */\nexport const Player = {\n /**\n * Asks Spotify to play the entity identified by the given URI.\n * Requires Spotify Premium for on-demand track playback; throws\n * `PlayerError(\"PREMIUM_REQUIRED\", ...)` for Free users.\n */\n play(uri: SpotifyURI): Promise<void> {\n return ExpoSpotifySDKModule.playerPlay(uri).catch(rethrowAsPlayerError);\n },\n\n /** Pauses playback. */\n pause(): Promise<void> {\n return ExpoSpotifySDKModule.playerPause().catch(rethrowAsPlayerError);\n },\n\n /** Resumes paused playback. */\n resume(): Promise<void> {\n return ExpoSpotifySDKModule.playerResume().catch(rethrowAsPlayerError);\n },\n\n /** Skips to the next track in the queue or context. */\n skipNext(): Promise<void> {\n return ExpoSpotifySDKModule.playerSkipNext().catch(rethrowAsPlayerError);\n },\n\n /** Skips to the previous track. */\n skipPrevious(): Promise<void> {\n return ExpoSpotifySDKModule.playerSkipPrevious().catch(\n rethrowAsPlayerError,\n );\n },\n\n /**\n * Seeks to the given position in milliseconds.\n * Only valid when `PlaybackRestrictions.canSeek` is `true`.\n */\n seekTo(positionMs: number): Promise<void> {\n return ExpoSpotifySDKModule.playerSeekTo(positionMs).catch(\n rethrowAsPlayerError,\n );\n },\n\n /** Enables or disables shuffle. */\n setShuffle(enabled: boolean): Promise<void> {\n return ExpoSpotifySDKModule.playerSetShuffle(enabled).catch(\n rethrowAsPlayerError,\n );\n },\n\n /**\n * Sets the repeat mode.\n * @param mode 0 = off, 1 = repeat track, 2 = repeat context.\n */\n setRepeatMode(mode: RepeatMode): Promise<void> {\n return ExpoSpotifySDKModule.playerSetRepeatMode(mode).catch(\n rethrowAsPlayerError,\n );\n },\n\n /**\n * Sets the podcast playback speed. Only takes effect when a podcast episode\n * is playing; valid speeds are `0.5 | 0.8 | 1.0 | 1.2 | 1.5 | 2.0 | 3.0`.\n */\n setPodcastPlaybackSpeed(speed: PodcastPlaybackSpeed): Promise<void> {\n return ExpoSpotifySDKModule.playerSetPodcastPlaybackSpeed(speed).catch(\n rethrowAsPlayerError,\n );\n },\n\n /** Adds a track URI to the end of the current playback queue. */\n queue(uri: SpotifyURI): Promise<void> {\n return ExpoSpotifySDKModule.playerQueue(uri).catch(rethrowAsPlayerError);\n },\n\n /** Returns the current {@link PlayerState} as a one-shot pull. */\n getPlayerState(): Promise<PlayerState> {\n return ExpoSpotifySDKModule.playerGetPlayerState().catch(\n rethrowAsPlayerError,\n );\n },\n\n /** Returns the current {@link CrossfadeState} as a one-shot pull. */\n getCrossfadeState(): Promise<CrossfadeState> {\n return ExpoSpotifySDKModule.playerGetCrossfadeState().catch(\n rethrowAsPlayerError,\n );\n },\n\n /**\n * Subscribes to player state changes. The callback fires whenever the\n * Spotify app reports a state update (track change, pause/resume, seek,\n * shuffle/repeat change, etc.).\n *\n * Returns a `Subscription` — call `.remove()` to unsubscribe.\n *\n * @example\n * ```ts\n * const sub = Player.addListener(\"playerStateChange\", (state) => {\n * console.log(\"track:\", state.track.name, \"paused:\", state.isPaused);\n * });\n * // ...later:\n * sub.remove();\n * ```\n */\n addListener(\n event: \"playerStateChange\",\n listener: (state: PlayerState) => void,\n ): EventSubscription {\n return ExpoSpotifySDKModule.addListener(\n \"onPlayerStateChange\",\n listener as (event: unknown) => void,\n ) as EventSubscription;\n },\n} as const;\n"]}
@@ -1,7 +1,7 @@
1
- export type { UserErrorCode } from "./error";
2
- export { UserError } from "./error";
3
1
  import type { EventSubscription } from "expo-modules-core";
4
2
  import type { SpotifyURI as SpotifyURIType } from "../uri";
3
+ export type { UserErrorCode } from "./error";
4
+ export { UserError } from "./error";
5
5
  /** Capabilities of the current user in Spotify's App Remote context. */
6
6
  export interface Capabilities {
7
7
  /** `true` for Premium users with on-demand playback capability. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,QAAQ,CAAC;AAG3D,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AA2CD;;;GAGG;AACH,eAAO,MAAM,IAAI;IACf,+CAA+C;oCAC5B,OAAO,CAAC,YAAY,CAAC;IAIxC,kEAAkE;oCAC7C,cAAc,KAAG,OAAO,CAAC,YAAY,CAAC;IAI3D,uDAAuD;iCAC/B,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC;IAOtD,4DAA4D;sCAC/B,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC;IAO3D;;;OAGG;kCAEM,oBAAoB,YACjB,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KACtC,iBAAiB;IAOpB;;;;;;;OAOG;4CAEI,cAAc,YACT,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KACtC,iBAAiB;CAiBZ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,QAAQ,CAAC;AAG3D,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AA2BD;;;GAGG;AACH,eAAO,MAAM,IAAI;IACf,+CAA+C;oCAC5B,OAAO,CAAC,YAAY,CAAC;IAIxC,kEAAkE;oCAC7C,cAAc,KAAG,OAAO,CAAC,YAAY,CAAC;IAM3D,uDAAuD;iCAC/B,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC;IAOtD,4DAA4D;sCAC/B,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC;IAO3D;;;OAGG;kCAEM,oBAAoB,YACjB,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KACtC,iBAAiB;IAOpB;;;;;;;OAOG;4CAEI,cAAc,YACT,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KACtC,iBAAiB;CAiBZ,CAAC"}
@@ -1,34 +1,24 @@
1
- export { UserError } from "./error";
1
+ // ---------------------------------------------------------------------------
2
+ // Types
3
+ // ---------------------------------------------------------------------------
2
4
  import ExpoSpotifySDKModule from "../ExpoSpotifySDKModule";
5
+ import { createNativeErrorRethrow } from "../internal/native-errors";
3
6
  import { UserError } from "./error";
7
+ export { UserError } from "./error";
4
8
  // ---------------------------------------------------------------------------
5
9
  // Internal helpers
6
10
  // ---------------------------------------------------------------------------
7
- const VALID_USER_CODES = new Set([
8
- "NOT_CONNECTED",
9
- "CONNECTION_LOST",
10
- "INVALID_URI",
11
- "OPERATION_NOT_ALLOWED",
12
- "UNKNOWN",
13
- ]);
14
- const CAUSE_SEPARATOR = "→ Caused by: ";
15
- function unwrapReason(message) {
16
- const idx = message.lastIndexOf(CAUSE_SEPARATOR);
17
- return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);
18
- }
19
- function rethrowAsUserError(err) {
20
- if (err instanceof UserError)
21
- throw err;
22
- if (err instanceof Error) {
23
- const reason = unwrapReason(err.message);
24
- const maybeCode = err.code;
25
- if (maybeCode && VALID_USER_CODES.has(maybeCode)) {
26
- throw new UserError(maybeCode, reason);
27
- }
28
- throw new UserError("UNKNOWN", reason);
29
- }
30
- throw new UserError("UNKNOWN", String(err));
31
- }
11
+ const rethrowAsUserError = createNativeErrorRethrow({
12
+ ErrorClass: UserError,
13
+ unknownCode: "UNKNOWN",
14
+ validCodes: new Set([
15
+ "NOT_CONNECTED",
16
+ "CONNECTION_LOST",
17
+ "INVALID_URI",
18
+ "OPERATION_NOT_ALLOWED",
19
+ "UNKNOWN",
20
+ ]),
21
+ });
32
22
  const libraryListeners = new Map();
33
23
  function notifyLibraryState(state) {
34
24
  const set = libraryListeners.get(state.uri);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"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","sourcesContent":["export type { UserErrorCode } from \"./error\";\nexport { UserError } from \"./error\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nimport type { EventSubscription } from \"expo-modules-core\";\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport type { SpotifyURI as SpotifyURIType } from \"../uri\";\nimport { UserError, type UserErrorCode } from \"./error\";\n\n/** Capabilities of the current user in Spotify's App Remote context. */\nexport interface Capabilities {\n /** `true` for Premium users with on-demand playback capability. */\n canPlayOnDemand: boolean;\n}\n\n/** Library save state for a specific album/track URI. */\nexport interface LibraryState {\n uri: string;\n isAdded: boolean;\n canAdd: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_USER_CODES = new Set<UserErrorCode>([\n \"NOT_CONNECTED\",\n \"CONNECTION_LOST\",\n \"INVALID_URI\",\n \"OPERATION_NOT_ALLOWED\",\n \"UNKNOWN\",\n]);\n\nconst CAUSE_SEPARATOR = \"→ Caused by: \";\n\nfunction unwrapReason(message: string): string {\n const idx = message.lastIndexOf(CAUSE_SEPARATOR);\n return idx === -1 ? message : message.slice(idx + CAUSE_SEPARATOR.length);\n}\n\nfunction rethrowAsUserError(err: unknown): never {\n if (err instanceof UserError) throw err;\n if (err instanceof Error) {\n const reason = unwrapReason(err.message);\n const maybeCode = (err as Error & { code?: string }).code;\n if (maybeCode && VALID_USER_CODES.has(maybeCode as UserErrorCode)) {\n throw new UserError(maybeCode as UserErrorCode, reason);\n }\n throw new UserError(\"UNKNOWN\", reason);\n }\n throw new UserError(\"UNKNOWN\", String(err));\n}\n\ntype LibraryListener = (state: LibraryState) => void;\nconst libraryListeners = new Map<string, Set<LibraryListener>>();\n\nfunction notifyLibraryState(state: LibraryState) {\n const set = libraryListeners.get(state.uri);\n if (!set) return;\n set.forEach((listener) => listener(state));\n}\n\n/**\n * Spotify User namespace. Capabilities and library-state operations.\n * Requires `AppRemote.connect()` to be resolved before any call.\n */\nexport const User = {\n /** Returns the current user's capabilities. */\n getCapabilities(): Promise<Capabilities> {\n return ExpoSpotifySDKModule.userGetCapabilities().catch(rethrowAsUserError);\n },\n\n /** Returns the current library state for a track or album URI. */\n getLibraryState(uri: SpotifyURIType): Promise<LibraryState> {\n return ExpoSpotifySDKModule.userGetLibraryState(uri).catch(rethrowAsUserError);\n },\n\n /** Adds a track or album URI to the user's library. */\n async addToLibrary(uri: SpotifyURIType): Promise<void> {\n const state = (await ExpoSpotifySDKModule.userAddToLibrary(uri).catch(\n rethrowAsUserError,\n )) as LibraryState;\n notifyLibraryState(state);\n },\n\n /** Removes a track or album URI from the user's library. */\n async removeFromLibrary(uri: SpotifyURIType): Promise<void> {\n const state = (await ExpoSpotifySDKModule.userRemoveFromLibrary(uri).catch(\n rethrowAsUserError,\n )) as LibraryState;\n notifyLibraryState(state);\n },\n\n /**\n * Subscribes to user-scoped events.\n * Supported event: `\"capabilitiesChange\"`.\n */\n addListener(\n event: \"capabilitiesChange\",\n listener: (event: Capabilities) => void,\n ): EventSubscription {\n return ExpoSpotifySDKModule.addListener(\n \"onCapabilitiesChange\",\n listener as (event: unknown) => void,\n ) as EventSubscription;\n },\n\n /**\n * Subscribes to library state changes for a specific URI.\n *\n * There is no native push stream for per-URI library state updates on all\n * platforms, so this listener is updated whenever library mutations are\n * performed via this SDK and can be manually seeded by calling\n * `User.getLibraryState(uri)` before subscribing.\n */\n addLibraryStateListener(\n uri: SpotifyURIType,\n listener: (state: LibraryState) => void,\n ): EventSubscription {\n const key = String(uri);\n let set = libraryListeners.get(key);\n if (!set) {\n set = new Set();\n libraryListeners.set(key, set);\n }\n set.add(listener);\n return {\n remove() {\n const current = libraryListeners.get(key);\n if (!current) return;\n current.delete(listener);\n if (current.size === 0) libraryListeners.delete(key);\n },\n } as EventSubscription;\n },\n} as const;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nimport type { EventSubscription } from \"expo-modules-core\";\n\nimport ExpoSpotifySDKModule from \"../ExpoSpotifySDKModule\";\nimport { createNativeErrorRethrow } from \"../internal/native-errors\";\nimport type { SpotifyURI as SpotifyURIType } from \"../uri\";\nimport { UserError, type UserErrorCode } from \"./error\";\n\nexport type { UserErrorCode } from \"./error\";\nexport { UserError } from \"./error\";\n\n/** Capabilities of the current user in Spotify's App Remote context. */\nexport interface Capabilities {\n /** `true` for Premium users with on-demand playback capability. */\n canPlayOnDemand: boolean;\n}\n\n/** Library save state for a specific album/track URI. */\nexport interface LibraryState {\n uri: string;\n isAdded: boolean;\n canAdd: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst rethrowAsUserError = createNativeErrorRethrow({\n ErrorClass: UserError,\n unknownCode: \"UNKNOWN\",\n validCodes: new Set<UserErrorCode>([\n \"NOT_CONNECTED\",\n \"CONNECTION_LOST\",\n \"INVALID_URI\",\n \"OPERATION_NOT_ALLOWED\",\n \"UNKNOWN\",\n ]),\n});\n\ntype LibraryListener = (state: LibraryState) => void;\nconst libraryListeners = new Map<string, Set<LibraryListener>>();\n\nfunction notifyLibraryState(state: LibraryState) {\n const set = libraryListeners.get(state.uri);\n if (!set) return;\n set.forEach((listener) => listener(state));\n}\n\n/**\n * Spotify User namespace. Capabilities and library-state operations.\n * Requires `AppRemote.connect()` to be resolved before any call.\n */\nexport const User = {\n /** Returns the current user's capabilities. */\n getCapabilities(): Promise<Capabilities> {\n return ExpoSpotifySDKModule.userGetCapabilities().catch(rethrowAsUserError);\n },\n\n /** Returns the current library state for a track or album URI. */\n getLibraryState(uri: SpotifyURIType): Promise<LibraryState> {\n return ExpoSpotifySDKModule.userGetLibraryState(uri).catch(\n rethrowAsUserError,\n );\n },\n\n /** Adds a track or album URI to the user's library. */\n async addToLibrary(uri: SpotifyURIType): Promise<void> {\n const state = (await ExpoSpotifySDKModule.userAddToLibrary(uri).catch(\n rethrowAsUserError,\n )) as LibraryState;\n notifyLibraryState(state);\n },\n\n /** Removes a track or album URI from the user's library. */\n async removeFromLibrary(uri: SpotifyURIType): Promise<void> {\n const state = (await ExpoSpotifySDKModule.userRemoveFromLibrary(uri).catch(\n rethrowAsUserError,\n )) as LibraryState;\n notifyLibraryState(state);\n },\n\n /**\n * Subscribes to user-scoped events.\n * Supported event: `\"capabilitiesChange\"`.\n */\n addListener(\n event: \"capabilitiesChange\",\n listener: (event: Capabilities) => void,\n ): EventSubscription {\n return ExpoSpotifySDKModule.addListener(\n \"onCapabilitiesChange\",\n listener as (event: unknown) => void,\n ) as EventSubscription;\n },\n\n /**\n * Subscribes to library state changes for a specific URI.\n *\n * There is no native push stream for per-URI library state updates on all\n * platforms, so this listener is updated whenever library mutations are\n * performed via this SDK and can be manually seeded by calling\n * `User.getLibraryState(uri)` before subscribing.\n */\n addLibraryStateListener(\n uri: SpotifyURIType,\n listener: (state: LibraryState) => void,\n ): EventSubscription {\n const key = String(uri);\n let set = libraryListeners.get(key);\n if (!set) {\n set = new Set();\n libraryListeners.set(key, set);\n }\n set.add(listener);\n return {\n remove() {\n const current = libraryListeners.get(key);\n if (!current) return;\n current.delete(listener);\n if (current.size === 0) libraryListeners.delete(key);\n },\n } as EventSubscription;\n },\n} as const;\n"]}
@@ -1,7 +1,7 @@
1
1
  import ExpoModulesCore
2
2
  import SpotifyiOS
3
3
 
4
- /// Delivers Spotify auth redirect URLs received via the legacy
4
+ /// Delivers Spotify redirect URLs received via the legacy
5
5
  /// `application(_:open:url:)` AppDelegate path.
6
6
  public class ExpoSpotifyAppDelegate: ExpoAppDelegateSubscriber {
7
7
  public func application(
@@ -9,6 +9,13 @@ public class ExpoSpotifyAppDelegate: ExpoAppDelegateSubscriber {
9
9
  open url: URL,
10
10
  options: [UIApplication.OpenURLOptionsKey: Any] = [:]
11
11
  ) -> Bool {
12
+ // Both the auth flow (SPTSessionManager) and App Remote's
13
+ // `authorizeAndPlay()` redirect through the same URL scheme. Offer the URL
14
+ // to the App Remote coordinator first — it only claims the redirect when an
15
+ // `authorizeAndPlay()` flow is actually pending — then fall back to auth.
16
+ if SpotifyAppRemoteCoordinator.shared?.handleAuthorizeRedirect(url) == true {
17
+ return true
18
+ }
12
19
  return SpotifyAuthCoordinator.shared?.handleOpenURL(url, options: options) ?? false
13
20
  }
14
21
  }
@@ -1,6 +1,18 @@
1
1
  require 'json'
2
2
 
3
+ absolute_react_native_path = ''
4
+ if !ENV['REACT_NATIVE_PATH'].nil?
5
+ absolute_react_native_path = File.expand_path(ENV['REACT_NATIVE_PATH'], Pod::Config.instance.project_root)
6
+ else
7
+ absolute_react_native_path = File.dirname(`node --print "require.resolve('react-native/package.json')"`)
8
+ end
9
+
10
+ unless defined?(spm_dependency)
11
+ require File.join(absolute_react_native_path, "scripts/react_native_pods")
12
+ end
13
+
3
14
  package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
15
+ spotify_native = JSON.parse(File.read(File.join(__dir__, 'spotify-native-sdk-versions.json')))
4
16
 
5
17
  Pod::Spec.new do |s|
6
18
  s.name = 'ExpoSpotifySDK'
@@ -23,6 +35,18 @@ Pod::Spec.new do |s|
23
35
  }
24
36
 
25
37
  s.source_files = "**/*.{h,m,swift}"
26
- s.exclude_files = "SpotifySDK/SpotifyiOS.xcframework/**/*.h"
27
- s.vendored_frameworks = "SpotifySDK/SpotifyiOS.xcframework"
38
+
39
+ ios_sdk = spotify_native['ios']
40
+ if ios_sdk.nil? ||
41
+ ios_sdk['spmRepositoryUrl'].to_s.empty? ||
42
+ ios_sdk['spmVersion'].to_s.empty? ||
43
+ ios_sdk['spmProduct'].to_s.empty?
44
+ raise "ios/spotify-native-sdk-versions.json is missing required iOS fields: spmRepositoryUrl, spmVersion, spmProduct"
45
+ end
46
+
47
+ spm_dependency(s,
48
+ url: ios_sdk['spmRepositoryUrl'],
49
+ requirement: { kind: 'exactVersion', version: ios_sdk['spmVersion'] },
50
+ products: [ios_sdk['spmProduct']]
51
+ )
28
52
  end