From 4d0f9573d724d426fc7f5393d454fcb25262cedb Mon Sep 17 00:00:00 2001 From: Shiva Nandan Date: Tue, 20 Aug 2024 17:35:09 +0530 Subject: [PATCH 1/6] refactor: refactor PreMountLoader --- src/Payments/PreMountLoader.res | 222 +++++++++++++------------------- 1 file changed, 93 insertions(+), 129 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 4e3abf9a7..0ef19f3ad 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -1,63 +1,53 @@ -@react.component -let make = ( - ~sessionId, - ~publishableKey, - ~clientSecret, - ~endpoint, - ~ephemeralKey, - ~hyperComponentName: Types.hyperComponentName, - ~merchantHostname, -) => { - open Utils - let (paymentMethodsResponseSent, setPaymentMethodsResponseSent) = React.useState(_ => false) - let ( - customerPaymentMethodsResponseSent, - setCustomerPaymentMethodsResponseSent, - ) = React.useState(_ => false) - let (savedPaymentMethodsResponseSent, setSavedPaymentMethodsResponseSent) = React.useState(_ => - false - ) - let (sessionTokensResponseSent, setSessionTokensResponseSent) = React.useState(_ => false) - let logger = OrcaLogger.make( - ~sessionId, - ~source=Loader, - ~merchantId=publishableKey, - ~clientSecret, - ) +let sendPromiseData = (promise, key) => { + open Promise + promise + ->then(res => resolve(res)) + ->catch(_err => resolve(JSON.Encode.null)) + ->thenResolve(response => { + Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) + }) + ->ignore +} - let ( - paymentMethodsResponse, - customerPaymentMethodsResponse, - sessionTokensResponse, - savedPaymentMethodsResponse, - ) = React.useMemo0(() => { - let paymentMethodsResponse = switch hyperComponentName { - | Elements => - PaymentHelpers.fetchPaymentMethodList( +let useMessageHandler = getPromisesAndMessageHandler => { + React.useEffect0(() => { + let (promises, messageHandler) = getPromisesAndMessageHandler() + + open Promise + Promise.all(promises) + ->thenResolve(_ => { + Utils.messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) + Window.removeEventListener("message", messageHandler) + }) + ->ignore + + Utils.messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) + Window.addEventListener("message", messageHandler) + Some(() => Window.removeEventListener("message", messageHandler)) + }) +} + +module PreMountLoaderForElements = { + @react.component + let make = (~logger, ~publishableKey, ~clientSecret, ~endpoint, ~merchantHostname) => { + useMessageHandler(() => { + let paymentMethodsPromise = PaymentHelpers.fetchPaymentMethodList( ~clientSecret, ~publishableKey, ~logger, ~switchToCustomPod=false, ~endpoint, ) - | _ => JSON.Encode.null->Promise.resolve - } - let customerPaymentMethodsResponse = switch hyperComponentName { - | Elements => - PaymentHelpers.fetchCustomerPaymentMethodList( + let customerPaymentMethodsPromise = PaymentHelpers.fetchCustomerPaymentMethodList( ~clientSecret, ~publishableKey, ~optLogger=Some(logger), ~switchToCustomPod=false, ~endpoint, ) - | _ => JSON.Encode.null->Promise.resolve - } - let sessionTokensResponse = switch hyperComponentName { - | Elements => - PaymentHelpers.fetchSessions( + let sessionTokensPromise = PaymentHelpers.fetchSessions( ~clientSecret, ~publishableKey, ~optLogger=Some(logger), @@ -65,101 +55,75 @@ let make = ( ~endpoint, ~merchantHostname, ) - | _ => JSON.Encode.null->Promise.resolve - } - let savedPaymentMethodsResponse = switch hyperComponentName { - | PaymentMethodsManagementElements => - PaymentHelpers.fetchSavedPaymentMethodList( + let messageHandler = (ev: Window.event) => { + let json = ev.data->Utils.safeParse + let dict = json->Utils.getDictFromJson + if dict->Dict.get("sendPaymentMethodsResponse")->Option.isSome { + paymentMethodsPromise->sendPromiseData("payment_methods") + } else if dict->Dict.get("sendCustomerPaymentMethodsResponse")->Option.isSome { + customerPaymentMethodsPromise->sendPromiseData("customer_payment_methods") + } else if dict->Dict.get("sendSessionTokensResponse")->Option.isSome { + sessionTokensPromise->sendPromiseData("session_tokens") + } + } + + let promises = [paymentMethodsPromise, customerPaymentMethodsPromise, sessionTokensPromise] + (promises, messageHandler) + }) + + React.null + } +} + +module PreMountLoaderForPMMElements = { + @react.component + let make = (~logger, ~endpoint, ~ephemeralKey) => { + useMessageHandler(() => { + let savedPaymentMethodsPromise = PaymentHelpers.fetchSavedPaymentMethodList( ~ephemeralKey, ~optLogger=Some(logger), ~switchToCustomPod=false, ~endpoint, ) - | _ => JSON.Encode.null->Promise.resolve - } - - ( - paymentMethodsResponse, - customerPaymentMethodsResponse, - sessionTokensResponse, - savedPaymentMethodsResponse, - ) - }) - let sendPromiseData = (promise, key) => { - open Promise - promise - ->then(res => { - messageParentWindow([("response", res), ("data", key->JSON.Encode.string)]) - switch key { - | "payment_methods" => setPaymentMethodsResponseSent(_ => true) - | "session_tokens" => setSessionTokensResponseSent(_ => true) - | "customer_payment_methods" => setCustomerPaymentMethodsResponseSent(_ => true) - | "saved_payment_methods" => setSavedPaymentMethodsResponseSent(_ => true) - | _ => () + let messageHandler = (ev: Window.event) => { + let json = ev.data->Utils.safeParse + let dict = json->Utils.getDictFromJson + if dict->Dict.get("sendSavedPaymentMethodsResponse")->Belt.Option.isSome { + savedPaymentMethodsPromise->sendPromiseData("saved_payment_methods") + } } - resolve() - }) - ->catch(_err => { - messageParentWindow([("response", JSON.Encode.null), ("data", key->JSON.Encode.string)]) - resolve() + + let promises = [savedPaymentMethodsPromise] + (promises, messageHandler) }) - ->ignore - } - let handle = (ev: Window.event) => { - let json = ev.data->safeParse - let dict = json->Utils.getDictFromJson - if dict->Dict.get("sendPaymentMethodsResponse")->Option.isSome { - paymentMethodsResponse->sendPromiseData("payment_methods") - } else if dict->Dict.get("sendCustomerPaymentMethodsResponse")->Option.isSome { - customerPaymentMethodsResponse->sendPromiseData("customer_payment_methods") - } else if dict->Dict.get("sendSessionTokensResponse")->Option.isSome { - sessionTokensResponse->sendPromiseData("session_tokens") - } else if dict->Dict.get("sendSavedPaymentMethodsResponse")->Belt.Option.isSome { - savedPaymentMethodsResponse->sendPromiseData("saved_payment_methods") - } + React.null } +} - React.useEffect0(() => { - Window.addEventListener("message", handle) - messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) - Some( - () => { - Window.removeEventListener("message", handle) - }, - ) - }) - - React.useEffect4(() => { - let handleUnmount = () => { - messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) - Window.removeEventListener("message", handle) - } - - switch hyperComponentName { - | Elements => - if ( - paymentMethodsResponseSent && - customerPaymentMethodsResponseSent && - sessionTokensResponseSent - ) { - handleUnmount() - } - | PaymentMethodsManagementElements => - if savedPaymentMethodsResponseSent { - handleUnmount() - } - } - - None - }, ( - paymentMethodsResponseSent, - customerPaymentMethodsResponseSent, - sessionTokensResponseSent, - savedPaymentMethodsResponseSent, - )) +@react.component +let make = ( + ~sessionId, + ~publishableKey, + ~clientSecret, + ~endpoint, + ~ephemeralKey, + ~hyperComponentName: Types.hyperComponentName, + ~merchantHostname, +) => { + let logger = OrcaLogger.make( + ~sessionId, + ~source=Loader, + ~merchantId=publishableKey, + ~clientSecret, + ) - React.null + switch hyperComponentName { + | Elements => + + | PaymentMethodsManagementElements => + + } } From ca298264b7e4680e28683524972b5d09c1bf5e16 Mon Sep 17 00:00:00 2001 From: Shiva Nandan Date: Mon, 26 Aug 2024 14:01:06 +0530 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: Pritish Budhiraja --- src/Payments/PreMountLoader.res | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 0ef19f3ad..9c2489c8b 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -2,7 +2,7 @@ let sendPromiseData = (promise, key) => { open Promise promise ->then(res => resolve(res)) - ->catch(_err => resolve(JSON.Encode.null)) + ->catch(_ => resolve(JSON.Encode.null)) ->thenResolve(response => { Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) }) @@ -90,7 +90,7 @@ module PreMountLoaderForPMMElements = { let messageHandler = (ev: Window.event) => { let json = ev.data->Utils.safeParse let dict = json->Utils.getDictFromJson - if dict->Dict.get("sendSavedPaymentMethodsResponse")->Belt.Option.isSome { + if dict->Dict.get("sendSavedPaymentMethodsResponse")->Option.isSome { savedPaymentMethodsPromise->sendPromiseData("saved_payment_methods") } } From 2999f22f2624181a2e0e3dd8845bef5439bfd826 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Tue, 3 Sep 2024 11:20:44 +0530 Subject: [PATCH 3/6] chore: comments addressed --- src/Payments/PreMountLoader.res | 16 ++++++++-------- src/Utilities/Utils.res | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 9c2489c8b..c1f680ea8 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -57,13 +57,13 @@ module PreMountLoaderForElements = { ) let messageHandler = (ev: Window.event) => { - let json = ev.data->Utils.safeParse - let dict = json->Utils.getDictFromJson - if dict->Dict.get("sendPaymentMethodsResponse")->Option.isSome { + open Utils + let dict = ev.data->safeParse->getDictFromJson + if dict->isKeyPresentInDict("sendPaymentMethodsResponse") { paymentMethodsPromise->sendPromiseData("payment_methods") - } else if dict->Dict.get("sendCustomerPaymentMethodsResponse")->Option.isSome { + } else if dict->isKeyPresentInDict("sendCustomerPaymentMethodsResponse") { customerPaymentMethodsPromise->sendPromiseData("customer_payment_methods") - } else if dict->Dict.get("sendSessionTokensResponse")->Option.isSome { + } else if dict->isKeyPresentInDict("sendSessionTokensResponse") { sessionTokensPromise->sendPromiseData("session_tokens") } } @@ -88,9 +88,9 @@ module PreMountLoaderForPMMElements = { ) let messageHandler = (ev: Window.event) => { - let json = ev.data->Utils.safeParse - let dict = json->Utils.getDictFromJson - if dict->Dict.get("sendSavedPaymentMethodsResponse")->Option.isSome { + open Utils + let dict = ev.data->safeParse->getDictFromJson + if dict->isKeyPresentInDict("sendSavedPaymentMethodsResponse") { savedPaymentMethodsPromise->sendPromiseData("saved_payment_methods") } } diff --git a/src/Utilities/Utils.res b/src/Utilities/Utils.res index deb9d3fa6..6aef9c586 100644 --- a/src/Utilities/Utils.res +++ b/src/Utilities/Utils.res @@ -1372,3 +1372,5 @@ let getFirstAndLastNameFromFullName = fullName => { (firstName, lastNameJson) } + +let isKeyPresentInDict = (dict, key) => dict->Dict.get(key)->Option.isSome From a69bbfe545eb071a632f681dc5f7b0d17ed14200 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Wed, 6 Nov 2024 07:57:28 +0530 Subject: [PATCH 4/6] refactor: premount loader-2 --- src/Payments/PreMountLoader.res | 51 +++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 54f6a7ebb..985f63693 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -1,29 +1,44 @@ let sendPromiseData = (promise, key) => { - open Promise - promise - ->then(res => resolve(res)) - ->catch(_ => resolve(JSON.Encode.null)) - ->thenResolve(response => { + let asyncOperation = async () => { + let response = try { + await promise + } catch { + | _ => JSON.Encode.null + } Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) - }) - ->ignore -} + } + asyncOperation()->ignore +} let useMessageHandler = getPromisesAndMessageHandler => { + let cleanup = messageHandler => { + Utils.messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) + Window.removeEventListener("message", messageHandler) + } + let setup = messageHandler => { + Utils.messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) + Window.addEventListener("message", messageHandler) + } + React.useEffect0(() => { let (promises, messageHandler) = getPromisesAndMessageHandler() + setup(messageHandler) - open Promise - Promise.all(promises) - ->thenResolve(_ => { - Utils.messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) - Window.removeEventListener("message", messageHandler) - }) - ->ignore + ( + async () => { + try { + let _ = await Promise.all(promises) + cleanup(messageHandler) + } catch { + | error => { + Console.error2("Error in useMessageHandler:", error) + cleanup(messageHandler) + } + } + } + )()->ignore - Utils.messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) - Window.addEventListener("message", messageHandler) - Some(() => Window.removeEventListener("message", messageHandler)) + Some(() => cleanup(messageHandler)) }) } From 99406b4e405f8f6ebc0b744d2884ce7016cdc3f4 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Wed, 6 Nov 2024 08:02:14 +0530 Subject: [PATCH 5/6] fix: small change --- src/Payments/PreMountLoader.res | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 985f63693..eef29c495 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -1,14 +1,14 @@ let sendPromiseData = (promise, key) => { - let asyncOperation = async () => { - let response = try { - await promise - } catch { - | _ => JSON.Encode.null + ( + async () => { + let response = try { + await promise + } catch { + | _ => JSON.Encode.null + } + Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) } - Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) - } - - asyncOperation()->ignore + )()->ignore } let useMessageHandler = getPromisesAndMessageHandler => { let cleanup = messageHandler => { From 264f7384f6329ee8e2b0d9683438e48bea684083 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 7 Nov 2024 12:02:09 +0530 Subject: [PATCH 6/6] fix: comments addressed --- src/Payments/PreMountLoader.res | 68 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/Payments/PreMountLoader.res b/src/Payments/PreMountLoader.res index 6f393cafd..1c6ecbc57 100644 --- a/src/Payments/PreMountLoader.res +++ b/src/Payments/PreMountLoader.res @@ -1,46 +1,42 @@ let sendPromiseData = (promise, key) => { - ( - async () => { - let response = try { - await promise - } catch { - | _ => JSON.Encode.null - } - Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) + let executePromise = async () => { + let response = try { + await promise + } catch { + | _ => JSON.Encode.null } - )()->ignore + Utils.messageParentWindow([("response", response), ("data", key->JSON.Encode.string)]) + } + executePromise()->ignore } -let useMessageHandler = getPromisesAndMessageHandler => { - let cleanup = messageHandler => { - Utils.messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) - Window.removeEventListener("message", messageHandler) - } - let setup = messageHandler => { - Utils.messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) - Window.addEventListener("message", messageHandler) - } +let useMessageHandler = getPromisesAndHandler => { + React.useEffect(_ => { + let (promises, messageHandler) = getPromisesAndHandler() + let setupMessageListener = _ => { + Utils.messageParentWindow([("preMountLoaderIframeMountedCallback", true->JSON.Encode.bool)]) + Window.addEventListener("message", messageHandler) + } - React.useEffect0(() => { - let (promises, messageHandler) = getPromisesAndMessageHandler() - setup(messageHandler) - - ( - async () => { - try { - let _ = await Promise.all(promises) - cleanup(messageHandler) - } catch { - | error => { - Console.error2("Error in useMessageHandler:", error) - cleanup(messageHandler) - } - } + let cleanupMessageListener = _ => { + Utils.messageParentWindow([("preMountLoaderIframeUnMount", true->JSON.Encode.bool)]) + Window.removeEventListener("message", messageHandler) + } + + setupMessageListener() + + let executeAllPromises = async () => { + try { + let _ = await Promise.all(promises) + } catch { + | error => Console.error2("Error in message handler:", error) } - )()->ignore + cleanupMessageListener() + } + executeAllPromises()->ignore - Some(() => cleanup(messageHandler)) - }) + Some(cleanupMessageListener) + }, []) } module PreMountLoaderForElements = {