@dismissible/react-client 0.3.2-canary.3.c1b8c41 → 0.3.2-canary.4.578bcba
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/README.md
CHANGED
|
@@ -100,7 +100,7 @@ import { Dismissible } from '@dismissible/react-client';
|
|
|
100
100
|
|
|
101
101
|
function WelcomeBanner() {
|
|
102
102
|
return (
|
|
103
|
-
<Dismissible
|
|
103
|
+
<Dismissible itemId="welcome-banner">
|
|
104
104
|
<div className="banner">
|
|
105
105
|
<h2>Welcome to our app!</h2>
|
|
106
106
|
<p>This banner can be dismissed and won't show again.</p>
|
|
@@ -193,22 +193,42 @@ The main component for creating dismissible content.
|
|
|
193
193
|
|
|
194
194
|
| Prop | Type | Required | Description |
|
|
195
195
|
|------|------|----------|-------------|
|
|
196
|
-
| `
|
|
196
|
+
| `itemId` | `string` | ✅ | Unique identifier for the dismissible item |
|
|
197
197
|
| `children` | `ReactNode` | ✅ | Content to render when not dismissed |
|
|
198
198
|
| `onDismiss` | `() => void` | ❌ | Callback fired when item is dismissed |
|
|
199
|
-
| `LoadingComponent` | `ComponentType<{
|
|
200
|
-
| `ErrorComponent` | `ComponentType<{
|
|
201
|
-
| `DismissButtonComponent` | `ComponentType<{
|
|
199
|
+
| `LoadingComponent` | `ComponentType<{itemId: string}>` | ❌ | Custom loading component |
|
|
200
|
+
| `ErrorComponent` | `ComponentType<{itemId: string, error: Error}>` | ❌ | Custom error component |
|
|
201
|
+
| `DismissButtonComponent` | `ComponentType<{onDismiss: () => Promise<void>, ariaLabel: string}>` | ❌ | Custom dismiss button |
|
|
202
202
|
| `ignoreErrors` | `boolean` | ❌ | Ignore errors and display component anyway (default: false) |
|
|
203
203
|
| `enableCache` | `boolean` | ❌ | Enable localStorage caching (default: true) |
|
|
204
204
|
| `cachePrefix` | `string` | ❌ | Cache key prefix (default: 'dismissible') |
|
|
205
205
|
| `cacheExpiration` | `number` | ❌ | Cache expiration time in milliseconds |
|
|
206
|
+
| `metadata` | `string[]` | ❌ | Optional metadata as key:value pairs (can be repeated) |
|
|
206
207
|
|
|
207
208
|
#### Example
|
|
208
209
|
|
|
209
210
|
```tsx
|
|
210
211
|
<Dismissible
|
|
211
|
-
|
|
212
|
+
itemId="promo-banner"
|
|
213
|
+
onDismiss={() => console.log('Banner dismissed')}
|
|
214
|
+
>
|
|
215
|
+
<div className="promo">
|
|
216
|
+
<h3>Special Offer!</h3>
|
|
217
|
+
<p>Get 50% off your first order</p>
|
|
218
|
+
</div>
|
|
219
|
+
</Dismissible>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Example with Metadata
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
<Dismissible
|
|
226
|
+
itemId="promo-banner"
|
|
227
|
+
metadata={{
|
|
228
|
+
version: 2,
|
|
229
|
+
category: "promotional",
|
|
230
|
+
campaign: "summer-sale"
|
|
231
|
+
}}
|
|
212
232
|
onDismiss={() => console.log('Banner dismissed')}
|
|
213
233
|
>
|
|
214
234
|
<div className="promo">
|
|
@@ -226,8 +246,18 @@ For custom implementations and advanced use cases.
|
|
|
226
246
|
|
|
227
247
|
| Parameter | Type | Required | Description |
|
|
228
248
|
|-----------|------|----------|-------------|
|
|
229
|
-
| `
|
|
230
|
-
| `options` | `object` | ❌ |
|
|
249
|
+
| `itemId` | `string` | ✅ | Unique identifier for the dismissible item |
|
|
250
|
+
| `options` | `object` | ❌ | Configuration options |
|
|
251
|
+
|
|
252
|
+
#### Options
|
|
253
|
+
|
|
254
|
+
| Option | Type | Required | Description |
|
|
255
|
+
|--------|------|----------|-------------|
|
|
256
|
+
| `enableCache` | `boolean` | ❌ | Enable localStorage caching (default: true) |
|
|
257
|
+
| `cachePrefix` | `string` | ❌ | Cache key prefix (default: 'dismissible') |
|
|
258
|
+
| `cacheExpiration` | `number` | ❌ | Cache expiration time in milliseconds |
|
|
259
|
+
| `metadata` | `IMetadata` | ❌ | Optional metadata object (`{ [key: string]: string \| number }`) |
|
|
260
|
+
| `initialData` | `IDismissibleItem` | ❌ | Initial data for the dismissible item |
|
|
231
261
|
|
|
232
262
|
#### Returns
|
|
233
263
|
|
|
@@ -245,8 +275,8 @@ For custom implementations and advanced use cases.
|
|
|
245
275
|
```tsx
|
|
246
276
|
import { useDismissibleItem } from '@dismissible/react-client';
|
|
247
277
|
|
|
248
|
-
function CustomDismissible({
|
|
249
|
-
const { dismissedOn, dismiss, restore, isLoading, error } = useDismissibleItem(
|
|
278
|
+
function CustomDismissible({ itemId, children }) {
|
|
279
|
+
const { dismissedOn, dismiss, restore, isLoading, error } = useDismissibleItem(itemId);
|
|
250
280
|
|
|
251
281
|
if (isLoading) {
|
|
252
282
|
return <div>Loading...</div>;
|
|
@@ -295,7 +325,7 @@ function App() {
|
|
|
295
325
|
|
|
296
326
|
function Dashboard() {
|
|
297
327
|
return (
|
|
298
|
-
<Dismissible
|
|
328
|
+
<Dismissible itemId="welcome-banner">
|
|
299
329
|
<div className="alert alert-info">
|
|
300
330
|
<h4>Welcome!</h4>
|
|
301
331
|
<p>Thanks for joining our platform. Here are some quick tips to get started.</p>
|
|
@@ -330,7 +360,7 @@ function Dashboard() {
|
|
|
330
360
|
return (
|
|
331
361
|
<div>
|
|
332
362
|
{/* Dismissible state is tracked per user */}
|
|
333
|
-
<Dismissible
|
|
363
|
+
<Dismissible itemId="user-welcome-banner">
|
|
334
364
|
<div className="alert alert-info">
|
|
335
365
|
<h4>Welcome back!</h4>
|
|
336
366
|
<p>You have 3 new notifications.</p>
|
|
@@ -359,7 +389,7 @@ const CustomDismissButton = ({ onDismiss, ariaLabel }) => (
|
|
|
359
389
|
function CustomBanner() {
|
|
360
390
|
return (
|
|
361
391
|
<Dismissible
|
|
362
|
-
|
|
392
|
+
itemId="custom-banner"
|
|
363
393
|
DismissButtonComponent={CustomDismissButton}
|
|
364
394
|
>
|
|
365
395
|
<div className="banner">
|
|
@@ -375,7 +405,7 @@ function CustomBanner() {
|
|
|
375
405
|
```tsx
|
|
376
406
|
import { Dismissible } from '@dismissible/react-client';
|
|
377
407
|
|
|
378
|
-
const CustomLoader = ({
|
|
408
|
+
const CustomLoader = ({ itemId }) => (
|
|
379
409
|
<div className="spinner">
|
|
380
410
|
<div className="bounce1"></div>
|
|
381
411
|
<div className="bounce2"></div>
|
|
@@ -396,7 +426,7 @@ const CustomError = ({ error }) => (
|
|
|
396
426
|
function AdvancedBanner() {
|
|
397
427
|
return (
|
|
398
428
|
<Dismissible
|
|
399
|
-
|
|
429
|
+
itemId="advanced-banner"
|
|
400
430
|
LoadingComponent={CustomLoader}
|
|
401
431
|
ErrorComponent={CustomError}
|
|
402
432
|
>
|
|
@@ -416,19 +446,19 @@ import { Dismissible } from '@dismissible/react-client';
|
|
|
416
446
|
function Dashboard() {
|
|
417
447
|
return (
|
|
418
448
|
<div>
|
|
419
|
-
<Dismissible
|
|
449
|
+
<Dismissible itemId="feature-announcement">
|
|
420
450
|
<div className="alert alert-success">
|
|
421
451
|
🎉 New feature: Dark mode is now available!
|
|
422
452
|
</div>
|
|
423
453
|
</Dismissible>
|
|
424
454
|
|
|
425
|
-
<Dismissible
|
|
455
|
+
<Dismissible itemId="maintenance-notice">
|
|
426
456
|
<div className="alert alert-warning">
|
|
427
457
|
⚠️ Scheduled maintenance: Sunday 2AM-4AM EST
|
|
428
458
|
</div>
|
|
429
459
|
</Dismissible>
|
|
430
460
|
|
|
431
|
-
<Dismissible
|
|
461
|
+
<Dismissible itemId="survey-request">
|
|
432
462
|
<div className="alert alert-info">
|
|
433
463
|
📝 Help us improve! Take our 2-minute survey.
|
|
434
464
|
</div>
|
|
@@ -447,7 +477,7 @@ import { Dismissible } from '@dismissible/react-client';
|
|
|
447
477
|
function RobustBanner() {
|
|
448
478
|
return (
|
|
449
479
|
<Dismissible
|
|
450
|
-
|
|
480
|
+
itemId="important-announcement"
|
|
451
481
|
ignoreErrors={true}
|
|
452
482
|
>
|
|
453
483
|
<div className="important-banner">
|
|
@@ -533,8 +563,8 @@ function AppWithTokenRefresh() {
|
|
|
533
563
|
import { useDismissibleItem } from '@dismissible/react-client';
|
|
534
564
|
import { useState, useEffect } from 'react';
|
|
535
565
|
|
|
536
|
-
function SmartNotification({
|
|
537
|
-
const { dismissedOn, dismiss, isLoading } = useDismissibleItem(
|
|
566
|
+
function SmartNotification({ itemId, message, type = 'info' }) {
|
|
567
|
+
const { dismissedOn, dismiss, isLoading } = useDismissibleItem(itemId);
|
|
538
568
|
const [autoHide, setAutoHide] = useState(false);
|
|
539
569
|
|
|
540
570
|
// Auto-hide after 10 seconds for info messages
|
|
@@ -568,6 +598,56 @@ function SmartNotification({ id, message, type = 'info' }) {
|
|
|
568
598
|
}
|
|
569
599
|
```
|
|
570
600
|
|
|
601
|
+
### Using Metadata with Dismissible Items
|
|
602
|
+
|
|
603
|
+
Metadata allows you to attach additional information to dismissible items, which can be useful for analytics, filtering, or conditional logic:
|
|
604
|
+
|
|
605
|
+
```tsx
|
|
606
|
+
import { Dismissible, useDismissibleItem } from '@dismissible/react-client';
|
|
607
|
+
|
|
608
|
+
// Using metadata with the Dismissible component (object format)
|
|
609
|
+
function PromotionalBanner({ campaignId, version }) {
|
|
610
|
+
return (
|
|
611
|
+
<Dismissible
|
|
612
|
+
itemId={`promo-${campaignId}`}
|
|
613
|
+
metadata={{
|
|
614
|
+
version: version,
|
|
615
|
+
category: "promotional",
|
|
616
|
+
campaign: campaignId,
|
|
617
|
+
}}
|
|
618
|
+
>
|
|
619
|
+
<div className="promo-banner">
|
|
620
|
+
<h3>Special Offer!</h3>
|
|
621
|
+
<p>Limited time promotion</p>
|
|
622
|
+
</div>
|
|
623
|
+
</Dismissible>
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Using metadata with the hook (same object format)
|
|
628
|
+
function CustomNotification({ itemId, category, priority }) {
|
|
629
|
+
const { dismissedOn, dismiss, isLoading } = useDismissibleItem(itemId, {
|
|
630
|
+
metadata: {
|
|
631
|
+
category,
|
|
632
|
+
priority,
|
|
633
|
+
},
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
if (dismissedOn) {
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return (
|
|
641
|
+
<div className={`notification notification-${category}`}>
|
|
642
|
+
<span>Notification content</span>
|
|
643
|
+
<button onClick={dismiss} disabled={isLoading}>
|
|
644
|
+
Dismiss
|
|
645
|
+
</button>
|
|
646
|
+
</div>
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
```
|
|
650
|
+
|
|
571
651
|
### Restoring Dismissed Items
|
|
572
652
|
|
|
573
653
|
Use the `restore` function to bring back previously dismissed content:
|
|
@@ -575,8 +655,8 @@ Use the `restore` function to bring back previously dismissed content:
|
|
|
575
655
|
```tsx
|
|
576
656
|
import { useDismissibleItem } from '@dismissible/react-client';
|
|
577
657
|
|
|
578
|
-
function RestorableBanner({
|
|
579
|
-
const { dismissedOn, dismiss, restore, isLoading } = useDismissibleItem(
|
|
658
|
+
function RestorableBanner({ itemId }) {
|
|
659
|
+
const { dismissedOn, dismiss, restore, isLoading } = useDismissibleItem(itemId);
|
|
580
660
|
|
|
581
661
|
if (dismissedOn) {
|
|
582
662
|
return (
|
|
@@ -674,10 +754,11 @@ The library includes minimal default styles. You can override them or provide yo
|
|
|
674
754
|
The library is written in TypeScript and exports all type definitions:
|
|
675
755
|
|
|
676
756
|
```tsx
|
|
677
|
-
import type {
|
|
757
|
+
import type {
|
|
678
758
|
DismissibleProps,
|
|
679
759
|
DismissibleProviderProps,
|
|
680
760
|
JwtToken,
|
|
761
|
+
IMetadata,
|
|
681
762
|
} from '@dismissible/react-client';
|
|
682
763
|
|
|
683
764
|
// Custom provider wrapper
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { IMetadata } from '../hooks/useDismissibleItem';
|
|
2
3
|
/**
|
|
3
4
|
* Props for the Dismissible component
|
|
4
5
|
*/
|
|
@@ -31,6 +32,8 @@ export interface DismissibleProps {
|
|
|
31
32
|
cacheExpiration?: number;
|
|
32
33
|
/** Ignore errors and display the component anyway (default: false) */
|
|
33
34
|
ignoreErrors?: boolean;
|
|
35
|
+
/** Optional metadata object that will be converted to key:value string pairs */
|
|
36
|
+
metadata?: IMetadata;
|
|
34
37
|
}
|
|
35
38
|
/**
|
|
36
39
|
* A wrapper component that can be dismissed and hidden by users
|
|
@@ -46,6 +49,7 @@ export interface DismissibleProps {
|
|
|
46
49
|
* @param cachePrefix - Cache key prefix
|
|
47
50
|
* @param cacheExpiration - Cache expiration time in milliseconds
|
|
48
51
|
* @param ignoreErrors - Ignore errors and display the component anyway
|
|
52
|
+
* @param metadata - Optional metadata object that will be converted to key:value string pairs
|
|
49
53
|
* @returns JSX element or null if dismissed
|
|
50
54
|
*/
|
|
51
55
|
export declare const Dismissible: React.FC<DismissibleProps>;
|
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
var he = Object.defineProperty, me = Object.defineProperties;
|
|
2
2
|
var ye = Object.getOwnPropertyDescriptors;
|
|
3
3
|
var M = Object.getOwnPropertySymbols;
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var ne = Object.prototype.hasOwnProperty, se = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var re = (e, r, t) => r in e ? he(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t, p = (e, r) => {
|
|
6
6
|
for (var t in r || (r = {}))
|
|
7
|
-
|
|
7
|
+
ne.call(r, t) && re(e, t, r[t]);
|
|
8
8
|
if (M)
|
|
9
9
|
for (var t of M(r))
|
|
10
|
-
|
|
10
|
+
se.call(r, t) && re(e, t, r[t]);
|
|
11
11
|
return e;
|
|
12
|
-
},
|
|
13
|
-
var
|
|
12
|
+
}, R = (e, r) => me(e, ye(r));
|
|
13
|
+
var V = (e, r) => {
|
|
14
14
|
var t = {};
|
|
15
15
|
for (var n in e)
|
|
16
|
-
|
|
16
|
+
ne.call(e, n) && r.indexOf(n) < 0 && (t[n] = e[n]);
|
|
17
17
|
if (e != null && M)
|
|
18
18
|
for (var n of M(e))
|
|
19
|
-
r.indexOf(n) < 0 &&
|
|
19
|
+
r.indexOf(n) < 0 && se.call(e, n) && (t[n] = e[n]);
|
|
20
20
|
return t;
|
|
21
21
|
};
|
|
22
22
|
var $ = (e, r, t) => new Promise((n, o) => {
|
|
23
23
|
var s = (f) => {
|
|
24
24
|
try {
|
|
25
|
-
|
|
26
|
-
} catch (
|
|
27
|
-
o(
|
|
25
|
+
i(t.next(f));
|
|
26
|
+
} catch (y) {
|
|
27
|
+
o(y);
|
|
28
28
|
}
|
|
29
|
-
},
|
|
29
|
+
}, u = (f) => {
|
|
30
30
|
try {
|
|
31
|
-
|
|
32
|
-
} catch (
|
|
33
|
-
o(
|
|
31
|
+
i(t.throw(f));
|
|
32
|
+
} catch (y) {
|
|
33
|
+
o(y);
|
|
34
34
|
}
|
|
35
|
-
},
|
|
36
|
-
|
|
35
|
+
}, i = (f) => f.done ? n(f.value) : Promise.resolve(f.value).then(s, u);
|
|
36
|
+
i((t = t.apply(e, r)).next());
|
|
37
37
|
});
|
|
38
|
-
import { jsx as
|
|
39
|
-
import { createContext as pe, useContext as we, useMemo as
|
|
38
|
+
import { jsx as T, jsxs as be } from "react/jsx-runtime";
|
|
39
|
+
import { createContext as pe, useContext as we, useMemo as Z, useRef as J, useState as W, useCallback as X, useEffect as _ } from "react";
|
|
40
40
|
const ge = /\{[^{}]+\}/g, Ee = () => {
|
|
41
41
|
var e, r;
|
|
42
42
|
return typeof process == "object" && Number.parseInt((r = (e = process == null ? void 0 : process.versions) == null ? void 0 : e.node) == null ? void 0 : r.substring(0, 2)) >= 18 && process.versions.undici;
|
|
43
43
|
};
|
|
44
|
-
function
|
|
44
|
+
function ve() {
|
|
45
45
|
return Math.random().toString(36).slice(2, 11);
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
let
|
|
47
|
+
function Re(e) {
|
|
48
|
+
let U = p({}, e), {
|
|
49
49
|
baseUrl: r = "",
|
|
50
50
|
Request: t = globalThis.Request,
|
|
51
51
|
fetch: n = globalThis.fetch,
|
|
52
52
|
querySerializer: o,
|
|
53
53
|
bodySerializer: s,
|
|
54
|
-
headers:
|
|
55
|
-
requestInitExt:
|
|
56
|
-
} =
|
|
54
|
+
headers: u,
|
|
55
|
+
requestInitExt: i = void 0
|
|
56
|
+
} = U, f = V(U, [
|
|
57
57
|
"baseUrl",
|
|
58
58
|
"Request",
|
|
59
59
|
"fetch",
|
|
@@ -62,23 +62,23 @@ function ve(e) {
|
|
|
62
62
|
"headers",
|
|
63
63
|
"requestInitExt"
|
|
64
64
|
]);
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
function
|
|
65
|
+
i = Ee() ? i : void 0, r = ae(r);
|
|
66
|
+
const y = [];
|
|
67
|
+
function d(l, a) {
|
|
68
68
|
return $(this, null, function* () {
|
|
69
|
-
var
|
|
70
|
-
const
|
|
71
|
-
baseUrl:
|
|
72
|
-
fetch:
|
|
73
|
-
Request:
|
|
74
|
-
headers:
|
|
75
|
-
params:
|
|
76
|
-
parseAs:
|
|
69
|
+
var te;
|
|
70
|
+
const ee = a || {}, {
|
|
71
|
+
baseUrl: v,
|
|
72
|
+
fetch: H = n,
|
|
73
|
+
Request: x = t,
|
|
74
|
+
headers: O,
|
|
75
|
+
params: E = {},
|
|
76
|
+
parseAs: A = "json",
|
|
77
77
|
querySerializer: S,
|
|
78
|
-
bodySerializer:
|
|
78
|
+
bodySerializer: j = s != null ? s : xe,
|
|
79
79
|
body: z,
|
|
80
|
-
middleware:
|
|
81
|
-
} =
|
|
80
|
+
middleware: G = []
|
|
81
|
+
} = ee, I = V(ee, [
|
|
82
82
|
"baseUrl",
|
|
83
83
|
"fetch",
|
|
84
84
|
"Request",
|
|
@@ -90,61 +90,61 @@ function ve(e) {
|
|
|
90
90
|
"body",
|
|
91
91
|
"middleware"
|
|
92
92
|
]);
|
|
93
|
-
let
|
|
94
|
-
|
|
95
|
-
let
|
|
96
|
-
S && (
|
|
97
|
-
const
|
|
93
|
+
let c = r;
|
|
94
|
+
v && (c = (te = ae(v)) != null ? te : r);
|
|
95
|
+
let b = typeof o == "function" ? o : oe(o);
|
|
96
|
+
S && (b = typeof S == "function" ? S : oe(p(p({}, typeof o == "object" ? o : {}), S)));
|
|
97
|
+
const h = z === void 0 ? void 0 : j(
|
|
98
98
|
z,
|
|
99
99
|
// Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
|
|
100
100
|
// bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,
|
|
101
101
|
// the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,
|
|
102
102
|
// setting the content-type at the very beginning to be overwritten.
|
|
103
103
|
// Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.
|
|
104
|
-
|
|
105
|
-
),
|
|
104
|
+
ie(u, O, E.header)
|
|
105
|
+
), k = ie(
|
|
106
106
|
// with no body, we should not to set Content-Type
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
h === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression
|
|
108
|
+
h instanceof FormData ? {} : {
|
|
109
109
|
"Content-Type": "application/json"
|
|
110
110
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
),
|
|
111
|
+
u,
|
|
112
|
+
O,
|
|
113
|
+
E.header
|
|
114
|
+
), C = [...y, ...G], K = R(p(p({
|
|
115
115
|
redirect: "follow"
|
|
116
|
-
}, f),
|
|
117
|
-
body:
|
|
118
|
-
headers:
|
|
116
|
+
}, f), I), {
|
|
117
|
+
body: h,
|
|
118
|
+
headers: k
|
|
119
119
|
});
|
|
120
|
-
let F, L,
|
|
121
|
-
Se(
|
|
122
|
-
|
|
120
|
+
let F, L, D = new x(
|
|
121
|
+
Se(l, { baseUrl: c, params: E, querySerializer: b }),
|
|
122
|
+
K
|
|
123
123
|
), m;
|
|
124
|
-
for (const
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
F =
|
|
128
|
-
baseUrl:
|
|
129
|
-
fetch:
|
|
130
|
-
parseAs:
|
|
131
|
-
querySerializer:
|
|
132
|
-
bodySerializer:
|
|
124
|
+
for (const g in I)
|
|
125
|
+
g in D || (D[g] = I[g]);
|
|
126
|
+
if (C.length) {
|
|
127
|
+
F = ve(), L = Object.freeze({
|
|
128
|
+
baseUrl: c,
|
|
129
|
+
fetch: H,
|
|
130
|
+
parseAs: A,
|
|
131
|
+
querySerializer: b,
|
|
132
|
+
bodySerializer: j
|
|
133
133
|
});
|
|
134
|
-
for (const
|
|
135
|
-
if (
|
|
136
|
-
const
|
|
137
|
-
request:
|
|
138
|
-
schemaPath:
|
|
139
|
-
params:
|
|
134
|
+
for (const g of C)
|
|
135
|
+
if (g && typeof g == "object" && typeof g.onRequest == "function") {
|
|
136
|
+
const w = yield g.onRequest({
|
|
137
|
+
request: D,
|
|
138
|
+
schemaPath: l,
|
|
139
|
+
params: E,
|
|
140
140
|
options: L,
|
|
141
141
|
id: F
|
|
142
142
|
});
|
|
143
|
-
if (
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
else if (
|
|
147
|
-
m =
|
|
143
|
+
if (w)
|
|
144
|
+
if (w instanceof x)
|
|
145
|
+
D = w;
|
|
146
|
+
else if (w instanceof Response) {
|
|
147
|
+
m = w;
|
|
148
148
|
break;
|
|
149
149
|
} else
|
|
150
150
|
throw new Error("onRequest: must return new Request() or Response() when modifying the request");
|
|
@@ -152,46 +152,46 @@ function ve(e) {
|
|
|
152
152
|
}
|
|
153
153
|
if (!m) {
|
|
154
154
|
try {
|
|
155
|
-
m = yield
|
|
156
|
-
} catch (
|
|
157
|
-
let
|
|
158
|
-
if (
|
|
159
|
-
for (let q =
|
|
160
|
-
const N =
|
|
155
|
+
m = yield H(D, i);
|
|
156
|
+
} catch (g) {
|
|
157
|
+
let w = g;
|
|
158
|
+
if (C.length)
|
|
159
|
+
for (let q = C.length - 1; q >= 0; q--) {
|
|
160
|
+
const N = C[q];
|
|
161
161
|
if (N && typeof N == "object" && typeof N.onError == "function") {
|
|
162
|
-
const
|
|
163
|
-
request:
|
|
164
|
-
error:
|
|
165
|
-
schemaPath:
|
|
166
|
-
params:
|
|
162
|
+
const P = yield N.onError({
|
|
163
|
+
request: D,
|
|
164
|
+
error: w,
|
|
165
|
+
schemaPath: l,
|
|
166
|
+
params: E,
|
|
167
167
|
options: L,
|
|
168
168
|
id: F
|
|
169
169
|
});
|
|
170
|
-
if (
|
|
171
|
-
if (
|
|
172
|
-
|
|
170
|
+
if (P) {
|
|
171
|
+
if (P instanceof Response) {
|
|
172
|
+
w = void 0, m = P;
|
|
173
173
|
break;
|
|
174
174
|
}
|
|
175
|
-
if (
|
|
176
|
-
|
|
175
|
+
if (P instanceof Error) {
|
|
176
|
+
w = P;
|
|
177
177
|
continue;
|
|
178
178
|
}
|
|
179
179
|
throw new Error("onError: must return new Response() or instance of Error");
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
-
if (
|
|
184
|
-
throw
|
|
183
|
+
if (w)
|
|
184
|
+
throw w;
|
|
185
185
|
}
|
|
186
|
-
if (
|
|
187
|
-
for (let
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
190
|
-
const q = yield
|
|
191
|
-
request:
|
|
186
|
+
if (C.length)
|
|
187
|
+
for (let g = C.length - 1; g >= 0; g--) {
|
|
188
|
+
const w = C[g];
|
|
189
|
+
if (w && typeof w == "object" && typeof w.onResponse == "function") {
|
|
190
|
+
const q = yield w.onResponse({
|
|
191
|
+
request: D,
|
|
192
192
|
response: m,
|
|
193
|
-
schemaPath:
|
|
194
|
-
params:
|
|
193
|
+
schemaPath: l,
|
|
194
|
+
params: E,
|
|
195
195
|
options: L,
|
|
196
196
|
id: F
|
|
197
197
|
});
|
|
@@ -203,68 +203,68 @@ function ve(e) {
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
|
-
if (m.status === 204 ||
|
|
206
|
+
if (m.status === 204 || D.method === "HEAD" || m.headers.get("Content-Length") === "0")
|
|
207
207
|
return m.ok ? { data: void 0, response: m } : { error: void 0, response: m };
|
|
208
208
|
if (m.ok)
|
|
209
|
-
return
|
|
210
|
-
let
|
|
209
|
+
return A === "stream" ? { data: m.body, response: m } : { data: yield m[A](), response: m };
|
|
210
|
+
let Q = yield m.text();
|
|
211
211
|
try {
|
|
212
|
-
|
|
213
|
-
} catch (
|
|
212
|
+
Q = JSON.parse(Q);
|
|
213
|
+
} catch (g) {
|
|
214
214
|
}
|
|
215
|
-
return { error:
|
|
215
|
+
return { error: Q, response: m };
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
return {
|
|
219
|
-
request(
|
|
220
|
-
return
|
|
219
|
+
request(l, a, v) {
|
|
220
|
+
return d(a, R(p({}, v), { method: l.toUpperCase() }));
|
|
221
221
|
},
|
|
222
222
|
/** Call a GET endpoint */
|
|
223
|
-
GET(
|
|
224
|
-
return
|
|
223
|
+
GET(l, a) {
|
|
224
|
+
return d(l, R(p({}, a), { method: "GET" }));
|
|
225
225
|
},
|
|
226
226
|
/** Call a PUT endpoint */
|
|
227
|
-
PUT(
|
|
228
|
-
return
|
|
227
|
+
PUT(l, a) {
|
|
228
|
+
return d(l, R(p({}, a), { method: "PUT" }));
|
|
229
229
|
},
|
|
230
230
|
/** Call a POST endpoint */
|
|
231
|
-
POST(
|
|
232
|
-
return
|
|
231
|
+
POST(l, a) {
|
|
232
|
+
return d(l, R(p({}, a), { method: "POST" }));
|
|
233
233
|
},
|
|
234
234
|
/** Call a DELETE endpoint */
|
|
235
|
-
DELETE(
|
|
236
|
-
return
|
|
235
|
+
DELETE(l, a) {
|
|
236
|
+
return d(l, R(p({}, a), { method: "DELETE" }));
|
|
237
237
|
},
|
|
238
238
|
/** Call a OPTIONS endpoint */
|
|
239
|
-
OPTIONS(
|
|
240
|
-
return
|
|
239
|
+
OPTIONS(l, a) {
|
|
240
|
+
return d(l, R(p({}, a), { method: "OPTIONS" }));
|
|
241
241
|
},
|
|
242
242
|
/** Call a HEAD endpoint */
|
|
243
|
-
HEAD(
|
|
244
|
-
return
|
|
243
|
+
HEAD(l, a) {
|
|
244
|
+
return d(l, R(p({}, a), { method: "HEAD" }));
|
|
245
245
|
},
|
|
246
246
|
/** Call a PATCH endpoint */
|
|
247
|
-
PATCH(
|
|
248
|
-
return
|
|
247
|
+
PATCH(l, a) {
|
|
248
|
+
return d(l, R(p({}, a), { method: "PATCH" }));
|
|
249
249
|
},
|
|
250
250
|
/** Call a TRACE endpoint */
|
|
251
|
-
TRACE(
|
|
252
|
-
return
|
|
251
|
+
TRACE(l, a) {
|
|
252
|
+
return d(l, R(p({}, a), { method: "TRACE" }));
|
|
253
253
|
},
|
|
254
254
|
/** Register middleware */
|
|
255
|
-
use(...
|
|
256
|
-
for (const a of
|
|
255
|
+
use(...l) {
|
|
256
|
+
for (const a of l)
|
|
257
257
|
if (a) {
|
|
258
258
|
if (typeof a != "object" || !("onRequest" in a || "onResponse" in a || "onError" in a))
|
|
259
259
|
throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
|
|
260
|
-
|
|
260
|
+
y.push(a);
|
|
261
261
|
}
|
|
262
262
|
},
|
|
263
263
|
/** Unregister middleware */
|
|
264
|
-
eject(...
|
|
265
|
-
for (const a of
|
|
266
|
-
const
|
|
267
|
-
|
|
264
|
+
eject(...l) {
|
|
265
|
+
for (const a of l) {
|
|
266
|
+
const v = y.indexOf(a);
|
|
267
|
+
v !== -1 && y.splice(v, 1);
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
};
|
|
@@ -278,7 +278,7 @@ function B(e, r, t) {
|
|
|
278
278
|
);
|
|
279
279
|
return `${e}=${(t == null ? void 0 : t.allowReserved) === !0 ? r : encodeURIComponent(r)}`;
|
|
280
280
|
}
|
|
281
|
-
function
|
|
281
|
+
function ue(e, r, t) {
|
|
282
282
|
if (!r || typeof r != "object")
|
|
283
283
|
return "";
|
|
284
284
|
const n = [], o = {
|
|
@@ -287,41 +287,41 @@ function le(e, r, t) {
|
|
|
287
287
|
matrix: ";"
|
|
288
288
|
}[t.style] || "&";
|
|
289
289
|
if (t.style !== "deepObject" && t.explode === !1) {
|
|
290
|
-
for (const
|
|
291
|
-
n.push(
|
|
292
|
-
const
|
|
290
|
+
for (const i in r)
|
|
291
|
+
n.push(i, t.allowReserved === !0 ? r[i] : encodeURIComponent(r[i]));
|
|
292
|
+
const u = n.join(",");
|
|
293
293
|
switch (t.style) {
|
|
294
294
|
case "form":
|
|
295
|
-
return `${e}=${
|
|
295
|
+
return `${e}=${u}`;
|
|
296
296
|
case "label":
|
|
297
|
-
return `.${
|
|
297
|
+
return `.${u}`;
|
|
298
298
|
case "matrix":
|
|
299
|
-
return `;${e}=${
|
|
299
|
+
return `;${e}=${u}`;
|
|
300
300
|
default:
|
|
301
|
-
return
|
|
301
|
+
return u;
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
|
-
for (const
|
|
305
|
-
const
|
|
306
|
-
n.push(B(
|
|
304
|
+
for (const u in r) {
|
|
305
|
+
const i = t.style === "deepObject" ? `${e}[${u}]` : u;
|
|
306
|
+
n.push(B(i, r[u], t));
|
|
307
307
|
}
|
|
308
308
|
const s = n.join(o);
|
|
309
309
|
return t.style === "label" || t.style === "matrix" ? `${o}${s}` : s;
|
|
310
310
|
}
|
|
311
|
-
function
|
|
311
|
+
function fe(e, r, t) {
|
|
312
312
|
if (!Array.isArray(r))
|
|
313
313
|
return "";
|
|
314
314
|
if (t.explode === !1) {
|
|
315
|
-
const s = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[t.style] || ",",
|
|
315
|
+
const s = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[t.style] || ",", u = (t.allowReserved === !0 ? r : r.map((i) => encodeURIComponent(i))).join(s);
|
|
316
316
|
switch (t.style) {
|
|
317
317
|
case "simple":
|
|
318
|
-
return
|
|
318
|
+
return u;
|
|
319
319
|
case "label":
|
|
320
|
-
return `.${
|
|
320
|
+
return `.${u}`;
|
|
321
321
|
case "matrix":
|
|
322
|
-
return `;${e}=${
|
|
322
|
+
return `;${e}=${u}`;
|
|
323
323
|
default:
|
|
324
|
-
return `${e}=${
|
|
324
|
+
return `${e}=${u}`;
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
const n = { simple: ",", label: ".", matrix: ";" }[t.style] || "&", o = [];
|
|
@@ -329,7 +329,7 @@ function ue(e, r, t) {
|
|
|
329
329
|
t.style === "simple" || t.style === "label" ? o.push(t.allowReserved === !0 ? s : encodeURIComponent(s)) : o.push(B(e, s, t));
|
|
330
330
|
return t.style === "label" || t.style === "matrix" ? `${n}${o.join(n)}` : o.join(n);
|
|
331
331
|
}
|
|
332
|
-
function
|
|
332
|
+
function oe(e) {
|
|
333
333
|
return function(t) {
|
|
334
334
|
const n = [];
|
|
335
335
|
if (t && typeof t == "object")
|
|
@@ -340,7 +340,7 @@ function se(e) {
|
|
|
340
340
|
if (s.length === 0)
|
|
341
341
|
continue;
|
|
342
342
|
n.push(
|
|
343
|
-
|
|
343
|
+
fe(o, s, R(p({
|
|
344
344
|
style: "form",
|
|
345
345
|
explode: !0
|
|
346
346
|
}, e == null ? void 0 : e.array), {
|
|
@@ -351,7 +351,7 @@ function se(e) {
|
|
|
351
351
|
}
|
|
352
352
|
if (typeof s == "object") {
|
|
353
353
|
n.push(
|
|
354
|
-
|
|
354
|
+
ue(o, s, R(p({
|
|
355
355
|
style: "deepObject",
|
|
356
356
|
explode: !0
|
|
357
357
|
}, e == null ? void 0 : e.object), {
|
|
@@ -370,23 +370,23 @@ function Ce(e, r) {
|
|
|
370
370
|
var n;
|
|
371
371
|
let t = e;
|
|
372
372
|
for (const o of (n = e.match(ge)) != null ? n : []) {
|
|
373
|
-
let s = o.substring(1, o.length - 1),
|
|
374
|
-
if (s.endsWith("*") && (
|
|
373
|
+
let s = o.substring(1, o.length - 1), u = !1, i = "simple";
|
|
374
|
+
if (s.endsWith("*") && (u = !0, s = s.substring(0, s.length - 1)), s.startsWith(".") ? (i = "label", s = s.substring(1)) : s.startsWith(";") && (i = "matrix", s = s.substring(1)), !r || r[s] === void 0 || r[s] === null)
|
|
375
375
|
continue;
|
|
376
376
|
const f = r[s];
|
|
377
377
|
if (Array.isArray(f)) {
|
|
378
|
-
t = t.replace(o,
|
|
378
|
+
t = t.replace(o, fe(s, f, { style: i, explode: u }));
|
|
379
379
|
continue;
|
|
380
380
|
}
|
|
381
381
|
if (typeof f == "object") {
|
|
382
|
-
t = t.replace(o,
|
|
382
|
+
t = t.replace(o, ue(s, f, { style: i, explode: u }));
|
|
383
383
|
continue;
|
|
384
384
|
}
|
|
385
|
-
if (
|
|
385
|
+
if (i === "matrix") {
|
|
386
386
|
t = t.replace(o, `;${B(s, f)}`);
|
|
387
387
|
continue;
|
|
388
388
|
}
|
|
389
|
-
t = t.replace(o,
|
|
389
|
+
t = t.replace(o, i === "label" ? `.${encodeURIComponent(f)}` : encodeURIComponent(f));
|
|
390
390
|
}
|
|
391
391
|
return t;
|
|
392
392
|
}
|
|
@@ -401,7 +401,7 @@ function Se(e, r) {
|
|
|
401
401
|
let n = r.querySerializer((s = r.params.query) != null ? s : {});
|
|
402
402
|
return n.startsWith("?") && (n = n.substring(1)), n && (t += `?${n}`), t;
|
|
403
403
|
}
|
|
404
|
-
function
|
|
404
|
+
function ie(...e) {
|
|
405
405
|
const r = new Headers();
|
|
406
406
|
for (const t of e) {
|
|
407
407
|
if (!t || typeof t != "object")
|
|
@@ -411,25 +411,25 @@ function oe(...e) {
|
|
|
411
411
|
if (s === null)
|
|
412
412
|
r.delete(o);
|
|
413
413
|
else if (Array.isArray(s))
|
|
414
|
-
for (const
|
|
415
|
-
r.append(o,
|
|
414
|
+
for (const u of s)
|
|
415
|
+
r.append(o, u);
|
|
416
416
|
else s !== void 0 && r.set(o, s);
|
|
417
417
|
}
|
|
418
418
|
return r;
|
|
419
419
|
}
|
|
420
|
-
function
|
|
420
|
+
function ae(e) {
|
|
421
421
|
return e.endsWith("/") ? e.substring(0, e.length - 1) : e;
|
|
422
422
|
}
|
|
423
|
-
const
|
|
423
|
+
const ce = (e, r, t) => {
|
|
424
424
|
try {
|
|
425
425
|
const n = `${r}_${e}`, o = localStorage.getItem(n);
|
|
426
426
|
if (!o) return null;
|
|
427
|
-
const { data: s, timestamp:
|
|
428
|
-
return t && Date.now() -
|
|
427
|
+
const { data: s, timestamp: u } = JSON.parse(o);
|
|
428
|
+
return t && Date.now() - u > t ? (localStorage.removeItem(n), null) : s;
|
|
429
429
|
} catch (n) {
|
|
430
430
|
return null;
|
|
431
431
|
}
|
|
432
|
-
},
|
|
432
|
+
}, Y = (e, r, t) => {
|
|
433
433
|
try {
|
|
434
434
|
const n = `${t}_${e}`, o = {
|
|
435
435
|
data: r,
|
|
@@ -439,184 +439,190 @@ const ae = (e, r, t) => {
|
|
|
439
439
|
} catch (n) {
|
|
440
440
|
console.warn("Failed to cache dismissible item:", n);
|
|
441
441
|
}
|
|
442
|
-
},
|
|
442
|
+
}, le = (e, r) => {
|
|
443
443
|
try {
|
|
444
444
|
const t = `${r}_${e}`;
|
|
445
445
|
localStorage.removeItem(t);
|
|
446
446
|
} catch (t) {
|
|
447
447
|
console.warn("Failed to remove cached dismissible item:", t);
|
|
448
448
|
}
|
|
449
|
-
},
|
|
449
|
+
}, de = pe(
|
|
450
450
|
null
|
|
451
451
|
), $e = () => {
|
|
452
|
-
const e = we(
|
|
452
|
+
const e = we(de);
|
|
453
453
|
if (!e)
|
|
454
454
|
throw new Error(
|
|
455
455
|
"useDismissibleContext must be used within a DismissibleProvider"
|
|
456
456
|
);
|
|
457
457
|
return e;
|
|
458
|
-
}, Ae =
|
|
459
|
-
|
|
458
|
+
}, Ae = (e) => {
|
|
459
|
+
if (e)
|
|
460
|
+
return Object.entries(e).map(([r, t]) => `${r}:${t}`);
|
|
461
|
+
}, je = "dismissible", De = (e, r = {}) => {
|
|
462
|
+
var I;
|
|
460
463
|
const {
|
|
461
464
|
initialData: t,
|
|
462
465
|
enableCache: n = !0,
|
|
463
|
-
cachePrefix: o =
|
|
464
|
-
cacheExpiration: s
|
|
465
|
-
|
|
466
|
+
cachePrefix: o = je,
|
|
467
|
+
cacheExpiration: s,
|
|
468
|
+
metadata: u
|
|
469
|
+
} = r, i = $e(), { userId: f } = i, y = Z(() => Re({
|
|
466
470
|
baseUrl: i.baseUrl,
|
|
467
471
|
headers: {}
|
|
468
|
-
}), [i.baseUrl]), d =
|
|
472
|
+
}), [i.baseUrl]), d = Z(() => `${f}-${e}`, [f, e]), U = J({
|
|
469
473
|
enableCache: n,
|
|
470
474
|
cachePrefix: o,
|
|
471
475
|
cacheExpiration: s
|
|
472
|
-
}),
|
|
476
|
+
}), l = J(e), a = J(d), v = J(null), [H, x] = W(!1), [O, E] = W(null), [A, S] = W(() => {
|
|
473
477
|
if (t) return t;
|
|
474
478
|
if (n) {
|
|
475
|
-
const c =
|
|
479
|
+
const c = ce(
|
|
476
480
|
d,
|
|
477
481
|
o,
|
|
478
482
|
s
|
|
479
483
|
);
|
|
480
484
|
if (c) return c;
|
|
481
485
|
}
|
|
482
|
-
}),
|
|
483
|
-
var
|
|
486
|
+
}), j = X(() => $(void 0, null, function* () {
|
|
487
|
+
var b;
|
|
484
488
|
if (n) {
|
|
485
|
-
const h =
|
|
489
|
+
const h = ce(
|
|
486
490
|
d,
|
|
487
491
|
o,
|
|
488
492
|
s
|
|
489
493
|
);
|
|
490
494
|
if (h != null && h.dismissedAt) {
|
|
491
|
-
|
|
495
|
+
S(h), x(!1);
|
|
492
496
|
return;
|
|
493
497
|
}
|
|
494
498
|
}
|
|
495
|
-
(
|
|
499
|
+
(b = v.current) == null || b.abort();
|
|
496
500
|
const c = new AbortController();
|
|
497
|
-
|
|
501
|
+
v.current = c, x(!0), E(null);
|
|
498
502
|
try {
|
|
499
|
-
const h = yield i.getAuthHeaders(), { data:
|
|
500
|
-
"/v1/
|
|
503
|
+
const h = yield i.getAuthHeaders(), k = Ae(u), { data: C, error: K } = yield y.GET(
|
|
504
|
+
"/v1/users/{userId}/items/{itemId}",
|
|
501
505
|
{
|
|
502
506
|
params: {
|
|
503
507
|
path: {
|
|
504
|
-
userId:
|
|
508
|
+
userId: f,
|
|
505
509
|
itemId: e
|
|
506
|
-
}
|
|
510
|
+
},
|
|
511
|
+
query: k ? { metadata: k } : void 0
|
|
507
512
|
},
|
|
508
513
|
headers: h,
|
|
509
514
|
signal: c.signal
|
|
510
515
|
}
|
|
511
516
|
);
|
|
512
|
-
if (
|
|
517
|
+
if (K || !C)
|
|
513
518
|
throw new Error("Failed to fetch dismissible item");
|
|
514
|
-
|
|
519
|
+
S(C.data), n && Y(d, C.data, o);
|
|
515
520
|
} catch (h) {
|
|
516
521
|
if (h instanceof Error && h.name === "AbortError")
|
|
517
522
|
return;
|
|
518
|
-
|
|
523
|
+
E(
|
|
519
524
|
h instanceof Error ? h : new Error("Unknown error occurred")
|
|
520
525
|
);
|
|
521
526
|
} finally {
|
|
522
|
-
|
|
527
|
+
x(!1);
|
|
523
528
|
}
|
|
524
529
|
}), [
|
|
525
530
|
e,
|
|
526
|
-
|
|
531
|
+
f,
|
|
527
532
|
d,
|
|
528
533
|
n,
|
|
529
534
|
o,
|
|
530
535
|
s,
|
|
531
|
-
|
|
536
|
+
u,
|
|
537
|
+
y,
|
|
532
538
|
i
|
|
533
539
|
]);
|
|
534
540
|
_(() => {
|
|
535
|
-
const c =
|
|
536
|
-
c ||
|
|
537
|
-
}, [e, d, t,
|
|
541
|
+
const c = l.current !== e, b = a.current !== d;
|
|
542
|
+
c || b ? (l.current = e, a.current = d, j()) : t || j();
|
|
543
|
+
}, [e, d, t, j]), _(() => () => {
|
|
538
544
|
var c;
|
|
539
|
-
(c =
|
|
545
|
+
(c = v.current) == null || c.abort();
|
|
540
546
|
}, []), _(() => {
|
|
541
|
-
const c =
|
|
542
|
-
(c.enableCache !== n || c.cachePrefix !== o || c.cacheExpiration !== s) && (c.cachePrefix !== o &&
|
|
547
|
+
const c = U.current;
|
|
548
|
+
(c.enableCache !== n || c.cachePrefix !== o || c.cacheExpiration !== s) && (c.cachePrefix !== o && le(d, c.cachePrefix), !n && c.enableCache && le(d, c.cachePrefix), U.current = {
|
|
543
549
|
enableCache: n,
|
|
544
550
|
cachePrefix: o,
|
|
545
551
|
cacheExpiration: s
|
|
546
|
-
},
|
|
547
|
-
}, [n, o, s, d,
|
|
548
|
-
const
|
|
549
|
-
|
|
552
|
+
}, j());
|
|
553
|
+
}, [n, o, s, d, j]);
|
|
554
|
+
const z = X(() => $(void 0, null, function* () {
|
|
555
|
+
E(null);
|
|
550
556
|
try {
|
|
551
|
-
const c = yield i.getAuthHeaders(), { data:
|
|
552
|
-
"/v1/
|
|
557
|
+
const c = yield i.getAuthHeaders(), { data: b, error: h } = yield y.DELETE(
|
|
558
|
+
"/v1/users/{userId}/items/{itemId}",
|
|
553
559
|
{
|
|
554
560
|
params: {
|
|
555
561
|
path: {
|
|
556
|
-
userId:
|
|
562
|
+
userId: f,
|
|
557
563
|
itemId: e
|
|
558
564
|
}
|
|
559
565
|
},
|
|
560
566
|
headers: c
|
|
561
567
|
}
|
|
562
568
|
);
|
|
563
|
-
if (h || !
|
|
569
|
+
if (h || !b)
|
|
564
570
|
throw new Error("Failed to dismiss item");
|
|
565
|
-
|
|
571
|
+
S(b.data), n && Y(d, b.data, o);
|
|
566
572
|
} catch (c) {
|
|
567
|
-
throw
|
|
573
|
+
throw E(
|
|
568
574
|
c instanceof Error ? c : new Error("Failed to dismiss item")
|
|
569
575
|
), c;
|
|
570
576
|
}
|
|
571
577
|
}), [
|
|
572
578
|
e,
|
|
573
|
-
|
|
579
|
+
f,
|
|
574
580
|
d,
|
|
575
581
|
n,
|
|
576
582
|
o,
|
|
577
|
-
|
|
583
|
+
y,
|
|
578
584
|
i
|
|
579
|
-
]),
|
|
580
|
-
|
|
585
|
+
]), G = X(() => $(void 0, null, function* () {
|
|
586
|
+
E(null);
|
|
581
587
|
try {
|
|
582
|
-
const c = yield i.getAuthHeaders(), { data:
|
|
583
|
-
"/v1/
|
|
588
|
+
const c = yield i.getAuthHeaders(), { data: b, error: h } = yield y.POST(
|
|
589
|
+
"/v1/users/{userId}/items/{itemId}",
|
|
584
590
|
{
|
|
585
591
|
params: {
|
|
586
592
|
path: {
|
|
587
|
-
userId:
|
|
593
|
+
userId: f,
|
|
588
594
|
itemId: e
|
|
589
595
|
}
|
|
590
596
|
},
|
|
591
597
|
headers: c
|
|
592
598
|
}
|
|
593
599
|
);
|
|
594
|
-
if (h || !
|
|
600
|
+
if (h || !b)
|
|
595
601
|
throw new Error("Failed to restore item");
|
|
596
|
-
|
|
602
|
+
S(b.data), n && Y(d, b.data, o);
|
|
597
603
|
} catch (c) {
|
|
598
|
-
throw
|
|
604
|
+
throw E(
|
|
599
605
|
c instanceof Error ? c : new Error("Failed to restore item")
|
|
600
606
|
), c;
|
|
601
607
|
}
|
|
602
608
|
}), [
|
|
603
609
|
e,
|
|
604
|
-
|
|
610
|
+
f,
|
|
605
611
|
d,
|
|
606
612
|
n,
|
|
607
613
|
o,
|
|
608
|
-
|
|
614
|
+
y,
|
|
609
615
|
i
|
|
610
616
|
]);
|
|
611
617
|
return {
|
|
612
|
-
dismissedOn: (
|
|
613
|
-
dismiss:
|
|
614
|
-
restore:
|
|
615
|
-
isLoading:
|
|
618
|
+
dismissedOn: (I = A == null ? void 0 : A.dismissedAt) != null ? I : null,
|
|
619
|
+
dismiss: z,
|
|
620
|
+
restore: G,
|
|
621
|
+
isLoading: H,
|
|
616
622
|
error: O,
|
|
617
|
-
item:
|
|
623
|
+
item: A
|
|
618
624
|
};
|
|
619
|
-
},
|
|
625
|
+
}, Te = () => /* @__PURE__ */ T("div", { className: "dismissible-loading", "aria-live": "polite", children: "Loading..." }), Ue = () => /* @__PURE__ */ T("div", { className: "dismissible-error", role: "alert", children: "Unable to load content. Please try again later." }), qe = ({ onDismiss: e, ariaLabel: r }) => /* @__PURE__ */ T(
|
|
620
626
|
"button",
|
|
621
627
|
{
|
|
622
628
|
className: "dismissible-button",
|
|
@@ -625,40 +631,42 @@ const ae = (e, r, t) => {
|
|
|
625
631
|
type: "button",
|
|
626
632
|
children: "×"
|
|
627
633
|
}
|
|
628
|
-
),
|
|
634
|
+
), Fe = ({
|
|
629
635
|
itemId: e,
|
|
630
636
|
children: r,
|
|
631
637
|
onDismiss: t,
|
|
632
|
-
LoadingComponent: n =
|
|
633
|
-
ErrorComponent: o =
|
|
634
|
-
DismissButtonComponent: s =
|
|
635
|
-
enableCache:
|
|
636
|
-
cachePrefix:
|
|
638
|
+
LoadingComponent: n = Te,
|
|
639
|
+
ErrorComponent: o = Ue,
|
|
640
|
+
DismissButtonComponent: s = qe,
|
|
641
|
+
enableCache: u,
|
|
642
|
+
cachePrefix: i,
|
|
637
643
|
cacheExpiration: f,
|
|
638
|
-
ignoreErrors:
|
|
644
|
+
ignoreErrors: y = !1,
|
|
645
|
+
metadata: d
|
|
639
646
|
}) => {
|
|
640
|
-
const { dismissedOn:
|
|
647
|
+
const { dismissedOn: U, isLoading: l, error: a, dismiss: v } = De(
|
|
641
648
|
e,
|
|
642
649
|
{
|
|
643
|
-
enableCache:
|
|
644
|
-
cachePrefix:
|
|
645
|
-
cacheExpiration: f
|
|
650
|
+
enableCache: u,
|
|
651
|
+
cachePrefix: i,
|
|
652
|
+
cacheExpiration: f,
|
|
653
|
+
metadata: d
|
|
646
654
|
}
|
|
647
|
-
), [
|
|
655
|
+
), [H, x] = W(!1);
|
|
648
656
|
_(() => {
|
|
649
|
-
|
|
657
|
+
x(!1);
|
|
650
658
|
}, [e]);
|
|
651
659
|
const O = () => $(void 0, null, function* () {
|
|
652
|
-
|
|
660
|
+
x(!0);
|
|
653
661
|
try {
|
|
654
|
-
yield
|
|
655
|
-
} catch (
|
|
656
|
-
|
|
662
|
+
yield v(), t == null || t();
|
|
663
|
+
} catch (E) {
|
|
664
|
+
x(!1);
|
|
657
665
|
}
|
|
658
666
|
});
|
|
659
|
-
return
|
|
660
|
-
/* @__PURE__ */
|
|
661
|
-
s ? /* @__PURE__ */
|
|
667
|
+
return l && n ? /* @__PURE__ */ T(n, { itemId: e }) : l && !n ? null : a && o && !y ? /* @__PURE__ */ T(o, { itemId: e, error: a }) : U || H ? null : /* @__PURE__ */ be("div", { className: "dismissible-container", children: [
|
|
668
|
+
/* @__PURE__ */ T("div", { className: "dismissible-content", children: r }),
|
|
669
|
+
s ? /* @__PURE__ */ T(
|
|
662
670
|
s,
|
|
663
671
|
{
|
|
664
672
|
onDismiss: O,
|
|
@@ -676,45 +684,45 @@ const ae = (e, r, t) => {
|
|
|
676
684
|
return;
|
|
677
685
|
}
|
|
678
686
|
return e;
|
|
679
|
-
}),
|
|
687
|
+
}), Oe = (e) => $(void 0, null, function* () {
|
|
680
688
|
const r = yield He(e);
|
|
681
689
|
return r ? { Authorization: `Bearer ${r}` } : {};
|
|
682
|
-
}),
|
|
690
|
+
}), Ie = (e) => {
|
|
683
691
|
try {
|
|
684
692
|
const r = new URL(e), t = r.hostname === "localhost" || r.hostname === "127.0.0.1" || r.hostname === "[::1]", n = r.protocol === "https:";
|
|
685
693
|
return { isSecure: n || t, isLocalhost: t, isHttps: n };
|
|
686
694
|
} catch (r) {
|
|
687
695
|
return { isSecure: !1, isLocalhost: !1, isHttps: !1 };
|
|
688
696
|
}
|
|
689
|
-
},
|
|
697
|
+
}, Le = ({
|
|
690
698
|
userId: e,
|
|
691
699
|
jwt: r,
|
|
692
700
|
baseUrl: t,
|
|
693
701
|
children: n
|
|
694
702
|
}) => {
|
|
695
|
-
const { isSecure: o } =
|
|
703
|
+
const { isSecure: o } = Ie(t);
|
|
696
704
|
o || console.warn(
|
|
697
705
|
`[dismissible] Insecure baseUrl "${t}". Use https:// in production (or localhost for development). JWT tokens may be exposed over insecure connections.`
|
|
698
706
|
);
|
|
699
|
-
const s =
|
|
707
|
+
const s = Z(
|
|
700
708
|
() => ({
|
|
701
709
|
userId: e,
|
|
702
710
|
jwt: r,
|
|
703
711
|
baseUrl: t,
|
|
704
712
|
getAuthHeaders: () => $(void 0, null, function* () {
|
|
705
|
-
return yield
|
|
713
|
+
return yield Oe(r);
|
|
706
714
|
})
|
|
707
715
|
}),
|
|
708
716
|
[e, r, t]
|
|
709
717
|
);
|
|
710
|
-
return /* @__PURE__ */
|
|
718
|
+
return /* @__PURE__ */ T(de.Provider, { value: s, children: n });
|
|
711
719
|
};
|
|
712
720
|
export {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
721
|
+
Fe as Dismissible,
|
|
722
|
+
de as DismissibleContext,
|
|
723
|
+
Le as DismissibleProvider,
|
|
724
|
+
Oe as getAuthHeaders,
|
|
717
725
|
He as resolveJwt,
|
|
718
726
|
$e as useDismissibleContext,
|
|
719
|
-
|
|
727
|
+
De as useDismissibleItem
|
|
720
728
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(c,d){typeof exports=="object"&&typeof module!="undefined"?d(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],d):(c=typeof globalThis!="undefined"?globalThis:c||self,d(c.DismissibleClient={},c.React.jsxRuntime,c.React))})(this,function(c,d,o){"use strict";var Ae=Object.defineProperty,$e=Object.defineProperties;var Te=Object.getOwnPropertyDescriptors;var Q=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var me=(c,d,o)=>d in c?Ae(c,d,{enumerable:!0,configurable:!0,writable:!0,value:o}):c[d]=o,g=(c,d)=>{for(var o in d||(d={}))ye.call(d,o)&&me(c,o,d[o]);if(Q)for(var o of Q(d))be.call(d,o)&&me(c,o,d[o]);return c},S=(c,d)=>$e(c,Te(d));var re=(c,d)=>{var o={};for(var R in c)ye.call(c,R)&&d.indexOf(R)<0&&(o[R]=c[R]);if(c!=null&&Q)for(var R of Q(c))d.indexOf(R)<0&&be.call(c,R)&&(o[R]=c[R]);return o};var U=(c,d,o)=>new Promise((R,M)=>{var V=j=>{try{q(o.next(j))}catch(F){M(F)}},X=j=>{try{q(o.throw(j))}catch(F){M(F)}},q=j=>j.done?R(j.value):Promise.resolve(j.value).then(V,X);q((o=o.apply(c,d)).next())});const R=/\{[^{}]+\}/g,M=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function V(){return Math.random().toString(36).slice(2,11)}function X(e){let H=g({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:n=globalThis.fetch,querySerializer:i,bodySerializer:s,headers:a,requestInitExt:h=void 0}=H,b=re(H,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);h=M()?h:void 0,r=ie(r);const m=[];function C(f,l){return U(this,null,function*(){var he;const de=l||{},{baseUrl:x,fetch:A=n,Request:L=t,headers:$,params:D={},parseAs:O="json",querySerializer:T,bodySerializer:J=s!=null?s:pe,body:W,middleware:_=[]}=de,u=re(de,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body","middleware"]);let p=r;x&&(p=(he=ie(x))!=null?he:r);let y=typeof i=="function"?i:se(i);T&&(y=typeof T=="function"?T:se(g(g({},typeof i=="object"?i:{}),T)));const k=W===void 0?void 0:J(W,ne(a,$,D.header)),ee=ne(k===void 0||k instanceof FormData?{}:{"Content-Type":"application/json"},a,$,D.header),P=[...m,..._],je=S(g(g({redirect:"follow"},b),u),{body:k,headers:ee});let B,G,I=new L(ge(f,{baseUrl:p,params:D,querySerializer:y}),je),w;for(const v in u)v in I||(I[v]=u[v]);if(P.length){B=V(),G=Object.freeze({baseUrl:p,fetch:A,parseAs:O,querySerializer:y,bodySerializer:J});for(const v of P)if(v&&typeof v=="object"&&typeof v.onRequest=="function"){const E=yield v.onRequest({request:I,schemaPath:f,params:D,options:G,id:B});if(E)if(E instanceof L)I=E;else if(E instanceof Response){w=E;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!w){try{w=yield A(I,h)}catch(v){let E=v;if(P.length)for(let z=P.length-1;z>=0;z--){const K=P[z];if(K&&typeof K=="object"&&typeof K.onError=="function"){const N=yield K.onError({request:I,error:E,schemaPath:f,params:D,options:G,id:B});if(N){if(N instanceof Response){E=void 0,w=N;break}if(N instanceof Error){E=N;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(E)throw E}if(P.length)for(let v=P.length-1;v>=0;v--){const E=P[v];if(E&&typeof E=="object"&&typeof E.onResponse=="function"){const z=yield E.onResponse({request:I,response:w,schemaPath:f,params:D,options:G,id:B});if(z){if(!(z instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");w=z}}}}if(w.status===204||I.method==="HEAD"||w.headers.get("Content-Length")==="0")return w.ok?{data:void 0,response:w}:{error:void 0,response:w};if(w.ok)return O==="stream"?{data:w.body,response:w}:{data:yield w[O](),response:w};let te=yield w.text();try{te=JSON.parse(te)}catch(v){}return{error:te,response:w}})}return{request(f,l,x){return C(l,S(g({},x),{method:f.toUpperCase()}))},GET(f,l){return C(f,S(g({},l),{method:"GET"}))},PUT(f,l){return C(f,S(g({},l),{method:"PUT"}))},POST(f,l){return C(f,S(g({},l),{method:"POST"}))},DELETE(f,l){return C(f,S(g({},l),{method:"DELETE"}))},OPTIONS(f,l){return C(f,S(g({},l),{method:"OPTIONS"}))},HEAD(f,l){return C(f,S(g({},l),{method:"HEAD"}))},PATCH(f,l){return C(f,S(g({},l),{method:"PATCH"}))},TRACE(f,l){return C(f,S(g({},l),{method:"TRACE"}))},use(...f){for(const l of f)if(l){if(typeof l!="object"||!("onRequest"in l||"onResponse"in l||"onError"in l))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");m.push(l)}},eject(...f){for(const l of f){const x=m.indexOf(l);x!==-1&&m.splice(x,1)}}}}function q(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function j(e,r,t){if(!r||typeof r!="object")return"";const n=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const h in r)n.push(h,t.allowReserved===!0?r[h]:encodeURIComponent(r[h]));const a=n.join(",");switch(t.style){case"form":return`${e}=${a}`;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return a}}for(const a in r){const h=t.style==="deepObject"?`${e}[${a}]`:a;n.push(q(h,r[a],t))}const s=n.join(i);return t.style==="label"||t.style==="matrix"?`${i}${s}`:s}function F(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",a=(t.allowReserved===!0?r:r.map(h=>encodeURIComponent(h))).join(s);switch(t.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return`${e}=${a}`}}const n={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(const s of r)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?s:encodeURIComponent(s)):i.push(q(e,s,t));return t.style==="label"||t.style==="matrix"?`${n}${i.join(n)}`:i.join(n)}function se(e){return function(t){const n=[];if(t&&typeof t=="object")for(const i in t){const s=t[i];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;n.push(F(i,s,S(g({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){n.push(j(i,s,S(g({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}n.push(q(i,s,e))}}return n.join("&")}}function we(e,r){var n;let t=e;for(const i of(n=e.match(R))!=null?n:[]){let s=i.substring(1,i.length-1),a=!1,h="simple";if(s.endsWith("*")&&(a=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(h="label",s=s.substring(1)):s.startsWith(";")&&(h="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const b=r[s];if(Array.isArray(b)){t=t.replace(i,F(s,b,{style:h,explode:a}));continue}if(typeof b=="object"){t=t.replace(i,j(s,b,{style:h,explode:a}));continue}if(h==="matrix"){t=t.replace(i,`;${q(s,b)}`);continue}t=t.replace(i,h==="label"?`.${encodeURIComponent(b)}`:encodeURIComponent(b))}return t}function pe(e,r){var t,n;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(n=r["Content-Type"])!=null?n:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function ge(e,r){var i,s;let t=`${r.baseUrl}${e}`;(i=r.params)!=null&&i.path&&(t=we(t,r.params.path));let n=r.querySerializer((s=r.params.query)!=null?s:{});return n.startsWith("?")&&(n=n.substring(1)),n&&(t+=`?${n}`),t}function ne(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const n=t instanceof Headers?t.entries():Object.entries(t);for(const[i,s]of n)if(s===null)r.delete(i);else if(Array.isArray(s))for(const a of s)r.append(i,a);else s!==void 0&&r.set(i,s)}return r}function ie(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const oe=(e,r,t)=>{try{const n=`${r}_${e}`,i=localStorage.getItem(n);if(!i)return null;const{data:s,timestamp:a}=JSON.parse(i);return t&&Date.now()-a>t?(localStorage.removeItem(n),null):s}catch(n){return null}},Y=(e,r,t)=>{try{const n=`${t}_${e}`,i={data:r,timestamp:Date.now()};localStorage.setItem(n,JSON.stringify(i))}catch(n){console.warn("Failed to cache dismissible item:",n)}},ae=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},Z=o.createContext(null),ce=()=>{const e=o.useContext(Z);if(!e)throw new Error("useDismissibleContext must be used within a DismissibleProvider");return e},Ee="dismissible",le=(e,r={})=>{var _;const{initialData:t,enableCache:n=!0,cachePrefix:i=Ee,cacheExpiration:s}=r,a=ce(),{userId:h}=a,b=o.useMemo(()=>X({baseUrl:a.baseUrl,headers:{}}),[a.baseUrl]),m=o.useMemo(()=>`${h}-${e}`,[h,e]),C=o.useRef({enableCache:n,cachePrefix:i,cacheExpiration:s}),H=o.useRef(e),f=o.useRef(m),l=o.useRef(null),[x,A]=o.useState(!1),[L,$]=o.useState(null),[D,O]=o.useState(()=>{if(t)return t;if(n){const u=oe(m,i,s);if(u)return u}}),T=o.useCallback(()=>U(this,null,function*(){var p;if(n){const y=oe(m,i,s);if(y!=null&&y.dismissedAt){O(y),A(!1);return}}(p=l.current)==null||p.abort();const u=new AbortController;l.current=u,A(!0),$(null);try{const y=yield a.getAuthHeaders(),{data:k,error:ee}=yield b.GET("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:y,signal:u.signal});if(ee||!k)throw new Error("Failed to fetch dismissible item");O(k.data),n&&Y(m,k.data,i)}catch(y){if(y instanceof Error&&y.name==="AbortError")return;$(y instanceof Error?y:new Error("Unknown error occurred"))}finally{A(!1)}}),[e,h,m,n,i,s,b,a]);o.useEffect(()=>{const u=H.current!==e,p=f.current!==m;u||p?(H.current=e,f.current=m,T()):t||T()},[e,m,t,T]),o.useEffect(()=>()=>{var u;(u=l.current)==null||u.abort()},[]),o.useEffect(()=>{const u=C.current;(u.enableCache!==n||u.cachePrefix!==i||u.cacheExpiration!==s)&&(u.cachePrefix!==i&&ae(m,u.cachePrefix),!n&&u.enableCache&&ae(m,u.cachePrefix),C.current={enableCache:n,cachePrefix:i,cacheExpiration:s},T())},[n,i,s,m,T]);const J=o.useCallback(()=>U(this,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.DELETE("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to dismiss item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to dismiss item")),u}}),[e,h,m,n,i,b,a]),W=o.useCallback(()=>U(this,null,function*(){$(null);try{const u=yield a.getAuthHeaders(),{data:p,error:y}=yield b.POST("/v1/user/{userId}/dismissible-item/{itemId}",{params:{path:{userId:h,itemId:e}},headers:u});if(y||!p)throw new Error("Failed to restore item");O(p.data),n&&Y(m,p.data,i)}catch(u){throw $(u instanceof Error?u:new Error("Failed to restore item")),u}}),[e,h,m,n,i,b,a]);return{dismissedOn:(_=D==null?void 0:D.dismissedAt)!=null?_:null,dismiss:J,restore:W,isLoading:x,error:L,item:D}},ve=()=>d.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Ce=()=>d.jsx("div",{className:"dismissible-error",role:"alert",children:"Unable to load content. Please try again later."}),Re=({onDismiss:e,ariaLabel:r})=>d.jsx("button",{className:"dismissible-button",onClick:e,"aria-label":r,type:"button",children:"×"}),Se=({itemId:e,children:r,onDismiss:t,LoadingComponent:n=ve,ErrorComponent:i=Ce,DismissButtonComponent:s=Re,enableCache:a,cachePrefix:h,cacheExpiration:b,ignoreErrors:m=!1})=>{const{dismissedOn:C,isLoading:H,error:f,dismiss:l}=le(e,{enableCache:a,cachePrefix:h,cacheExpiration:b}),[x,A]=o.useState(!1);o.useEffect(()=>{A(!1)},[e]);const L=()=>U(this,null,function*(){A(!0);try{yield l(),t==null||t()}catch($){A(!1)}});return H&&n?d.jsx(n,{itemId:e}):H&&!n?null:f&&i&&!m?d.jsx(i,{itemId:e,error:f}):C||x?null:d.jsxs("div",{className:"dismissible-container",children:[d.jsx("div",{className:"dismissible-content",children:r}),s?d.jsx(s,{onDismiss:L,ariaLabel:`Dismiss ${e}`}):null]})},ue=e=>U(this,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),fe=e=>U(this,null,function*(){const r=yield ue(e);return r?{Authorization:`Bearer ${r}`}:{}}),xe=e=>{try{const r=new URL(e),t=r.hostname==="localhost"||r.hostname==="127.0.0.1"||r.hostname==="[::1]",n=r.protocol==="https:";return{isSecure:n||t,isLocalhost:t,isHttps:n}}catch(r){return{isSecure:!1,isLocalhost:!1,isHttps:!1}}},De=({userId:e,jwt:r,baseUrl:t,children:n})=>{const{isSecure:i}=xe(t);i||console.warn(`[dismissible] Insecure baseUrl "${t}". Use https:// in production (or localhost for development). JWT tokens may be exposed over insecure connections.`);const s=o.useMemo(()=>({userId:e,jwt:r,baseUrl:t,getAuthHeaders:()=>U(this,null,function*(){return yield fe(r)})}),[e,r,t]);return d.jsx(Z.Provider,{value:s,children:n})};c.Dismissible=Se,c.DismissibleContext=Z,c.DismissibleProvider=De,c.getAuthHeaders=fe,c.resolveJwt=ue,c.useDismissibleContext=ce,c.useDismissibleItem=le,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(a,f){typeof exports=="object"&&typeof module!="undefined"?f(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],f):(a=typeof globalThis!="undefined"?globalThis:a||self,f(a.DismissibleClient={},a.React.jsxRuntime,a.React))})(this,function(a,f,o){"use strict";var $e=Object.defineProperty,Te=Object.defineProperties;var Ue=Object.getOwnPropertyDescriptors;var Q=Object.getOwnPropertySymbols;var be=Object.prototype.hasOwnProperty,we=Object.prototype.propertyIsEnumerable;var ye=(a,f,o)=>f in a?$e(a,f,{enumerable:!0,configurable:!0,writable:!0,value:o}):a[f]=o,g=(a,f)=>{for(var o in f||(f={}))be.call(f,o)&&ye(a,o,f[o]);if(Q)for(var o of Q(f))we.call(f,o)&&ye(a,o,f[o]);return a},x=(a,f)=>Te(a,Ue(f));var se=(a,f)=>{var o={};for(var R in a)be.call(a,R)&&f.indexOf(R)<0&&(o[R]=a[R]);if(a!=null&&Q)for(var R of Q(a))f.indexOf(R)<0&&we.call(a,R)&&(o[R]=a[R]);return o};var U=(a,f,o)=>new Promise((R,J)=>{var V=D=>{try{q(o.next(D))}catch(z){J(z)}},X=D=>{try{q(o.throw(D))}catch(z){J(z)}},q=D=>D.done?R(D.value):Promise.resolve(D.value).then(V,X);q((o=o.apply(a,f)).next())});const R=/\{[^{}]+\}/g,J=()=>{var e,r;return typeof process=="object"&&Number.parseInt((r=(e=process==null?void 0:process.versions)==null?void 0:e.node)==null?void 0:r.substring(0,2))>=18&&process.versions.undici};function V(){return Math.random().toString(36).slice(2,11)}function X(e){let I=g({},e),{baseUrl:r="",Request:t=globalThis.Request,fetch:n=globalThis.fetch,querySerializer:i,bodySerializer:s,headers:h,requestInitExt:d=void 0}=I,y=se(I,["baseUrl","Request","fetch","querySerializer","bodySerializer","headers","requestInitExt"]);d=J()?d:void 0,r=oe(r);const S=[];function m(u,c){return U(this,null,function*(){var me;const he=c||{},{baseUrl:j,fetch:F=n,Request:$=t,headers:L,params:C={},parseAs:H="json",querySerializer:T,bodySerializer:O=s!=null?s:ge,body:W,middleware:ee=[]}=he,N=se(he,["baseUrl","fetch","Request","headers","params","parseAs","querySerializer","bodySerializer","body","middleware"]);let l=r;j&&(l=(me=oe(j))!=null?me:r);let p=typeof i=="function"?i:ne(i);T&&(p=typeof T=="function"?T:ne(g(g({},typeof i=="object"?i:{}),T)));const b=W===void 0?void 0:O(W,ie(h,L,C.header)),_=ie(b===void 0||b instanceof FormData?{}:{"Content-Type":"application/json"},h,L,C.header),A=[...S,...ee],te=x(g(g({redirect:"follow"},y),N),{body:b,headers:_});let B,G,P=new $(Ee(u,{baseUrl:l,params:C,querySerializer:p}),te),w;for(const v in N)v in P||(P[v]=N[v]);if(A.length){B=V(),G=Object.freeze({baseUrl:l,fetch:F,parseAs:H,querySerializer:p,bodySerializer:O});for(const v of A)if(v&&typeof v=="object"&&typeof v.onRequest=="function"){const E=yield v.onRequest({request:P,schemaPath:u,params:C,options:G,id:B});if(E)if(E instanceof $)P=E;else if(E instanceof Response){w=E;break}else throw new Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!w){try{w=yield F(P,d)}catch(v){let E=v;if(A.length)for(let k=A.length-1;k>=0;k--){const K=A[k];if(K&&typeof K=="object"&&typeof K.onError=="function"){const M=yield K.onError({request:P,error:E,schemaPath:u,params:C,options:G,id:B});if(M){if(M instanceof Response){E=void 0,w=M;break}if(M instanceof Error){E=M;continue}throw new Error("onError: must return new Response() or instance of Error")}}}if(E)throw E}if(A.length)for(let v=A.length-1;v>=0;v--){const E=A[v];if(E&&typeof E=="object"&&typeof E.onResponse=="function"){const k=yield E.onResponse({request:P,response:w,schemaPath:u,params:C,options:G,id:B});if(k){if(!(k instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");w=k}}}}if(w.status===204||P.method==="HEAD"||w.headers.get("Content-Length")==="0")return w.ok?{data:void 0,response:w}:{error:void 0,response:w};if(w.ok)return H==="stream"?{data:w.body,response:w}:{data:yield w[H](),response:w};let re=yield w.text();try{re=JSON.parse(re)}catch(v){}return{error:re,response:w}})}return{request(u,c,j){return m(c,x(g({},j),{method:u.toUpperCase()}))},GET(u,c){return m(u,x(g({},c),{method:"GET"}))},PUT(u,c){return m(u,x(g({},c),{method:"PUT"}))},POST(u,c){return m(u,x(g({},c),{method:"POST"}))},DELETE(u,c){return m(u,x(g({},c),{method:"DELETE"}))},OPTIONS(u,c){return m(u,x(g({},c),{method:"OPTIONS"}))},HEAD(u,c){return m(u,x(g({},c),{method:"HEAD"}))},PATCH(u,c){return m(u,x(g({},c),{method:"PATCH"}))},TRACE(u,c){return m(u,x(g({},c),{method:"TRACE"}))},use(...u){for(const c of u)if(c){if(typeof c!="object"||!("onRequest"in c||"onResponse"in c||"onError"in c))throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");S.push(c)}},eject(...u){for(const c of u){const j=S.indexOf(c);j!==-1&&S.splice(j,1)}}}}function q(e,r,t){if(r==null)return"";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${(t==null?void 0:t.allowReserved)===!0?r:encodeURIComponent(r)}`}function D(e,r,t){if(!r||typeof r!="object")return"";const n=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(const d in r)n.push(d,t.allowReserved===!0?r[d]:encodeURIComponent(r[d]));const h=n.join(",");switch(t.style){case"form":return`${e}=${h}`;case"label":return`.${h}`;case"matrix":return`;${e}=${h}`;default:return h}}for(const h in r){const d=t.style==="deepObject"?`${e}[${h}]`:h;n.push(q(d,r[h],t))}const s=n.join(i);return t.style==="label"||t.style==="matrix"?`${i}${s}`:s}function z(e,r,t){if(!Array.isArray(r))return"";if(t.explode===!1){const s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",h=(t.allowReserved===!0?r:r.map(d=>encodeURIComponent(d))).join(s);switch(t.style){case"simple":return h;case"label":return`.${h}`;case"matrix":return`;${e}=${h}`;default:return`${e}=${h}`}}const n={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(const s of r)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?s:encodeURIComponent(s)):i.push(q(e,s,t));return t.style==="label"||t.style==="matrix"?`${n}${i.join(n)}`:i.join(n)}function ne(e){return function(t){const n=[];if(t&&typeof t=="object")for(const i in t){const s=t[i];if(s!=null){if(Array.isArray(s)){if(s.length===0)continue;n.push(z(i,s,x(g({style:"form",explode:!0},e==null?void 0:e.array),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}if(typeof s=="object"){n.push(D(i,s,x(g({style:"deepObject",explode:!0},e==null?void 0:e.object),{allowReserved:(e==null?void 0:e.allowReserved)||!1})));continue}n.push(q(i,s,e))}}return n.join("&")}}function pe(e,r){var n;let t=e;for(const i of(n=e.match(R))!=null?n:[]){let s=i.substring(1,i.length-1),h=!1,d="simple";if(s.endsWith("*")&&(h=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(d="label",s=s.substring(1)):s.startsWith(";")&&(d="matrix",s=s.substring(1)),!r||r[s]===void 0||r[s]===null)continue;const y=r[s];if(Array.isArray(y)){t=t.replace(i,z(s,y,{style:d,explode:h}));continue}if(typeof y=="object"){t=t.replace(i,D(s,y,{style:d,explode:h}));continue}if(d==="matrix"){t=t.replace(i,`;${q(s,y)}`);continue}t=t.replace(i,d==="label"?`.${encodeURIComponent(y)}`:encodeURIComponent(y))}return t}function ge(e,r){var t,n;return e instanceof FormData?e:r&&(r.get instanceof Function?(t=r.get("Content-Type"))!=null?t:r.get("content-type"):(n=r["Content-Type"])!=null?n:r["content-type"])==="application/x-www-form-urlencoded"?new URLSearchParams(e).toString():JSON.stringify(e)}function Ee(e,r){var i,s;let t=`${r.baseUrl}${e}`;(i=r.params)!=null&&i.path&&(t=pe(t,r.params.path));let n=r.querySerializer((s=r.params.query)!=null?s:{});return n.startsWith("?")&&(n=n.substring(1)),n&&(t+=`?${n}`),t}function ie(...e){const r=new Headers;for(const t of e){if(!t||typeof t!="object")continue;const n=t instanceof Headers?t.entries():Object.entries(t);for(const[i,s]of n)if(s===null)r.delete(i);else if(Array.isArray(s))for(const h of s)r.append(i,h);else s!==void 0&&r.set(i,s)}return r}function oe(e){return e.endsWith("/")?e.substring(0,e.length-1):e}const ae=(e,r,t)=>{try{const n=`${r}_${e}`,i=localStorage.getItem(n);if(!i)return null;const{data:s,timestamp:h}=JSON.parse(i);return t&&Date.now()-h>t?(localStorage.removeItem(n),null):s}catch(n){return null}},Y=(e,r,t)=>{try{const n=`${t}_${e}`,i={data:r,timestamp:Date.now()};localStorage.setItem(n,JSON.stringify(i))}catch(n){console.warn("Failed to cache dismissible item:",n)}},ce=(e,r)=>{try{const t=`${r}_${e}`;localStorage.removeItem(t)}catch(t){console.warn("Failed to remove cached dismissible item:",t)}},Z=o.createContext(null),le=()=>{const e=o.useContext(Z);if(!e)throw new Error("useDismissibleContext must be used within a DismissibleProvider");return e},ve=e=>{if(e)return Object.entries(e).map(([r,t])=>`${r}:${t}`)},Ce="dismissible",ue=(e,r={})=>{var N;const{initialData:t,enableCache:n=!0,cachePrefix:i=Ce,cacheExpiration:s,metadata:h}=r,d=le(),{userId:y}=d,S=o.useMemo(()=>X({baseUrl:d.baseUrl,headers:{}}),[d.baseUrl]),m=o.useMemo(()=>`${y}-${e}`,[y,e]),I=o.useRef({enableCache:n,cachePrefix:i,cacheExpiration:s}),u=o.useRef(e),c=o.useRef(m),j=o.useRef(null),[F,$]=o.useState(!1),[L,C]=o.useState(null),[H,T]=o.useState(()=>{if(t)return t;if(n){const l=ae(m,i,s);if(l)return l}}),O=o.useCallback(()=>U(this,null,function*(){var p;if(n){const b=ae(m,i,s);if(b!=null&&b.dismissedAt){T(b),$(!1);return}}(p=j.current)==null||p.abort();const l=new AbortController;j.current=l,$(!0),C(null);try{const b=yield d.getAuthHeaders(),_=ve(h),{data:A,error:te}=yield S.GET("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:y,itemId:e},query:_?{metadata:_}:void 0},headers:b,signal:l.signal});if(te||!A)throw new Error("Failed to fetch dismissible item");T(A.data),n&&Y(m,A.data,i)}catch(b){if(b instanceof Error&&b.name==="AbortError")return;C(b instanceof Error?b:new Error("Unknown error occurred"))}finally{$(!1)}}),[e,y,m,n,i,s,h,S,d]);o.useEffect(()=>{const l=u.current!==e,p=c.current!==m;l||p?(u.current=e,c.current=m,O()):t||O()},[e,m,t,O]),o.useEffect(()=>()=>{var l;(l=j.current)==null||l.abort()},[]),o.useEffect(()=>{const l=I.current;(l.enableCache!==n||l.cachePrefix!==i||l.cacheExpiration!==s)&&(l.cachePrefix!==i&&ce(m,l.cachePrefix),!n&&l.enableCache&&ce(m,l.cachePrefix),I.current={enableCache:n,cachePrefix:i,cacheExpiration:s},O())},[n,i,s,m,O]);const W=o.useCallback(()=>U(this,null,function*(){C(null);try{const l=yield d.getAuthHeaders(),{data:p,error:b}=yield S.DELETE("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:y,itemId:e}},headers:l});if(b||!p)throw new Error("Failed to dismiss item");T(p.data),n&&Y(m,p.data,i)}catch(l){throw C(l instanceof Error?l:new Error("Failed to dismiss item")),l}}),[e,y,m,n,i,S,d]),ee=o.useCallback(()=>U(this,null,function*(){C(null);try{const l=yield d.getAuthHeaders(),{data:p,error:b}=yield S.POST("/v1/users/{userId}/items/{itemId}",{params:{path:{userId:y,itemId:e}},headers:l});if(b||!p)throw new Error("Failed to restore item");T(p.data),n&&Y(m,p.data,i)}catch(l){throw C(l instanceof Error?l:new Error("Failed to restore item")),l}}),[e,y,m,n,i,S,d]);return{dismissedOn:(N=H==null?void 0:H.dismissedAt)!=null?N:null,dismiss:W,restore:ee,isLoading:F,error:L,item:H}},Re=()=>f.jsx("div",{className:"dismissible-loading","aria-live":"polite",children:"Loading..."}),Se=()=>f.jsx("div",{className:"dismissible-error",role:"alert",children:"Unable to load content. Please try again later."}),je=({onDismiss:e,ariaLabel:r})=>f.jsx("button",{className:"dismissible-button",onClick:e,"aria-label":r,type:"button",children:"×"}),xe=({itemId:e,children:r,onDismiss:t,LoadingComponent:n=Re,ErrorComponent:i=Se,DismissButtonComponent:s=je,enableCache:h,cachePrefix:d,cacheExpiration:y,ignoreErrors:S=!1,metadata:m})=>{const{dismissedOn:I,isLoading:u,error:c,dismiss:j}=ue(e,{enableCache:h,cachePrefix:d,cacheExpiration:y,metadata:m}),[F,$]=o.useState(!1);o.useEffect(()=>{$(!1)},[e]);const L=()=>U(this,null,function*(){$(!0);try{yield j(),t==null||t()}catch(C){$(!1)}});return u&&n?f.jsx(n,{itemId:e}):u&&!n?null:c&&i&&!S?f.jsx(i,{itemId:e,error:c}):I||F?null:f.jsxs("div",{className:"dismissible-container",children:[f.jsx("div",{className:"dismissible-content",children:r}),s?f.jsx(s,{onDismiss:L,ariaLabel:`Dismiss ${e}`}):null]})},fe=e=>U(this,null,function*(){if(typeof e=="function")try{const r=e();return yield Promise.resolve(r)}catch(r){console.warn("Failed to resolve JWT from function:",r);return}return e}),de=e=>U(this,null,function*(){const r=yield fe(e);return r?{Authorization:`Bearer ${r}`}:{}}),Ae=e=>{try{const r=new URL(e),t=r.hostname==="localhost"||r.hostname==="127.0.0.1"||r.hostname==="[::1]",n=r.protocol==="https:";return{isSecure:n||t,isLocalhost:t,isHttps:n}}catch(r){return{isSecure:!1,isLocalhost:!1,isHttps:!1}}},De=({userId:e,jwt:r,baseUrl:t,children:n})=>{const{isSecure:i}=Ae(t);i||console.warn(`[dismissible] Insecure baseUrl "${t}". Use https:// in production (or localhost for development). JWT tokens may be exposed over insecure connections.`);const s=o.useMemo(()=>({userId:e,jwt:r,baseUrl:t,getAuthHeaders:()=>U(this,null,function*(){return yield de(r)})}),[e,r,t]);return f.jsx(Z.Provider,{value:s,children:n})};a.Dismissible=xe,a.DismissibleContext=Z,a.DismissibleProvider=De,a.getAuthHeaders=de,a.resolveJwt=fe,a.useDismissibleContext=le,a.useDismissibleItem=ue,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { components } from '../generated/contract';
|
|
2
2
|
type DismissibleItem = components["schemas"]["DismissibleItemResponseDto"];
|
|
3
3
|
export type IDismissibleItem = DismissibleItem;
|
|
4
|
+
/** Metadata object with string or number values */
|
|
5
|
+
export type IMetadata = {
|
|
6
|
+
[key: string]: string | number;
|
|
7
|
+
};
|
|
4
8
|
export interface UseDismissibleItemOptions {
|
|
5
9
|
/** Initial data for the dismissible item */
|
|
6
10
|
initialData?: IDismissibleItem;
|
|
@@ -10,6 +14,8 @@ export interface UseDismissibleItemOptions {
|
|
|
10
14
|
cachePrefix?: string;
|
|
11
15
|
/** Cache expiration time in milliseconds (default: never expires) */
|
|
12
16
|
cacheExpiration?: number;
|
|
17
|
+
/** Optional metadata object that will be converted to key:value string pairs */
|
|
18
|
+
metadata?: IMetadata;
|
|
13
19
|
}
|
|
14
20
|
/**
|
|
15
21
|
* Hook for managing dismissible items
|