@croct/plug-react 0.2.4 → 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 +94 -43
- package/index.js +25 -19
- package/index.js.map +1 -0
- package/package.json +43 -38
- 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,15 +159,16 @@ 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
|
|
165
168
|
|
|
166
|
-
We strongly recommend
|
|
167
|
-
the personalization. In this way, the UI will still be fully functional even in maintenance
|
|
169
|
+
We strongly recommend specifying the `fallback` property in client-side rendered applications to ensure your app behaves
|
|
170
|
+
the same way regardless of the personalization. In this way, the UI will still be fully functional even in maintenance
|
|
171
|
+
windows. **Specifying a `fallback` is required for server-side rendering (SSR).**
|
|
168
172
|
|
|
169
173
|
The following example shows how you can specify a fallback behaviour for the docs link:
|
|
170
174
|
|
|
@@ -182,7 +186,7 @@ export default function OnboardingPage(): ReactElement {
|
|
|
182
186
|
return (
|
|
183
187
|
<Suspense fallback="✨ Personalizing...">
|
|
184
188
|
{/* Using the <Personalization /> component */}
|
|
185
|
-
<Personalization expression="user's persona is 'developer'"
|
|
189
|
+
<Personalization expression="user's persona is 'developer'" fallback={false}>
|
|
186
190
|
{(isDeveloper: boolean) => (
|
|
187
191
|
<Fragment>
|
|
188
192
|
{isDeveloper && <a href="/docs">View docs</a>}
|
|
@@ -201,23 +205,23 @@ For a full list of the available options, please refer to the [API documentation
|
|
|
201
205
|
|
|
202
206
|
### Using slots
|
|
203
207
|
|
|
204
|
-
Evaluating expression is a flexible and powerful way to customize your UI. However, for components whose content
|
|
205
|
-
changes too often, this approach can be overkill. For those cases, we encourage you to use the Slots feature instead.
|
|
206
|
-
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
|
|
207
211
|
touching the component code.
|
|
208
212
|
|
|
209
213
|

|
|
210
214
|
|
|
211
|
-
To render a slot, all you need to do is provide the `id` you configured in your Croct workspace. Based on the
|
|
212
|
-
slot's personalization rules and the user's context, the component will decide which content show to that user.
|
|
213
|
-
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
|
|
214
218
|
slot content as they need without requiring an update to your React app.
|
|
215
219
|
|
|
216
|
-
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
|
|
217
221
|
with the following structure:
|
|
218
222
|
|
|
219
223
|
```ts
|
|
220
|
-
type
|
|
224
|
+
type HomeBannerContent = {
|
|
221
225
|
title: string,
|
|
222
226
|
subtitle: string,
|
|
223
227
|
cta: {
|
|
@@ -235,11 +239,20 @@ Here's how to use the `<Slot />` component:
|
|
|
235
239
|
import {ReactElement, Suspense} from 'react';
|
|
236
240
|
import {Slot} from '@croct/plug-react';
|
|
237
241
|
|
|
242
|
+
type HomeBannerContent = {
|
|
243
|
+
title: string,
|
|
244
|
+
subtitle: string,
|
|
245
|
+
cta: {
|
|
246
|
+
label: string,
|
|
247
|
+
link: string,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
|
|
238
251
|
export default function OnboardingPage(): ReactElement {
|
|
239
252
|
return (
|
|
240
253
|
<Suspense fallback="✨ Personalizing content...">
|
|
241
254
|
<Slot id="home-banner">
|
|
242
|
-
{({title, subtitle, cta}:
|
|
255
|
+
{({title, subtitle, cta}: HomeBannerContent) => (
|
|
243
256
|
<div>
|
|
244
257
|
<strong>{title}</strong>
|
|
245
258
|
<p>{subtitle}</p>
|
|
@@ -258,17 +271,26 @@ To avoid the component from suspending while loading, you can provide an `initia
|
|
|
258
271
|
import {ReactElement} from 'react';
|
|
259
272
|
import {Slot} from '@croct/plug-react';
|
|
260
273
|
|
|
274
|
+
type HomeBannerContent = {
|
|
275
|
+
title: string,
|
|
276
|
+
subtitle: string,
|
|
277
|
+
cta: {
|
|
278
|
+
label: string,
|
|
279
|
+
link: string,
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
|
|
261
283
|
export default function OnboardingPage(): ReactElement {
|
|
262
284
|
return (
|
|
263
285
|
<Slot id="home-banner" initial={null}>
|
|
264
|
-
{(props:
|
|
286
|
+
{(props: HomeBannerContent|null) => (
|
|
265
287
|
props === null
|
|
266
288
|
? '✨ Personalizing...'
|
|
267
289
|
: (
|
|
268
290
|
<div>
|
|
269
|
-
<strong>{title}</strong>
|
|
270
|
-
<p>{subtitle}</p>
|
|
271
|
-
<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>
|
|
272
294
|
</div>
|
|
273
295
|
)
|
|
274
296
|
)}
|
|
@@ -283,8 +305,17 @@ And here's an example using the `useContent` hook:
|
|
|
283
305
|
import {ReactElement, Suspense} from 'react';
|
|
284
306
|
import {useContent} from '@croct/plug-react';
|
|
285
307
|
|
|
308
|
+
type HomeBannerContent = {
|
|
309
|
+
title: string,
|
|
310
|
+
subtitle: string,
|
|
311
|
+
cta: {
|
|
312
|
+
label: string,
|
|
313
|
+
link: string,
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
|
|
286
317
|
function HomeBanner(): ReactElement {
|
|
287
|
-
const
|
|
318
|
+
const {title, subtitle, cta} = useContent<HomeBannerContent>('home-banner');
|
|
288
319
|
|
|
289
320
|
return (
|
|
290
321
|
<div>
|
|
@@ -312,7 +343,16 @@ The following example shows how you can specify a fallback state for the `home-b
|
|
|
312
343
|
import {ReactElement, Suspense} from 'react';
|
|
313
344
|
import {Slot, useContent} from '@croct/plug-react';
|
|
314
345
|
|
|
315
|
-
|
|
346
|
+
type HomeBannerContent = {
|
|
347
|
+
title: string,
|
|
348
|
+
subtitle: string,
|
|
349
|
+
cta: {
|
|
350
|
+
label: string,
|
|
351
|
+
link: string,
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const fallbackBanner: HomeBannerContent = {
|
|
316
356
|
title: 'Default title',
|
|
317
357
|
subtitle: 'Default subtitle',
|
|
318
358
|
cta: {
|
|
@@ -322,7 +362,7 @@ const fallbackBanner: HomeBanner = {
|
|
|
322
362
|
};
|
|
323
363
|
|
|
324
364
|
function HomeBanner(): ReactElement {
|
|
325
|
-
const {title, subtitle, cta} = useContent<
|
|
365
|
+
const {title, subtitle, cta} = useContent<HomeBannerContent>('home-banner', {fallback: fallbackBanner});
|
|
326
366
|
|
|
327
367
|
return (
|
|
328
368
|
<div>
|
|
@@ -338,7 +378,7 @@ export default function HomePage(): ReactElement {
|
|
|
338
378
|
<Suspense fallback="Personalizing content...">
|
|
339
379
|
{/* Using the <Slot /> component */}
|
|
340
380
|
<Slot id="home-banner" fallback={fallbackBanner}>
|
|
341
|
-
{({title, subtitle, cta}:
|
|
381
|
+
{({title, subtitle, cta}: HomeBannerContent) => (
|
|
342
382
|
<div>
|
|
343
383
|
<strong>{title}</strong>
|
|
344
384
|
<p>{subtitle}</p>
|
|
@@ -354,15 +394,15 @@ export default function HomePage(): ReactElement {
|
|
|
354
394
|
}
|
|
355
395
|
```
|
|
356
396
|
|
|
357
|
-
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,
|
|
358
398
|
please refer to the [API documentation](#component-api-reference).
|
|
359
399
|
|
|
360
400
|
#### 💡 ProTip
|
|
361
401
|
|
|
362
|
-
In the previous examples, you may have noticed that we specified the content type in the `userFetch` call and in the
|
|
363
|
-
`<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.
|
|
364
404
|
|
|
365
|
-
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
|
|
366
406
|
using module augmentation as follows:
|
|
367
407
|
|
|
368
408
|
```ts
|
|
@@ -384,16 +424,16 @@ slot IDs and content properties as a bonus:
|
|
|
384
424
|
|
|
385
425
|
### Server-side rendering
|
|
386
426
|
|
|
387
|
-
You can use the same components and hooks on the server-side by simply providing an `initial` state which is used to
|
|
388
|
-
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.
|
|
389
429
|
That means it's SEO friendly and can be cached with no performance overhead.
|
|
390
430
|
|
|
391
|
-
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),
|
|
392
432
|
the operations have to be executed inside the `useEffect` hook or client-side callbacks, such as `onClick` or `onChange`, for example.
|
|
393
433
|
|
|
394
434
|
### Accessing the Plug instance
|
|
395
435
|
|
|
396
|
-
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,
|
|
397
437
|
login and logout users, and more.
|
|
398
438
|
|
|
399
439
|
In the following example we use the `useCroct` to get the Plug instance and set an attribute to the user profile:
|
|
@@ -422,7 +462,7 @@ This reference documents all components available in the library.
|
|
|
422
462
|
### <CroctProvider />
|
|
423
463
|
|
|
424
464
|
The `<CroctProvider />` component leverages [React's Context API](https://reactjs.org/docs/context.html) to
|
|
425
|
-
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
|
|
426
466
|
a React component tree.
|
|
427
467
|
|
|
428
468
|
#### Properties
|
|
@@ -453,7 +493,7 @@ import {CroctProvider} from '@croct/plug-react';
|
|
|
453
493
|
|
|
454
494
|
function App() {
|
|
455
495
|
return (
|
|
456
|
-
<CroctProvider appId="
|
|
496
|
+
<CroctProvider appId="<APP_ID>">
|
|
457
497
|
<div>
|
|
458
498
|
<h1>My first personalized app 🚀</h1>
|
|
459
499
|
</div>
|
|
@@ -462,6 +502,8 @@ function App() {
|
|
|
462
502
|
}
|
|
463
503
|
```
|
|
464
504
|
|
|
505
|
+
> Replace "<APP_ID>" with your public app ID that you can find at Workspaces > Applications > API Keys.
|
|
506
|
+
|
|
465
507
|
### <Personalization />
|
|
466
508
|
|
|
467
509
|
The `<Personalization />` component evaluates and renders a CQL query.
|
|
@@ -585,7 +627,7 @@ These are the currently supported options:
|
|
|
585
627
|
|
|
586
628
|
| Option | Type | Description
|
|
587
629
|
|--------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
588
|
-
| `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.
|
|
589
631
|
| `timeout` | number | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail.
|
|
590
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`.
|
|
591
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.
|
|
@@ -634,8 +676,17 @@ Here's a simple example showing how to fetch the content for a banner:
|
|
|
634
676
|
import {ReactElement} from 'react';
|
|
635
677
|
import {useContent} from '@croct/plug-react';
|
|
636
678
|
|
|
637
|
-
|
|
638
|
-
|
|
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');
|
|
639
690
|
|
|
640
691
|
return (
|
|
641
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.
|
|
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",
|
|
@@ -34,54 +34,59 @@
|
|
|
34
34
|
"build-storybook": "build-storybook -s ./.storybook/static"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"react": "^16.8.0 || ^17.0.0",
|
|
38
|
-
"react-dom": "^16.8.0 || ^17.0.0"
|
|
37
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
38
|
+
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@croct/plug": "^0.
|
|
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
|