@croct/plug-react 0.7.1 → 0.8.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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.Personalization = void 0;
4
+ exports.Personalization = Personalization;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const hooks_1 = require("../../hooks");
@@ -10,5 +10,4 @@ function Personalization(props) {
10
10
  const result = (0, hooks_1.useEvaluation)(query, options);
11
11
  return ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: children(result) }));
12
12
  }
13
- exports.Personalization = Personalization;
14
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/Personalization/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAEb,iCAA6C;AAE7C,uCAAgE;AAgBhE,SAAgB,eAAe,CAAO,KAA4C;IAC9E,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAC,GAAG,KAAK,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE7C,OAAO,CAAC,uBAAC,gBAAQ,cAAE,QAAQ,CAAC,MAAM,CAAC,GAAY,CAAC,CAAC;AACrD,CAAC;AALD,0CAKC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/Personalization/index.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAoBb,0CAKC;;AAvBD,iCAA6C;AAE7C,uCAAgE;AAgBhE,SAAgB,eAAe,CAAO,KAA4C;IAC9E,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAC,GAAG,KAAK,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE7C,OAAO,CAAC,uBAAC,gBAAQ,cAAE,QAAQ,CAAC,MAAM,CAAC,GAAY,CAAC,CAAC;AACrD,CAAC"}
package/hash.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function hash(value: string): string;
package/hash.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hash = hash;
4
+ function hash(value) {
5
+ let code = 0;
6
+ for (const char of value) {
7
+ const charCode = char.charCodeAt(0);
8
+ code = (code << 5) - code + charCode;
9
+ code |= 0; // Convert to 32bit integer
10
+ }
11
+ return code.toString(16);
12
+ }
13
+ //# sourceMappingURL=hash.js.map
package/hash.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["src/hash.ts"],"names":[],"mappings":";;AAAA,oBAWC;AAXD,SAAgB,IAAI,CAAC,KAAa;IAC9B,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAEpC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,QAAQ,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,2BAA2B;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC"}
@@ -4,11 +4,17 @@ exports.useContent = void 0;
4
4
  const useLoader_1 = require("./useLoader");
5
5
  const useCroct_1 = require("./useCroct");
6
6
  const ssr_polyfills_1 = require("../ssr-polyfills");
