@siteed/expo-audio-studio 2.8.2 → 2.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
 
11
+ ## [2.8.3] - 2025-05-06
12
+ ### Changed
13
+ - chore(expo-audio-studio): update plugin configuration to use ESM format and streamline build process ([97432eb](https://github.com/deeeed/expo-audio-stream/commit/97432eb2944f43e03a1464fdc166a49392582b08))
14
+ - chore(expo-audio-studio): release @siteed/expo-audio-studio@2.8.2 ([255c802](https://github.com/deeeed/expo-audio-stream/commit/255c802feacec8e4ba21bf442381062620d9b5f0))
11
15
  ## [2.8.2] - 2025-05-06
12
16
  ### Changed
13
17
  - chore(expo-audio-studio): update TypeScript configurations for dual module support and enhance CommonJS compatibility ([7377a5f](https://github.com/deeeed/expo-audio-stream/commit/7377a5fd3925a21d8628eb31b64c8c65102a1713))
@@ -230,7 +234,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
230
234
  - Feature: Audio features extraction during recording.
231
235
  - Feature: Consistent WAV PCM recording format across all platforms.
232
236
 
233
- [unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.2...HEAD
237
+ [unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.3...HEAD
238
+ [2.8.3]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.2...@siteed/expo-audio-studio@2.8.3
234
239
  [2.8.2]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.1...@siteed/expo-audio-studio@2.8.2
235
240
  [2.8.1]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.0...@siteed/expo-audio-studio@2.8.1
236
241
  [2.8.0]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.7.0...@siteed/expo-audio-studio@2.8.0
package/app.plugin.cjs CHANGED
@@ -1,7 +1,7 @@
1
- // This is a CommonJS file (.cjs) which loads the plugin configuration
1
+ // only here for ts-node and projects using app.config.ts instead of app.json.
2
2
  try {
3
3
  // Export the plugin from its CommonJS build
4
- module.exports = require('./plugin/build/cjs/index.js')
4
+ module.exports = require('./plugin/build/')
5
5
  } catch (error) {
6
6
  console.error(
7
7
  '[@siteed/expo-audio-studio] Plugin loading error:',
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./plugin/build')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siteed/expo-audio-studio",
3
- "version": "2.8.2",
3
+ "version": "2.8.3",
4
4
  "description": "Comprehensive audio processing library for React Native and Expo with recording, analysis, visualization, and streaming capabilities across iOS, Android, and web",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -17,7 +17,7 @@
17
17
  "./package.json": "./package.json"
18
18
  },
19
19
  "expo": {
20
- "plugin": "./app.plugin.cjs"
20
+ "plugin": "./app.plugin.js"
21
21
  },
22
22
  "author": "Arthur Breton <abreton@siteed.net> (https://github.com/deeeed)",
23
23
  "homepage": "https://github.com/deeeed/expo-audio-stream/blob/main/packages/expo-audio-studio/README.md",
@@ -59,6 +59,7 @@
59
59
  "cpp",
60
60
  "plugin",
61
61
  "app.plugin.cjs",
62
+ "app.plugin.js",
62
63
  "LICENSE",
63
64
  "CHANGELOG.md",
64
65
  "generated",
@@ -79,13 +80,11 @@
79
80
  "!**/.*"
80
81
  ],
81
82
  "scripts": {
82
- "build": "rimraf build && npm run build:types && npm run build:cjs && npm run build:esm && npm run build:plugin",
83
+ "build": "rimraf build && yarn build:types && yarn build:cjs && yarn build:esm && yarn build:plugin",
83
84
  "build:cjs": "tsc -p tsconfig.cjs.json",
84
85
  "build:esm": "tsc -p tsconfig.esm.json",
85
86
  "build:types": "tsc -p tsconfig.types.json",
86
- "build:plugin": "rimraf plugin/build && npm run build:plugin:esm && npm run build:plugin:cjs && node ./post-build.js",
87
- "build:plugin:esm": "tsc -p plugin/tsconfig.esm.json",
88
- "build:plugin:cjs": "tsc -p plugin/tsconfig.cjs.json",
87
+ "build:plugin": "tsc --build plugin/tsconfig.json",
89
88
  "build:plugin:dev": "expo-module build plugin",
90
89
  "build:dev": "expo-module build",
91
90
  "clean": "expo-module clean && rimraf build plugin/build",
@@ -190,4 +190,4 @@ const withRecordingPermission = (config, props) => {
190
190
  return config;
191
191
  };
192
192
  // Export as default
193
- module.exports = withRecordingPermission;
193
+ exports.default = withRecordingPermission;
@@ -7,4 +7,4 @@
7
7
  },
8
8
  "include": ["./src"],
9
9
  "exclude": ["**/__mocks__/*", "**/__tests__/*"]
10
- }
10
+ }
@@ -1,191 +0,0 @@
1
- import { withAndroidManifest, withInfoPlist, AndroidConfig, } from '@expo/config-plugins';
2
- const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
3
- const NOTIFICATION_USAGE = 'Show recording notifications and controls';
4
- const LOG_PREFIX = '[@siteed/expo-audio-studio]';
5
- function debugLog(message, ...args) {
6
- if (process.env.EXPO_DEBUG) {
7
- console.log(`${LOG_PREFIX} ${message}`, ...args);
8
- }
9
- }
10
- const withRecordingPermission = (config, props) => {
11
- const options = {
12
- enablePhoneStateHandling: true, // Default to true for backward compatibility
13
- enableNotifications: true,
14
- enableBackgroundAudio: true,
15
- iosBackgroundModes: {
16
- useVoIP: false,
17
- useAudio: false,
18
- useProcessing: false,
19
- useLocation: false,
20
- useExternalAccessory: false,
21
- },
22
- iosConfig: {
23
- microphoneUsageDescription: MICROPHONE_USAGE,
24
- notificationUsageDescription: NOTIFICATION_USAGE,
25
- },
26
- ...(props || {}),
27
- };
28
- const { enablePhoneStateHandling, enableNotifications, enableBackgroundAudio, } = options;
29
- debugLog('📱 Configuring Recording Permissions Plugin...', options);
30
- // iOS Configuration
31
- config = withInfoPlist(config, (config) => {
32
- // Always set the microphone usage description from options first
33
- config.modResults['NSMicrophoneUsageDescription'] =
34
- options.iosConfig?.microphoneUsageDescription ||
35
- config.modResults['NSMicrophoneUsageDescription'] ||
36
- MICROPHONE_USAGE;
37
- if (enableNotifications) {
38
- config.modResults['NSUserNotificationsUsageDescription'] =
39
- options.iosConfig?.notificationUsageDescription ||
40
- config.modResults['NSUserNotificationsUsageDescription'] ||
41
- NOTIFICATION_USAGE;
42
- config.modResults['NSUserNotificationAlertStyle'] = 'alert';
43
- }
44
- const existingBackgroundModes = config.modResults.UIBackgroundModes || [];
45
- // If background audio is enabled with useAudio, add the audio background mode
46
- if (options.iosBackgroundModes?.useAudio === true &&
47
- enableBackgroundAudio === true &&
48
- !existingBackgroundModes.includes('audio')) {
49
- // Add 'audio' background mode - REQUIRED for background recording
50
- existingBackgroundModes.push('audio');
51
- debugLog('✅ Added audio background mode for iOS background recording');
52
- // Also ensure processing mode is recommended
53
- if (options.iosBackgroundModes?.useProcessing !== true) {
54
- console.warn(`${LOG_PREFIX} Warning: Background audio recording works best with both 'audio' and 'processing' background modes. Consider enabling 'useProcessing' in iosBackgroundModes.`);
55
- }
56
- }
57
- if (options.iosBackgroundModes?.useVoIP === true &&
58
- enablePhoneStateHandling === true) {
59
- if (!existingBackgroundModes.includes('voip')) {
60
- existingBackgroundModes.push('voip');
61
- }
62
- const existingCapabilities = (config.modResults
63
- .UIRequiredDeviceCapabilities || []);
64
- if (!existingCapabilities.includes('telephony')) {
65
- existingCapabilities.push('telephony');
66
- }
67
- config.modResults.UIRequiredDeviceCapabilities =
68
- existingCapabilities;
69
- }
70
- // Add additional background modes only if explicitly set to true
71
- if (options.iosBackgroundModes?.useProcessing === true) {
72
- if (!existingBackgroundModes.includes('processing')) {
73
- existingBackgroundModes.push('processing');
74
- }
75
- // Add processing info if enabled
76
- // Note: We keep the 'audiostream' namespace for native modules to maintain compatibility
77
- config.modResults.BGTaskSchedulerPermittedIdentifiers = [
78
- 'com.siteed.audiostream.processing',
79
- ];
80
- }
81
- if (options.iosBackgroundModes?.useLocation === true) {
82
- if (!existingBackgroundModes.includes('location')) {
83
- existingBackgroundModes.push('location');
84
- }
85
- }
86
- if (options.iosBackgroundModes?.useExternalAccessory === true) {
87
- if (!existingBackgroundModes.includes('external-accessory')) {
88
- existingBackgroundModes.push('external-accessory');
89
- }
90
- }
91
- // Configure background processing info if enabled
92
- if (options.iosConfig?.backgroundProcessingTitle) {
93
- config.modResults.BGProcessingTaskTitle =
94
- options.iosConfig.backgroundProcessingTitle;
95
- }
96
- // Configure audio session behavior
97
- if (options.iosConfig?.allowBackgroundAudioControls) {
98
- config.modResults.UIBackgroundModes = [
99
- ...existingBackgroundModes,
100
- 'remote-notification',
101
- ];
102
- config.modResults.MPNowPlayingInfoPropertyPlaybackRate = true;
103
- }
104
- config.modResults.UIBackgroundModes = existingBackgroundModes;
105
- return config;
106
- });
107
- // Android Configuration
108
- config = withAndroidManifest(config, (config) => {
109
- const basePermissions = [
110
- 'android.permission.RECORD_AUDIO',
111
- 'android.permission.WAKE_LOCK',
112
- ];
113
- const optionalPermissions = [
114
- enableNotifications && 'android.permission.POST_NOTIFICATIONS',
115
- enablePhoneStateHandling && 'android.permission.READ_PHONE_STATE', // Only add if enabled
116
- enableBackgroundAudio && 'android.permission.FOREGROUND_SERVICE',
117
- enableBackgroundAudio && 'android.permission.FOREGROUND_SERVICE_MICROPHONE',
118
- ].filter(Boolean);
119
- const permissionsToAdd = [...basePermissions, ...optionalPermissions];
120
- debugLog('📋 Existing Android permissions:', config.modResults.manifest['uses-permission']?.map((p) => p.$?.['android:name']) || []);
121
- debugLog('➕ Adding Android permissions:', permissionsToAdd);
122
- const { addPermission } = AndroidConfig.Permissions;
123
- // Add each permission only if it doesn't exist
124
- permissionsToAdd.forEach((permission) => {
125
- const existingPermission = config.modResults.manifest['uses-permission']?.find((p) => p.$?.['android:name'] === permission);
126
- if (!existingPermission) {
127
- addPermission(config.modResults, permission);
128
- }
129
- });
130
- // Get the main application node
131
- const mainApplication = config.modResults.manifest.application?.[0];
132
- if (mainApplication) {
133
- debugLog('📱 Configuring Android application components...');
134
- // Add RecordingActionReceiver
135
- if (!mainApplication.receiver) {
136
- mainApplication.receiver = [];
137
- }
138
- const receiverConfig = {
139
- $: {
140
- 'android:name': '.RecordingActionReceiver',
141
- 'android:exported': 'false',
142
- },
143
- 'intent-filter': [
144
- {
145
- action: [
146
- { $: { 'android:name': 'PAUSE_RECORDING' } },
147
- { $: { 'android:name': 'RESUME_RECORDING' } },
148
- { $: { 'android:name': 'STOP_RECORDING' } },
149
- ],
150
- },
151
- ],
152
- };
153
- const receiverIndex = mainApplication.receiver.findIndex((receiver) => receiver.$?.['android:name'] === '.RecordingActionReceiver');
154
- if (receiverIndex >= 0) {
155
- mainApplication.receiver[receiverIndex] = receiverConfig;
156
- }
157
- else {
158
- mainApplication.receiver.push(receiverConfig);
159
- }
160
- debugLog('✅ RecordingActionReceiver configured');
161
- // Add AudioRecordingService
162
- if (!mainApplication.service) {
163
- mainApplication.service = [];
164
- }
165
- const serviceConfig = {
166
- $: {
167
- 'android:name': '.AudioRecordingService',
168
- 'android:enabled': 'true',
169
- 'android:exported': 'false',
170
- 'android:foregroundServiceType': 'microphone',
171
- },
172
- };
173
- const serviceIndex = mainApplication.service.findIndex((service) => service.$?.['android:name'] === '.AudioRecordingService');
174
- if (serviceIndex >= 0) {
175
- mainApplication.service[serviceIndex] = serviceConfig;
176
- }
177
- else {
178
- mainApplication.service.push(serviceConfig);
179
- }
180
- debugLog('✅ AudioRecordingService configured');
181
- }
182
- else {
183
- console.error(`${LOG_PREFIX} ❌ Main application node not found in Android Manifest`);
184
- }
185
- return config;
186
- });
187
- debugLog('✨ Recording Permissions Plugin configuration completed');
188
- return config;
189
- };
190
- // Export as default
191
- export default withRecordingPermission;
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "module": "CommonJS",
5
- "moduleResolution": "node",
6
- "target": "ES2020",
7
- "esModuleInterop": true,
8
- "outDir": "build/cjs",
9
- "declaration": false
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "module": "ESNext",
5
- "moduleResolution": "node",
6
- "target": "ES2020",
7
- "outDir": "build/esm",
8
- "declaration": true,
9
- "declarationDir": "build/types"
10
- }
11
- }
@@ -1 +0,0 @@
1
- {"root":["./src/index.ts"],"version":"5.7.2"}
File without changes