@croct/plug-react 0.5.0-next.1 → 0.5.0-next.2

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.
Files changed (41) hide show
  1. package/CroctProvider.js.map +1 -1
  2. package/api/evaluate.js.map +1 -1
  3. package/api/fetchContent.js +4 -1
  4. package/api/fetchContent.js.map +1 -1
  5. package/api/index.js.map +1 -1
  6. package/components/Personalization/index.js.map +1 -1
  7. package/components/Slot/index.js.map +1 -1
  8. package/components/index.js.map +1 -1
  9. package/hooks/Cache.js.map +1 -1
  10. package/hooks/index.js.map +1 -1
  11. package/hooks/useContent.js.map +1 -1
  12. package/hooks/useCroct.js.map +1 -1
  13. package/hooks/useEvaluation.js.map +1 -1
  14. package/hooks/useLoader.js.map +1 -1
  15. package/index.js.map +1 -1
  16. package/package.json +5 -5
  17. package/src/api/evaluate.test.ts +59 -0
  18. package/src/api/evaluate.ts +19 -0
  19. package/src/api/fetchContent.test.ts +134 -0
  20. package/src/api/fetchContent.ts +47 -0
  21. package/src/api/index.ts +2 -0
  22. package/src/components/index.ts +2 -0
  23. package/src/global.d.ts +7 -0
  24. package/src/hooks/Cache.test.ts +280 -0
  25. package/src/hooks/Cache.ts +97 -0
  26. package/src/hooks/index.ts +3 -0
  27. package/src/hooks/useContent.ssr.test.ts +23 -0
  28. package/src/hooks/useContent.test.ts +66 -0
  29. package/src/hooks/useContent.ts +69 -0
  30. package/src/hooks/useCroct.ts +13 -0
  31. package/src/hooks/useEvaluation.ssr.test.ts +23 -0
  32. package/src/hooks/useEvaluation.test.ts +92 -0
  33. package/src/hooks/useEvaluation.ts +58 -0
  34. package/src/hooks/useLoader.test.ts +320 -0
  35. package/src/hooks/useLoader.ts +50 -0
  36. package/src/index.ts +5 -0
  37. package/src/react-app-env.d.ts +1 -0
  38. package/src/ssr-polyfills.ssr.test.ts +46 -0
  39. package/src/ssr-polyfills.test.ts +65 -0
  40. package/src/ssr-polyfills.ts +68 -0
  41. package/ssr-polyfills.js.map +1 -1
