@croct/plug-react 0.4.0 → 0.4.1
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/CroctProvider.d.ts +2 -2
- package/README.md +91 -41
- package/index.js +25 -19
- package/index.js.map +1 -0
- package/package.json +41 -36
- package/index.modern.js +0 -308
package/CroctProvider.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
1
|
+
import { FunctionComponent, PropsWithChildren } from 'react';
|
|
2
2
|
import { Configuration, Plug } from '@croct/plug';
|
|
3
|
-
export declare type CroctProviderProps = Configuration & Required<Pick<Configuration, 'appId'
|
|
3
|
+
export declare type CroctProviderProps = PropsWithChildren<Configuration & Required<Pick<Configuration, 'appId'>>>;
|
|
4
4
|
export declare const CroctContext: import("react").Context<{
|
|
5
5
|
plug: Plug;
|
|
6
6
|
} | null>;
|
package/README.md
CHANGED
|
@@ -33,16 +33,16 @@ The React Plug library provides components and hooks for personalizing applicati
|
|
|
33
33
|
- **Blazing-fast queries**: double-digit millisecond latency for real-time evaluations.
|
|
34
34
|
- **Playground integration**: one-click to connect, no configuration needed.
|
|
35
35
|
|
|
36
|
-
Check out the [Storybook](https://croct-tech.github.io/plug-react) to see some minimal examples in action,
|
|
36
|
+
Check out the [Storybook](https://croct-tech.github.io/plug-react) to see some minimal examples in action,
|
|
37
37
|
or the [example folder](examples) for full code examples.
|
|
38
38
|
|
|
39
39
|
## Getting Started
|
|
40
40
|
|
|
41
41
|
The following steps will walk you through installing the library and integrating it into your application.
|
|
42
42
|
|
|
43
|
-
This guide assumes you're already familiar with some key concepts and tools around Croct, like
|
|
44
|
-
Contextual Query Language (CQL) and the playground. If you're not,
|
|
45
|
-
[this 15-minute quickstart](https://croct.link/plug-js/quick-start) that will give you a hands-on overview of
|
|
43
|
+
This guide assumes you're already familiar with some key concepts and tools around Croct, like
|
|
44
|
+
Contextual Query Language (CQL) and the playground. If you're not,
|
|
45
|
+
[this 15-minute quickstart](https://croct.link/plug-js/quick-start) that will give you a hands-on overview of
|
|
46
46
|
all the terms and tools you need to get started.
|
|
47
47
|
|
|
48
48
|
### Installation
|
|
@@ -57,10 +57,10 @@ npm install @croct/plug-react
|
|
|
57
57
|
|
|
58
58
|
### Plugging in
|
|
59
59
|
|
|
60
|
-
You connect Croct to React with the `<CroctProvider
|
|
60
|
+
You connect Croct to React with the `<CroctProvider />` component. The `<CroctProvider />` uses a regular React's
|
|
61
61
|
`<Context.Provider />` to wrap your React app and make the SDK available anywhere in your component tree.
|
|
62
62
|
|
|
63
|
-
We suggest putting the `<CroctProvider
|
|
63
|
+
We suggest putting the `<CroctProvider />` somewhere high in your app, above any component that might be personalized,
|
|
64
64
|
ideally in the top-level `<App/>` component.
|
|
65
65
|
|
|
66
66
|
```tsx
|
|
@@ -69,7 +69,7 @@ import {CroctProvider} from '@croct/plug-react';
|
|
|
69
69
|
|
|
70
70
|
function App() {
|
|
71
71
|
return (
|
|
72
|
-
<CroctProvider appId="
|
|
72
|
+
<CroctProvider appId="<APP_ID>">
|
|
73
73
|
<div>
|
|
74
74
|
<h1>My first personalized app 🚀</h1>
|
|
75
75
|
</div>
|
|
@@ -80,6 +80,9 @@ function App() {
|
|
|
80
80
|
render(<App />, document.getElementById('root'));
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
> Replace `<APP_ID>` with your public app ID that you can find at Workspaces > Applications > Setup.
|
|
84
|
+
> In case you don't have an account yet, you can use the sandbox application ID `00000000-0000-0000-0000-000000000000`
|
|
85
|
+
|
|
83
86
|
### Evaluating expressions
|
|
84
87
|
|
|
85
88
|
Once your application is plugged in, you're ready to start personalizing your components using the `<Personalization />`
|
|
@@ -90,7 +93,7 @@ to conditionally renders a different button depending on the user's persona.
|
|
|
90
93
|
|
|
91
94
|

|
|
92
95
|
|
|
93
|
-
Let's first implement the use-case using the `<Personalization/>` component. It takes an expression (e.g. `user's persona`)
|
|
96
|
+
Let's first implement the use-case using the `<Personalization />` component. It takes an expression (e.g. `user's persona`)
|
|
94
97
|
and a render function, which tells the component how to render the UI, depending on the evaluation result.
|
|
95
98
|
|
|
96
99
|
This is what our component would look like:
|
|
@@ -156,9 +159,9 @@ export default function OnboardingPage(): ReactElement {
|
|
|
156
159
|
}
|
|
157
160
|
```
|
|
158
161
|
|
|
159
|
-
If you run the application and there is no persona assigned to your profile, you will see the button for non-developers
|
|
162
|
+
If you run the application and there is no persona assigned to your profile, you will see the button for non-developers
|
|
160
163
|
— otherwise, the button for sharing the code with developers.
|
|
161
|
-
Check out [Accessing the Plug instance](#accessing-the-plug-instance) for an example of how to save information in a
|
|
164
|
+
Check out [Accessing the Plug instance](#accessing-the-plug-instance) for an example of how to save information in a
|
|
162
165
|
user's profile.
|
|
163
166
|
|
|
164
167
|
#### Fault tolerance
|
|
@@ -183,7 +186,7 @@ export default function OnboardingPage(): ReactElement {
|
|
|
183
186
|
return (
|
|
184
187
|
<Suspense fallback="✨ Personalizing...">
|
|
185
188
|
{/* Using the <Personalization /> component */}
|
|
186
|
-
<Personalization expression="user's persona is 'developer'"
|
|
189
|
+
<Personalization expression="user's persona is 'developer'" fallback={false}>
|
|
187
190
|
{(isDeveloper: boolean) => (
|
|
188
191
|
<Fragment>
|
|
189
192
|
{isDeveloper && <a href="/docs">View docs</a>}
|
|
@@ -202,23 +205,23 @@ For a full list of the available options, please refer to the [API documentation
|
|
|
202
205
|
|
|
203
206
|
### Using slots
|
|
204
207
|
|
|
205
|
-
Evaluating expression is a flexible and powerful way to customize your UI. However, for components whose content
|
|
206
|
-
changes too often, this approach can be overkill. For those cases, we encourage you to use the Slots feature instead.
|
|
207
|
-
Using slots gives your team the flexibility to change the content or personalization rules whenever needed without
|
|
208
|
+
Evaluating expression is a flexible and powerful way to customize your UI. However, for components whose content
|
|
209
|
+
changes too often, this approach can be overkill. For those cases, we encourage you to use the Slots feature instead.
|
|
210
|
+
Using slots gives your team the flexibility to change the content or personalization rules whenever needed without
|
|
208
211
|
touching the component code.
|
|
209
212
|
|
|
210
213
|

|
|
211
214
|
|
|
212
|
-
To render a slot, all you need to do is provide the `id` you configured in your Croct workspace. Based on the
|
|
213
|
-
slot's personalization rules and the user's context, the component will decide which content show to that user.
|
|
214
|
-
Notice that there's no logic on the client-side, meaning that your marketing or product team can freely change the
|
|
215
|
+
To render a slot, all you need to do is provide the `id` you configured in your Croct workspace. Based on the
|
|
216
|
+
slot's personalization rules and the user's context, the component will decide which content show to that user.
|
|
217
|
+
Notice that there's no logic on the client-side, meaning that your marketing or product team can freely change the
|
|
215
218
|
slot content as they need without requiring an update to your React app.
|
|
216
219
|
|
|
217
|
-
For the next example, we assume that you have already defined a slot with id `home-banner` in your Croct workspace
|
|
220
|
+
For the next example, we assume that you have already defined a slot with id `home-banner` in your Croct workspace
|
|
218
221
|
with the following structure:
|
|
219
222
|
|
|
220
223
|
```ts
|
|
221
|
-
type
|
|
224
|
+
type HomeBannerContent = {
|
|
222
225
|
title: string,
|
|
223
226
|
subtitle: string,
|
|
224
227
|
cta: {
|
|
@@ -236,11 +239,20 @@ Here's how to use the `<Slot />` component:
|
|
|
236
239
|
import {ReactElement, Suspense} from 'react';
|
|
237
240
|
import {Slot} from '@croct/plug-react';
|
|
238
241
|
|
|
242
|
+
type HomeBannerContent = {
|
|
243
|
+
title: string,
|
|
244
|
+
subtitle: string,
|
|
245
|
+
cta: {
|
|
246
|
+
label: string,
|
|
247
|
+
link: string,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
|
|
239
251
|
export default function OnboardingPage(): ReactElement {
|
|
240
252
|
return (
|
|
241
253
|
<Suspense fallback="✨ Personalizing content...">
|
|
242
254
|
<Slot id="home-banner">
|
|
243
|
-
{({title, subtitle, cta}:
|
|
255
|
+
{({title, subtitle, cta}: HomeBannerContent) => (
|
|
244
256
|
<div>
|
|
245
257
|
<strong>{title}</strong>
|
|
246
258
|
<p>{subtitle}</p>
|
|
@@ -259,17 +271,26 @@ To avoid the component from suspending while loading, you can provide an `initia
|
|
|
259
271
|
import {ReactElement} from 'react';
|
|
260
272
|
import {Slot} from '@croct/plug-react';
|
|
261
273
|
|
|
274
|
+
type HomeBannerContent = {
|
|
275
|
+
title: string,
|
|
276
|
+
subtitle: string,
|
|
277
|
+
cta: {
|
|
278
|
+
label: string,
|
|
279
|
+
link: string,
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
|
|
262
283
|
export default function OnboardingPage(): ReactElement {
|
|
263
284
|
return (
|
|
264
285
|
<Slot id="home-banner" initial={null}>
|
|
265
|
-
{(props:
|
|
286
|
+
{(props: HomeBannerContent|null) => (
|
|
266
287
|
props === null
|
|
267
288
|
? '✨ Personalizing...'
|
|
268
289
|
: (
|
|
269
290
|
<div>
|
|
270
|
-
<strong>{title}</strong>
|
|
271
|
-
<p>{subtitle}</p>
|
|
272
|
-
<a href={cta.link}>{cta.label}</a>
|
|
291
|
+
<strong>{props.title}</strong>
|
|
292
|
+
<p>{props.subtitle}</p>
|
|
293
|
+
<a href={props.cta.link}>{props.cta.label}</a>
|
|
273
294
|
</div>
|
|
274
295
|
)
|
|
275
296
|
)}
|
|
@@ -284,8 +305,17 @@ And here's an example using the `useContent` hook:
|
|
|
284
305
|
import {ReactElement, Suspense} from 'react';
|
|
285
306
|
import {useContent} from '@croct/plug-react';
|
|
286
307
|
|
|
308
|
+
type HomeBannerContent = {
|
|
309
|
+
title: string,
|
|
310
|
+
subtitle: string,
|
|
311
|
+
cta: {
|
|
312
|
+
label: string,
|
|
313
|
+
link: string,
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
|
|
287
317
|
function HomeBanner(): ReactElement {
|
|
288
|
-
const
|
|
318
|
+
const {title, subtitle, cta} = useContent<HomeBannerContent>('home-banner');
|
|
289
319
|
|
|
290
320
|
return (
|
|
291
321
|
<div>
|
|
@@ -313,7 +343,16 @@ The following example shows how you can specify a fallback state for the `home-b
|
|
|
313
343
|
import {ReactElement, Suspense} from 'react';
|
|
314
344
|
import {Slot, useContent} from '@croct/plug-react';
|
|
315
345
|
|
|
316
|
-
|
|
346
|
+
type HomeBannerContent = {
|
|
347
|
+
title: string,
|
|
348
|
+
subtitle: string,
|
|
349
|
+
cta: {
|
|
350
|
+
label: string,
|
|
351
|
+
link: string,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const fallbackBanner: HomeBannerContent = {
|
|
317
356
|
title: 'Default title',
|
|
318
357
|
subtitle: 'Default subtitle',
|
|
319
358
|
cta: {
|
|
@@ -323,7 +362,7 @@ const fallbackBanner: HomeBanner = {
|
|
|
323
362
|
};
|
|
324
363
|
|
|
325
364
|
function HomeBanner(): ReactElement {
|
|
326
|
-
const {title, subtitle, cta} = useContent<
|
|
365
|
+
const {title, subtitle, cta} = useContent<HomeBannerContent>('home-banner', {fallback: fallbackBanner});
|
|
327
366
|
|
|
328
367
|
return (
|
|
329
368
|
<div>
|
|
@@ -339,7 +378,7 @@ export default function HomePage(): ReactElement {
|
|
|
339
378
|
<Suspense fallback="Personalizing content...">
|
|
340
379
|
{/* Using the <Slot /> component */}
|
|
341
380
|
<Slot id="home-banner" fallback={fallbackBanner}>
|
|
342
|
-
{({title, subtitle, cta}:
|
|
381
|
+
{({title, subtitle, cta}: HomeBannerContent) => (
|
|
343
382
|
<div>
|
|
344
383
|
<strong>{title}</strong>
|
|
345
384
|
<p>{subtitle}</p>
|
|
@@ -355,15 +394,15 @@ export default function HomePage(): ReactElement {
|
|
|
355
394
|
}
|
|
356
395
|
```
|
|
357
396
|
|
|
358
|
-
Again, we strongly recommend always providing a value for the `fallback` property. For a full list of the available options,
|
|
397
|
+
Again, we strongly recommend always providing a value for the `fallback` property. For a full list of the available options,
|
|
359
398
|
please refer to the [API documentation](#component-api-reference).
|
|
360
399
|
|
|
361
400
|
#### 💡 ProTip
|
|
362
401
|
|
|
363
|
-
In the previous examples, you may have noticed that we specified the content type in the `userFetch` call and in the
|
|
364
|
-
`<Slot />` component's render function to have the benefit of strong typing.
|
|
402
|
+
In the previous examples, you may have noticed that we specified the content type in the `userFetch` call and in the
|
|
403
|
+
`<Slot />` component's render function to have the benefit of strong typing.
|
|
365
404
|
|
|
366
|
-
For an even more robust approach, you can also declare the type of all available slots in a single declaration file
|
|
405
|
+
For an even more robust approach, you can also declare the type of all available slots in a single declaration file
|
|
367
406
|
using module augmentation as follows:
|
|
368
407
|
|
|
369
408
|
```ts
|
|
@@ -385,16 +424,16 @@ slot IDs and content properties as a bonus:
|
|
|
385
424
|
|
|
386
425
|
### Server-side rendering
|
|
387
426
|
|
|
388
|
-
You can use the same components and hooks on the server-side by simply providing an `initial` state which is used to
|
|
389
|
-
pre-render on the server - the personalization happens transparently on the client during the initial render.
|
|
427
|
+
You can use the same components and hooks on the server-side by simply providing an `initial` state which is used to
|
|
428
|
+
pre-render on the server - the personalization happens transparently on the client during the initial render.
|
|
390
429
|
That means it's SEO friendly and can be cached with no performance overhead.
|
|
391
430
|
|
|
392
|
-
Notice that the methods exposed by the Plug work only on the client-side. Therefore, if you are using [`useCroct`](#usecroct),
|
|
431
|
+
Notice that the methods exposed by the Plug work only on the client-side. Therefore, if you are using [`useCroct`](#usecroct),
|
|
393
432
|
the operations have to be executed inside the `useEffect` hook or client-side callbacks, such as `onClick` or `onChange`, for example.
|
|
394
433
|
|
|
395
434
|
### Accessing the Plug instance
|
|
396
435
|
|
|
397
|
-
This library is built on top of the PlugJS. You can access the Plug instance through the `useCroct` hook to track events,
|
|
436
|
+
This library is built on top of the PlugJS. You can access the Plug instance through the `useCroct` hook to track events,
|
|
398
437
|
login and logout users, and more.
|
|
399
438
|
|
|
400
439
|
In the following example we use the `useCroct` to get the Plug instance and set an attribute to the user profile:
|
|
@@ -423,7 +462,7 @@ This reference documents all components available in the library.
|
|
|
423
462
|
### <CroctProvider />
|
|
424
463
|
|
|
425
464
|
The `<CroctProvider />` component leverages [React's Context API](https://reactjs.org/docs/context.html) to
|
|
426
|
-
make a configured [Plug instance](https://github.com/croct-tech/plug-js/blob/master/docs/plug.md) available throughout
|
|
465
|
+
make a configured [Plug instance](https://github.com/croct-tech/plug-js/blob/master/docs/plug.md) available throughout
|
|
427
466
|
a React component tree.
|
|
428
467
|
|
|
429
468
|
#### Properties
|
|
@@ -454,7 +493,7 @@ import {CroctProvider} from '@croct/plug-react';
|
|
|
454
493
|
|
|
455
494
|
function App() {
|
|
456
495
|
return (
|
|
457
|
-
<CroctProvider appId="
|
|
496
|
+
<CroctProvider appId="<APP_ID>">
|
|
458
497
|
<div>
|
|
459
498
|
<h1>My first personalized app 🚀</h1>
|
|
460
499
|
</div>
|
|
@@ -463,6 +502,8 @@ function App() {
|
|
|
463
502
|
}
|
|
464
503
|
```
|
|
465
504
|
|
|
505
|
+
> Replace "<APP_ID>" with your public app ID that you can find at Workspaces > Applications > API Keys.
|
|
506
|
+
|
|
466
507
|
### <Personalization />
|
|
467
508
|
|
|
468
509
|
The `<Personalization />` component evaluates and renders a CQL query.
|
|
@@ -586,7 +627,7 @@ These are the currently supported options:
|
|
|
586
627
|
|
|
587
628
|
| Option | Type | Description
|
|
588
629
|
|--------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
589
|
-
| `fallback` | Result | The value returned when the evaluation fails. If not specified, the hook will throw an exception in case of failures.
|
|
630
|
+
| `fallback` | Result | The value returned when the evaluation fails. If not specified, the hook will throw an exception in case of failures.
|
|
590
631
|
| `timeout` | number | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail.
|
|
591
632
|
| `attributes` | JSON | The map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in expressions like `context's cities include location's city`.
|
|
592
633
|
| `cacheKey` | string | An identifier that allows keeping the cached result separate from other cached items. By default, the cache key is formed from the expression and attributes.
|
|
@@ -635,8 +676,17 @@ Here's a simple example showing how to fetch the content for a banner:
|
|
|
635
676
|
import {ReactElement} from 'react';
|
|
636
677
|
import {useContent} from '@croct/plug-react';
|
|
637
678
|
|
|
638
|
-
|
|
639
|
-
|
|
679
|
+
type HomeBannerContent = {
|
|
680
|
+
title: string,
|
|
681
|
+
subtitle: string,
|
|
682
|
+
cta: {
|
|
683
|
+
label: string,
|
|
684
|
+
link: string,
|
|
685
|
+
},
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
export default function HeroBanner(): ReactElement {
|
|
689
|
+
const {title, subtitle} = useContent<HomeBannerContent>('hero');
|
|
640
690
|
|
|
641
691
|
return (
|
|
642
692
|
<div>
|
package/index.js
CHANGED
|
@@ -24,7 +24,7 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
24
24
|
function isSsr() {
|
|
25
25
|
return typeof window === 'undefined';
|
|
26
26
|
}
|
|
27
|
-
var croct = !isSsr() ? csrPlug__default[
|
|
27
|
+
var croct = !isSsr() ? csrPlug__default["default"] : new Proxy(csrPlug__default["default"], {
|
|
28
28
|
get(_, property) {
|
|
29
29
|
switch (property) {
|
|
30
30
|
case 'initialized':
|
|
@@ -44,13 +44,14 @@ var croct = !isSsr() ? csrPlug__default['default'] : new Proxy(csrPlug__default[
|
|
|
44
44
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
var _excluded$4 = ["children"];
|
|
47
48
|
var CroctContext = /*#__PURE__*/react.createContext(null);
|
|
48
49
|
CroctContext.displayName = 'CroctContext';
|
|
49
50
|
var CroctProvider = _ref => {
|
|
50
51
|
var {
|
|
51
52
|
children
|
|
52
53
|
} = _ref,
|
|
53
|
-
configuration = _objectWithoutPropertiesLoose(_ref,
|
|
54
|
+
configuration = _objectWithoutPropertiesLoose(_ref, _excluded$4);
|
|
54
55
|
|
|
55
56
|
var parent = react.useContext(CroctContext);
|
|
56
57
|
|
|
@@ -74,11 +75,10 @@ var CroctProvider = _ref => {
|
|
|
74
75
|
croct.unplug();
|
|
75
76
|
};
|
|
76
77
|
}, []);
|
|
77
|
-
return jsxRuntime.jsx(CroctContext.Provider,
|
|
78
|
-
value: context
|
|
79
|
-
}, {
|
|
78
|
+
return jsxRuntime.jsx(CroctContext.Provider, {
|
|
79
|
+
value: context,
|
|
80
80
|
children: children
|
|
81
|
-
})
|
|
81
|
+
});
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
class Cache {
|
|
@@ -154,6 +154,7 @@ class Cache {
|
|
|
154
154
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
var _excluded$3 = ["initial"];
|
|
157
158
|
var cache = new Cache(60 * 1000);
|
|
158
159
|
function useLoader(_ref) {
|
|
159
160
|
var _cache$get;
|
|
@@ -161,7 +162,7 @@ function useLoader(_ref) {
|
|
|
161
162
|
var {
|
|
162
163
|
initial
|
|
163
164
|
} = _ref,
|
|
164
|
-
options = _objectWithoutPropertiesLoose(_ref,
|
|
165
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded$3);
|
|
165
166
|
|
|
166
167
|
var loadedValue = (_cache$get = cache.get(options.cacheKey)) == null ? void 0 : _cache$get.result;
|
|
167
168
|
var [value, setValue] = react.useState(loadedValue !== undefined ? loadedValue : initial);
|
|
@@ -171,16 +172,17 @@ function useLoader(_ref) {
|
|
|
171
172
|
try {
|
|
172
173
|
setValue(cache.load(options));
|
|
173
174
|
} catch (result) {
|
|
174
|
-
if (
|
|
175
|
-
|
|
175
|
+
if (result instanceof Promise) {
|
|
176
|
+
result.then(resolvedValue => {
|
|
177
|
+
if (!isUnmounted) {
|
|
178
|
+
setValue(resolvedValue);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
176
181
|
return;
|
|
177
182
|
}
|
|
178
183
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
setValue(resolvedValue);
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
+
setValue(undefined);
|
|
185
|
+
return;
|
|
184
186
|
}
|
|
185
187
|
}
|
|
186
188
|
|
|
@@ -206,6 +208,8 @@ function useCroct() {
|
|
|
206
208
|
return context.plug;
|
|
207
209
|
}
|
|
208
210
|
|
|
211
|
+
var _excluded$2 = ["cacheKey", "fallback", "initial", "expiration"];
|
|
212
|
+
|
|
209
213
|
function cleanEvaluationOptions(options) {
|
|
210
214
|
var result = {};
|
|
211
215
|
|
|
@@ -231,7 +235,7 @@ function useCsrEvaluation(expression, options) {
|
|
|
231
235
|
initial,
|
|
232
236
|
expiration
|
|
233
237
|
} = options,
|
|
234
|
-
evaluationOptions = _objectWithoutPropertiesLoose(options,
|
|
238
|
+
evaluationOptions = _objectWithoutPropertiesLoose(options, _excluded$2);
|
|
235
239
|
|
|
236
240
|
var croct = useCroct();
|
|
237
241
|
return useLoader({
|
|
@@ -297,30 +301,32 @@ function useSsrContent(_, _temp) {
|
|
|
297
301
|
|
|
298
302
|
var useContent = isSsr() ? useSsrContent : useCsrContent;
|
|
299
303
|
|
|
304
|
+
var _excluded$1 = ["expression", "children"];
|
|
300
305
|
function Personalization(props) {
|
|
301
306
|
var {
|
|
302
307
|
expression,
|
|
303
308
|
children
|
|
304
309
|
} = props,
|
|
305
|
-
options = _objectWithoutPropertiesLoose(props,
|
|
310
|
+
options = _objectWithoutPropertiesLoose(props, _excluded$1);
|
|
306
311
|
|
|
307
312
|
var result = useEvaluation(expression, options);
|
|
308
313
|
return jsxRuntime.jsx(react.Fragment, {
|
|
309
314
|
children: children(result)
|
|
310
|
-
}
|
|
315
|
+
});
|
|
311
316
|
}
|
|
312
317
|
|
|
318
|
+
var _excluded = ["id", "children"];
|
|
313
319
|
var Slot = props => {
|
|
314
320
|
var {
|
|
315
321
|
id,
|
|
316
322
|
children
|
|
317
323
|
} = props,
|
|
318
|
-
options = _objectWithoutPropertiesLoose(props,
|
|
324
|
+
options = _objectWithoutPropertiesLoose(props, _excluded);
|
|
319
325
|
|
|
320
326
|
var data = useContent(id, options);
|
|
321
327
|
return jsxRuntime.jsx(react.Fragment, {
|
|
322
328
|
children: children(data)
|
|
323
|
-
}
|
|
329
|
+
});
|
|
324
330
|
};
|
|
325
331
|
|
|
326
332
|
exports.CroctContext = CroctContext;
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/ssr-polyfills.ts","../src/CroctProvider.tsx","../src/hooks/Cache.ts","../src/hooks/useLoader.ts","../src/hooks/useCroct.ts","../src/hooks/useEvaluation.ts","../src/hooks/useContent.ts","../src/components/Personalization/index.tsx","../src/components/Slot/index.tsx"],"sourcesContent":["import csrPlug, {Plug} from '@croct/plug';\n\nexport function isSsr(): boolean {\n return typeof window === 'undefined';\n}\n\nexport const croct: Plug = !isSsr() ? csrPlug : new Proxy(csrPlug, {\n get(_, property: keyof Plug) {\n switch (property) {\n case 'initialized':\n return false;\n\n case 'plug':\n return () => {\n // no-op\n };\n\n case 'unplug':\n return () => Promise.resolve();\n\n default:\n throw new Error(\n `Property croct.${String(property)} is not supported on server-side (SSR). Consider refactoring `\n + 'the logic as a side-effect (useEffect) or a client-side callback (onClick, onChange, etc).',\n );\n }\n },\n});\n\n","import {createContext, FunctionComponent, PropsWithChildren, ReactElement, useContext, useEffect, useMemo} from 'react';\nimport {Configuration, Plug} from '@croct/plug';\nimport {croct} from './ssr-polyfills';\n\nexport type CroctProviderProps = PropsWithChildren<Configuration & Required<Pick<Configuration, 'appId'>>>;\n\nexport const CroctContext = createContext<{plug: Plug}|null>(null);\nCroctContext.displayName = 'CroctContext';\n\nexport const CroctProvider: FunctionComponent<CroctProviderProps> = ({children, ...configuration}): ReactElement => {\n const parent = useContext(CroctContext);\n\n if (parent !== null) {\n throw new Error(\n 'You cannot render <CroctProvider> inside another <CroctProvider>. '\n + 'Croct should only be initialized once in the application.',\n );\n }\n\n const context = useMemo(() => ({\n get plug() {\n if (!croct.initialized) {\n croct.plug(configuration);\n }\n\n return croct;\n },\n }), [configuration]);\n\n useEffect(() => {\n croct.plug(configuration);\n\n return () => {\n croct.unplug();\n };\n }, []);\n\n return (\n <CroctContext.Provider value={context}>\n {children}\n </CroctContext.Provider>\n );\n};\n","export type EntryLoader<R> = (...args: any) => Promise<R>;\n\nexport type EntryOptions<R> = {\n cacheKey: string,\n loader: EntryLoader<R>,\n fallback?: R,\n expiration?: number,\n};\n\ntype Entry<R = any> = {\n promise: Promise<any>,\n result?: R,\n dispose: () => void,\n timeout?: number,\n error?: any,\n};\n\nexport class Cache {\n private readonly cache: Record<string, Entry> = {};\n\n private readonly defaultExpiration: number;\n\n public constructor(defaultExpiration: number) {\n this.defaultExpiration = defaultExpiration;\n }\n\n public load<R>(configuration: EntryOptions<R>): R {\n const {cacheKey, loader, fallback, expiration = this.defaultExpiration} = configuration;\n\n const cachedEntry = this.get<R>(cacheKey);\n\n if (cachedEntry !== undefined) {\n if (cachedEntry.error !== undefined) {\n if (fallback !== undefined) {\n return fallback;\n }\n\n throw cachedEntry.error;\n }\n\n if (cachedEntry.result !== undefined) {\n return cachedEntry.result;\n }\n\n throw cachedEntry.promise;\n }\n\n const entry: Entry<R> = {\n dispose: () => {\n if (entry.timeout !== undefined || expiration < 0) {\n return;\n }\n\n entry.timeout = window.setTimeout(\n (): void => {\n delete this.cache[cacheKey];\n },\n expiration,\n );\n },\n promise: loader()\n .then((result): R => {\n entry.result = result;\n\n return result;\n })\n .catch(error => {\n entry.error = error;\n })\n .finally(() => {\n entry.dispose();\n }),\n };\n\n this.cache[cacheKey] = entry;\n\n throw entry.promise;\n }\n\n public get<R>(cacheKey: string): Entry<R>|undefined {\n const entry = this.cache[cacheKey];\n\n if (entry === undefined) {\n return undefined;\n }\n\n if (entry.timeout !== undefined) {\n clearTimeout(entry.timeout);\n\n delete entry.timeout;\n\n entry.dispose();\n }\n\n return entry;\n }\n}\n","import {useEffect, useState} from 'react';\nimport {Cache, EntryOptions} from './Cache';\n\nconst cache = new Cache(60 * 1000);\n\nexport type CacheOptions<R> = EntryOptions<R> & {\n initial?: R,\n};\n\nexport function useLoader<R>({initial, ...options}: CacheOptions<R>): R {\n const loadedValue: R|undefined = cache.get<R>(options.cacheKey)?.result;\n const [value, setValue] = useState(loadedValue !== undefined ? loadedValue : initial);\n const [isUnmounted, setUnmounted] = useState(false);\n\n useEffect(\n () => {\n if (initial !== undefined) {\n try {\n setValue(cache.load(options));\n } catch (result: unknown) {\n if (result instanceof Promise) {\n result.then((resolvedValue: R) => {\n if (!isUnmounted) {\n setValue(resolvedValue);\n }\n });\n\n return;\n }\n\n setValue(undefined);\n\n return;\n }\n }\n\n return () => {\n setUnmounted(true);\n };\n },\n [],\n );\n\n if (value === undefined) {\n return cache.load(options);\n }\n\n return value;\n}\n","import {Plug} from '@croct/plug';\nimport {useContext} from 'react';\nimport {CroctContext} from '../CroctProvider';\n\nexport function useCroct(): Plug {\n const context = useContext(CroctContext);\n\n if (context === null) {\n throw new Error('useCroct() can only be used in the context of a <CroctProvider> component.');\n }\n\n return context.plug;\n}\n","import {JsonValue} from '@croct/plug/sdk/json';\nimport {EvaluationOptions} from '@croct/sdk/facade/evaluatorFacade';\nimport {useLoader} from './useLoader';\nimport {useCroct} from './useCroct';\nimport {isSsr} from '../ssr-polyfills';\n\nfunction cleanEvaluationOptions(options: EvaluationOptions): EvaluationOptions {\n const result: EvaluationOptions = {};\n\n for (const [key, value] of Object.entries(options)) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nexport type UseEvaluationOptions<I, F> = EvaluationOptions & {\n initial?: I,\n fallback?: F,\n cacheKey?: string,\n expiration?: number,\n};\n\ntype UseEvaluationHook = <T extends JsonValue, I = T, F = T>(\n expression: string,\n options?: UseEvaluationOptions<I, F>,\n) => T | I | F;\n\nfunction useCsrEvaluation<T = JsonValue, I = T, F = T>(\n expression: string,\n options: UseEvaluationOptions<I, F> = {},\n): T | I | F {\n const {cacheKey, fallback, initial, expiration, ...evaluationOptions} = options;\n const croct = useCroct();\n\n return useLoader<T | I | F>({\n cacheKey: `useEvaluation:${cacheKey ?? ''}:${expression}:${JSON.stringify(options.attributes ?? '')}`,\n loader: () => croct.evaluate<T & JsonValue>(expression, cleanEvaluationOptions(evaluationOptions)),\n initial: initial,\n fallback: fallback,\n expiration: expiration,\n });\n}\n\nfunction useSsrEvaluation<T = JsonValue, I = T, F = T>(\n _: string,\n {initial}: UseEvaluationOptions<I, F> = {},\n): T | I | F {\n if (initial === undefined) {\n throw new Error('The initial value is required for server-side rendering (SSR).');\n }\n\n return initial;\n}\n\nexport const useEvaluation: UseEvaluationHook = isSsr() ? useSsrEvaluation : useCsrEvaluation;\n","import {SlotContent, SlotId, SlotMap} from '@croct/plug/fetch';\nimport {NullableJsonObject} from '@croct/plug/sdk/json';\nimport {useLoader} from './useLoader';\nimport {useCroct} from './useCroct';\nimport {isSsr} from '../ssr-polyfills';\n\nexport type UseContentOptions<I, F> = {\n fallback?: F,\n initial?: I,\n cacheKey?: string,\n expiration?: number,\n};\n\nfunction useCsrContent<I, F>(id: SlotId, options: UseContentOptions<I, F> = {}): SlotContent<SlotId> | I | F {\n const {fallback, initial, cacheKey, expiration} = options;\n const croct = useCroct();\n\n return useLoader({\n cacheKey: `useContent:${cacheKey ?? ''}:${id}`,\n loader: () => croct.fetch<SlotContent<SlotId>>(id).then(({payload}) => payload),\n initial: initial,\n fallback: fallback,\n expiration: expiration,\n });\n}\n\nfunction useSsrContent<I, F>(_: SlotId, {initial}: UseContentOptions<I, F> = {}): SlotContent<SlotId> | I | F {\n if (initial === undefined) {\n throw new Error('The initial value is required for server-side rendering (SSR).');\n }\n\n return initial;\n}\n\ntype UseContentHook = {\n <P extends NullableJsonObject, I = P, F = P>(\n id: keyof SlotMap extends never ? string : never,\n options?: UseContentOptions<I, F>\n ): P | I | F,\n\n <S extends keyof SlotMap>(\n id: S,\n options?: UseContentOptions<never, never>\n ): SlotContent<S>,\n\n <I, S extends keyof SlotMap>(\n id: S,\n options?: UseContentOptions<I, never>\n ): SlotContent<S> | I,\n\n <F, S extends keyof SlotMap>(\n id: S,\n options?: UseContentOptions<never, F>\n ): SlotContent<S> | F,\n\n <I, F, S extends keyof SlotMap>(\n id: S,\n options?: UseContentOptions<I, F>\n ): SlotContent<S> | I | F,\n};\n\nexport const useContent: UseContentHook = isSsr() ? useSsrContent : useCsrContent;\n","import {ReactChild, ReactElement, Fragment} from 'react';\nimport {JsonValue} from '@croct/plug/sdk/json';\nimport {UseEvaluationOptions, useEvaluation} from '../../hooks';\n\ntype Renderer<T> = (result: T) => ReactChild;\n\nexport type PersonalizationProps<T extends JsonValue = JsonValue, I = T, F = T> = UseEvaluationOptions<I, F> & {\n expression: string,\n children: Renderer<T | I | F>,\n};\n\nexport function Personalization<T extends JsonValue, I, F>(\n props:\n Extract<T | I | F, JsonValue> extends never\n ? PersonalizationProps\n : PersonalizationProps<T, I, F>,\n): ReactElement;\n\nexport function Personalization<I, F>(props: PersonalizationProps<JsonValue, I, F>): ReactElement {\n const {expression, children, ...options} = props;\n const result = useEvaluation(expression, options);\n\n return (<Fragment>{children(result)}</Fragment>);\n}\n","import {Fragment, ReactChild, ReactElement} from 'react';\nimport {SlotContent, SlotId, SlotMap} from '@croct/plug/fetch';\nimport {NullableJsonObject} from '@croct/plug/sdk/json';\nimport {useContent, UseContentOptions} from '../../hooks';\n\ntype Renderer<P> = (props: P) => ReactChild;\n\nexport type SlotProps<P, I = P, F = P, S extends SlotId = SlotId> = UseContentOptions<I, F> & {\n id: S,\n children: Renderer<P | I | F>,\n};\n\ntype SlotComponent = {\n <P, I, F>(\n props:\n Extract<P | I | F, NullableJsonObject> extends never\n ? SlotProps<NullableJsonObject, never, never, keyof SlotMap extends never ? string : never>\n : SlotProps<P, I, F, keyof SlotMap extends never ? string : never>\n ): ReactElement,\n\n <S extends keyof SlotMap>(props: SlotProps<SlotContent<S>, never, never, S>): ReactElement,\n\n <I, S extends keyof SlotMap>(props: SlotProps<SlotContent<S>, I, never, S>): ReactElement,\n\n <F, S extends keyof SlotMap>(props: SlotProps<SlotContent<S>, never, F, S>): ReactElement,\n\n <I, F, S extends keyof SlotMap>(props: SlotProps<SlotContent<S>, I, F, S>): ReactElement,\n\n (props: SlotProps<void, void, void>): ReactElement,\n};\n\nexport const Slot: SlotComponent = <I, F>(props: SlotProps<NullableJsonObject, I, F>): ReactElement => {\n const {id, children, ...options} = props;\n const data: SlotContent<SlotId> | I | F = useContent(id, options);\n\n return <Fragment>{children(data)}</Fragment>;\n};\n"],"names":["isSsr","window","croct","csrPlug","Proxy","get","_","property","Promise","resolve","Error","String","CroctContext","createContext","displayName","CroctProvider","children","configuration","_excluded","parent","useContext","context","useMemo","plug","initialized","useEffect","unplug","_jsx","Provider","value","Cache","constructor","defaultExpiration","cache","load","cacheKey","loader","fallback","expiration","cachedEntry","undefined","error","result","promise","entry","dispose","timeout","setTimeout","then","catch","finally","clearTimeout","useLoader","initial","options","loadedValue","setValue","useState","isUnmounted","setUnmounted","resolvedValue","useCroct","cleanEvaluationOptions","key","Object","entries","useCsrEvaluation","expression","evaluationOptions","JSON","stringify","attributes","evaluate","useSsrEvaluation","useEvaluation","useCsrContent","id","fetch","payload","useSsrContent","useContent","Personalization","props","Fragment","Slot","data"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@croct/plug-react",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "React components and hooks to plug your React applications into Croct.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Croct",
|
|
@@ -38,50 +38,55 @@
|
|
|
38
38
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@croct/plug": "^0.10.
|
|
41
|
+
"@croct/plug": "^0.10.1"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@babel/core": "^7.
|
|
45
|
-
"@babel/preset-env": "^7.
|
|
46
|
-
"@babel/preset-react": "^7.
|
|
47
|
-
"@babel/preset-typescript": "^7.
|
|
48
|
-
"@storybook/addon-actions": "^6.
|
|
49
|
-
"@storybook/addon-essentials": "^6.
|
|
50
|
-
"@storybook/addon-links": "^6.
|
|
51
|
-
"@storybook/
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@testing-library/
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@types/
|
|
58
|
-
"@types/
|
|
59
|
-
"@
|
|
60
|
-
"@
|
|
44
|
+
"@babel/core": "^7.18.5",
|
|
45
|
+
"@babel/preset-env": "^7.18.2",
|
|
46
|
+
"@babel/preset-react": "^7.17.12",
|
|
47
|
+
"@babel/preset-typescript": "^7.17.12",
|
|
48
|
+
"@storybook/addon-actions": "^6.5.9",
|
|
49
|
+
"@storybook/addon-essentials": "^6.5.9",
|
|
50
|
+
"@storybook/addon-links": "^6.5.9",
|
|
51
|
+
"@storybook/builder-webpack5": "^6.5.9",
|
|
52
|
+
"@storybook/manager-webpack5": "^6.5.9",
|
|
53
|
+
"@storybook/react": "^6.5.9",
|
|
54
|
+
"@testing-library/jest-dom": "^5.16.4",
|
|
55
|
+
"@testing-library/react": "^13.3.0",
|
|
56
|
+
"@testing-library/react-hooks": "^8.0.0",
|
|
57
|
+
"@types/jest": "^28.1.2",
|
|
58
|
+
"@types/node": "^16.11.41",
|
|
59
|
+
"@types/react": "^18.0.14",
|
|
60
|
+
"@types/react-dom": "^18.0.5",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
|
62
|
+
"@typescript-eslint/parser": "^5.28.0",
|
|
61
63
|
"babel-eslint": "^10.1.0",
|
|
62
|
-
"babel-jest": "^
|
|
63
|
-
"babel-loader": "8.
|
|
64
|
-
"eslint": "^
|
|
65
|
-
"eslint-config-airbnb-base": "^
|
|
66
|
-
"eslint-config-standard": "^
|
|
64
|
+
"babel-jest": "^28.1.1",
|
|
65
|
+
"babel-loader": "^8.2.5",
|
|
66
|
+
"eslint": "^8.17.0",
|
|
67
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
68
|
+
"eslint-config-standard": "^17.0.0",
|
|
67
69
|
"eslint-config-standard-react": "^11.0.1",
|
|
68
|
-
"eslint-plugin-import": "^2.
|
|
69
|
-
"eslint-plugin-jest": "^
|
|
70
|
+
"eslint-plugin-import": "^2.26.0",
|
|
71
|
+
"eslint-plugin-jest": "^26.5.3",
|
|
72
|
+
"eslint-plugin-n": "^15.2.3",
|
|
70
73
|
"eslint-plugin-node": "^11.1.0",
|
|
71
|
-
"eslint-plugin-promise": "^
|
|
72
|
-
"eslint-plugin-react": "^7.
|
|
74
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
75
|
+
"eslint-plugin-react": "^7.30.0",
|
|
73
76
|
"eslint-plugin-standard": "^5.0.0",
|
|
74
|
-
"jest": "
|
|
75
|
-
"jest-environment-
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"react
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
77
|
+
"jest": "^28.1.1",
|
|
78
|
+
"jest-environment-jsdom": "^28.1.1",
|
|
79
|
+
"jest-environment-node": "^28.1.1",
|
|
80
|
+
"microbundle": "^0.15.0",
|
|
81
|
+
"react": "^18.2.0",
|
|
82
|
+
"react-dom": "^18.2.0",
|
|
83
|
+
"ts-node": "^10.8.1",
|
|
84
|
+
"typescript": "^4.7.3",
|
|
85
|
+
"webpack": "^5.73.0"
|
|
82
86
|
},
|
|
83
87
|
"files": [
|
|
84
88
|
"**/*.js",
|
|
89
|
+
"**/*.js.map",
|
|
85
90
|
"**/*.ts"
|
|
86
91
|
]
|
|
87
92
|
}
|
package/index.modern.js
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createContext, useContext, useMemo, useEffect, useState, Fragment } from 'react';
|
|
3
|
-
import csrPlug from '@croct/plug';
|
|
4
|
-
|
|
5
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
6
|
-
if (source == null) return {};
|
|
7
|
-
var target = {};
|
|
8
|
-
var sourceKeys = Object.keys(source);
|
|
9
|
-
var key, i;
|
|
10
|
-
|
|
11
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
12
|
-
key = sourceKeys[i];
|
|
13
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
14
|
-
target[key] = source[key];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return target;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function isSsr() {
|
|
21
|
-
return typeof window === 'undefined';
|
|
22
|
-
}
|
|
23
|
-
const croct = !isSsr() ? csrPlug : new Proxy(csrPlug, {
|
|
24
|
-
get(_, property) {
|
|
25
|
-
switch (property) {
|
|
26
|
-
case 'initialized':
|
|
27
|
-
return false;
|
|
28
|
-
|
|
29
|
-
case 'plug':
|
|
30
|
-
return () => {// no-op
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
case 'unplug':
|
|
34
|
-
return () => Promise.resolve();
|
|
35
|
-
|
|
36
|
-
default:
|
|
37
|
-
throw new Error(`Property croct.${String(property)} is not supported on server-side (SSR). Consider refactoring ` + 'the logic as a side-effect (useEffect) or a client-side callback (onClick, onChange, etc).');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const CroctContext = /*#__PURE__*/createContext(null);
|
|
44
|
-
CroctContext.displayName = 'CroctContext';
|
|
45
|
-
const CroctProvider = _ref => {
|
|
46
|
-
let {
|
|
47
|
-
children
|
|
48
|
-
} = _ref,
|
|
49
|
-
configuration = _objectWithoutPropertiesLoose(_ref, ["children"]);
|
|
50
|
-
|
|
51
|
-
const parent = useContext(CroctContext);
|
|
52
|
-
|
|
53
|
-
if (parent !== null) {
|
|
54
|
-
throw new Error('You cannot render <CroctProvider> inside another <CroctProvider>. ' + 'Croct should only be initialized once in the application.');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const context = useMemo(() => ({
|
|
58
|
-
get plug() {
|
|
59
|
-
if (!croct.initialized) {
|
|
60
|
-
croct.plug(configuration);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return croct;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
}), [configuration]);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
croct.plug(configuration);
|
|
69
|
-
return () => {
|
|
70
|
-
croct.unplug();
|
|
71
|
-
};
|
|
72
|
-
}, []);
|
|
73
|
-
return jsx(CroctContext.Provider, Object.assign({
|
|
74
|
-
value: context
|
|
75
|
-
}, {
|
|
76
|
-
children: children
|
|
77
|
-
}), void 0);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
class Cache {
|
|
81
|
-
constructor(defaultExpiration) {
|
|
82
|
-
this.cache = {};
|
|
83
|
-
this.defaultExpiration = void 0;
|
|
84
|
-
this.defaultExpiration = defaultExpiration;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
load(configuration) {
|
|
88
|
-
const {
|
|
89
|
-
cacheKey,
|
|
90
|
-
loader,
|
|
91
|
-
fallback,
|
|
92
|
-
expiration = this.defaultExpiration
|
|
93
|
-
} = configuration;
|
|
94
|
-
const cachedEntry = this.get(cacheKey);
|
|
95
|
-
|
|
96
|
-
if (cachedEntry !== undefined) {
|
|
97
|
-
if (cachedEntry.error !== undefined) {
|
|
98
|
-
if (fallback !== undefined) {
|
|
99
|
-
return fallback;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
throw cachedEntry.error;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (cachedEntry.result !== undefined) {
|
|
106
|
-
return cachedEntry.result;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
throw cachedEntry.promise;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const entry = {
|
|
113
|
-
dispose: () => {
|
|
114
|
-
if (entry.timeout !== undefined || expiration < 0) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
entry.timeout = window.setTimeout(() => {
|
|
119
|
-
delete this.cache[cacheKey];
|
|
120
|
-
}, expiration);
|
|
121
|
-
},
|
|
122
|
-
promise: loader().then(result => {
|
|
123
|
-
entry.result = result;
|
|
124
|
-
return result;
|
|
125
|
-
}).catch(error => {
|
|
126
|
-
entry.error = error;
|
|
127
|
-
}).finally(() => {
|
|
128
|
-
entry.dispose();
|
|
129
|
-
})
|
|
130
|
-
};
|
|
131
|
-
this.cache[cacheKey] = entry;
|
|
132
|
-
throw entry.promise;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
get(cacheKey) {
|
|
136
|
-
const entry = this.cache[cacheKey];
|
|
137
|
-
|
|
138
|
-
if (entry === undefined) {
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (entry.timeout !== undefined) {
|
|
143
|
-
clearTimeout(entry.timeout);
|
|
144
|
-
delete entry.timeout;
|
|
145
|
-
entry.dispose();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return entry;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const cache = new Cache(60 * 1000);
|
|
154
|
-
function useLoader(_ref) {
|
|
155
|
-
var _cache$get;
|
|
156
|
-
|
|
157
|
-
let {
|
|
158
|
-
initial
|
|
159
|
-
} = _ref,
|
|
160
|
-
options = _objectWithoutPropertiesLoose(_ref, ["initial"]);
|
|
161
|
-
|
|
162
|
-
const loadedValue = (_cache$get = cache.get(options.cacheKey)) == null ? void 0 : _cache$get.result;
|
|
163
|
-
const [value, setValue] = useState(loadedValue !== undefined ? loadedValue : initial);
|
|
164
|
-
const [isUnmounted, setUnmounted] = useState(false);
|
|
165
|
-
useEffect(() => {
|
|
166
|
-
if (initial !== undefined) {
|
|
167
|
-
try {
|
|
168
|
-
setValue(cache.load(options));
|
|
169
|
-
} catch (result) {
|
|
170
|
-
if (typeof (result == null ? void 0 : result.then) !== 'function') {
|
|
171
|
-
setValue(undefined);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
result.then(resolvedValue => {
|
|
176
|
-
if (!isUnmounted) {
|
|
177
|
-
setValue(resolvedValue);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return () => {
|
|
184
|
-
setUnmounted(true);
|
|
185
|
-
};
|
|
186
|
-
}, []);
|
|
187
|
-
|
|
188
|
-
if (value === undefined) {
|
|
189
|
-
return cache.load(options);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return value;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function useCroct() {
|
|
196
|
-
const context = useContext(CroctContext);
|
|
197
|
-
|
|
198
|
-
if (context === null) {
|
|
199
|
-
throw new Error('useCroct() can only be used in the context of a <CroctProvider> component.');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return context.plug;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function cleanEvaluationOptions(options) {
|
|
206
|
-
const result = {};
|
|
207
|
-
|
|
208
|
-
for (const [key, value] of Object.entries(options)) {
|
|
209
|
-
if (value !== undefined) {
|
|
210
|
-
result[key] = value;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return result;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function useCsrEvaluation(expression, options = {}) {
|
|
218
|
-
var _options$attributes;
|
|
219
|
-
|
|
220
|
-
const {
|
|
221
|
-
cacheKey,
|
|
222
|
-
fallback,
|
|
223
|
-
initial,
|
|
224
|
-
expiration
|
|
225
|
-
} = options,
|
|
226
|
-
evaluationOptions = _objectWithoutPropertiesLoose(options, ["cacheKey", "fallback", "initial", "expiration"]);
|
|
227
|
-
|
|
228
|
-
const croct = useCroct();
|
|
229
|
-
return useLoader({
|
|
230
|
-
cacheKey: `useEvaluation:${cacheKey != null ? cacheKey : ''}:${expression}:${JSON.stringify((_options$attributes = options.attributes) != null ? _options$attributes : '')}`,
|
|
231
|
-
loader: () => croct.evaluate(expression, cleanEvaluationOptions(evaluationOptions)),
|
|
232
|
-
initial: initial,
|
|
233
|
-
fallback: fallback,
|
|
234
|
-
expiration: expiration
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function useSsrEvaluation(_, {
|
|
239
|
-
initial
|
|
240
|
-
} = {}) {
|
|
241
|
-
if (initial === undefined) {
|
|
242
|
-
throw new Error('The initial value is required for server-side rendering (SSR).');
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return initial;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const useEvaluation = isSsr() ? useSsrEvaluation : useCsrEvaluation;
|
|
249
|
-
|
|
250
|
-
function useCsrContent(id, options = {}) {
|
|
251
|
-
const {
|
|
252
|
-
fallback,
|
|
253
|
-
initial,
|
|
254
|
-
cacheKey,
|
|
255
|
-
expiration
|
|
256
|
-
} = options;
|
|
257
|
-
const croct = useCroct();
|
|
258
|
-
return useLoader({
|
|
259
|
-
cacheKey: `useContent:${cacheKey != null ? cacheKey : ''}:${id}`,
|
|
260
|
-
loader: () => croct.fetch(id).then(({
|
|
261
|
-
payload
|
|
262
|
-
}) => payload),
|
|
263
|
-
initial: initial,
|
|
264
|
-
fallback: fallback,
|
|
265
|
-
expiration: expiration
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function useSsrContent(_, {
|
|
270
|
-
initial
|
|
271
|
-
} = {}) {
|
|
272
|
-
if (initial === undefined) {
|
|
273
|
-
throw new Error('The initial value is required for server-side rendering (SSR).');
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return initial;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const useContent = isSsr() ? useSsrContent : useCsrContent;
|
|
280
|
-
|
|
281
|
-
function Personalization(props) {
|
|
282
|
-
const {
|
|
283
|
-
expression,
|
|
284
|
-
children
|
|
285
|
-
} = props,
|
|
286
|
-
options = _objectWithoutPropertiesLoose(props, ["expression", "children"]);
|
|
287
|
-
|
|
288
|
-
const result = useEvaluation(expression, options);
|
|
289
|
-
return jsx(Fragment, {
|
|
290
|
-
children: children(result)
|
|
291
|
-
}, void 0);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const Slot = props => {
|
|
295
|
-
const {
|
|
296
|
-
id,
|
|
297
|
-
children
|
|
298
|
-
} = props,
|
|
299
|
-
options = _objectWithoutPropertiesLoose(props, ["id", "children"]);
|
|
300
|
-
|
|
301
|
-
const data = useContent(id, options);
|
|
302
|
-
return jsx(Fragment, {
|
|
303
|
-
children: children(data)
|
|
304
|
-
}, void 0);
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export { CroctContext, CroctProvider, Personalization, Slot, useContent, useCroct, useEvaluation };
|
|
308
|
-
//# sourceMappingURL=index.modern.js.map
|