UNPKG

@adapty/capacitor

Version:
185 lines 8.09 kB
import { AdaptyCapacitorPlugin } from './bridge/plugin'; import { parseCommonEvent } from './shared/coders/parse'; import { LogContext } from './shared/logger'; // Type-safe parser functions for each event function parseProfileEvent(raw, eventCtx) { const profile = parseCommonEvent('did_load_latest_profile', raw, eventCtx); return profile ? { profile: profile } : null; } function parseInstallationDetailsSuccessEvent(raw, eventCtx) { const details = parseCommonEvent('on_installation_details_success', raw, eventCtx); return details ? { details: details } : null; } function parseInstallationDetailsFailEvent(raw, eventCtx) { const error = parseCommonEvent('on_installation_details_fail', raw, eventCtx); return error ? { error: error } : null; } const EVENT_MAP = { onLatestProfileLoad: { native: 'did_load_latest_profile', parse: parseProfileEvent, }, onInstallationDetailsSuccess: { native: 'on_installation_details_success', parse: parseInstallationDetailsSuccessEvent, }, onInstallationDetailsFail: { native: 'on_installation_details_fail', parse: parseInstallationDetailsFailEvent, }, }; export class AdaptyEmitter { constructor() { this.nativeEventListeners = new Map(); this.externalHandlers = new Map(); this.addListener = async (eventName, listener) => { var _a; const ctx = new LogContext(); const log = ctx.call({ methodName: 'addListener' }); log.start(() => ({ eventName })); const eventConfig = EVENT_MAP[eventName]; if (!eventConfig) { throw new Error(`[Adapty] Unsupported event: ${eventName}`); } const handlerId = `${eventName}_${Math.random().toString(36)}`; const handlersForEvent = (_a = this.externalHandlers.get(eventConfig.native)) !== null && _a !== void 0 ? _a : []; handlersForEvent.push({ id: handlerId, handlerName: eventName, listener: listener, config: eventConfig, }); this.externalHandlers.set(eventConfig.native, handlersForEvent); if (!this.nativeEventListeners.has(eventConfig.native)) { const handlers = this.externalHandlers; const subscription = await AdaptyCapacitorPlugin.addListener(eventConfig.native, (arg) => { var _a; const eventCtx = new LogContext(); const eventLog = eventCtx.event({ methodName: eventConfig.native }); eventLog.start(() => ({ raw: arg })); const rawEventData = arg === null || arg === void 0 ? void 0 : arg.data; if (typeof rawEventData !== 'string') { eventLog.failed(() => ({ error: new Error('[Adapty] Expected event data to be JSON string') })); return; } const eventHandlers = (_a = handlers.get(eventConfig.native)) !== null && _a !== void 0 ? _a : []; for (const { handlerName, listener, config } of eventHandlers) { let payload = null; try { payload = config.parse(rawEventData, eventCtx); } catch (err) { eventLog.failed(() => ({ error: err })); continue; } if (!payload) { eventLog.failed(() => ({ error: new Error('[Adapty] Parsed payload is null') })); continue; } try { listener(payload); eventLog.success(() => ({ message: 'Event handled successfully', handlerName })); } catch (handlerError) { eventLog.failed(() => ({ handlerName, handlerError })); } } }); this.nativeEventListeners.set(eventConfig.native, subscription); } // Return wrapper handle that can remove this specific handler const wrappedHandle = { remove: async () => { await this.removeHandler(eventConfig.native, handlerId); }, }; return wrappedHandle; }; } async removeHandler(nativeEvent, handlerId) { const ctx = new LogContext(); const log = ctx.call({ methodName: 'removeHandler' }); log.start(() => ({ nativeEvent, handlerId })); const handlersForEvent = this.externalHandlers.get(nativeEvent); if (!handlersForEvent) { log.success(() => ({ message: 'No handlers found for native event', nativeEvent })); return; } const initialHandlersCount = handlersForEvent.length; // Remove the specific handler const filteredHandlers = handlersForEvent.filter((h) => h.id !== handlerId); this.externalHandlers.set(nativeEvent, filteredHandlers); const handlerRemoved = filteredHandlers.length < initialHandlersCount; if (!handlerRemoved) { log.success(() => ({ message: 'Handler not found in handlers list', nativeEvent, handlerId, remainingHandlers: filteredHandlers.length, })); return; } // If no more handlers for this native event, remove the subscription if (filteredHandlers.length === 0) { this.externalHandlers.delete(nativeEvent); const subscription = this.nativeEventListeners.get(nativeEvent); if (subscription) { try { await subscription.remove(); this.nativeEventListeners.delete(nativeEvent); log.success(() => ({ message: 'Handler and native subscription removed successfully', nativeEvent, handlerId, })); } catch (error) { log.failed(() => ({ message: `Failed to remove subscription for ${nativeEvent}`, error, nativeEvent, handlerId, })); } } else { log.success(() => ({ message: 'Handler removed, no native subscription found', nativeEvent, handlerId, })); } } else { log.success(() => ({ message: 'Handler removed successfully', nativeEvent, handlerId, remainingHandlers: filteredHandlers.length, })); } } async removeAllListeners() { const ctx = new LogContext(); const log = ctx.call({ methodName: 'removeAllListeners' }); log.start(() => ({ listenersCount: this.nativeEventListeners.size })); try { const removePromises = Array.from(this.nativeEventListeners.values()).map((handle, index) => handle.remove().catch((error) => { log.failed(() => ({ message: `Failed to remove event listener ${index}`, error, index, })); })); this.nativeEventListeners.clear(); this.externalHandlers.clear(); await Promise.all(removePromises); log.success(() => ({ message: 'All listeners removed successfully' })); } catch (error) { log.failed(() => ({ error })); throw error; } } } //# sourceMappingURL=adapty-emitter.js.map