airbridge-react-native-sdk
Version:
Airbridge SDK for React Native
187 lines (165 loc) • 5.89 kB
text/typescript
import { NativeEventEmitter, NativeModules } from 'react-native'
import { createInteractor } from '../architecture/Interactor'
import { check } from '../utility/check'
import { log } from '../utility/log'
import { AirbridgeTrackingLink } from '../type/AirbridgeTrackingLink'
export const createDependency = () => { }
type PlacementInteractor = {
click(
promiseID: string,
trackingLink: string,
onSuccess: () => void,
onFailure: (message: string) => void,
): Promise<boolean>
impression(
promiseID: string,
trackingLink: string,
onSuccess: () => void,
onFailure: (message: string) => void,
): Promise<boolean>
createTrackingLink(
channel: string,
option: Record<string, any>,
onSuccess: (airbridgeTrackingLink: Record<string, string>) => void,
onFailure: (message: string) => void,
): void
}
createDependency.PlacementModule = () => ({
emitter: new NativeEventEmitter(NativeModules.PlacementInteractor),
interactor: createInteractor<PlacementInteractor>(NativeModules.PlacementInteractor),
})
export type PlacementModule = ReturnType<typeof createPlacementModule>
export const createPlacementModule = () => {
// create dependency
const { emitter, interactor } = createDependency.PlacementModule()
// define member
let id = 0
// define method
const click = async (
trackingLink: string,
onSuccess?: () => void,
onFailure?: (error: Error) => void
): Promise<boolean> => {
if (!check.string(trackingLink)) {
log.unmatchedType('trackingLink', 'string')
return false
}
if (!(check.function(onSuccess) || check.undefined(onSuccess))) {
log.unmatchedType('onSuccess', 'function?')
return false
}
if (!(check.function(onFailure) || check.undefined(onFailure))) {
log.unmatchedType('onFailure', 'function?')
return false
}
const promiseID = `${id++}`
return new Promise((onResolve, onReject) => {
const subscription = emitter.addListener('airbridge.placement', (message) => {
if (message.id !== promiseID) {
return
}
switch (message.type) {
case 'onResolve':
onResolve(message.value)
break
case 'onReject':
onReject(Error(message.value))
break
}
subscription.remove()
})
interactor.click(
promiseID,
trackingLink,
() => { onSuccess?.() },
(message: string) => { onFailure?.(Error(message)) }
)
})
}
const impression = async (
trackingLink: string,
onSuccess?: () => void,
onFailure?: (error: Error) => void
): Promise<boolean> => {
if (!check.string(trackingLink)) {
log.unmatchedType('trackingLink', 'string')
return false
}
if (!(check.function(onSuccess) || check.undefined(onSuccess))) {
log.unmatchedType('onSuccess', 'function?')
return false
}
if (!(check.function(onFailure) || check.undefined(onFailure))) {
log.unmatchedType('onFailure', 'function?')
return false
}
const promiseID = `${id++}`
return new Promise((onResolve, onReject) => {
const subscription = emitter.addListener('airbridge.placement', (message) => {
if (message.id !== promiseID) {
return
}
switch (message.type) {
case 'onResolve':
onResolve(message.value)
break
case 'onReject':
onReject(Error(message.value))
break
}
subscription.remove()
})
interactor.impression(
promiseID,
trackingLink,
() => { onSuccess?.() },
(message: string) => { onFailure?.(Error(message)) }
)
})
}
const createTrackingLink = (
channel: string,
option: Record<string, any>,
onSuccess: (airbridgeTrackingLink: AirbridgeTrackingLink) => void,
onFailure?: (error: Error) => void
): void => {
if (!check.string(channel)) {
log.unmatchedType('channel', 'string')
return
}
if (!(check.undefined(option) || check.object(option))) {
log.unmatchedType('option', 'object')
return
}
if (!check.function(onSuccess)) {
log.unmatchedType('onSuccess', 'function?')
return
}
if (!(check.function(onFailure) || check.undefined(onFailure))) {
log.unmatchedType('onFailure', 'function?')
return
}
interactor.createTrackingLink(
channel,
option,
(airbridgeTrackingLink: Record<string, string>) => {
if (
check.string(airbridgeTrackingLink['qrcodeURL']) &&
check.string(airbridgeTrackingLink['shortURL'])
) {
onSuccess?.({
qrcodeURL: airbridgeTrackingLink['qrcodeURL'],
shortURL: airbridgeTrackingLink['shortURL']
})
}
},
(message: string) => { onFailure?.(Error(message)) }
)
}
// create object
return {
click,
impression,
createTrackingLink
}
}