@constructor-io/constructorio-ui-asa 1.6.0 → 1.7.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.
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importDefault(require("react"));
5
+ const CioAsaProvider_1 = tslib_1.__importDefault(require("../CioAsaProvider/CioAsaProvider"));
6
+ const Chat_1 = tslib_1.__importDefault(require("../Chat/Chat"));
7
+ /**
8
+ * The whole agent in one component: the provider and the chat UI composed together.
9
+ *
10
+ * Consumers that need to place `Chat` inside their own tree, or render several
11
+ * components against one client, should compose `CioAsaProvider` and `Chat`
12
+ * directly. This is the single-entry-point convenience wrapper, and it is what the
13
+ * standalone browser bundle (`src/bundled.jsx`) mounts.
14
+ */
15
+ const CioAsa = react_1.default.forwardRef((props, ref) => {
16
+ const {
17
+ // Provider configuration — everything else belongs to Chat.
18
+ apiKey, cioClient, testCells, staticRequestConfigs, formatters, urlHelpers, callbacks, section } = props, chatProps = tslib_1.__rest(props, ["apiKey", "cioClient", "testCells", "staticRequestConfigs", "formatters", "urlHelpers", "callbacks", "section"]);
19
+ return (react_1.default.createElement(CioAsaProvider_1.default, { apiKey: apiKey, cioClient: cioClient, testCells: testCells, staticRequestConfigs: staticRequestConfigs, formatters: formatters, urlHelpers: urlHelpers, callbacks: callbacks, section: section },
20
+ react_1.default.createElement(Chat_1.default, Object.assign({}, chatProps, { ref: ref }))));
21
+ });
22
+ CioAsa.displayName = 'CioAsa';
23
+ exports.default = CioAsa;
@@ -7,9 +7,14 @@ const useCioAsaContext_1 = require("../../hooks/useCioAsaContext");
7
7
  const defaultFormatters = tslib_1.__importStar(require("../../utils/formatters"));
8
8
  const defaultUrlHelpers = tslib_1.__importStar(require("../../utils/urlHelpers"));
