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