고급 기능과 최적화 팁
const bridge = new FlutterBridge({
debug: true, // 디버그 로그
timeout: 15000, // 타임아웃 15초
retries: 3, // 자동 재시도
throwOnError: false // 에러 시 throw 여부
});
// Flutter에서 보낸 이벤트 수신
window.addEventListener('flutter-event', (event) => {
console.log('Flutter 이벤트:', event.detail);
});
// 위치 업데이트 이벤트
window.addEventListener('location-updated', (event) => {
const { lat, lng } = event.detail;
updateMap(lat, lng);
});
// stores/bridge.ts
import { defineStore } from 'pinia';
import FlutterBridge from '@/utils/flutter-bridge';
export const useBridgeStore = defineStore('bridge', {
state: () => ({
bridge: new FlutterBridge({ debug: true }),
location: null,
deviceInfo: null
}),
actions: {
async fetchLocation() {
this.location = await this.bridge.getLocation();
}
}
});
// BridgeContext.tsx
import { createContext, useContext } from 'react';
import FlutterBridge from './flutter-bridge';
const BridgeContext = createContext(null);
export function BridgeProvider({ children }) {
const bridge = new FlutterBridge({ debug: true });
return (
<BridgeContext.Provider value={bridge}>
{children}
</BridgeContext.Provider>
);
}
export const useBridge = () => useContext(BridgeContext);
const [loading, setLoading] = useState(false);
async function getLocation() {
setLoading(true);
try {
const loc = await bridge.getLocation();
setLocation(loc);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
}
try {
const photo = await bridge.takePhoto();
} catch (error) {
if (error.message.includes('permission')) {
showPermissionDialog();
} else if (error.message === 'Request timeout') {
showTimeoutMessage();
} else {
showGenericError();
}
}
let pendingRequest = null;
async function getLocation() {
if (pendingRequest) {
return pendingRequest;
}
pendingRequest = bridge.getLocation();
const result = await pendingRequest;
pendingRequest = null;
return result;
}
class BridgeCache {
constructor(bridge) {
this.bridge = bridge;
this.cache = new Map();
}
async getDeviceInfo() {
if (this.cache.has('deviceInfo')) {
return this.cache.get('deviceInfo');
}
const info = await this.bridge.getDeviceInfo();
this.cache.set('deviceInfo', info);
return info;
}
}
class TTLCache {
constructor(ttl = 60000) {
this.cache = new Map();
this.ttl = ttl;
}
set(key, value) {
this.cache.set(key, {
value,
expires: Date.now() + this.ttl
});
}
get(key) {
const item = this.cache.get(key);
if (!item) return null;
if (Date.now() > item.expires) {
this.cache.delete(key);
return null;
}
return item.value;
}
}
// 여러 요청을 한 번에
const [location, deviceInfo, data] = await Promise.all([
bridge.getLocation(),
bridge.getDeviceInfo(),
bridge.loadData('user')
]);
import { debounce } from 'lodash';
const debouncedSave = debounce(async (data) => {
await bridge.saveData('draft', data);
}, 1000);
// 1초 후에 저장
debouncedSave({ title: '제목' });
const bridge = new FlutterBridge({ debug: true });
// 콘솔에 모든 요청/응답 출력
// [Bridge] Request: GET_LOCATION
// [Bridge] Response: { lat: 37.123, lng: 127.456 }
class LoggingBridge extends FlutterBridge {
async request(action, payload) {
console.time(action);
try {
const result = await super.request(action, payload);
console.timeEnd(action);
return result;
} catch (error) {
console.error(`${action} failed:`, error);
throw error;
}
}
}