Refactor the message management system to address synchronization issues and improve performance through request deduplication and enhanced lifecycle management. - Implement in-flight promise tracking in `MessageSyncService` to prevent redundant network requests for conversations and messages. - Enhance `useMessages` hook with `useFocusEffect` to trigger automatic synchronization when a chat screen regains focus. - Add `forceSync` capability to `MessageManager` and `MessageSyncService` to allow manual overrides of loading states during re-entry. - Consolidate WebSocket synchronization logic in `WSMessageHandler` using a throttled and deduplicated trigger mechanism. - Clean up unused styles and deprecated hooks (`baseHooks.ts`, `bubbleStyles.ts`, `inputStyles.ts`). - Update `metro.config.js` and `package.json` to include `@expo/ui` and optimize resolver settings.
82 lines
3.2 KiB
JavaScript
82 lines
3.2 KiB
JavaScript
/** @type {import('expo/metro-config').MetroConfig} */
|
|
const { getDefaultConfig } = require('expo/metro-config');
|
|
const path = require('path');
|
|
|
|
const config = getDefaultConfig(__dirname);
|
|
|
|
// Add wasm asset support
|
|
config.resolver.assetExts.push('wasm');
|
|
|
|
// Support TypeScript path aliases (@/ -> ./src/)
|
|
config.resolver.alias = {
|
|
'@': path.resolve(__dirname, 'src'),
|
|
};
|
|
|
|
// Ensure platform-specific files are resolved correctly
|
|
config.resolver.platforms = ['ios', 'android', 'native', 'web'];
|
|
|
|
// Web shims for native-only React Native APIs that don't exist in react-native-web.
|
|
// Packages like react-native-pager-view import codegenNativeComponent from
|
|
// react-native/Libraries/Utilities/codegenNativeComponent, which calls
|
|
// requireNativeComponent internally. On web (react-native-web), these APIs
|
|
// don't exist, causing "(0 , _reactNativeWebDistIndex.requireNativeComponent)
|
|
// is not a function".
|
|
const webShimPaths = [
|
|
'react-native/Libraries/Utilities/codegenNativeComponent',
|
|
'react-native/Libraries/Utilities/codegenNativeCommands',
|
|
'react-native/Libraries/Types/CodegenTypes',
|
|
'react-native/Libraries/ReactNative/requireNativeComponent',
|
|
];
|
|
|
|
// Packages that should be entirely replaced with web shims on web platform.
|
|
// These packages import requireNativeComponent directly from 'react-native'
|
|
// (which resolves to react-native-web on web) and don't have web implementations.
|
|
const webPackageShims = {
|
|
};
|
|
|
|
const originalResolveRequest = config.resolver.resolveRequest;
|
|
const shimDir = path.resolve(__dirname, 'web-shims');
|
|
|
|
config.resolver.resolveRequest = (context, moduleName, platform) => {
|
|
// Redirect entire native-only packages to web shims
|
|
if (platform === 'web' && webPackageShims[moduleName]) {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: webPackageShims[moduleName],
|
|
};
|
|
}
|
|
|
|
// Redirect specific React Native internal modules to web shims
|
|
if (platform === 'web' && webShimPaths.some((p) => moduleName.endsWith(p))) {
|
|
// For requireNativeComponent, the path doesn't follow the Libraries/* pattern
|
|
if (moduleName.endsWith('react-native/Libraries/ReactNative/requireNativeComponent')) {
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: path.join(shimDir, 'react-native', 'Libraries', 'ReactNative', 'requireNativeComponent.js'),
|
|
};
|
|
}
|
|
const shimName = moduleName.replace('react-native/Libraries/', '');
|
|
return {
|
|
type: 'sourceFile',
|
|
filePath: path.join(shimDir, 'react-native', 'Libraries', shimName + '.js'),
|
|
};
|
|
}
|
|
if (originalResolveRequest) {
|
|
return originalResolveRequest(context, moduleName, platform);
|
|
}
|
|
return context.resolveRequest(context, moduleName, platform);
|
|
};
|
|
|
|
// NOTE: enhanceMiddleware is marked as deprecated in Metro's types,
|
|
// but there's currently no official alternative for custom dev server headers.
|
|
// For production, configure COEP/COOP headers on your hosting platform.
|
|
// These headers are required for SharedArrayBuffer (used by expo-sqlite on web).
|
|
config.server.enhanceMiddleware = (middleware) => {
|
|
return (req, res, next) => {
|
|
res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless');
|
|
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
middleware(req, res, next);
|
|
};
|
|
};
|
|
|
|
module.exports = config; |