7
+ const hash_1 = require("../hash");
7
8
  function useCsrContent(id, options = {}) {
9
+ var _a;
8
10
  const { fallback, initial, cacheKey, expiration, ...fetchOptions } = options;
11
+ const { preferredLocale } = fetchOptions;
9
12
  const croct = (0, useCroct_1.useCroct)();
10
13
  return (0, useLoader_1.useLoader)({
11
- cacheKey: `useContent:${cacheKey !== null && cacheKey !== void 0 ? cacheKey : ''}:${id}`,
14
+ cacheKey: (0, hash_1.hash)(`useContent:${cacheKey !== null && cacheKey !== void 0 ? cacheKey : ''}`
15
+ + `:${id}`
16
+ + `:${preferredLocale !== null && preferredLocale !== void 0 ? preferredLocale : ''}`
17
+ + `:${JSON.stringify((_a = fetchOptions.attributes) !== null && _a !== void 0 ? _a : '')}`),
12
18
  loader: () => croct.fetch(id, fetchOptions).then(({ content }) => content),
13
19
  initial: initial,
14
20
  fallback: fallback,
@@ -17,7 +23,8 @@ function useCsrContent(id, options = {}) {
17
23
  }
18
24
  function useSsrContent(_, { initial } = {}) {
19
25
  if (initial === undefined) {
20
- throw new Error('The initial value is required for server-side rendering (SSR).');
26
+ throw new Error('The initial content is required for server-side rendering (SSR). '
27
+ + 'For help, see https://croct.help/sdk/react/missing-slot-content');
21
28
  }
22
29
  return initial;
23
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useContent.js","sourceRoot":"","sources":["../src/hooks/useContent.ts"],"names":[],"mappings":";;;AAGA,2CAAsC;AACtC,yCAAoC;AACpC,oDAAuC;AASvC,SAAS,aAAa,CAClB,EAAmB,EACnB,UAAmC,EAAE;IAErC,MAAM,EAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,YAAY,EAAC,GAAG,OAAO,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAA,mBAAQ,GAAE,CAAC;IAEzB,OAAO,IAAA,qBAAS,EAAC;QACb,QAAQ,EAAE,cAAc,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,IAAI,EAAE,EAAE;QAC9C,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE,CAAC,OAAO,CAAC;QACxE,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC;AACP,CAAC;AAED,SAAS,aAAa,CAClB,CAAkB,EAClB,EAAC,OAAO,KAA6B,EAAE;IAEvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AA6BY,QAAA,UAAU,GAAmB,IAAA,qBAAK,GAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC"}
1
+ {"version":3,"file":"useContent.js","sourceRoot":"","sources":["../src/hooks/useContent.ts"],"names":[],"mappings":";;;AAGA,2CAAsC;AACtC,yCAAoC;AACpC,oDAAuC;AACvC,kCAA6B;AAS7B,SAAS,aAAa,CAClB,EAAmB,EACnB,UAAmC,EAAE;;IAErC,MAAM,EAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,YAAY,EAAC,GAAG,OAAO,CAAC;IAC3E,MAAM,EAAC,eAAe,EAAC,GAAG,YAAY,CAAC;IACvC,MAAM,KAAK,GAAG,IAAA,mBAAQ,GAAE,CAAC;IAEzB,OAAO,IAAA,qBAAS,EAAC;QACb,QAAQ,EAAE,IAAA,WAAI,EACV,cAAc,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,EAAE;cAC5B,IAAI,EAAE,EAAE;cACR,IAAI,eAAe,aAAf,eAAe,cAAf,eAAe,GAAI,EAAE,EAAE;cAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAA,YAAY,CAAC,UAAU,mCAAI,EAAE,CAAC,EAAE,CACxD;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE,CAAC,OAAO,CAAC;QACxE,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC;AACP,CAAC;AAED,SAAS,aAAa,CAClB,CAAkB,EAClB,EAAC,OAAO,KAA6B,EAAE;IAEvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACX,mEAAmE;cACjE,iEAAiE,CACtE,CAAC;IACN,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AA6BY,QAAA,UAAU,GAAmB,IAAA,qBAAK,GAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC"}
package/hooks/useCroct.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useCroct = void 0;
3
+ exports.useCroct = useCroct;
4
4
  const react_1 = require("react");
5
5
  const CroctProvider_1 = require("../CroctProvider");
6
6
  function useCroct() {
7
7
  const context = (0, react_1.useContext)(CroctProvider_1.CroctContext);
8
8
  if (context === null) {
9
- throw new Error('useCroct() can only be used in the context of a <CroctProvider> component.');
9
+ throw new Error('useCroct() can only be used in the context of a <CroctProvider> component. '
10
+ + 'For help, see https://croct.help/sdk/react/missing-provider');
10
11
  }
11
12
  return context.plug;
12
13
  }
13
- exports.useCroct = useCroct;
14
14
  //# sourceMappingURL=useCroct.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCroct.js","sourceRoot":"","sources":["../src/hooks/useCroct.ts"],"names":[],"mappings":";;;AACA,iCAAiC;AACjC,oDAA8C;AAE9C,SAAgB,QAAQ;IACpB,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,4BAAY,CAAC,CAAC;IAEzC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAClG,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC;AACxB,CAAC;AARD,4BAQC"}
1
+ {"version":3,"file":"useCroct.js","sourceRoot":"","sources":["../src/hooks/useCroct.ts"],"names":[],"mappings":";;AAIA,4BAWC;AAdD,iCAAiC;AACjC,oDAA8C;AAE9C,SAAgB,QAAQ;IACpB,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,4BAAY,CAAC,CAAC;IAEzC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACX,6EAA6E;cAC3E,6DAA6D,CAClE,CAAC;IACN,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC;AACxB,CAAC"}
@@ -4,6 +4,7 @@ exports.useEvaluation = void 0;
4
4
  const useLoader_1 = require("./useLoader");
5
5
  const useCroct_1 = require("./useCroct");
6
6
  const ssr_polyfills_1 = require("../ssr-polyfills");
7
+ const hash_1 = require("../hash");
7
8
  function cleanEvaluationOptions(options) {
8
9
  const result = {};
9
10
  for (const [key, value] of Object.entries(options)) {
@@ -18,7 +19,9 @@ function useCsrEvaluation(query, options = {}) {
18
19
  const { cacheKey, fallback, initial, expiration, ...evaluationOptions } = options;
19
20
  const croct = (0, useCroct_1.useCroct)();
20
21
  return (0, useLoader_1.useLoader)({
21
- cacheKey: `useEvaluation:${cacheKey !== null && cacheKey !== void 0 ? cacheKey : ''}:${query}:${JSON.stringify((_a = options.attributes) !== null && _a !== void 0 ? _a : '')}`,
22
+ cacheKey: (0, hash_1.hash)(`useEvaluation:${cacheKey !== null && cacheKey !== void 0 ? cacheKey : ''}`
23
+ + `:${query}`
24
+ + `:${JSON.stringify((_a = options.attributes) !== null && _a !== void 0 ? _a : '')}`),
22
25
  loader: () => croct.evaluate(query, cleanEvaluationOptions(evaluationOptions)),
23
26
  initial: initial,
24
27
  fallback: fallback,
@@ -27,7 +30,8 @@ function useCsrEvaluation(query, options = {}) {
27
30
  }
28
31
  function useSsrEvaluation(_, { initial } = {}) {
29
32
  if (initial === undefined) {
30
- throw new Error('The initial value is required for server-side rendering (SSR).');
33
+ throw new Error('The initial value is required for server-side rendering (SSR). '
34
+ + 'For help, see https://croct.help/sdk/react/missing-evaluation-result');
31
35
  }
32
36
  return initial;
33
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useEvaluation.js","sourceRoot":"","sources":["../src/hooks/useEvaluation.ts"],"names":[],"mappings":";;;AAEA,2CAAsC;AACtC,yCAAoC;AACpC,oDAAuC;AAEvC,SAAS,sBAAsB,CAAC,OAA0B;IACtD,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAA0C,EAAE,CAAC;QAC1F,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAcD,SAAS,gBAAgB,CACrB,KAAa,EACb,UAAsC,EAAE;;IAExC,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAC,GAAG,OAAO,CAAC;IAChF,MAAM,KAAK,GAAG,IAAA,mBAAQ,GAAE,CAAC;IAEzB,OAAO,IAAA,qBAAS,EAAY;QACxB,QAAQ,EAAE,iBAAiB,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,MAAA,OAAO,CAAC,UAAU,mCAAI,EAAE,CAAC,EAAE;QAChG,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAgB,KAAK,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QAC7F,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC;AACP,CAAC;AAED,SAAS,gBAAgB,CACrB,CAAS,EACT,EAAC,OAAO,KAAgC,EAAE;IAE1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAEY,QAAA,aAAa,GAAsB,IAAA,qBAAK,GAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC"}
1
+ {"version":3,"file":"useEvaluation.js","sourceRoot":"","sources":["../src/hooks/useEvaluation.ts"],"names":[],"mappings":";;;AAEA,2CAAsC;AACtC,yCAAoC;AACpC,oDAAuC;AACvC,kCAA6B;AAE7B,SAAS,sBAAsB,CAAC,OAA0B;IACtD,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAA0C,EAAE,CAAC;QAC1F,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAcD,SAAS,gBAAgB,CACrB,KAAa,EACb,UAAsC,EAAE;;IAExC,MAAM,EAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAC,GAAG,OAAO,CAAC;IAChF,MAAM,KAAK,GAAG,IAAA,mBAAQ,GAAE,CAAC;IAEzB,OAAO,IAAA,qBAAS,EAAY;QACxB,QAAQ,EAAE,IAAA,WAAI,EACV,iBAAiB,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,EAAE;cAC/B,IAAI,KAAK,EAAE;cACX,IAAI,IAAI,CAAC,SAAS,CAAC,MAAA,OAAO,CAAC,UAAU,mCAAI,EAAE,CAAC,EAAE,CACnD;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAgB,KAAK,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QAC7F,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,QAAQ;QAClB,UAAU,EAAE,UAAU;KACzB,CAAC,CAAC;AACP,CAAC;AAED,SAAS,gBAAgB,CACrB,CAAS,EACT,EAAC,OAAO,KAAgC,EAAE;IAE1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACX,iEAAiE;cAC/D,sEAAsE,CAC3E,CAAC;IACN,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAEY,QAAA,aAAa,GAAsB,IAAA,qBAAK,GAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useLoader = void 0;
3
+ exports.useLoader = useLoader;
4
4
  const react_1 = require("react");
5
5
  const Cache_1 = require("./Cache");
6
6
  const cache = new Cache_1.Cache(60 * 1000);
@@ -37,5 +37,4 @@ function useLoader({ initial, ...options }) {
37
37
  }
38
38
  return value;
39
39
  }
40
- exports.useLoader = useLoader;
41
40
  //# sourceMappingURL=useLoader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLoader.js","sourceRoot":"","sources":["../src/hooks/useLoader.ts"],"names":[],"mappings":";;;AAAA,iCAAkD;AAClD,mCAA4C;AAE5C,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAMnC,SAAgB,SAAS,CAAI,EAAC,OAAO,EAAE,GAAG,OAAO,EAAkB;;IAC/D,MAAM,WAAW,GAAgB,MAAA,KAAK,CAAC,GAAG,CAAI,OAAO,CAAC,QAAQ,CAAC,0CAAE,MAAM,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACtF,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,IAAI,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEvE,IAAA,iBAAS,EACL,GAAG,EAAE;QACD,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC;gBACD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,MAAe,EAAE,CAAC;gBACvB,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,aAAgB,EAAE,EAAE;wBAC7B,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;4BACrB,QAAQ,CAAC,aAAa,CAAC,CAAC;wBAC5B,CAAC;oBACL,CAAC,CAAC,CAAC;oBAEH,OAAO;gBACX,CAAC;gBAED,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAEpB,OAAO;YACX,CAAC;QACL,CAAC;QAED,OAAO,GAAG,EAAE;YACR,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;QAC/B,CAAC,CAAC;IACN,CAAC,EACD,EAAE,CACL,CAAC;IAEF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAxCD,8BAwCC"}
1
+ {"version":3,"file":"useLoader.js","sourceRoot":"","sources":["../src/hooks/useLoader.ts"],"names":[],"mappings":";;AASA,8BAwCC;AAjDD,iCAAkD;AAClD,mCAA4C;AAE5C,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AAMnC,SAAgB,SAAS,CAAI,EAAC,OAAO,EAAE,GAAG,OAAO,EAAkB;;IAC/D,MAAM,WAAW,GAAgB,MAAA,KAAK,CAAC,GAAG,CAAI,OAAO,CAAC,QAAQ,CAAC,0CAAE,MAAM,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACtF,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,IAAI,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEvE,IAAA,iBAAS,EACL,GAAG,EAAE;QACD,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC;gBACD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,MAAe,EAAE,CAAC;gBACvB,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,aAAgB,EAAE,EAAE;wBAC7B,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;4BACrB,QAAQ,CAAC,aAAa,CAAC,CAAC;wBAC5B,CAAC;oBACL,CAAC,CAAC,CAAC;oBAEH,OAAO;gBACX,CAAC;gBAED,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAEpB,OAAO;YACX,CAAC;QACL,CAAC;QAED,OAAO,GAAG,EAAE;YACR,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;QAC/B,CAAC,CAAC;IACN,CAAC,EACD,EAAE,CACL,CAAC;IAEF,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/plug-react",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "React components and hooks to plug your React applications into Croct.",
5
5
  "author": {
6
6
  "name": "Croct",
@@ -37,39 +37,39 @@
37
37
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
38
38
  },
39
39
  "dependencies": {
40
- "@croct/plug": "^0.14.1",
41
- "@croct/sdk": "^0.16.0"
40
+ "@croct/plug": "^0.16.0",
41
+ "@croct/sdk": "^0.17.2"
42
42
  },
43
43
  "devDependencies": {
44
- "@babel/core": "^7.20.2",
45
- "@babel/preset-env": "^7.20.2",
46
- "@babel/preset-react": "^7.18.6",
47
- "@babel/preset-typescript": "^7.18.6",
48
- "@croct/eslint-plugin": "^0.7.0",
49
- "@storybook/addon-actions": "^8.0.0",
50
- "@storybook/addon-essentials": "^8.0.0",
51
- "@storybook/addon-links": "^8.0.0",
52
- "@storybook/builder-webpack5": "^8.0.0",
53
- "@storybook/manager-webpack5": "^6.5.13",
54
- "@storybook/react": "^8.0.0",
55
- "@testing-library/jest-dom": "^6.0.0",
56
- "@testing-library/react": "^15.0.0",
57
- "@types/jest": "^29.2.3",
58
- "@types/node": "^20.0.0",
59
- "@types/react": "^18.0.25",
60
- "@types/react-dom": "^18.0.9",
61
- "@typescript-eslint/eslint-plugin": "^7.0.0",
62
- "@typescript-eslint/parser": "^7.0.0",
63
- "babel-loader": "^9.1.0",
44
+ "@babel/core": "^7.25.2",
45
+ "@babel/preset-env": "^7.25.4",
46
+ "@babel/preset-react": "^7.24.7",
47
+ "@babel/preset-typescript": "^7.24.7",
48
+ "@croct/eslint-plugin": "^0.7.1",
49
+ "@storybook/addon-actions": "^8.2.9",
50
+ "@storybook/addon-essentials": "^8.2.9",
51
+ "@storybook/addon-links": "^8.2.9",
52
+ "@storybook/builder-webpack5": "^8.2.9",
53
+ "@storybook/manager-webpack5": "^6.5.16",
54
+ "@storybook/react": "^8.2.9",
55
+ "@testing-library/jest-dom": "^6.5.0",
56
+ "@testing-library/react": "^16.0.1",
57
+ "@types/jest": "^29.5.12",
58
+ "@types/node": "^22.5.4",
59
+ "@types/react": "^18.3.5",
60
+ "@types/react-dom": "^18.3.0",
61
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
62
+ "@typescript-eslint/parser": "^7.18.0",
63
+ "babel-loader": "^9.1.3",
64
64
  "eslint": "^8.57.0",
65
- "jest": "^29.0.0",
66
- "jest-environment-jsdom": "^29.0.0",
67
- "jest-environment-node": "^29.0.0",
68
- "react": "^18.2.0",
69
- "react-dom": "^18.2.0",
70
- "ts-node": "^10.8.1",
71
- "typescript": "^5.0.0",
72
- "webpack": "^5.75.0"
65
+ "jest": "^29.7.0",
66
+ "jest-environment-jsdom": "^29.7.0",
67
+ "jest-environment-node": "^29.7.0",
68
+ "react": "^18.3.1",
69
+ "react-dom": "^18.3.1",
70
+ "ts-node": "^10.9.2",
71
+ "typescript": "^5.6.2",
72
+ "webpack": "^5.94.0"
73
73
  },
74
74
  "files": [
75
75
  "**/*.js",
@@ -0,0 +1,22 @@
1
+ import {hash} from './hash';
2
+
3
+ describe('hash', () => {
4
+ it('should generate a hash from a string', () => {
5
+ const result = hash('foo');
6
+
7
+ expect(result).toEqual('18cc6');
8
+ expect(result).toEqual(hash('foo'));
9
+ });
10
+
11
+ it('should handle special characters', () => {
12
+ expect(hash('✨')).toEqual('2728');
13
+ expect(hash('💥')).toEqual('d83d');
14
+ expect(hash('✨💥')).toEqual('59615');
15
+ });
16
+
17
+ it('should generate a hash from an empty string', () => {
18
+ const result = hash('');
19
+
20
+ expect(result).toEqual('0');
21
+ });
22
+ });
package/src/hash.ts ADDED
@@ -0,0 +1,12 @@
1
+ export function hash(value: string): string {
2
+ let code = 0;
3
+
4
+ for (const char of value) {
5
+ const charCode = char.charCodeAt(0);
6
+
7
+ code = (code << 5) - code + charCode;
8
+ code |= 0; // Convert to 32bit integer
9
+ }
10
+
11
+ return code.toString(16);
12
+ }
@@ -18,6 +18,6 @@ describe('useContent (SSR)', () => {
18
18
 
19
19
  it('should require an initial value for server-side rending', () => {
20
20
  expect(() => useContent('slot-id'))
21
- .toThrow(new Error('The initial value is required for server-side rendering (SSR).'));
21
+ .toThrow('The initial content is required for server-side rendering (SSR).');
22
22
  });
23
23
  });
@@ -3,6 +3,7 @@ import {Plug} from '@croct/plug';
3
3
  import {useCroct} from './useCroct';
4
4
  import {useLoader} from './useLoader';
5
5
  import {useContent} from './useContent';
6
+ import {hash} from '../hash';
6
7
 
7
8
  jest.mock(
8
9
  './useCroct',
@@ -30,11 +31,15 @@ describe('useContent (CSR)', () => {
30
31
  jest.mocked(useLoader).mockReturnValue('foo');
31
32
 
32
33
  const slotId = 'home-banner@1';
34
+ const preferredLocale = 'en';
35
+ const attributes = {example: 'value'};
36
+ const cacheKey = 'unique';
33
37
 
34
38
  const {result} = renderHook(
35
39
  () => useContent<{title: string}>(slotId, {
36
- preferredLocale: 'en',
37
- cacheKey: 'unique',
40
+ preferredLocale: preferredLocale,
41
+ attributes: attributes,
42
+ cacheKey: cacheKey,
38
43
  fallback: {
39
44
  title: 'error',
40
45
  },
@@ -44,7 +49,7 @@ describe('useContent (CSR)', () => {
44
49
 
45
50
  expect(useCroct).toHaveBeenCalled();
46
51
  expect(useLoader).toHaveBeenCalledWith({
47
- cacheKey: `useContent:unique:${slotId}`,
52
+ cacheKey: hash(`useContent:${cacheKey}:${slotId}:${preferredLocale}:${JSON.stringify(attributes)}`),
48
53
  fallback: {
49
54
  title: 'error',
50
55
  },
@@ -59,6 +64,7 @@ describe('useContent (CSR)', () => {
59
64
 
60
65
  expect(fetch).toHaveBeenCalledWith(slotId, {
61
66
  preferredLocale: 'en',
67
+ attributes: attributes,
62
68
  });
63
69
 
64
70
  expect(result.current).toBe('foo');
@@ -4,6 +4,7 @@ import {FetchOptions} from '@croct/plug/plug';
4
4
  import {useLoader} from './useLoader';
5
5
  import {useCroct} from './useCroct';
6
6
  import {isSsr} from '../ssr-polyfills';
7
+ import {hash} from '../hash';
7
8
 
8
9
  export type UseContentOptions<I, F> = FetchOptions & {
9
10
  fallback?: F,
@@ -17,10 +18,16 @@ function useCsrContent<I, F>(
17
18
  options: UseContentOptions<I, F> = {},
18
19
  ): SlotContent | I | F {
19
20
  const {fallback, initial, cacheKey, expiration, ...fetchOptions} = options;
21
+ const {preferredLocale} = fetchOptions;
20
22
  const croct = useCroct();
21
23
 
22
24
  return useLoader({
23
- cacheKey: `useContent:${cacheKey ?? ''}:${id}`,
25
+ cacheKey: hash(
26
+ `useContent:${cacheKey ?? ''}`
27
+ + `:${id}`
28
+ + `:${preferredLocale ?? ''}`
29
+ + `:${JSON.stringify(fetchOptions.attributes ?? '')}`,
30
+ ),
24
31
  loader: () => croct.fetch(id, fetchOptions).then(({content}) => content),
25
32
  initial: initial,
26
33
  fallback: fallback,
@@ -33,7 +40,10 @@ function useSsrContent<I, F>(
33
40
  {initial}: UseContentOptions<I, F> = {},
34
41
  ): SlotContent | I | F {
35
42
  if (initial === undefined) {
36
- throw new Error('The initial value is required for server-side rendering (SSR).');
43
+ throw new Error(
44
+ 'The initial content is required for server-side rendering (SSR). '
45
+ + 'For help, see https://croct.help/sdk/react/missing-slot-content',
46
+ );
37
47
  }
38
48
 
39
49
  return initial;
@@ -6,7 +6,10 @@ export function useCroct(): Plug {
6
6
  const context = useContext(CroctContext);
7
7
 
8
8
  if (context === null) {
9
- throw new Error('useCroct() can only be used in the context of a <CroctProvider> component.');
9
+ throw new Error(
10
+ 'useCroct() can only be used in the context of a <CroctProvider> component. '
11
+ + 'For help, see https://croct.help/sdk/react/missing-provider',
12
+ );
10
13
  }
11
14
 
12
15
  return context.plug;
@@ -18,6 +18,6 @@ describe('useEvaluation (SSR)', () => {
18
18
 
19
19
  it('should require an initial value for server-side rending', () => {
20
20
  expect(() => useEvaluation('location'))
21
- .toThrow(new Error('The initial value is required for server-side rendering (SSR).'));
21
+ .toThrow('The initial value is required for server-side rendering (SSR).');
22
22
  });
23
23
  });
@@ -4,6 +4,7 @@ import {Plug} from '@croct/plug';
4
4
  import {useEvaluation} from './useEvaluation';
5
5
  import {useCroct} from './useCroct';
6
6
  import {useLoader} from './useLoader';
7
+ import {hash} from '../hash';
7
8
 
8
9
  jest.mock(
9
10
  './useCroct',
@@ -39,11 +40,12 @@ describe('useEvaluation', () => {
39
40
  jest.mocked(useLoader).mockReturnValue('foo');
40
41
 
41
42
  const query = 'location';
43
+ const cacheKey = 'unique';
42
44
 
43
45
  const {result} = renderHook(
44
46
  () => useEvaluation(query, {
45
47
  ...evaluationOptions,
46
- cacheKey: 'unique',
48
+ cacheKey: cacheKey,
47
49
  fallback: 'error',
48
50
  expiration: 50,
49
51
  }),
@@ -51,7 +53,7 @@ describe('useEvaluation', () => {
51
53
 
52
54
  expect(useCroct).toHaveBeenCalled();
53
55
  expect(useLoader).toHaveBeenCalledWith({
54
- cacheKey: 'useEvaluation:unique:location:{"foo":"bar"}',
56
+ cacheKey: hash(`useEvaluation:${cacheKey}:${query}:${JSON.stringify(evaluationOptions.attributes)}`),
55
57
  fallback: 'error',
56
58
  expiration: 50,
57
59
  loader: expect.any(Function),
@@ -3,6 +3,7 @@ import {EvaluationOptions} from '@croct/sdk/facade/evaluatorFacade';
3
3
  import {useLoader} from './useLoader';
4
4
  import {useCroct} from './useCroct';
5
5
  import {isSsr} from '../ssr-polyfills';
6
+ import {hash} from '../hash';
6
7
 
7
8
  function cleanEvaluationOptions(options: EvaluationOptions): EvaluationOptions {
8
9
  const result: EvaluationOptions = {};
@@ -36,7 +37,11 @@ function useCsrEvaluation<T = JsonValue, I = T, F = T>(
36
37
  const croct = useCroct();
37
38
 
38
39
  return useLoader<T | I | F>({
39
- cacheKey: `useEvaluation:${cacheKey ?? ''}:${query}:${JSON.stringify(options.attributes ?? '')}`,
40
+ cacheKey: hash(
41
+ `useEvaluation:${cacheKey ?? ''}`
42
+ + `:${query}`
43
+ + `:${JSON.stringify(options.attributes ?? '')}`,
44
+ ),
40
45
  loader: () => croct.evaluate<T & JsonValue>(query, cleanEvaluationOptions(evaluationOptions)),
41
46
  initial: initial,
42
47
  fallback: fallback,
@@ -49,7 +54,10 @@ function useSsrEvaluation<T = JsonValue, I = T, F = T>(
49
54
  {initial}: UseEvaluationOptions<I, F> = {},
50
55
  ): T | I | F {
51
56
  if (initial === undefined) {
52
- throw new Error('The initial value is required for server-side rendering (SSR).');
57
+ throw new Error(
58
+ 'The initial value is required for server-side rendering (SSR). '
59
+ + 'For help, see https://croct.help/sdk/react/missing-evaluation-result',
60
+ );
53
61
  }
54
62
 
55
63
  return initial;
@@ -62,7 +62,8 @@ export const croct: Plug = !isSsr()
62
62
  throw new Error(
63
63
  `Property croct.${String(property)} is not supported on server-side (SSR). `
64
64
  + 'Consider refactoring the logic as a side-effect (useEffect) or a client-side callback '
65
- + '(onClick, onChange, etc).',
65
+ + '(onClick, onChange, etc). '
66
+ + 'For help, see https://croct.help/sdk/react/client-logic-ssr',
66
67
  );
67
68
  }
68
69
  },
package/ssr-polyfills.js CHANGED
@@ -3,7 +3,8 @@ 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.croct = exports.isSsr = void 0;
6
+ exports.croct = void 0;
7
+ exports.isSsr = isSsr;
7
8
  const plug_1 = __importDefault(require("@croct/plug"));
8
9
  function isSsr() {
9
10
  // eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- The window can be undefined.
@@ -11,7 +12,6 @@ function isSsr() {
11
12
  || typeof window.document === 'undefined'
12
13
  || typeof window.document.createElement === 'undefined';
13
14
  }
14
- exports.isSsr = isSsr;
15
15
  exports.croct = !isSsr()
16
16
  ? (function factory() {
17
17
  let timeoutId = null;
@@ -58,7 +58,8 @@ exports.croct = !isSsr()
58
58
  default:
59
59
  throw new Error(`Property croct.${String(property)} is not supported on server-side (SSR). `
60
60
  + 'Consider refactoring the logic as a side-effect (useEffect) or a client-side callback '
61
- + '(onClick, onChange, etc).');
61
+ + '(onClick, onChange, etc). '
62
+ + 'For help, see https://croct.help/sdk/react/client-logic-ssr');
62
63
  }
63
64
  },
64
65
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-polyfills.js","sourceRoot":"","sources":["src/ssr-polyfills.ts"],"names":[],"mappings":";;;;;;AAAA,uDAA0C;AAE1C,SAAgB,KAAK;IACjB,oGAAoG;IACpG,OAAO,OAAO,MAAM,KAAK,WAAW;WAC7B,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW;WACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,KAAK,WAAW,CAAC;AAChE,CAAC;AALD,sBAKC;AAEY,QAAA,KAAK,GAAS,CAAC,KAAK,EAAE;IAC/B,CAAC,CAAC,CAAC,SAAS,OAAO;QACf,IAAI,SAAS,GAAuC,IAAI,CAAC;QACzD,IAAI,eAA2B,CAAC;QAChC,IAAI,cAAqC,CAAC;QAE1C,OAAO,IAAI,KAAK,CAAC,cAAO,EAAE;YACtB,GAAG,EAAE,SAAS,WAAW,CAAC,MAAM,EAAE,QAAoB;gBAClD,QAAQ,QAAQ,EAAE,CAAC;oBACf,KAAK,MAAM;wBACP,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;4BACrB,YAAY,CAAC,SAAS,CAAC,CAAC;4BACxB,SAAS,GAAG,IAAI,CAAC;4BACjB,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;wBACrD,CAAC;wBAED,MAAM;oBAEV,KAAK,QAAQ;wBACT,OAAO,GAAG,EAAE;4BACR,+EAA+E;4BAC/E,sFAAsF;4BACtF,oFAAoF;4BACpF,+DAA+D;4BAC/D,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,CAAC;4BAEzF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gCACzC,eAAe,GAAG,OAAO,CAAC;gCAC1B,cAAc,GAAG,MAAM,CAAC;4BAC5B,CAAC,CAAC,CAAC;wBACP,CAAC,CAAC;gBACV,CAAC;gBAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC,EAAE,CAAC;IACJ,CAAC,CAAC,IAAI,KAAK,CAAC,cAAO,EAAE;QACjB,GAAG,EAAE,SAAS,WAAW,CAAC,CAAC,EAAE,QAAoB;YAC7C,QAAQ,QAAQ,EAAE,CAAC;gBACf,KAAK,aAAa;oBACd,OAAO,KAAK,CAAC;gBAEjB,KAAK,MAAM;oBACP,OAAO,GAAG,EAAE;wBACR,QAAQ;oBACZ,CAAC,CAAC;gBAEN,KAAK,QAAQ;oBACT,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEnC;oBACI,MAAM,IAAI,KAAK,CACX,kBAAkB,MAAM,CAAC,QAAQ,CAAC,0CAA0C;0BAC1E,yFAAyF;0BACzF,2BAA2B,CAChC,CAAC;YACV,CAAC;QACL,CAAC;KACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"ssr-polyfills.js","sourceRoot":"","sources":["src/ssr-polyfills.ts"],"names":[],"mappings":";;;;;;AAEA,sBAKC;AAPD,uDAA0C;AAE1C,SAAgB,KAAK;IACjB,oGAAoG;IACpG,OAAO,OAAO,MAAM,KAAK,WAAW;WAC7B,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW;WACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,KAAK,WAAW,CAAC;AAChE,CAAC;AAEY,QAAA,KAAK,GAAS,CAAC,KAAK,EAAE;IAC/B,CAAC,CAAC,CAAC,SAAS,OAAO;QACf,IAAI,SAAS,GAAuC,IAAI,CAAC;QACzD,IAAI,eAA2B,CAAC;QAChC,IAAI,cAAqC,CAAC;QAE1C,OAAO,IAAI,KAAK,CAAC,cAAO,EAAE;YACtB,GAAG,EAAE,SAAS,WAAW,CAAC,MAAM,EAAE,QAAoB;gBAClD,QAAQ,QAAQ,EAAE,CAAC;oBACf,KAAK,MAAM;wBACP,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;4BACrB,YAAY,CAAC,SAAS,CAAC,CAAC;4BACxB,SAAS,GAAG,IAAI,CAAC;4BACjB,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;wBACrD,CAAC;wBAED,MAAM;oBAEV,KAAK,QAAQ;wBACT,OAAO,GAAG,EAAE;4BACR,+EAA+E;4BAC/E,sFAAsF;4BACtF,oFAAoF;4BACpF,+DAA+D;4BAC/D,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,CAAC;4BAEzF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gCACzC,eAAe,GAAG,OAAO,CAAC;gCAC1B,cAAc,GAAG,MAAM,CAAC;4BAC5B,CAAC,CAAC,CAAC;wBACP,CAAC,CAAC;gBACV,CAAC;gBAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC,EAAE,CAAC;IACJ,CAAC,CAAC,IAAI,KAAK,CAAC,cAAO,EAAE;QACjB,GAAG,EAAE,SAAS,WAAW,CAAC,CAAC,EAAE,QAAoB;YAC7C,QAAQ,QAAQ,EAAE,CAAC;gBACf,KAAK,aAAa;oBACd,OAAO,KAAK,CAAC;gBAEjB,KAAK,MAAM;oBACP,OAAO,GAAG,EAAE;wBACR,QAAQ;oBACZ,CAAC,CAAC;gBAEN,KAAK,QAAQ;oBACT,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEnC;oBACI,MAAM,IAAI,KAAK,CACX,kBAAkB,MAAM,CAAC,QAAQ,CAAC,0CAA0C;0BAC1E,yFAAyF;0BACzF,4BAA4B;0BAC5B,6DAA6D,CAClE,CAAC;YACV,CAAC;QACL,CAAC;KACJ,CAAC,CAAC"}