@adapty/capacitor
Version:
Official Adapty SDK for Capacitor
105 lines • 4.79 kB
JavaScript
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