@nosto/nosto-react 2.2.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/index.d.ts +12 -177
- package/dist/index.es.js +197 -164
- package/dist/index.umd.js +1 -1
- package/package.json +20 -17
- package/src/components/NostoProvider.tsx +2 -1
- package/src/context.ts +2 -1
- package/src/hooks/useLoadClientScript.ts +17 -13
- package/src/hooks/useNostoApi.ts +4 -3
- package/src/hooks/useNostoOrder.tsx +1 -1
- package/src/hooks/useNostoProduct.tsx +11 -5
- package/src/hooks/useNostoSession.tsx +3 -2
- package/src/hooks/useRenderCampaigns.tsx +6 -3
- package/src/index.ts +2 -1
- package/src/types.ts +1 -965
- package/src/components/helpers.ts +0 -3
|
@@ -3,6 +3,7 @@ import { NostoContext, RecommendationComponent } from "../context"
|
|
|
3
3
|
import type { ReactNode } from "react"
|
|
4
4
|
import { ScriptLoadOptions } from "../hooks/scriptLoader"
|
|
5
5
|
import { useLoadClientScript } from "../hooks/useLoadClientScript"
|
|
6
|
+
import { nostojs } from "@nosto/nosto-js"
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @group Components
|
|
@@ -88,7 +89,7 @@ export function NostoProvider(props: NostoProviderProps) {
|
|
|
88
89
|
const { clientScriptLoaded } = useLoadClientScript(props)
|
|
89
90
|
|
|
90
91
|
if (clientScriptLoaded) {
|
|
91
|
-
|
|
92
|
+
nostojs(api => {
|
|
92
93
|
api.defaultSession().setVariation(currentVariation!).setResponseMode(responseMode)
|
|
93
94
|
})
|
|
94
95
|
}
|
package/src/context.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useState, useEffect } from "react"
|
|
2
|
-
import { isNostoLoaded } from "../components/helpers"
|
|
3
|
-
import type { NostoClient } from "../types"
|
|
4
2
|
import type { NostoProviderProps } from "../components/NostoProvider"
|
|
5
3
|
import scriptLoaderFn from "./scriptLoader"
|
|
4
|
+
import { init, initNostoStub, isNostoLoaded, nostojs } from "@nosto/nosto-js"
|
|
5
|
+
import { reloadNosto } from "@nosto/nosto-js/testing"
|
|
6
6
|
|
|
7
7
|
type NostoScriptProps = Pick<NostoProviderProps, "account" | "host" | "shopifyMarkets" | "loadScript" | "scriptLoader">
|
|
8
8
|
|
|
@@ -20,7 +20,7 @@ export function useLoadClientScript(props: NostoScriptProps) {
|
|
|
20
20
|
function scriptOnload() {
|
|
21
21
|
// Override for production scripts to work in unit tests
|
|
22
22
|
if ("nostoReactTest" in window) {
|
|
23
|
-
|
|
23
|
+
reloadNosto({
|
|
24
24
|
site: "localhost"
|
|
25
25
|
})
|
|
26
26
|
}
|
|
@@ -60,23 +60,27 @@ export function useLoadClientScript(props: NostoScriptProps) {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
if (!window.nostojs) {
|
|
65
|
-
window.nostojs = (cb: (api: NostoClient) => void) => {
|
|
66
|
-
(window.nostojs.q = window.nostojs.q || []).push(cb)
|
|
67
|
-
}
|
|
68
|
-
window.nostojs(api => api.setAutoLoad(false))
|
|
69
|
-
}
|
|
63
|
+
initNostoStub()
|
|
70
64
|
|
|
71
65
|
if (!loadScript) {
|
|
72
|
-
|
|
66
|
+
nostojs(scriptOnload)
|
|
73
67
|
return
|
|
74
68
|
}
|
|
75
69
|
|
|
70
|
+
async function initClientScript() {
|
|
71
|
+
await init({
|
|
72
|
+
merchantId: account,
|
|
73
|
+
options: {
|
|
74
|
+
attributes: { "nosto-client-script": ""}
|
|
75
|
+
},
|
|
76
|
+
scriptLoader
|
|
77
|
+
})
|
|
78
|
+
scriptOnload()
|
|
79
|
+
}
|
|
80
|
+
|
|
76
81
|
// Load Nosto client script if not already loaded externally
|
|
77
82
|
if (!isNostoLoaded() && !shopifyMarkets) {
|
|
78
|
-
|
|
79
|
-
injectScriptElement(urlPartial)
|
|
83
|
+
initClientScript()
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
// Load Shopify Markets scripts
|
package/src/hooks/useNostoApi.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { DependencyList, useEffect } from "react"
|
|
2
2
|
import { useNostoContext } from "./useNostoContext"
|
|
3
|
-
import { NostoClient } from "../types"
|
|
4
3
|
import { useDeepCompareEffect } from "./useDeepCompareEffect"
|
|
4
|
+
import { nostojs } from "@nosto/nosto-js"
|
|
5
|
+
import { API } from "@nosto/nosto-js/client"
|
|
5
6
|
|
|
6
|
-
export function useNostoApi(cb: (api:
|
|
7
|
+
export function useNostoApi(cb: (api: API) => void, deps?: DependencyList, flags?: { deep?: boolean }): void {
|
|
7
8
|
const { clientScriptLoaded } = useNostoContext()
|
|
8
9
|
const useEffectFn = flags?.deep ? useDeepCompareEffect : useEffect
|
|
9
10
|
|
|
10
11
|
useEffectFn(() => {
|
|
11
12
|
if (clientScriptLoaded) {
|
|
12
|
-
|
|
13
|
+
nostojs(cb)
|
|
13
14
|
}
|
|
14
15
|
}, [clientScriptLoaded, ...(deps ?? [])])
|
|
15
16
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { snakeize } from "../utils/snakeize"
|
|
2
|
-
import { Order } from "../types"
|
|
3
2
|
import { useRenderCampaigns } from "./useRenderCampaigns"
|
|
4
3
|
import { useNostoApi } from "./useNostoApi"
|
|
5
4
|
import { ToCamelCase } from "../utils/types"
|
|
5
|
+
import { WebsiteOrder as Order } from "@nosto/nosto-js/client"
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @group Hooks
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Product } from "../types"
|
|
2
1
|
import { useNostoApi } from "./useNostoApi"
|
|
3
2
|
import { useRenderCampaigns } from "./useRenderCampaigns"
|
|
3
|
+
import { Product } from "@nosto/nosto-js/client"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @group Hooks
|
|
7
7
|
*/
|
|
8
8
|
export type NostoProductProps = {
|
|
9
9
|
product: string
|
|
10
|
+
reference?: string
|
|
10
11
|
tagging?: Product
|
|
11
12
|
placements?: string[]
|
|
12
13
|
}
|
|
@@ -16,22 +17,27 @@ export type NostoProductProps = {
|
|
|
16
17
|
*
|
|
17
18
|
* @group Hooks
|
|
18
19
|
*/
|
|
19
|
-
export function useNostoProduct({ product, tagging, placements }: NostoProductProps) {
|
|
20
|
+
export function useNostoProduct({ product, tagging, placements, reference }: NostoProductProps) {
|
|
20
21
|
const { renderCampaigns } = useRenderCampaigns()
|
|
21
22
|
|
|
22
23
|
if (tagging && !tagging.product_id) {
|
|
23
24
|
throw new Error("The product object must contain a product_id property")
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
const productId = tagging?.product_id ?? product
|
|
28
|
+
|
|
26
29
|
useNostoApi(
|
|
27
30
|
async api => {
|
|
28
|
-
const
|
|
31
|
+
const action = api
|
|
29
32
|
.defaultSession()
|
|
30
33
|
.viewProduct(tagging ?? product)
|
|
31
34
|
.setPlacements(placements || api.placements.getPlacements())
|
|
32
|
-
|
|
35
|
+
if (reference) {
|
|
36
|
+
action.setRef(productId, reference)
|
|
37
|
+
}
|
|
38
|
+
const data = await action.load()
|
|
33
39
|
renderCampaigns(data)
|
|
34
40
|
},
|
|
35
|
-
[
|
|
41
|
+
[productId, tagging?.selected_sku_id]
|
|
36
42
|
)
|
|
37
43
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { snakeize } from "../utils/snakeize"
|
|
2
|
-
import {
|
|
2
|
+
import { PushedCustomer as CustomerSnakeCase, Cart as CartSnakeCase } from "@nosto/nosto-js/client"
|
|
3
3
|
import { ToCamelCase } from "../utils/types"
|
|
4
4
|
import { useNostoContext } from "./useNostoContext"
|
|
5
5
|
import { useDeepCompareEffect } from "./useDeepCompareEffect"
|
|
6
|
+
import { nostojs } from "@nosto/nosto-js"
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @group Hooks
|
|
@@ -25,7 +26,7 @@ export function useNostoSession({ cart, customer }: NostoSessionProps = {}) {
|
|
|
25
26
|
const currentCustomer = customer ? snakeize(customer) : undefined
|
|
26
27
|
|
|
27
28
|
if (clientScriptLoaded) {
|
|
28
|
-
|
|
29
|
+
nostojs(api => {
|
|
29
30
|
api.defaultSession().setCart(currentCart).setCustomer(currentCustomer).viewOther().load({ skipPageViews: true })
|
|
30
31
|
})
|
|
31
32
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { cloneElement, useRef } from "react"
|
|
2
2
|
import { createRoot, Root } from "react-dom/client"
|
|
3
|
-
import {
|
|
3
|
+
import { Recommendation } from "../types"
|
|
4
4
|
import { useNostoContext } from "./useNostoContext"
|
|
5
5
|
import { RecommendationComponent } from "../context"
|
|
6
|
+
import { ActionResponse, API } from "@nosto/nosto-js/client"
|
|
7
|
+
import { nostojs } from "@nosto/nosto-js"
|
|
6
8
|
|
|
7
9
|
type CampaignData = Pick<ActionResponse, "campaigns" | "recommendations">
|
|
8
10
|
|
|
@@ -18,11 +20,12 @@ function RecommendationComponentWrapper(props: {
|
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
function injectCampaigns(data: CampaignData) {
|
|
23
|
+
// @ts-expect-error not defined
|
|
21
24
|
if (!window.nostojs) {
|
|
22
25
|
throw new Error("Nosto has not yet been initialized")
|
|
23
26
|
}
|
|
24
|
-
|
|
25
|
-
api.placements.injectCampaigns(data.recommendations)
|
|
27
|
+
nostojs(api => {
|
|
28
|
+
api.placements.injectCampaigns(data.recommendations as Parameters<API['placements']['injectCampaigns']>[0])
|
|
26
29
|
})
|
|
27
30
|
}
|
|
28
31
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { Product, PushedCustomer as Customer, Cart, WebsiteOrder as Order } from "@nosto/nosto-js/client"
|
|
2
|
+
export type { Recommendation } from "./types"
|
|
2
3
|
export { type ScriptLoadOptions } from "./hooks/scriptLoader"
|
|
3
4
|
export { NostoContext, type NostoContextType } from "./context"
|
|
4
5
|
export { useNostoContext } from "./hooks/useNostoContext"
|