9
9
  function CioAsaProvider(props) {
10
- const { apiKey, formatters, urlHelpers, staticRequestConfigs = { domain: 'chatbot' }, cioClient: customCioClient, callbacks, section = 'Products', children, } = props;
10
+ const { apiKey, formatters, urlHelpers, staticRequestConfigs = { domain: 'chatbot' }, cioClient: customCioClient, testCells, callbacks, section = 'Products', children, } = props;
11
11
  const [cioClientOptions, setCioClientOptions] = (0, react_1.useState)({});
12
- const cioClient = (0, useCioClient_1.default)({ apiKey, cioClient: customCioClient, cioClientOptions });
12
+ const cioClient = (0, useCioClient_1.default)({
13
+ apiKey,
14
+ cioClient: customCioClient,
15
+ cioClientOptions,
16
+ testCells,
17
+ });
13
18
  const contextValue = (0, react_1.useMemo)(() => ({
14
19
  cioClient,
15
20
  cioClientOptions,
@@ -4,18 +4,29 @@ const tslib_1 = require("tslib");
4
4
  const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
5
5
  const react_1 = require("react");
6
6
  const version_1 = tslib_1.__importDefault(require("../version"));
7
- const useCioClient = ({ apiKey, cioClient, cioClientOptions } = {}) => {
7
+ const useCioClient = ({ apiKey, cioClient, cioClientOptions, testCells } = {}) => {
8
8
  if (!apiKey && !cioClient) {
9
9
  throw new Error('Api Key or Constructor Client required');
10
10
  }
11
+ const serializedOptions = (0, react_1.useMemo)(() => JSON.stringify({ cioClientOptions: cioClientOptions !== null && cioClientOptions !== void 0 ? cioClientOptions : null, testCells: testCells !== null && testCells !== void 0 ? testCells : null }), [cioClientOptions, testCells]);
11
12
  const memoizedCioClient = (0, react_1.useMemo)(() => {
12
13
  if (cioClient)
13
14
  return cioClient;
14
15
  if (apiKey && typeof window !== 'undefined') {
15
- return new constructorio_client_javascript_1.default(Object.assign({ apiKey, sendTrackingEvents: true, version: `cio-ui-asa-${version_1.default}` }, cioClientOptions));
16
+ return new constructorio_client_javascript_1.default(Object.assign(Object.assign({ apiKey, sendTrackingEvents: true, version: `cio-ui-asa-${version_1.default}` }, (testCells && { testCells })), cioClientOptions));
16
17
  }
17
18
  return null;
18
- }, [apiKey, cioClient, cioClientOptions]);
19
+ // options are compared by serializedOptions so inline objects do not rebuild the client
20
+ // eslint-disable-next-line react-hooks/exhaustive-deps
21
+ }, [apiKey, cioClient, serializedOptions]);
22
+ // A caller's client owns its own options, so say so rather than dropping these silently.
23
+ (0, react_1.useEffect)(() => {
24
+ if (!cioClient || !testCells || Object.keys(testCells).length === 0)
25
+ return;
26
+ // eslint-disable-next-line no-console
27
+ console.warn('[CioAsa] testCells is ignored when you supply your own cioClient. Set testCells on that client instead.');
28
+ // eslint-disable-next-line react-hooks/exhaustive-deps
29
+ }, [cioClient, serializedOptions]);
19
30
  return memoizedCioClient;
20
31
  };
21
32
  exports.default = useCioClient;
package/lib/cjs/index.js CHANGED
@@ -3,8 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ConstructorIOClient = exports.normalizeItemToProduct = exports.useCioAsaContext = exports.useAsaTracking = exports.useAsaResults = exports.Button = exports.ResultsBlock = exports.Chat = exports.CioAsaProvider = void 0;
6
+ exports.ConstructorIOClient = exports.normalizeItemToProduct = exports.useCioAsaContext = exports.useAsaTracking = exports.useAsaResults = exports.Button = exports.ResultsBlock = exports.Chat = exports.CioAsaProvider = exports.CioAsa = void 0;
7
7
  // Components
8
+ var CioAsa_1 = require("./components/CioAsa/CioAsa");
9
+ Object.defineProperty(exports, "CioAsa", { enumerable: true, get: function () { return __importDefault(CioAsa_1).default; } });
8
10
  var CioAsaProvider_1 = require("./components/CioAsaProvider/CioAsaProvider");
9
11
  Object.defineProperty(exports, "CioAsaProvider", { enumerable: true, get: function () { return __importDefault(CioAsaProvider_1).default; } });
10
12
  var Chat_1 = require("./components/Chat/Chat");
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = '1.6.0';
3
+ exports.default = '1.7.0';
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import CioAsaProvider from '../CioAsaProvider/CioAsaProvider';
3
+ import Chat from '../Chat/Chat';
4
+ /**
5
+ * The whole agent in one component: the provider and the chat UI composed together.
6
+ *
7
+ * Consumers that need to place `Chat` inside their own tree, or render several
8
+ * components against one client, should compose `CioAsaProvider` and `Chat`
9
+ * directly. This is the single-entry-point convenience wrapper, and it is what the
10
+ * standalone browser bundle (`src/bundled.jsx`) mounts.
11
+ */
12
+ const CioAsa = React.forwardRef((props, ref) => {
13
+ const {
14
+ // Provider configuration — everything else belongs to Chat.
15
+ apiKey, cioClient, testCells, staticRequestConfigs, formatters, urlHelpers, callbacks, section, ...chatProps } = props;
16
+ return (React.createElement(CioAsaProvider, { apiKey: apiKey, cioClient: cioClient, testCells: testCells, staticRequestConfigs: staticRequestConfigs, formatters: formatters, urlHelpers: urlHelpers, callbacks: callbacks, section: section },
17
+ React.createElement(Chat, { ...chatProps, ref: ref })));
18
+ });
19
+ CioAsa.displayName = 'CioAsa';
20
+ export default CioAsa;
@@ -4,9 +4,14 @@ import { AsaContext } from '../../hooks/useCioAsaContext';
4
4
  import * as defaultFormatters from '../../utils/formatters';
5
5
  import * as defaultUrlHelpers from '../../utils/urlHelpers';
6
6
  export default function CioAsaProvider(props) {
7
- const { apiKey, formatters, urlHelpers, staticRequestConfigs = { domain: 'chatbot' }, cioClient: customCioClient, callbacks, section = 'Products', children, } = props;
7
+ const { apiKey, formatters, urlHelpers, staticRequestConfigs = { domain: 'chatbot' }, cioClient: customCioClient, testCells, callbacks, section = 'Products', children, } = props;
8
8
  const [cioClientOptions, setCioClientOptions] = useState({});
9
- const cioClient = useCioClient({ apiKey, cioClient: customCioClient, cioClientOptions });
9
+ const cioClient = useCioClient({
10
+ apiKey,
11
+ cioClient: customCioClient,
12
+ cioClientOptions,
13
+ testCells,
14
+ });
10
15
  const contextValue = useMemo(() => ({
11
16
  cioClient,
12
17
  cioClientOptions,
@@ -1,10 +1,11 @@
1
1
  import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
2
- import { useMemo } from 'react';
2
+ import { useEffect, useMemo } from 'react';
3
3
  import version from '../version';
4
- const useCioClient = ({ apiKey, cioClient, cioClientOptions } = {}) => {
4
+ const useCioClient = ({ apiKey, cioClient, cioClientOptions, testCells } = {}) => {
5
5
  if (!apiKey && !cioClient) {
6
6
  throw new Error('Api Key or Constructor Client required');
7
7
  }
8
+ const serializedOptions = useMemo(() => JSON.stringify({ cioClientOptions: cioClientOptions ?? null, testCells: testCells ?? null }), [cioClientOptions, testCells]);
8
9
  const memoizedCioClient = useMemo(() => {
9
10
  if (cioClient)
10
11
  return cioClient;
@@ -13,11 +14,22 @@ const useCioClient = ({ apiKey, cioClient, cioClientOptions } = {}) => {
13
14
  apiKey,
14
15
  sendTrackingEvents: true,
15
16
  version: `cio-ui-asa-${version}`,
17
+ ...(testCells && { testCells }),
16
18
  ...cioClientOptions,
17
19
  });
18
20
  }
19
21
  return null;
20
- }, [apiKey, cioClient, cioClientOptions]);
22
+ // options are compared by serializedOptions so inline objects do not rebuild the client
23
+ // eslint-disable-next-line react-hooks/exhaustive-deps
24
+ }, [apiKey, cioClient, serializedOptions]);
25
+ // A caller's client owns its own options, so say so rather than dropping these silently.
26
+ useEffect(() => {
27
+ if (!cioClient || !testCells || Object.keys(testCells).length === 0)
28
+ return;
29
+ // eslint-disable-next-line no-console
30
+ console.warn('[CioAsa] testCells is ignored when you supply your own cioClient. Set testCells on that client instead.');
31
+ // eslint-disable-next-line react-hooks/exhaustive-deps
32
+ }, [cioClient, serializedOptions]);
21
33
  return memoizedCioClient;
22
34
  };
23
35
  export default useCioClient;
package/lib/mjs/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // Components
2
+ export { default as CioAsa } from './components/CioAsa/CioAsa';
2
3
  export { default as CioAsaProvider } from './components/CioAsaProvider/CioAsaProvider';
3
4
  export { default as Chat } from './components/Chat/Chat';
4
5
  export { default as ResultsBlock } from './components/ResultsBlock/ResultsBlock';
@@ -1 +1 @@
1
- export default '1.6.0';
1
+ export default '1.7.0';
@@ -12,7 +12,7 @@ export interface ChatHandle {
12
12
  /** Cancel any active response, then reset the conversation and the thread. */
13
13
  clearHistory: () => void;
14
14
  }
15
- interface ChatProps {
15
+ export interface ChatProps {
16
16
  /** Called when the close button (✕) is clicked. The consumer controls visibility. */
17
17
  onClose?: () => void;
18
18
  /** Additional CSS class name for the root container */
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { ChatHandle, ChatProps } from '../Chat/Chat';
3
+ import { CioAsaProviderProps } from '../../types';
4
+ export type CioAsaProps = CioAsaProviderProps & ChatProps;
5
+ /**
6
+ * The whole agent in one component: the provider and the chat UI composed together.
7
+ *
8
+ * Consumers that need to place `Chat` inside their own tree, or render several
9
+ * components against one client, should compose `CioAsaProvider` and `Chat`
10
+ * directly. This is the single-entry-point convenience wrapper, and it is what the
11
+ * standalone browser bundle (`src/bundled.jsx`) mounts.
12
+ */
13
+ declare const CioAsa: React.ForwardRefExoticComponent<CioAsaProviderProps & ChatProps & React.RefAttributes<ChatHandle>>;
14
+ export default CioAsa;
@@ -1,6 +1,8 @@
1
+ export { default as CioAsa } from './components/CioAsa/CioAsa';
2
+ export type { CioAsaProps } from './components/CioAsa/CioAsa';
1
3
  export { default as CioAsaProvider } from './components/CioAsaProvider/CioAsaProvider';
2
4
  export { default as Chat } from './components/Chat/Chat';
3
- export type { ChatHandle } from './components/Chat/Chat';
5
+ export type { ChatHandle, ChatProps } from './components/Chat/Chat';
4
6
  export { default as ResultsBlock } from './components/ResultsBlock/ResultsBlock';
5
7
  export type { AspectRatio } from './components/ResultsBlock/ResultsBlock';
6
8
  export { default as Button } from './components/Button/Button';
@@ -37,11 +37,23 @@ export interface UrlHelpers {
37
37
  }
38
38
  export interface CioAsaProviderProps extends Omit<Partial<AsaContextValue>, 'setCioClientOptions' | 'cioClientOptions'> {
39
39
  apiKey?: string;
40
+ /**
41
+ * A/B test cells to attach to tracking events, as `{ [testName]: cellName }`. Each entry is
42
+ * sent as an `ef-<testName>` parameter. Constructor's docs have the page set
43
+ * `window.cnstrc.testCell` to a bare cell name, so label it with your test name:
44
+ * `{ constructorio: window.cnstrc.testCell }`.
45
+ *
46
+ * Ignored when you supply your own `cioClient`: that client owns its own options, so set
47
+ * `testCells` there instead, as a `ConstructorIOClient` constructor option. Passing both
48
+ * logs a warning.
49
+ */
50
+ testCells?: Record<string, string>;
40
51
  }
41
52
  export interface UseCioClientProps {
42
53
  apiKey?: string;
43
54
  cioClient?: Nullable<ConstructorIOClient>;
44
55
  cioClientOptions?: CioClientOptions;
56
+ testCells?: Record<string, string>;
45
57
  }
46
58
  export type DefaultQueryStringMap = {
47
59
  intent: 'q';
@@ -1,2 +1,2 @@
1
- declare const _default: "1.6.0";
1
+ declare const _default: "1.7.0";
2
2
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-asa",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Constructor.io AI Shopping Agent UI library for web applications",
5
5
  "author": "constructor.io",
6
6
  "license": "MIT",