@@ -0,0 +1,58 @@
1
+ import {JsonValue} from '@croct/plug/sdk/json';
2
+ import {EvaluationOptions} from '@croct/sdk/facade/evaluatorFacade';
3
+ import {useLoader} from './useLoader';
4
+ import {useCroct} from './useCroct';
5
+ import {isSsr} from '../ssr-polyfills';
6
+
7
+ function cleanEvaluationOptions(options: EvaluationOptions): EvaluationOptions {
8
+ const result: EvaluationOptions = {};
9
+
10
+ for (const [key, value] of Object.entries(options)) {
11
+ if (value !== undefined) {
12
+ result[key] = value;
13
+ }
14
+ }
15
+
16
+ return result;
17
+ }
18
+
19
+ export type UseEvaluationOptions<I, F> = EvaluationOptions & {
20
+ initial?: I,
21
+ fallback?: F,
22
+ cacheKey?: string,
23
+ expiration?: number,
24
+ };
25
+
26
+ type UseEvaluationHook = <T extends JsonValue, I = T, F = T>(
27
+ query: string,
28
+ options?: UseEvaluationOptions<I, F>,
29
+ ) => T | I | F;
30
+
31
+ function useCsrEvaluation<T = JsonValue, I = T, F = T>(
32
+ query: string,
33
+ options: UseEvaluationOptions<I, F> = {},
34
+ ): T | I | F {
35
+ const {cacheKey, fallback, initial, expiration, ...evaluationOptions} = options;
36
+ const croct = useCroct();
37
+
38
+ return useLoader<T | I | F>({
39
+ cacheKey: `useEvaluation:${cacheKey ?? ''}:${query}:${JSON.stringify(options.attributes ?? '')}`,
40
+ loader: () => croct.evaluate<T & JsonValue>(query, cleanEvaluationOptions(evaluationOptions)),
41
+ initial: initial,
42
+ fallback: fallback,
43
+ expiration: expiration,
44
+ });
45
+ }
46
+
47
+ function useSsrEvaluation<T = JsonValue, I = T, F = T>(
48
+ _: string,
49
+ {initial}: UseEvaluationOptions<I, F> = {},
50
+ ): T | I | F {
51
+ if (initial === undefined) {
52
+ throw new Error('The initial value is required for server-side rendering (SSR).');
53
+ }
54
+
55
+ return initial;
56
+ }
57
+
58
+ export const useEvaluation: UseEvaluationHook = isSsr() ? useSsrEvaluation : useCsrEvaluation;
@@ -0,0 +1,320 @@
1
+ import {act, renderHook, waitFor} from '@testing-library/react';
2
+ import {useLoader} from './useLoader';
3
+
4
+ describe('useLoader', () => {
5
+ const cacheKey = {
6
+ index: 0,
7
+ next: function next(): string {
8
+ this.index++;
9
+
10
+ return this.current();
11
+ },
12
+ current: function current(): string {
13
+ return `key-${this.index}`;
14
+ },
15
+ };
16
+
17
+ beforeEach(() => {
18
+ cacheKey.next();
19
+ });
20
+
21
+ afterEach(() => {
22
+ jest.clearAllTimers();
23
+ jest.resetAllMocks();
24
+ });
25
+
26
+ // Needed to use fake timers and promises:
27
+ // https://github.com/testing-library/react-testing-library/issues/244#issuecomment-449461804
28
+ function flushPromises(): Promise<void> {
29
+ return Promise.resolve();
30
+ }
31
+
32
+ it('should return the load the value and cache on success', async () => {
33
+ const loader = jest.fn().mockResolvedValue('foo');
34
+
35
+ const {result, rerender} = renderHook(
36
+ () => useLoader({
37
+ cacheKey: cacheKey.current(),
38
+ loader: loader,
39
+ }),
40
+ );
41
+
42
+ rerender();
43
+
44
+ await waitFor(() => expect(result.current).toBe('foo'));
45
+
46
+ expect(loader).toHaveBeenCalledTimes(1);
47
+ });
48
+
49
+ it('should load the value and cache on error', async () => {
50
+ const error = new Error('fail');
51
+ const loader = jest.fn().mockRejectedValue(error);
52
+
53
+ const {result, rerender} = renderHook(
54
+ () => useLoader({
55
+ cacheKey: cacheKey.current(),
56
+ fallback: error,
57
+ loader: loader,
58
+ }),
59
+ );
60
+
61
+ rerender();
62
+
63
+ await waitFor(() => expect(result.current).toBe(error));
64
+
65
+ expect(loader).toHaveBeenCalledTimes(1);
66
+ });
67
+
68
+ it('should reload the value on error', async () => {
69
+ const content = {foo: 'qux'};
70
+
71
+ const loader = jest.fn()
72
+ .mockImplementationOnce(() => {
73
+ throw new Error('fail');
74
+ })
75
+ .mockImplementationOnce(() => Promise.resolve(content));
76
+
77
+ const {result, rerender} = renderHook(
78
+ () => useLoader({
79
+ cacheKey: cacheKey.current(),
80
+ initial: {},
81
+ loader: loader,
82
+ }),
83
+ );
84
+
85
+ await act(flushPromises);
86
+
87
+ rerender();
88
+
89
+ await waitFor(() => expect(result.current).toBe(content));
90
+
91
+ expect(loader).toHaveBeenCalledTimes(2);
92
+ });
93
+
94
+ it('should return the initial state on the initial render', async () => {
95
+ const loader = jest.fn(() => Promise.resolve('loaded'));
96
+
97
+ const {result} = renderHook(
98
+ () => useLoader({
99
+ cacheKey: cacheKey.current(),
100
+ initial: 'loading',
101
+ loader: loader,
102
+ }),
103
+ );
104
+
105
+ expect(result.current).toBe('loading');
106
+
107
+ await waitFor(() => expect(result.current).toBe('loaded'));
108
+ });
109
+
110
+ it('should update the initial state with the fallback state on error', async () => {
111
+ const loader = jest.fn().mockRejectedValue(new Error('fail'));
112
+
113
+ const {result} = renderHook(
114
+ () => useLoader({
115
+ cacheKey: cacheKey.current(),
116
+ initial: 'loading',
117
+ fallback: 'error',
118
+ loader: loader,
119
+ }),
120
+ );
121
+
122
+ expect(result.current).toBe('loading');
123
+
124
+ await waitFor(() => expect(result.current).toBe('error'));
125
+ });
126
+
127
+ it('should return the fallback state on error', async () => {
128
+ const loader = jest.fn().mockRejectedValue(new Error('fail'));
129
+
130
+ const {result} = renderHook(
131
+ () => useLoader({
132
+ cacheKey: cacheKey.current(),
133
+ fallback: 'foo',
134
+ loader: loader,
135
+ }),
136
+ );
137
+
138
+ await waitFor(() => expect(result.current).toBe('foo'));
139
+
140
+ expect(loader).toHaveBeenCalled();
141
+ });
142
+
143
+ it('should extend the cache expiration on every render', async () => {
144
+ jest.useFakeTimers();
145
+
146
+ const loader = jest.fn().mockResolvedValue('foo');
147
+
148
+ const {rerender, unmount} = renderHook(
149
+ () => useLoader({
150
+ cacheKey: cacheKey.current(),
151
+ loader: loader,
152
+ expiration: 15,
153
+ }),
154
+ );
155
+
156
+ await act(flushPromises);
157
+
158
+ jest.advanceTimersByTime(14);
159
+
160
+ rerender();
161
+
162
+ jest.advanceTimersByTime(14);
163
+
164
+ rerender();
165
+
166
+ expect(loader).toHaveBeenCalledTimes(1);
167
+
168
+ jest.advanceTimersByTime(15);
169
+
170
+ unmount();
171
+
172
+ renderHook(
173
+ () => useLoader({
174
+ cacheKey: cacheKey.current(),
175
+ loader: loader,
176
+ expiration: 15,
177
+ }),
178
+ );
179
+
180
+ await act(flushPromises);
181
+
182
+ expect(loader).toHaveBeenCalledTimes(2);
183
+ });
184
+
185
+ it('should not expire the cache when the expiration is negative', async () => {
186
+ jest.useFakeTimers();
187
+
188
+ const loader = jest.fn(
189
+ () => new Promise(resolve => {
190
+ setTimeout(() => resolve('foo'), 10);
191
+ }),
192
+ );
193
+
194
+ const {rerender} = renderHook(
195
+ () => useLoader({
196
+ cacheKey: cacheKey.current(),
197
+ loader: loader,
198
+ expiration: -1,
199
+ }),
200
+ );
201
+
202
+ jest.advanceTimersByTime(10);
203
+
204
+ await act(flushPromises);
205
+
206
+ // First rerender
207
+ rerender();
208
+
209
+ // Second rerender
210
+ rerender();
211
+
212
+ expect(loader).toHaveBeenCalledTimes(1);
213
+ });
214
+
215
+ it.each<[number, number|undefined]>(
216
+ [
217
+ // [Expected elapsed time, Expiration]
218
+ [60_000, undefined],
219
+ [15_000, 15_000],
220
+ ],
221
+ )('should cache the values for %d milliseconds', async (step, expiration) => {
222
+ jest.useFakeTimers();
223
+
224
+ const delay = 10;
225
+ const loader = jest.fn(
226
+ () => new Promise(resolve => {
227
+ setTimeout(() => resolve('foo'), delay);
228
+ }),
229
+ );
230
+
231
+ const {result: firstTime} = renderHook(
232
+ () => useLoader({
233
+ cacheKey: cacheKey.current(),
234
+ expiration: expiration,
235
+ loader: loader,
236
+ }),
237
+ );
238
+
239
+ jest.advanceTimersByTime(delay);
240
+
241
+ await act(flushPromises);
242
+
243
+ await waitFor(() => expect(firstTime.current).toBe('foo'));
244
+
245
+ const {result: secondTime} = renderHook(
246
+ () => useLoader({
247
+ cacheKey: cacheKey.current(),
248
+ expiration: expiration,
249
+ loader: loader,
250
+ }),
251
+ );
252
+
253
+ expect(secondTime.current).toBe('foo');
254
+
255
+ expect(loader).toHaveBeenCalledTimes(1);
256
+
257
+ jest.advanceTimersByTime(step);
258
+
259
+ const {result: thirdTime} = renderHook(
260
+ () => useLoader({
261
+ cacheKey: cacheKey.current(),
262
+ expiration: expiration,
263
+ loader: loader,
264
+ }),
265
+ );
266
+
267
+ jest.advanceTimersByTime(delay);
268
+
269
+ await act(flushPromises);
270
+
271
+ await waitFor(() => expect(thirdTime.current).toBe('foo'));
272
+
273
+ expect(loader).toHaveBeenCalledTimes(2);
274
+ });
275
+
276
+ it('should dispose the cache on unmount', async () => {
277
+ jest.useFakeTimers();
278
+
279
+ const delay = 10;
280
+ const loader = jest.fn(
281
+ () => new Promise(resolve => {
282
+ setTimeout(() => resolve('foo'), delay);
283
+ }),
284
+ );
285
+
286
+ const {unmount} = renderHook(
287
+ () => useLoader({
288
+ cacheKey: cacheKey.current(),
289
+ expiration: 5,
290
+ loader: loader,
291
+ }),
292
+ );
293
+
294
+ jest.advanceTimersByTime(delay);
295
+
296
+ await act(flushPromises);
297
+
298
+ unmount();
299
+
300
+ jest.advanceTimersByTime(5);
301
+
302
+ await act(flushPromises);
303
+
304
+ const {result: secondTime} = renderHook(
305
+ () => useLoader({
306
+ cacheKey: cacheKey.current(),
307
+ expiration: 5,
308
+ loader: loader,
309
+ }),
310
+ );
311
+
312
+ jest.advanceTimersByTime(delay);
313
+
314
+ await act(flushPromises);
315
+
316
+ expect(loader).toHaveBeenCalledTimes(2);
317
+
318
+ await waitFor(() => expect(secondTime.current).toBe('foo'));
319
+ });
320
+ });
@@ -0,0 +1,50 @@
1
+ import {useEffect, useRef, useState} from 'react';
2
+ import {Cache, EntryOptions} from './Cache';
3
+
4
+ const cache = new Cache(60 * 1000);
5
+
6
+ export type CacheOptions<R> = EntryOptions<R> & {
7
+ initial?: R,
8
+ };
9
+
10
+ export function useLoader<R>({initial, ...options}: CacheOptions<R>): R {
11
+ const loadedValue: R|undefined = cache.get<R>(options.cacheKey)?.result;
12
+ const [value, setValue] = useState(loadedValue !== undefined ? loadedValue : initial);
13
+ const mountedRef = useRef(true);
14
+ const optionsRef = useRef(initial !== undefined ? options : undefined);
15
+
16
+ useEffect(
17
+ () => {
18
+ if (optionsRef.current !== undefined) {
19
+ try {
20
+ setValue(cache.load(optionsRef.current));
21
+ } catch (result: unknown) {
22
+ if (result instanceof Promise) {
23
+ result.then((resolvedValue: R) => {
24
+ if (mountedRef.current) {
25
+ setValue(resolvedValue);
26
+ }
27
+ });
28
+
29
+ return;
30
+ }
31
+
32
+ setValue(undefined);
33
+
34
+ return;
35
+ }
36
+ }
37
+
38
+ return () => {
39
+ mountedRef.current = false;
40
+ };
41
+ },
42
+ [],
43
+ );
44
+
45
+ if (value === undefined) {
46
+ return cache.load(options);
47
+ }
48
+
49
+ return value;
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from '@croct/plug/sdk/json';
2
+ export * from '@croct/plug/slot';
3
+ export * from './CroctProvider';
4
+ export * from './hooks';
5
+ export * from './components';
@@ -0,0 +1 @@
1
+ /// <reference types="react-scripts" />
@@ -0,0 +1,46 @@
1
+ /*
2
+ * @jest-environment node
3
+ */
4
+ import croct from '@croct/plug';
5
+ import {croct as croctPolyfill, isSsr} from './ssr-polyfills';
6
+
7
+ jest.mock(
8
+ '@croct/plug',
9
+ () => ({
10
+ plug: jest.fn(),
11
+ unplug: jest.fn(),
12
+ }),
13
+ );
14
+
15
+ describe('Croct polyfill (SSR)', () => {
16
+ it('should not plug', () => {
17
+ croctPolyfill.plug({appId: '00000000-0000-0000-0000-000000000000'});
18
+
19
+ expect(croct.plug).not.toHaveBeenCalled();
20
+ });
21
+
22
+ it('should not unplug', async () => {
23
+ await expect(croctPolyfill.unplug()).resolves.toBeUndefined();
24
+
25
+ expect(croct.unplug).not.toHaveBeenCalled();
26
+ });
27
+
28
+ it('should not initialize', () => {
29
+ expect(croctPolyfill.initialized).toBe(false);
30
+
31
+ croctPolyfill.plug({appId: '00000000-0000-0000-0000-000000000000'});
32
+
33
+ expect(croctPolyfill.initialized).toBe(false);
34
+ });
35
+
36
+ it('should not allow accessing properties other than plug or unplug', () => {
37
+ expect(() => croctPolyfill.user)
38
+ .toThrow('Property croct.user is not supported on server-side (SSR).');
39
+ });
40
+ });
41
+
42
+ describe('isSsr', () => {
43
+ it('should always return true', () => {
44
+ expect(isSsr()).toBe(true);
45
+ });
46
+ });
@@ -0,0 +1,65 @@
1
+ import croct, {Configuration} from '@croct/plug';
2
+ import {croct as croctPolyfill, isSsr} from './ssr-polyfills';
3
+ import spyOn = jest.spyOn;
4
+
5
+ describe('Croct polyfill (CSR)', () => {
6
+ beforeAll(() => {
7
+ jest.clearAllMocks();
8
+ });
9
+
10
+ const config: Configuration = {appId: '00000000-0000-0000-0000-000000000000'};
11
+
12
+ it('should delay unplugging to avoid reconnections', async () => {
13
+ jest.useFakeTimers();
14
+
15
+ const unplug = spyOn(croct, 'unplug');
16
+
17
+ const plug = spyOn(croct, 'plug');
18
+
19
+ croctPolyfill.plug(config);
20
+
21
+ expect(plug).toHaveBeenCalledTimes(1);
22
+
23
+ // First attempt: cancelling
24
+
25
+ const firstAttempt = croctPolyfill.unplug();
26
+
27
+ expect(unplug).not.toHaveBeenCalled();
28
+
29
+ croctPolyfill.plug(config);
30
+
31
+ jest.runOnlyPendingTimers();
32
+
33
+ await expect(firstAttempt).rejects.toThrow('Unplug cancelled.');
34
+
35
+ expect(unplug).not.toHaveBeenCalled();
36
+
37
+ // Second attempt: failing
38
+
39
+ unplug.mockRejectedValueOnce(new Error('Unplug failed.'));
40
+
41
+ const secondAttempt = croct.unplug();
42
+
43
+ jest.runOnlyPendingTimers();
44
+
45
+ await expect(secondAttempt).rejects.toThrow('Unplug failed.');
46
+
47
+ // Third attempt: succeeding
48
+
49
+ unplug.mockResolvedValueOnce();
50
+
51
+ const thirdAttempt = croct.unplug();
52
+
53
+ jest.runOnlyPendingTimers();
54
+
55
+ await expect(thirdAttempt).resolves.toBeUndefined();
56
+
57
+ expect(unplug).toHaveBeenCalledTimes(2);
58
+ });
59
+ });
60
+
61
+ describe('isSsr', () => {
62
+ it('should always return false', () => {
63
+ expect(isSsr()).toBe(false);
64
+ });
65
+ });
@@ -0,0 +1,68 @@
1
+ import csrPlug, {Plug} from '@croct/plug';
2
+
3
+ export function isSsr(): boolean {
4
+ return typeof window === 'undefined'
5
+ || typeof window.document === 'undefined'
6
+ || typeof window.document.createElement === 'undefined';
7
+ }
8
+
9
+ export const croct: Plug = !isSsr()
10
+ ? (function factory(): Plug {
11
+ let timeoutId: ReturnType<typeof setTimeout>|null = null;
12
+ let resolveCallback: () => void;
13
+ let rejectCallback: (reason: any) => void;
14
+
15
+ return new Proxy(csrPlug, {
16
+ get: function getProperty(target, property: keyof Plug): any {
17
+ switch (property) {
18
+ case 'plug':
19
+ if (timeoutId !== null) {
20
+ clearTimeout(timeoutId);
21
+ timeoutId = null;
22
+ rejectCallback?.(new Error('Unplug cancelled.'));
23
+ }
24
+
25
+ break;
26
+
27
+ case 'unplug':
28
+ return () => {
29
+ // Delay unplugging to avoid reconnections between remounts (e.g. strict mode).
30
+ // It can be problematic when aiming to replug the SDK with a different configuration.
31
+ // However, since it is an unusual use case and there is a log message to warn about
32
+ // the plugin being already plugged, the trade-off is worth it.
33
+ timeoutId = setTimeout(() => target.unplug().then(resolveCallback, rejectCallback), 100);
34
+
35
+ return new Promise<void>((resolve, reject) => {
36
+ resolveCallback = resolve;
37
+ rejectCallback = reject;
38
+ });
39
+ };
40
+ }
41
+
42
+ return target[property];
43
+ },
44
+ });
45
+ }())
46
+ : new Proxy(csrPlug, {
47
+ get: function getProperty(_, property: keyof Plug): any {
48
+ switch (property) {
49
+ case 'initialized':
50
+ return false;
51
+
52
+ case 'plug':
53
+ return () => {
54
+ // no-op
55
+ };
56
+
57
+ case 'unplug':
58
+ return () => Promise.resolve();
59
+
60
+ default:
61
+ throw new Error(
62
+ `Property croct.${String(property)} is not supported on server-side (SSR). `
63
+ + 'Consider refactoring the logic as a side-effect (useEffect) or a client-side callback '
64
+ + '(onClick, onChange, etc).',
65
+ );
66
+ }
67
+ },
68
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-polyfills.js","sourceRoot":"","sources":["../src/ssr-polyfills.ts"],"names":[],"mappings":";;;;;;AAAA,uDAA0C;AAE1C,SAAgB,KAAK;IACjB,OAAO,OAAO,MAAM,KAAK,WAAW;WAC7B,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW;WACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,KAAK,WAAW,CAAC;AAChE,CAAC;AAJD,sBAIC;AAEY,QAAA,KAAK,GAAS,CAAC,KAAK,EAAE;IAC/B,CAAC,CAAC,CAAC,SAAS,OAAO;QACf,IAAI,SAAS,GAAuC,IAAI,CAAC;QACzD,IAAI,eAA2B,CAAC;QAChC,IAAI,cAAqC,CAAC;QAE1C,OAAO,IAAI,KAAK,CAAC,cAAO,EAAE;YACtB,GAAG,EAAE,SAAS,WAAW,CAAC,MAAM,EAAE,QAAoB;gBAClD,QAAQ,QAAQ,EAAE;oBACd,KAAK,MAAM;wBACP,IAAI,SAAS,KAAK,IAAI,EAAE;4BACpB,YAAY,CAAC,SAAS,CAAC,CAAC;4BACxB,SAAS,GAAG,IAAI,CAAC;4BACjB,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;yBACpD;wBAED,MAAM;oBAEV,KAAK,QAAQ;wBACT,OAAO,GAAG,EAAE;4BACR,+EAA+E;4BAC/E,sFAAsF;4BACtF,oFAAoF;4BACpF,+DAA+D;4BAC/D,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,CAAC;4BAEzF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gCACzC,eAAe,GAAG,OAAO,CAAC;gCAC1B,cAAc,GAAG,MAAM,CAAC;4BAC5B,CAAC,CAAC,CAAC;wBACP,CAAC,CAAC;iBACT;gBAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC,EAAE,CAAC;IACJ,CAAC,CAAC,IAAI,KAAK,CAAC,cAAO,EAAE;QACjB,GAAG,EAAE,SAAS,WAAW,CAAC,CAAC,EAAE,QAAoB;YAC7C,QAAQ,QAAQ,EAAE;gBACd,KAAK,aAAa;oBACd,OAAO,KAAK,CAAC;gBAEjB,KAAK,MAAM;oBACP,OAAO,GAAG,EAAE;wBACR,QAAQ;oBACZ,CAAC,CAAC;gBAEN,KAAK,QAAQ;oBACT,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEnC;oBACI,MAAM,IAAI,KAAK,CACX,kBAAkB,MAAM,CAAC,QAAQ,CAAC,0CAA0C;0BAC1E,yFAAyF;0BACzF,2BAA2B,CAChC,CAAC;aACT;QACL,CAAC;KACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"ssr-polyfills.js","sourceRoot":"","sources":["src/ssr-polyfills.ts"],"names":[],"mappings":";;;;;;AAAA,uDAA0C;AAE1C,SAAgB,KAAK;IACjB,OAAO,OAAO,MAAM,KAAK,WAAW;WAC7B,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW;WACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,KAAK,WAAW,CAAC;AAChE,CAAC;AAJD,sBAIC;AAEY,QAAA,KAAK,GAAS,CAAC,KAAK,EAAE;IAC/B,CAAC,CAAC,CAAC,SAAS,OAAO;QACf,IAAI,SAAS,GAAuC,IAAI,CAAC;QACzD,IAAI,eAA2B,CAAC;QAChC,IAAI,cAAqC,CAAC;QAE1C,OAAO,IAAI,KAAK,CAAC,cAAO,EAAE;YACtB,GAAG,EAAE,SAAS,WAAW,CAAC,MAAM,EAAE,QAAoB;gBAClD,QAAQ,QAAQ,EAAE;oBACd,KAAK,MAAM;wBACP,IAAI,SAAS,KAAK,IAAI,EAAE;4BACpB,YAAY,CAAC,SAAS,CAAC,CAAC;4BACxB,SAAS,GAAG,IAAI,CAAC;4BACjB,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;yBACpD;wBAED,MAAM;oBAEV,KAAK,QAAQ;wBACT,OAAO,GAAG,EAAE;4BACR,+EAA+E;4BAC/E,sFAAsF;4BACtF,oFAAoF;4BACpF,+DAA+D;4BAC/D,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,CAAC;4BAEzF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gCACzC,eAAe,GAAG,OAAO,CAAC;gCAC1B,cAAc,GAAG,MAAM,CAAC;4BAC5B,CAAC,CAAC,CAAC;wBACP,CAAC,CAAC;iBACT;gBAED,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC,EAAE,CAAC;IACJ,CAAC,CAAC,IAAI,KAAK,CAAC,cAAO,EAAE;QACjB,GAAG,EAAE,SAAS,WAAW,CAAC,CAAC,EAAE,QAAoB;YAC7C,QAAQ,QAAQ,EAAE;gBACd,KAAK,aAAa;oBACd,OAAO,KAAK,CAAC;gBAEjB,KAAK,MAAM;oBACP,OAAO,GAAG,EAAE;wBACR,QAAQ;oBACZ,CAAC,CAAC;gBAEN,KAAK,QAAQ;oBACT,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEnC;oBACI,MAAM,IAAI,KAAK,CACX,kBAAkB,MAAM,CAAC,QAAQ,CAAC,0CAA0C;0BAC1E,yFAAyF;0BACzF,2BAA2B,CAChC,CAAC;aACT;QACL,CAAC;KACJ,CAAC,CAAC"}