UNPKG

@adapty/capacitor

Version:
105 lines 4.79 kB
import { AdaptyCapacitorPlugin } from '../bridge/plugin'; import { LogContext } from '../shared/logger'; /** * Base class for view event emitters that manages common event handling logic. * Each event type can have only one handler - new handlers replace existing ones. */ export class BaseViewEmitter { constructor(viewId) { this.eventListeners = new Map(); this.handlers = new Map(); this.viewId = viewId; } async addListener(event, callback, onRequestClose) { const viewId = this.viewId; const config = this.getEventConfig(event); if (!config) { throw new Error(`No event config found for handler: ${String(event)}`); } // Replace existing handler for this event type this.handlers.set(event, { handler: callback, config, onRequestClose, }); if (!this.eventListeners.has(config.nativeEvent)) { const handlers = this.handlers; const emitterName = this.getEmitterName(); const subscription = await AdaptyCapacitorPlugin.addListener(config.nativeEvent, (arg) => { const ctx = new LogContext(); const log = ctx.event({ methodName: config.nativeEvent }); log.start(() => ({ raw: arg })); // Strict validation: events must come in {data: "json_string"} format if (!arg || typeof arg !== 'object' || !arg.data) { const error = new Error(`[${emitterName}] Invalid event format received. Expected {data: "json_string"}, got: ${JSON.stringify(arg)}`); log.failed(() => ({ error })); throw error; } const rawEventData = arg.data; // Parse JSON string using specific parser with decode logging let eventData; if (typeof rawEventData === 'string') { try { eventData = this.parseEventData(rawEventData, ctx); } catch (error) { log.failed(() => ({ error })); throw error; } } else { const err = new Error(`[${emitterName}] Expected event data to be JSON string, got ${typeof rawEventData}: ${rawEventData}`); log.failed(() => ({ error: err })); throw err; } const eventViewId = this.getEventViewId(eventData); if (viewId !== eventViewId) { return; } // Get all possible handler names for this native event const possibleHandlers = this.getPossibleHandlers(config.nativeEvent); for (const handlerName of possibleHandlers) { const handlerData = handlers.get(handlerName); if (!handlerData) { continue; // Handler not registered for this view } const { handler, config: handlerConfig, onRequestClose } = handlerData; if (!this.shouldCallHandler(handlerName, handlerConfig, eventData)) { continue; } const callbackArgs = this.extractCallbackArgs(handlerName, eventData); const cb = handler; try { const shouldClose = cb(...callbackArgs); if (shouldClose) { onRequestClose().catch((error) => { log.failed(() => ({ error, handlerName })); }); } log.success(() => ({ message: 'Event handled successfully', handlerName })); } catch (error) { log.failed(() => ({ error, handlerName })); } break; // Only one handler can match per event } }); this.eventListeners.set(config.nativeEvent, subscription); } const ensured = this.eventListeners.get(config.nativeEvent); if (!ensured) { throw new Error(`Failed to register listener for ${config.nativeEvent}`); } return ensured; } removeAllListeners() { this.eventListeners.forEach((subscription) => { subscription.remove().catch(() => { // intentionally ignore errors during cleanup }); }); this.eventListeners.clear(); this.handlers.clear(); } } //# sourceMappingURL=base-view-emitter.js.map