@embeddable/sdk 1.0.5 → 1.0.7
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 +392 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useFormSubmission.d.ts +15 -0
- package/dist/hooks/useFormSubmission.d.ts.map +1 -0
- package/dist/hooks/useVote.d.ts +15 -0
- package/dist/hooks/useVote.d.ts.map +1 -0
- package/dist/hooks/useVoteAggregations.d.ts +22 -0
- package/dist/hooks/useVoteAggregations.d.ts.map +1 -0
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.js +5 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +5 -2
- package/dist/types/index.d.ts +45 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/useVoteAggregations-BX1Qpabx.cjs +10 -0
- package/dist/{useLocalStorage-CNlX4Id5.js → useVoteAggregations-BYDav8LQ.js} +223 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/useLocalStorage-CITMwtY8.cjs +0 -10
package/README.md
CHANGED
|
@@ -197,6 +197,388 @@ function MyWidget() {
|
|
|
197
197
|
|
|
198
198
|
**Note:** This hook must be used within an `EmbeddableProvider`.
|
|
199
199
|
|
|
200
|
+
#### `useFormSubmission<TPayload>(options?: FormSubmissionOptions)`
|
|
201
|
+
|
|
202
|
+
A React hook for handling form submissions with loading states, error handling, and payload validation. Automatically uses the widget ID from the global configuration.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { useFormSubmission } from '@embeddable/sdk/hooks';
|
|
206
|
+
|
|
207
|
+
// Define your form data type
|
|
208
|
+
interface ContactForm {
|
|
209
|
+
name: string;
|
|
210
|
+
email: string;
|
|
211
|
+
message: string;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function ContactFormComponent() {
|
|
215
|
+
const [formData, setFormData] = useState<ContactForm>({
|
|
216
|
+
name: '',
|
|
217
|
+
email: '',
|
|
218
|
+
message: ''
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const { submit, loading, error, success, reset } = useFormSubmission<ContactForm>({
|
|
222
|
+
collectionName: 'contact-forms', // Optional, defaults to 'submissions'
|
|
223
|
+
validatePayload: (payload) => {
|
|
224
|
+
if (!payload.email) return 'Email is required';
|
|
225
|
+
if (!payload.name) return 'Name is required';
|
|
226
|
+
if (!payload.message) return 'Message is required';
|
|
227
|
+
return null; // No validation errors
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
|
|
234
|
+
const result = await submit(formData);
|
|
235
|
+
if (result.success) {
|
|
236
|
+
console.log('Form submitted successfully!', result.id);
|
|
237
|
+
// Reset form or show success message
|
|
238
|
+
setFormData({ name: '', email: '', message: '' });
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
return (
|
|
243
|
+
<form onSubmit={handleSubmit}>
|
|
244
|
+
<input
|
|
245
|
+
type="text"
|
|
246
|
+
placeholder="Name"
|
|
247
|
+
value={formData.name}
|
|
248
|
+
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
|
|
249
|
+
/>
|
|
250
|
+
<input
|
|
251
|
+
type="email"
|
|
252
|
+
placeholder="Email"
|
|
253
|
+
value={formData.email}
|
|
254
|
+
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
|
|
255
|
+
/>
|
|
256
|
+
<textarea
|
|
257
|
+
placeholder="Message"
|
|
258
|
+
value={formData.message}
|
|
259
|
+
onChange={(e) => setFormData(prev => ({ ...prev, message: e.target.value }))}
|
|
260
|
+
/>
|
|
261
|
+
|
|
262
|
+
<button type="submit" disabled={loading}>
|
|
263
|
+
{loading ? 'Submitting...' : 'Submit'}
|
|
264
|
+
</button>
|
|
265
|
+
|
|
266
|
+
{error && <p style={{ color: 'red' }}>{error}</p>}
|
|
267
|
+
{success && <p style={{ color: 'green' }}>Message sent successfully!</p>}
|
|
268
|
+
|
|
269
|
+
<button type="button" onClick={reset}>Reset Status</button>
|
|
270
|
+
</form>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Options:**
|
|
276
|
+
|
|
277
|
+
- `collectionName?: string` - The collection name for submissions (defaults to 'submissions')
|
|
278
|
+
- `validatePayload?: (payload: any) => string | null` - Optional validation function
|
|
279
|
+
|
|
280
|
+
**Returns:**
|
|
281
|
+
|
|
282
|
+
- `submit: (payload: TPayload) => Promise<FormSubmissionResponse>` - Function to submit the form
|
|
283
|
+
- `loading: boolean` - Whether the submission is in progress
|
|
284
|
+
- `error: string | null` - Error message if submission failed
|
|
285
|
+
- `success: boolean` - Whether the submission was successful
|
|
286
|
+
- `reset: () => void` - Function to reset the hook state
|
|
287
|
+
|
|
288
|
+
#### `useVote(options?: VoteOptions)`
|
|
289
|
+
|
|
290
|
+
A React hook for handling votes with loading states and error handling. Automatically uses the widget ID from the global configuration.
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
import { useVote } from '@embeddable/sdk/hooks';
|
|
294
|
+
|
|
295
|
+
function VotingComponent() {
|
|
296
|
+
const { vote, loading, error, success, reset } = useVote({
|
|
297
|
+
collectionName: 'product-poll' // Optional, defaults to 'votes'
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const handleVote = async (optionId: string) => {
|
|
301
|
+
const result = await vote(optionId);
|
|
302
|
+
if (result.success) {
|
|
303
|
+
console.log('Vote submitted!', result.id);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<div>
|
|
309
|
+
<h3>Which product do you prefer?</h3>
|
|
310
|
+
|
|
311
|
+
<button
|
|
312
|
+
onClick={() => handleVote('product-a')}
|
|
313
|
+
disabled={loading}
|
|
314
|
+
>
|
|
315
|
+
Product A
|
|
316
|
+
</button>
|
|
317
|
+
|
|
318
|
+
<button
|
|
319
|
+
onClick={() => handleVote('product-b')}
|
|
320
|
+
disabled={loading}
|
|
321
|
+
>
|
|
322
|
+
Product B
|
|
323
|
+
</button>
|
|
324
|
+
|
|
325
|
+
<button
|
|
326
|
+
onClick={() => handleVote('product-c')}
|
|
327
|
+
disabled={loading}
|
|
328
|
+
>
|
|
329
|
+
Product C
|
|
330
|
+
</button>
|
|
331
|
+
|
|
332
|
+
{loading && <p>Submitting your vote...</p>}
|
|
333
|
+
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
|
|
334
|
+
{success && <p style={{ color: 'green' }}>Thank you for voting!</p>}
|
|
335
|
+
|
|
336
|
+
<button onClick={reset}>Reset</button>
|
|
337
|
+
</div>
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Example with dynamic voting options
|
|
342
|
+
function DynamicVotingComponent() {
|
|
343
|
+
const { vote, loading, error, success } = useVote({
|
|
344
|
+
collectionName: 'feature-requests'
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const features = [
|
|
348
|
+
{ id: 'dark-mode', name: 'Dark Mode' },
|
|
349
|
+
{ id: 'mobile-app', name: 'Mobile App' },
|
|
350
|
+
{ id: 'api-access', name: 'API Access' },
|
|
351
|
+
];
|
|
352
|
+
|
|
353
|
+
const handleFeatureVote = async (featureId: string, featureName: string) => {
|
|
354
|
+
const result = await vote(featureId);
|
|
355
|
+
if (result.success) {
|
|
356
|
+
alert(`Thank you for voting for ${featureName}!`);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
return (
|
|
361
|
+
<div>
|
|
362
|
+
<h3>Vote for the next feature:</h3>
|
|
363
|
+
{features.map(feature => (
|
|
364
|
+
<button
|
|
365
|
+
key={feature.id}
|
|
366
|
+
onClick={() => handleFeatureVote(feature.id, feature.name)}
|
|
367
|
+
disabled={loading}
|
|
368
|
+
style={{
|
|
369
|
+
margin: '5px',
|
|
370
|
+
padding: '10px',
|
|
371
|
+
opacity: loading ? 0.6 : 1
|
|
372
|
+
}}
|
|
373
|
+
>
|
|
374
|
+
{feature.name}
|
|
375
|
+
</button>
|
|
376
|
+
))}
|
|
377
|
+
|
|
378
|
+
{loading && <p>Processing vote...</p>}
|
|
379
|
+
{error && <p style={{ color: 'red' }}>{error}</p>}
|
|
380
|
+
{success && <p style={{ color: 'green' }}>Vote recorded!</p>}
|
|
381
|
+
</div>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**Options:**
|
|
387
|
+
|
|
388
|
+
- `collectionName?: string` - The collection name for votes (defaults to 'votes')
|
|
389
|
+
|
|
390
|
+
**Returns:**
|
|
391
|
+
|
|
392
|
+
- `vote: (voteFor: string) => Promise<VoteResponse>` - Function to submit a vote
|
|
393
|
+
- `loading: boolean` - Whether the vote submission is in progress
|
|
394
|
+
- `error: string | null` - Error message if vote submission failed
|
|
395
|
+
- `success: boolean` - Whether the vote was submitted successfully
|
|
396
|
+
- `reset: () => void` - Function to reset the hook state
|
|
397
|
+
|
|
398
|
+
**Note:** Both `useFormSubmission` and `useVote` hooks must be used within an `EmbeddableProvider` as they automatically retrieve the `widgetId` from the global configuration.
|
|
399
|
+
|
|
400
|
+
#### `useVoteAggregations(options?: UseVoteAggregationsOptions)`
|
|
401
|
+
|
|
402
|
+
A React hook for fetching vote aggregations with loading states, error handling, and optional auto-refresh. Automatically uses the widget ID from the global configuration.
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import { useVoteAggregations } from '@embeddable/sdk/hooks';
|
|
406
|
+
|
|
407
|
+
function VoteResultsComponent() {
|
|
408
|
+
const { data, loading, error, refetch, reset } = useVoteAggregations({
|
|
409
|
+
collectionName: 'product-poll', // Optional, defaults to 'votes'
|
|
410
|
+
autoFetch: true, // Optional, defaults to true
|
|
411
|
+
refetchInterval: 30000, // Optional, refetch every 30 seconds
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
if (loading) {
|
|
415
|
+
return <div>Loading vote results...</div>;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (error) {
|
|
419
|
+
return (
|
|
420
|
+
<div>
|
|
421
|
+
<p style={{ color: 'red' }}>Error: {error}</p>
|
|
422
|
+
<button onClick={refetch}>Retry</button>
|
|
423
|
+
</div>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (!data) {
|
|
428
|
+
return <div>No vote data available</div>;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<div>
|
|
433
|
+
<h3>Vote Results</h3>
|
|
434
|
+
|
|
435
|
+
<div>
|
|
436
|
+
<p><strong>Total Votes:</strong> {data.summary.totalVotes}</p>
|
|
437
|
+
<p><strong>Total Options:</strong> {data.summary.totalOptions}</p>
|
|
438
|
+
</div>
|
|
439
|
+
|
|
440
|
+
<div>
|
|
441
|
+
{data.results.map((result) => (
|
|
442
|
+
<div key={result._id} style={{ margin: '10px 0', padding: '10px', border: '1px solid #ccc' }}>
|
|
443
|
+
<h4>{result._id}</h4>
|
|
444
|
+
<p>Votes: {result.count}</p>
|
|
445
|
+
{result.percentage && <p>Percentage: {result.percentage.toFixed(1)}%</p>}
|
|
446
|
+
<div style={{ width: '100%', backgroundColor: '#e0e0e0', borderRadius: '4px' }}>
|
|
447
|
+
<div
|
|
448
|
+
style={{
|
|
449
|
+
width: `${result.percentage || 0}%`,
|
|
450
|
+
backgroundColor: '#4caf50',
|
|
451
|
+
height: '20px',
|
|
452
|
+
borderRadius: '4px',
|
|
453
|
+
transition: 'width 0.3s ease'
|
|
454
|
+
}}
|
|
455
|
+
/>
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
458
|
+
))}
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<button onClick={refetch}>Refresh Results</button>
|
|
462
|
+
<button onClick={reset}>Reset</button>
|
|
463
|
+
</div>
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Example with manual fetching
|
|
468
|
+
function ManualVoteResultsComponent() {
|
|
469
|
+
const { data, loading, error, fetch } = useVoteAggregations({
|
|
470
|
+
collectionName: 'feature-requests',
|
|
471
|
+
autoFetch: false, // Don't fetch automatically
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
const handleLoadResults = async () => {
|
|
475
|
+
const response = await fetch();
|
|
476
|
+
if (response.success) {
|
|
477
|
+
console.log('Results loaded:', response.data);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
return (
|
|
482
|
+
<div>
|
|
483
|
+
<button onClick={handleLoadResults} disabled={loading}>
|
|
484
|
+
{loading ? 'Loading...' : 'Load Vote Results'}
|
|
485
|
+
</button>
|
|
486
|
+
|
|
487
|
+
{error && <p style={{ color: 'red' }}>{error}</p>}
|
|
488
|
+
|
|
489
|
+
{data && (
|
|
490
|
+
<div>
|
|
491
|
+
<h3>Feature Request Votes</h3>
|
|
492
|
+
<p>Total: {data.summary.totalVotes} votes</p>
|
|
493
|
+
<ul>
|
|
494
|
+
{data.results.map(result => (
|
|
495
|
+
<li key={result._id}>
|
|
496
|
+
{result._id}: {result.count} votes
|
|
497
|
+
</li>
|
|
498
|
+
))}
|
|
499
|
+
</ul>
|
|
500
|
+
</div>
|
|
501
|
+
)}
|
|
502
|
+
</div>
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Example with real-time updates
|
|
507
|
+
function LiveVoteResultsComponent() {
|
|
508
|
+
const { data, loading, error } = useVoteAggregations({
|
|
509
|
+
collectionName: 'live-poll',
|
|
510
|
+
refetchInterval: 5000, // Update every 5 seconds
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
return (
|
|
514
|
+
<div>
|
|
515
|
+
<h3>Live Poll Results {loading && '(Updating...)'}</h3>
|
|
516
|
+
|
|
517
|
+
{error ? (
|
|
518
|
+
<p style={{ color: 'red' }}>Failed to load results</p>
|
|
519
|
+
) : (
|
|
520
|
+
<div>
|
|
521
|
+
{data?.results.map(result => (
|
|
522
|
+
<div key={result._id} style={{ display: 'flex', alignItems: 'center', margin: '5px 0' }}>
|
|
523
|
+
<span style={{ minWidth: '100px' }}>{result._id}:</span>
|
|
524
|
+
<div style={{ flex: 1, margin: '0 10px', backgroundColor: '#e0e0e0', borderRadius: '10px' }}>
|
|
525
|
+
<div
|
|
526
|
+
style={{
|
|
527
|
+
width: `${result.percentage || 0}%`,
|
|
528
|
+
backgroundColor: '#2196f3',
|
|
529
|
+
height: '20px',
|
|
530
|
+
borderRadius: '10px',
|
|
531
|
+
transition: 'all 0.5s ease'
|
|
532
|
+
}}
|
|
533
|
+
/>
|
|
534
|
+
</div>
|
|
535
|
+
<span>{result.count} votes</span>
|
|
536
|
+
</div>
|
|
537
|
+
))}
|
|
538
|
+
<p style={{ marginTop: '10px', fontSize: '12px', color: '#666' }}>
|
|
539
|
+
Last updated: {new Date().toLocaleTimeString()}
|
|
540
|
+
</p>
|
|
541
|
+
</div>
|
|
542
|
+
)}
|
|
543
|
+
</div>
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Options:**
|
|
549
|
+
|
|
550
|
+
- `collectionName?: string` - The collection name for votes (defaults to 'votes')
|
|
551
|
+
- `autoFetch?: boolean` - Whether to automatically fetch data on mount (defaults to true)
|
|
552
|
+
- `refetchInterval?: number` - Interval in milliseconds for automatic refetching (optional)
|
|
553
|
+
|
|
554
|
+
**Returns:**
|
|
555
|
+
|
|
556
|
+
- `data: VoteAggregationData | null` - The aggregation data with results and summary
|
|
557
|
+
- `loading: boolean` - Whether a request is in progress
|
|
558
|
+
- `error: string | null` - Error message if request failed
|
|
559
|
+
- `fetch: () => Promise<VoteAggregationResponse>` - Function to manually fetch aggregations
|
|
560
|
+
- `refetch: () => Promise<VoteAggregationResponse>` - Alias for fetch function
|
|
561
|
+
- `reset: () => void` - Function to reset the hook state
|
|
562
|
+
|
|
563
|
+
**Data Structure:**
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
interface VoteAggregationData {
|
|
567
|
+
results: Array<{
|
|
568
|
+
_id: string; // The option that was voted for
|
|
569
|
+
count: number; // Number of votes for this option
|
|
570
|
+
percentage?: number; // Percentage of total votes
|
|
571
|
+
}>;
|
|
572
|
+
summary: {
|
|
573
|
+
totalVotes: number; // Total number of votes cast
|
|
574
|
+
totalOptions: number; // Number of different options
|
|
575
|
+
groupBy: string; // The field used for grouping
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
**Note:** This hook must be used within an `EmbeddableProvider` as it automatically retrieves the `widgetId` from the global configuration.
|
|
581
|
+
|
|
200
582
|
### Utilities
|
|
201
583
|
|
|
202
584
|
#### `debounce<T>(func: T, wait: number)`
|
|
@@ -256,6 +638,16 @@ import type {
|
|
|
256
638
|
EmbeddableApiConfig,
|
|
257
639
|
ApiResponse,
|
|
258
640
|
LocalStorageOptions,
|
|
641
|
+
FormSubmission,
|
|
642
|
+
FormSubmissionResponse,
|
|
643
|
+
FormSubmissionOptions,
|
|
644
|
+
Vote,
|
|
645
|
+
VoteResponse,
|
|
646
|
+
VoteOptions,
|
|
647
|
+
VoteAggregationResult,
|
|
648
|
+
VoteAggregationSummary,
|
|
649
|
+
VoteAggregationData,
|
|
650
|
+
VoteAggregationResponse,
|
|
259
651
|
} from '@embeddable/sdk';
|
|
260
652
|
```
|
|
261
653
|
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -2,5 +2,8 @@ export { useApi } from './useApi';
|
|
|
2
2
|
export { useDebounce } from './useDebounce';
|
|
3
3
|
export { useEmbeddableConfig, useEmbeddableConfigSafe } from './useEmbeddableConfig';
|
|
4
4
|
export { useEmbeddableData } from './useEmbeddableData';
|
|
5
|
+
export { useFormSubmission } from './useFormSubmission';
|
|
5
6
|
export { useLocalStorage } from './useLocalStorage';
|
|
7
|
+
export { useVote } from './useVote';
|
|
8
|
+
export { useVoteAggregations } from './useVoteAggregations';
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FormSubmissionOptions, FormSubmissionResponse } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React hook for handling form submissions with loading, error states, and validation
|
|
5
|
+
* @param options - Optional configuration for the hook including payload validation and collection name
|
|
6
|
+
* @returns Object with submit function and state management
|
|
7
|
+
*/
|
|
8
|
+
export declare function useFormSubmission<TPayload = Record<string, any>>(options?: FormSubmissionOptions): {
|
|
9
|
+
submit: (payload: TPayload) => Promise<FormSubmissionResponse>;
|
|
10
|
+
reset: () => void;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
error: string | null;
|
|
13
|
+
success: boolean;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useFormSubmission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormSubmission.d.ts","sourceRoot":"","sources":["../../src/hooks/useFormSubmission.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAU9F;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB;sBAS7E,QAAQ,KAAG,OAAO,CAAC,sBAAsB,CAAC;;aAnBnD,OAAO;WACT,MAAM,GAAG,IAAI;aACX,OAAO;EAmGjB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { VoteOptions, VoteResponse } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React hook for handling votes with loading, error states
|
|
5
|
+
* @param options - Optional configuration for the hook including collection name
|
|
6
|
+
* @returns Object with vote function and state management
|
|
7
|
+
*/
|
|
8
|
+
export declare function useVote(options?: VoteOptions): {
|
|
9
|
+
vote: (voteFor: string) => Promise<VoteResponse>;
|
|
10
|
+
reset: () => void;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
error: string | null;
|
|
13
|
+
success: boolean;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useVote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVote.d.ts","sourceRoot":"","sources":["../../src/hooks/useVote.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAUhE;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW;oBASzB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC;;aAnBvC,OAAO;WACT,MAAM,GAAG,IAAI;aACX,OAAO;EAwFjB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { VoteAggregationData, VoteAggregationResponse } from '../types';
|
|
2
|
+
|
|
3
|
+
interface UseVoteAggregationsOptions {
|
|
4
|
+
collectionName?: string;
|
|
5
|
+
autoFetch?: boolean;
|
|
6
|
+
refetchInterval?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* React hook for fetching vote aggregations with loading, error states
|
|
10
|
+
* @param options - Optional configuration for the hook including collection name and auto-fetch behavior
|
|
11
|
+
* @returns Object with aggregation data, fetch function, and state management
|
|
12
|
+
*/
|
|
13
|
+
export declare function useVoteAggregations(options?: UseVoteAggregationsOptions): {
|
|
14
|
+
fetch: () => Promise<VoteAggregationResponse>;
|
|
15
|
+
refetch: () => Promise<VoteAggregationResponse>;
|
|
16
|
+
reset: () => void;
|
|
17
|
+
data: VoteAggregationData | null;
|
|
18
|
+
loading: boolean;
|
|
19
|
+
error: string | null;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=useVoteAggregations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVoteAggregations.d.ts","sourceRoot":"","sources":["../../src/hooks/useVoteAggregations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAU7E,UAAU,0BAA0B;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,0BAA0B;iBAQtB,OAAO,CAAC,uBAAuB,CAAC;;;UAxB1E,mBAAmB,GAAG,IAAI;aACvB,OAAO;WACT,MAAM,GAAG,IAAI;EAgGrB"}
|
package/dist/hooks.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVoteAggregations-BX1Qpabx.cjs");exports.useApi=e.useApi,exports.useDebounce=e.useDebounce,exports.useEmbeddableConfig=e.useEmbeddableConfig,exports.useEmbeddableConfigSafe=e.useEmbeddableConfigSafe,exports.useEmbeddableData=e.useEmbeddableData,exports.useFormSubmission=e.useFormSubmission,exports.useLocalStorage=e.useLocalStorage,exports.useVote=e.useVote,exports.useVoteAggregations=e.useVoteAggregations;
|
package/dist/hooks.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { a, b, c, d, e, f } from "./
|
|
1
|
+
import { a, b, c, d, e, f, g, h, i } from "./useVoteAggregations-BYDav8LQ.js";
|
|
2
2
|
export {
|
|
3
3
|
a as useApi,
|
|
4
4
|
b as useDebounce,
|
|
5
5
|
c as useEmbeddableConfig,
|
|
6
6
|
d as useEmbeddableConfigSafe,
|
|
7
7
|
e as useEmbeddableData,
|
|
8
|
-
f as
|
|
8
|
+
f as useFormSubmission,
|
|
9
|
+
g as useLocalStorage,
|
|
10
|
+
h as useVote,
|
|
11
|
+
i as useVoteAggregations
|
|
9
12
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVoteAggregations-BX1Qpabx.cjs"),s=require("./storage-3dk6ww91.cjs"),o=require("./utils.cjs");exports.EmbeddableProvider=e.EmbeddableProvider,exports.useApi=e.useApi,exports.useDebounce=e.useDebounce,exports.useEmbeddableConfig=e.useEmbeddableConfig,exports.useEmbeddableConfigSafe=e.useEmbeddableConfigSafe,exports.useEmbeddableContext=e.useEmbeddableContext,exports.useEmbeddableData=e.useEmbeddableData,exports.useFormSubmission=e.useFormSubmission,exports.useLocalStorage=e.useLocalStorage,exports.useVote=e.useVote,exports.useVoteAggregations=e.useVoteAggregations,exports.createApiClient=s.createApiClient,exports.storage=s.storage,exports.debounce=o.debounce;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E, a, b, c, d, u, e, f } from "./
|
|
1
|
+
import { E, a, b, c, d, u, e, f, g, h, i } from "./useVoteAggregations-BYDav8LQ.js";
|
|
2
2
|
import { c as c2, s } from "./storage-CRPDfSRn.js";
|
|
3
3
|
import { debounce } from "./utils.js";
|
|
4
4
|
export {
|
|
@@ -12,5 +12,8 @@ export {
|
|
|
12
12
|
d as useEmbeddableConfigSafe,
|
|
13
13
|
u as useEmbeddableContext,
|
|
14
14
|
e as useEmbeddableData,
|
|
15
|
-
f as
|
|
15
|
+
f as useFormSubmission,
|
|
16
|
+
g as useLocalStorage,
|
|
17
|
+
h as useVote,
|
|
18
|
+
i as useVoteAggregations
|
|
16
19
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -25,4 +25,49 @@ export interface EmbeddableConfig {
|
|
|
25
25
|
_containerId?: string;
|
|
26
26
|
_shadowRoot?: ShadowRoot;
|
|
27
27
|
}
|
|
28
|
+
export interface FormSubmission<TPayload = Record<string, any>> {
|
|
29
|
+
widgetId: string;
|
|
30
|
+
collectionName: string;
|
|
31
|
+
payload: TPayload;
|
|
32
|
+
}
|
|
33
|
+
export interface FormSubmissionResponse {
|
|
34
|
+
id?: string;
|
|
35
|
+
success: boolean;
|
|
36
|
+
message?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface FormSubmissionOptions {
|
|
39
|
+
collectionName?: string;
|
|
40
|
+
validatePayload?: (payload: any) => string | null;
|
|
41
|
+
}
|
|
42
|
+
export interface Vote {
|
|
43
|
+
widgetId: string;
|
|
44
|
+
collectionName: string;
|
|
45
|
+
voteFor: string;
|
|
46
|
+
}
|
|
47
|
+
export interface VoteResponse {
|
|
48
|
+
id?: string;
|
|
49
|
+
success: boolean;
|
|
50
|
+
message?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface VoteOptions {
|
|
53
|
+
collectionName?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface VoteAggregationResult {
|
|
56
|
+
_id: string;
|
|
57
|
+
count: number;
|
|
58
|
+
percentage?: number;
|
|
59
|
+
}
|
|
60
|
+
export interface VoteAggregationSummary {
|
|
61
|
+
totalVotes: number;
|
|
62
|
+
totalOptions: number;
|
|
63
|
+
groupBy: string;
|
|
64
|
+
}
|
|
65
|
+
export interface VoteAggregationData {
|
|
66
|
+
results: VoteAggregationResult[];
|
|
67
|
+
summary: VoteAggregationSummary;
|
|
68
|
+
}
|
|
69
|
+
export interface VoteAggregationResponse {
|
|
70
|
+
success: boolean;
|
|
71
|
+
data: VoteAggregationData;
|
|
72
|
+
}
|
|
28
73
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B;AAGD,MAAM,WAAW,cAAc,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD;AAGD,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,mBAAmB,CAAC;CAC3B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";const e=require("react"),r=require("./storage-3dk6ww91.cjs");var t,n={exports:{}},o={};var a,s={};
|
|
2
|
+
/**
|
|
3
|
+
* @license React
|
|
4
|
+
* react-jsx-runtime.development.js
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
7
|
+
*
|
|
8
|
+
* This source code is licensed under the MIT license found in the
|
|
9
|
+
* LICENSE file in the root directory of this source tree.
|
|
10
|
+
*/"production"===process.env.NODE_ENV?n.exports=function(){if(t)return o;t=1;var r=e,n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function l(e,r,t){var o,a={},l=null,u=null;for(o in void 0!==t&&(l=""+t),void 0!==r.key&&(l=""+r.key),void 0!==r.ref&&(u=r.ref),r)s.call(r,o)&&!c.hasOwnProperty(o)&&(a[o]=r[o]);if(e&&e.defaultProps)for(o in r=e.defaultProps)void 0===a[o]&&(a[o]=r[o]);return{$$typeof:n,type:e,key:l,ref:u,props:a,_owner:i.current}}return o.Fragment=a,o.jsx=l,o.jsxs=l,o}():n.exports=(a||(a=1,"production"!==process.env.NODE_ENV&&function(){var r,t=e,n=Symbol.for("react.element"),o=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),i=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),l=Symbol.for("react.provider"),u=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),y=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),m=Symbol.for("react.offscreen"),v=Symbol.iterator,b=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function h(e){for(var r=arguments.length,t=new Array(r>1?r-1:0),n=1;n<r;n++)t[n-1]=arguments[n];!function(e,r,t){var n=b.ReactDebugCurrentFrame.getStackAddendum();""!==n&&(r+="%s",t=t.concat([n]));var o=t.map((function(e){return String(e)}));o.unshift("Warning: "+r),Function.prototype.apply.call(console[e],console,o)}("error",e,t)}function w(e){return e.displayName||"Context"}function k(e){if(null==e)return null;if("number"==typeof e.tag&&h("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),"function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case a:return"Fragment";case o:return"Portal";case c:return"Profiler";case i:return"StrictMode";case p:return"Suspense";case d:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case u:return w(e)+".Consumer";case l:return w(e._context)+".Provider";case f:return function(e,r,t){var n=e.displayName;if(n)return n;var o=r.displayName||r.name||"";return""!==o?t+"("+o+")":t}(e,e.render,"ForwardRef");case y:var r=e.displayName||null;return null!==r?r:k(e.type)||"Memo";case g:var t=e,n=t._payload,s=t._init;try{return k(s(n))}catch(m){return null}}return null}r=Symbol.for("react.module.reference");var _,E,S,O,j,C,P,R=Object.assign,T=0;function x(){}x.__reactDisabledLog=!0;var $,N=b.ReactCurrentDispatcher;function I(e,r,t){if(void 0===$)try{throw Error()}catch(o){var n=o.stack.trim().match(/\n( *(at )?)/);$=n&&n[1]||""}return"\n"+$+e}var D,F=!1,L="function"==typeof WeakMap?WeakMap:Map;function U(e,r){if(!e||F)return"";var t,n=D.get(e);if(void 0!==n)return n;F=!0;var o,a=Error.prepareStackTrace;Error.prepareStackTrace=void 0,o=N.current,N.current=null,function(){if(0===T){_=console.log,E=console.info,S=console.warn,O=console.error,j=console.group,C=console.groupCollapsed,P=console.groupEnd;var e={configurable:!0,enumerable:!0,value:x,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}T++}();try{if(r){var s=function(){throw Error()};if(Object.defineProperty(s.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(s,[])}catch(y){t=y}Reflect.construct(e,[],s)}else{try{s.call()}catch(y){t=y}e.call(s.prototype)}}else{try{throw Error()}catch(y){t=y}e()}}catch(g){if(g&&t&&"string"==typeof g.stack){for(var i=g.stack.split("\n"),c=t.stack.split("\n"),l=i.length-1,u=c.length-1;l>=1&&u>=0&&i[l]!==c[u];)u--;for(;l>=1&&u>=0;l--,u--)if(i[l]!==c[u]){if(1!==l||1!==u)do{if(l--,--u<0||i[l]!==c[u]){var f="\n"+i[l].replace(" at new "," at ");return e.displayName&&f.includes("<anonymous>")&&(f=f.replace("<anonymous>",e.displayName)),"function"==typeof e&&D.set(e,f),f}}while(l>=1&&u>=0);break}}}finally{F=!1,N.current=o,function(){if(0===--T){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:R({},e,{value:_}),info:R({},e,{value:E}),warn:R({},e,{value:S}),error:R({},e,{value:O}),group:R({},e,{value:j}),groupCollapsed:R({},e,{value:C}),groupEnd:R({},e,{value:P})})}T<0&&h("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}(),Error.prepareStackTrace=a}var p=e?e.displayName||e.name:"",d=p?I(p):"";return"function"==typeof e&&D.set(e,d),d}function A(e,r,t){if(null==e)return"";if("function"==typeof e)return U(e,!(!(n=e.prototype)||!n.isReactComponent));var n;if("string"==typeof e)return I(e);switch(e){case p:return I("Suspense");case d:return I("SuspenseList")}if("object"==typeof e)switch(e.$$typeof){case f:return U(e.render,!1);case y:return A(e.type,r,t);case g:var o=e,a=o._payload,s=o._init;try{return A(s(a),r,t)}catch(i){}}return""}D=new L;var V=Object.prototype.hasOwnProperty,W={},z=b.ReactDebugCurrentFrame;function M(e){if(e){var r=e._owner,t=A(e.type,e._source,r?r.type:null);z.setExtraStackFrame(t)}else z.setExtraStackFrame(null)}var B=Array.isArray;function J(e){return B(e)}function Y(e){return""+e}function q(e){if(function(e){try{return Y(e),!1}catch(r){return!0}}(e))return h("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",function(e){return"function"==typeof Symbol&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object"}(e)),Y(e)}var H,K,X=b.ReactCurrentOwner,G={key:!0,ref:!0,__self:!0,__source:!0};function Q(e,r,t,o,a){var s,i={},c=null,l=null;for(s in void 0!==t&&(q(t),c=""+t),function(e){if(V.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return void 0!==e.key}(r)&&(q(r.key),c=""+r.key),function(e){if(V.call(e,"ref")){var r=Object.getOwnPropertyDescriptor(e,"ref").get;if(r&&r.isReactWarning)return!1}return void 0!==e.ref}(r)&&(l=r.ref,function(e){"string"==typeof e.ref&&X.current}(r)),r)V.call(r,s)&&!G.hasOwnProperty(s)&&(i[s]=r[s]);if(e&&e.defaultProps){var u=e.defaultProps;for(s in u)void 0===i[s]&&(i[s]=u[s])}if(c||l){var f="function"==typeof e?e.displayName||e.name||"Unknown":e;c&&function(e,r){var t=function(){H||(H=!0,h("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}(i,f),l&&function(e,r){var t=function(){K||(K=!0,h("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"ref",{get:t,configurable:!0})}(i,f)}return function(e,r,t,o,a,s,i){var c={$$typeof:n,type:e,key:r,ref:t,props:i,_owner:s,_store:{}};return Object.defineProperty(c._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(c,"_self",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.defineProperty(c,"_source",{configurable:!1,enumerable:!1,writable:!1,value:a}),Object.freeze&&(Object.freeze(c.props),Object.freeze(c)),c}(e,c,l,a,o,X.current,i)}var Z,ee=b.ReactCurrentOwner,re=b.ReactDebugCurrentFrame;function te(e){if(e){var r=e._owner,t=A(e.type,e._source,r?r.type:null);re.setExtraStackFrame(t)}else re.setExtraStackFrame(null)}function ne(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}function oe(){if(ee.current){var e=k(ee.current.type);if(e)return"\n\nCheck the render method of `"+e+"`."}return""}Z=!1;var ae={};function se(e,r){if(e._store&&!e._store.validated&&null==e.key){e._store.validated=!0;var t=function(e){var r=oe();if(!r){var t="string"==typeof e?e:e.displayName||e.name;t&&(r="\n\nCheck the top-level render call using <"+t+">.")}return r}(r);if(!ae[t]){ae[t]=!0;var n="";e&&e._owner&&e._owner!==ee.current&&(n=" It was passed a child from "+k(e._owner.type)+"."),te(e),h('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',t,n),te(null)}}}function ie(e,r){if("object"==typeof e)if(J(e))for(var t=0;t<e.length;t++){var n=e[t];ne(n)&&se(n,r)}else if(ne(e))e._store&&(e._store.validated=!0);else if(e){var o=function(e){if(null===e||"object"!=typeof e)return null;var r=v&&e[v]||e["@@iterator"];return"function"==typeof r?r:null}(e);if("function"==typeof o&&o!==e.entries)for(var a,s=o.call(e);!(a=s.next()).done;)ne(a.value)&&se(a.value,r)}}function ce(e){var r,t=e.type;if(null!=t&&"string"!=typeof t){if("function"==typeof t)r=t.propTypes;else{if("object"!=typeof t||t.$$typeof!==f&&t.$$typeof!==y)return;r=t.propTypes}if(r){var n=k(t);!function(e,r,t,n,o){var a=Function.call.bind(V);for(var s in e)if(a(e,s)){var i=void 0;try{if("function"!=typeof e[s]){var c=Error((n||"React class")+": "+t+" type `"+s+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[s]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw c.name="Invariant Violation",c}i=e[s](r,s,n,t,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(l){i=l}!i||i instanceof Error||(M(o),h("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",n||"React class",t,s,typeof i),M(null)),i instanceof Error&&!(i.message in W)&&(W[i.message]=!0,M(o),h("Failed %s type: %s",t,i.message),M(null))}}(r,e.props,"prop",n,e)}else void 0===t.PropTypes||Z||(Z=!0,h("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",k(t)||"Unknown"));"function"!=typeof t.getDefaultProps||t.getDefaultProps.isReactClassApproved||h("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}var le={};function ue(e,t,o,s,v,b){var w=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===c||e===i||e===p||e===d||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===y||e.$$typeof===l||e.$$typeof===u||e.$$typeof===f||e.$$typeof===r||void 0!==e.getModuleId)}(e);if(!w){var _,E="";(void 0===e||"object"==typeof e&&null!==e&&0===Object.keys(e).length)&&(E+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."),E+=oe(),null===e?_="null":J(e)?_="array":void 0!==e&&e.$$typeof===n?(_="<"+(k(e.type)||"Unknown")+" />",E=" Did you accidentally export a JSX literal instead of a component?"):_=typeof e,h("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",_,E)}var S=Q(e,t,o,v,b);if(null==S)return S;if(w){var O=t.children;if(void 0!==O)if(s)if(J(O)){for(var j=0;j<O.length;j++)ie(O[j],e);Object.freeze&&Object.freeze(O)}else h("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else ie(O,e)}if(V.call(t,"key")){var C=k(e),P=Object.keys(t).filter((function(e){return"key"!==e})),R=P.length>0?"{key: someKey, "+P.join(": ..., ")+": ...}":"{key: someKey}";le[C+R]||(h('A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',R,C,P.length>0?"{"+P.join(": ..., ")+": ...}":"{}",C),le[C+R]=!0)}return e===a?function(e){for(var r=Object.keys(e.props),t=0;t<r.length;t++){var n=r[t];if("children"!==n&&"key"!==n){te(e),h("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",n),te(null);break}}null!==e.ref&&(te(e),h("Invalid attribute `ref` supplied to `React.Fragment`."),te(null))}(S):ce(S),S}var fe=function(e,r,t){return ue(e,r,t,!1)},pe=function(e,r,t){return ue(e,r,t,!0)};s.Fragment=a,s.jsx=fe,s.jsxs=pe}()),s);var i=n.exports;const c={version:"latest",mode:"embeddable",ignoreCache:!1,lazyLoad:!1,loader:!0,widgetId:"",_containerId:"",_shadowRoot:void 0},l=e.createContext({config:{...c},setConfig:()=>{},data:{},setData:()=>{}});function u(){const r=e.useContext(l);if(!r)throw new Error("useEmbeddableContext must be used within an EmbeddableProvider");return r}function f(){const{config:e}=u();if(!e)throw new Error("No Embeddable configuration found. Make sure to wrap your app with EmbeddableProvider and provide a valid config.");return e}const p="https://events.embeddable.co";exports.EmbeddableProvider=function({config:r,data:t,children:n}){const[o,a]=e.useState(c),[s,u]=e.useState(t||{});return e.useEffect((()=>{a({...c,...r})}),[r]),e.useEffect((()=>{const e=e=>{("https://embeddable.co"===e.origin||e.origin.includes("localhost"))&&e.data&&"object"==typeof e.data&&"embeddable-update-data"===e.data.type&&u(e.data.data||{})};return window.addEventListener("message",e),()=>{window.removeEventListener("message",e)}}),[]),i.jsx(l.Provider,{value:{config:o,setConfig:a,data:s,setData:u},children:n})},exports.useApi=function(t){const n=t;if(!n)throw new Error("No API configuration provided. Either pass a config parameter or wrap your app with EmbeddableProvider.");const[o,a]=e.useState({data:null,loading:!1,error:null}),s=r.createApiClient(n),i=e.useCallback((async(e,r,t)=>{a((e=>({...e,loading:!0,error:null})));try{let n;switch(e){case"get":n=await s.get(r);break;case"post":n=await s.post(r,t);break;case"put":n=await s.put(r,t);break;case"delete":n=await s.delete(r);break;default:throw new Error(`Unsupported method: ${e}`)}return a({data:n.data,loading:!1,error:n.success?null:n.error||"Unknown error"}),n}catch(n){const e=n instanceof Error?n.message:"Unknown error";return a({data:null,loading:!1,error:e}),{data:null,success:!1,error:e}}}),[s]);return{...o,get:e.useCallback((e=>i("get",e)),[i]),post:e.useCallback(((e,r)=>i("post",e,r)),[i]),put:e.useCallback(((e,r)=>i("put",e,r)),[i]),delete:e.useCallback((e=>i("delete",e)),[i]),reset:e.useCallback((()=>{a({data:null,loading:!1,error:null})}),[])}},exports.useDebounce=function(r,t){const[n,o]=e.useState(r);return e.useEffect((()=>{const e=setTimeout((()=>{o(r)}),t);return()=>{clearTimeout(e)}}),[r,t]),n},exports.useEmbeddableConfig=f,exports.useEmbeddableConfigSafe=function(){const{config:e}=u();return e},exports.useEmbeddableContext=u,exports.useEmbeddableData=function(){const{data:e}=u();return{data:e}},exports.useFormSubmission=function(r){const{widgetId:t}=f(),[n,o]=e.useState({loading:!1,error:null,success:!1});return{...n,submit:e.useCallback((async e=>{var n,a,s;o({loading:!0,error:null,success:!1});try{if(null==r?void 0:r.validatePayload){const t=r.validatePayload(e);if(t)return o({loading:!1,error:t,success:!1}),{success:!1,message:t}}const i={payload:e,widgetId:t,collectionName:(null==r?void 0:r.collectionName)||"submissions"},c=await fetch(`${p}/api/submissions`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"omit",body:JSON.stringify(i)}),l=await c.json();if(!c.ok){const e=l.message||l.error||`HTTP ${c.status}`;return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}if(l.success)return o({loading:!1,error:null,success:!0}),{id:(null==(n=l.data)?void 0:n.id)||(null==(a=l.data)?void 0:a._id),success:!0,message:(null==(s=l.data)?void 0:s.message)||"Submission successful"};{const e=l.message||l.error||"Submission failed";return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}}catch(i){const e=i instanceof Error?i.message:"Unknown error occurred";return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}}),[r,t]),reset:e.useCallback((()=>{o({loading:!1,error:null,success:!1})}),[])}},exports.useLocalStorage=function(t,n,o={}){const[a,s]=e.useState((()=>{const e=r.storage.get(t,o);return null!==e?e:n})),i=e.useCallback((e=>{try{const n=e instanceof Function?e(a):e;s(n),r.storage.set(t,n,o)}catch(n){}}),[t,a,o]),c=e.useCallback((()=>{try{s(n),r.storage.remove(t,o)}catch(e){}}),[t,n,o]);return e.useEffect((()=>{const e=e=>{const{prefix:r=""}=o,n=r+t;if(e.key===n&&null!==e.newValue)try{const{deserialize:r=JSON.parse}=o,t=r(e.newValue);s(t)}catch(a){}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,o]),[a,i,c]},exports.useVote=function(r){const{widgetId:t}=f(),[n,o]=e.useState({loading:!1,error:null,success:!1});return{...n,vote:e.useCallback((async e=>{var n,a,s;o({loading:!0,error:null,success:!1});try{const i={voteFor:e,widgetId:t,collectionName:(null==r?void 0:r.collectionName)||"votes"},c=await fetch(`${p}/api/votes`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"omit",body:JSON.stringify(i)}),l=await c.json();if(!c.ok){const e=l.message||l.error||`HTTP ${c.status}`;return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}if(l.success)return o({loading:!1,error:null,success:!0}),{id:(null==(n=l.data)?void 0:n.id)||(null==(a=l.data)?void 0:a._id),success:!0,message:(null==(s=l.data)?void 0:s.message)||"Vote submitted successfully"};{const e=l.message||l.error||"Vote submission failed";return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}}catch(i){const e=i instanceof Error?i.message:"Unknown error occurred";return o({loading:!1,error:e,success:!1}),{success:!1,message:e}}}),[r,t]),reset:e.useCallback((()=>{o({loading:!1,error:null,success:!1})}),[])}},exports.useVoteAggregations=function(r){const{widgetId:t}=f(),[n,o]=e.useState({data:null,loading:!1,error:null}),a=e.useCallback((async()=>{o((e=>({...e,loading:!0,error:null})));try{const e=(null==r?void 0:r.collectionName)||"votes",n=new URL(`${p}/api/votes/aggregations`);n.searchParams.append("widgetId",t),n.searchParams.append("collectionName",e);const a=await fetch(n.toString(),{method:"GET",headers:{"Content-Type":"application/json"},credentials:"omit"}),s=await a.json();if(!a.ok){const e=s.message||s.error||`HTTP ${a.status}`;return o({data:null,loading:!1,error:e}),{success:!1,data:{results:[],summary:{totalVotes:0,totalOptions:0,groupBy:""}}}}return o({data:s.data,loading:!1,error:null}),s}catch(e){const r=e instanceof Error?e.message:"Unknown error occurred";return o({data:null,loading:!1,error:r}),{success:!1,data:{results:[],summary:{totalVotes:0,totalOptions:0,groupBy:""}}}}}),[t,null==r?void 0:r.collectionName]),s=e.useCallback((()=>a()),[a]),i=e.useCallback((()=>{o({data:null,loading:!1,error:null})}),[]);return e.useEffect((()=>{!1!==(null==r?void 0:r.autoFetch)&&a()}),[a,null==r?void 0:r.autoFetch]),e.useEffect((()=>{if((null==r?void 0:r.refetchInterval)&&r.refetchInterval>0){const e=setInterval((()=>{a()}),r.refetchInterval);return()=>clearInterval(e)}}),[a,null==r?void 0:r.refetchInterval]),{...n,fetch:a,refetch:s,reset:i}};
|
|
@@ -1082,6 +1082,87 @@ function useEmbeddableData() {
|
|
|
1082
1082
|
const { data } = useEmbeddableContext();
|
|
1083
1083
|
return { data };
|
|
1084
1084
|
}
|
|
1085
|
+
const EVENTS_BASE_URL = "https://events.embeddable.co";
|
|
1086
|
+
function useFormSubmission(options) {
|
|
1087
|
+
const { widgetId } = useEmbeddableConfig();
|
|
1088
|
+
const [state, setState] = useState({
|
|
1089
|
+
loading: false,
|
|
1090
|
+
error: null,
|
|
1091
|
+
success: false
|
|
1092
|
+
});
|
|
1093
|
+
const submit = useCallback(
|
|
1094
|
+
async (payload) => {
|
|
1095
|
+
var _a, _b, _c;
|
|
1096
|
+
setState({ loading: true, error: null, success: false });
|
|
1097
|
+
try {
|
|
1098
|
+
if (options == null ? void 0 : options.validatePayload) {
|
|
1099
|
+
const validationError = options.validatePayload(payload);
|
|
1100
|
+
if (validationError) {
|
|
1101
|
+
setState({ loading: false, error: validationError, success: false });
|
|
1102
|
+
return {
|
|
1103
|
+
success: false,
|
|
1104
|
+
message: validationError
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
const submission = {
|
|
1109
|
+
payload,
|
|
1110
|
+
widgetId,
|
|
1111
|
+
collectionName: (options == null ? void 0 : options.collectionName) || "submissions"
|
|
1112
|
+
};
|
|
1113
|
+
const response = await fetch(`${EVENTS_BASE_URL}/api/submissions`, {
|
|
1114
|
+
method: "POST",
|
|
1115
|
+
headers: {
|
|
1116
|
+
"Content-Type": "application/json"
|
|
1117
|
+
},
|
|
1118
|
+
// Explicitly set credentials to 'omit' for CORS support
|
|
1119
|
+
credentials: "omit",
|
|
1120
|
+
body: JSON.stringify(submission)
|
|
1121
|
+
});
|
|
1122
|
+
const responseData = await response.json();
|
|
1123
|
+
if (!response.ok) {
|
|
1124
|
+
const errorMessage = responseData.message || responseData.error || `HTTP ${response.status}`;
|
|
1125
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1126
|
+
return {
|
|
1127
|
+
success: false,
|
|
1128
|
+
message: errorMessage
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
if (responseData.success) {
|
|
1132
|
+
setState({ loading: false, error: null, success: true });
|
|
1133
|
+
return {
|
|
1134
|
+
id: ((_a = responseData.data) == null ? void 0 : _a.id) || ((_b = responseData.data) == null ? void 0 : _b._id),
|
|
1135
|
+
success: true,
|
|
1136
|
+
message: ((_c = responseData.data) == null ? void 0 : _c.message) || "Submission successful"
|
|
1137
|
+
};
|
|
1138
|
+
} else {
|
|
1139
|
+
const errorMessage = responseData.message || responseData.error || "Submission failed";
|
|
1140
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1141
|
+
return {
|
|
1142
|
+
success: false,
|
|
1143
|
+
message: errorMessage
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
} catch (error) {
|
|
1147
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1148
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1149
|
+
return {
|
|
1150
|
+
success: false,
|
|
1151
|
+
message: errorMessage
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
},
|
|
1155
|
+
[options, widgetId]
|
|
1156
|
+
);
|
|
1157
|
+
const reset = useCallback(() => {
|
|
1158
|
+
setState({ loading: false, error: null, success: false });
|
|
1159
|
+
}, []);
|
|
1160
|
+
return {
|
|
1161
|
+
...state,
|
|
1162
|
+
submit,
|
|
1163
|
+
reset
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1085
1166
|
function useLocalStorage(key, initialValue, options = {}) {
|
|
1086
1167
|
const [storedValue, setStoredValue] = useState(() => {
|
|
1087
1168
|
const item = storage.get(key, options);
|
|
@@ -1126,6 +1207,144 @@ function useLocalStorage(key, initialValue, options = {}) {
|
|
|
1126
1207
|
}, [key, options]);
|
|
1127
1208
|
return [storedValue, setValue, removeValue];
|
|
1128
1209
|
}
|
|
1210
|
+
function useVote(options) {
|
|
1211
|
+
const { widgetId } = useEmbeddableConfig();
|
|
1212
|
+
const [state, setState] = useState({
|
|
1213
|
+
loading: false,
|
|
1214
|
+
error: null,
|
|
1215
|
+
success: false
|
|
1216
|
+
});
|
|
1217
|
+
const vote = useCallback(
|
|
1218
|
+
async (voteFor) => {
|
|
1219
|
+
var _a, _b, _c;
|
|
1220
|
+
setState({ loading: true, error: null, success: false });
|
|
1221
|
+
try {
|
|
1222
|
+
const voteData = {
|
|
1223
|
+
voteFor,
|
|
1224
|
+
widgetId,
|
|
1225
|
+
collectionName: (options == null ? void 0 : options.collectionName) || "votes"
|
|
1226
|
+
};
|
|
1227
|
+
const response = await fetch(`${EVENTS_BASE_URL}/api/votes`, {
|
|
1228
|
+
method: "POST",
|
|
1229
|
+
headers: {
|
|
1230
|
+
"Content-Type": "application/json"
|
|
1231
|
+
},
|
|
1232
|
+
// Explicitly set credentials to 'omit' for CORS support
|
|
1233
|
+
credentials: "omit",
|
|
1234
|
+
body: JSON.stringify(voteData)
|
|
1235
|
+
});
|
|
1236
|
+
const responseData = await response.json();
|
|
1237
|
+
if (!response.ok) {
|
|
1238
|
+
const errorMessage = responseData.message || responseData.error || `HTTP ${response.status}`;
|
|
1239
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1240
|
+
return {
|
|
1241
|
+
success: false,
|
|
1242
|
+
message: errorMessage
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
if (responseData.success) {
|
|
1246
|
+
setState({ loading: false, error: null, success: true });
|
|
1247
|
+
return {
|
|
1248
|
+
id: ((_a = responseData.data) == null ? void 0 : _a.id) || ((_b = responseData.data) == null ? void 0 : _b._id),
|
|
1249
|
+
success: true,
|
|
1250
|
+
message: ((_c = responseData.data) == null ? void 0 : _c.message) || "Vote submitted successfully"
|
|
1251
|
+
};
|
|
1252
|
+
} else {
|
|
1253
|
+
const errorMessage = responseData.message || responseData.error || "Vote submission failed";
|
|
1254
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1255
|
+
return {
|
|
1256
|
+
success: false,
|
|
1257
|
+
message: errorMessage
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
} catch (error) {
|
|
1261
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1262
|
+
setState({ loading: false, error: errorMessage, success: false });
|
|
1263
|
+
return {
|
|
1264
|
+
success: false,
|
|
1265
|
+
message: errorMessage
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
[options, widgetId]
|
|
1270
|
+
);
|
|
1271
|
+
const reset = useCallback(() => {
|
|
1272
|
+
setState({ loading: false, error: null, success: false });
|
|
1273
|
+
}, []);
|
|
1274
|
+
return {
|
|
1275
|
+
...state,
|
|
1276
|
+
vote,
|
|
1277
|
+
reset
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
function useVoteAggregations(options) {
|
|
1281
|
+
const { widgetId } = useEmbeddableConfig();
|
|
1282
|
+
const [state, setState] = useState({
|
|
1283
|
+
data: null,
|
|
1284
|
+
loading: false,
|
|
1285
|
+
error: null
|
|
1286
|
+
});
|
|
1287
|
+
const fetchAggregations = useCallback(async () => {
|
|
1288
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1289
|
+
try {
|
|
1290
|
+
const collectionName = (options == null ? void 0 : options.collectionName) || "votes";
|
|
1291
|
+
const url = new URL(`${EVENTS_BASE_URL}/api/votes/aggregations`);
|
|
1292
|
+
url.searchParams.append("widgetId", widgetId);
|
|
1293
|
+
url.searchParams.append("collectionName", collectionName);
|
|
1294
|
+
const response = await fetch(url.toString(), {
|
|
1295
|
+
method: "GET",
|
|
1296
|
+
headers: {
|
|
1297
|
+
"Content-Type": "application/json"
|
|
1298
|
+
},
|
|
1299
|
+
// Explicitly set credentials to 'omit' for CORS support
|
|
1300
|
+
credentials: "omit"
|
|
1301
|
+
});
|
|
1302
|
+
const responseData = await response.json();
|
|
1303
|
+
if (!response.ok) {
|
|
1304
|
+
const errorMessage = responseData.message || responseData.error || `HTTP ${response.status}`;
|
|
1305
|
+
setState({ data: null, loading: false, error: errorMessage });
|
|
1306
|
+
return {
|
|
1307
|
+
success: false,
|
|
1308
|
+
data: { results: [], summary: { totalVotes: 0, totalOptions: 0, groupBy: "" } }
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
setState({ data: responseData.data, loading: false, error: null });
|
|
1312
|
+
return responseData;
|
|
1313
|
+
} catch (error) {
|
|
1314
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1315
|
+
setState({ data: null, loading: false, error: errorMessage });
|
|
1316
|
+
return {
|
|
1317
|
+
success: false,
|
|
1318
|
+
data: { results: [], summary: { totalVotes: 0, totalOptions: 0, groupBy: "" } }
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
}, [widgetId, options == null ? void 0 : options.collectionName]);
|
|
1322
|
+
const refetch = useCallback(() => {
|
|
1323
|
+
return fetchAggregations();
|
|
1324
|
+
}, [fetchAggregations]);
|
|
1325
|
+
const reset = useCallback(() => {
|
|
1326
|
+
setState({ data: null, loading: false, error: null });
|
|
1327
|
+
}, []);
|
|
1328
|
+
useEffect(() => {
|
|
1329
|
+
if ((options == null ? void 0 : options.autoFetch) !== false) {
|
|
1330
|
+
fetchAggregations();
|
|
1331
|
+
}
|
|
1332
|
+
}, [fetchAggregations, options == null ? void 0 : options.autoFetch]);
|
|
1333
|
+
useEffect(() => {
|
|
1334
|
+
if ((options == null ? void 0 : options.refetchInterval) && options.refetchInterval > 0) {
|
|
1335
|
+
const interval = setInterval(() => {
|
|
1336
|
+
fetchAggregations();
|
|
1337
|
+
}, options.refetchInterval);
|
|
1338
|
+
return () => clearInterval(interval);
|
|
1339
|
+
}
|
|
1340
|
+
}, [fetchAggregations, options == null ? void 0 : options.refetchInterval]);
|
|
1341
|
+
return {
|
|
1342
|
+
...state,
|
|
1343
|
+
fetch: fetchAggregations,
|
|
1344
|
+
refetch,
|
|
1345
|
+
reset
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1129
1348
|
export {
|
|
1130
1349
|
EmbeddableProvider as E,
|
|
1131
1350
|
useApi as a,
|
|
@@ -1133,6 +1352,9 @@ export {
|
|
|
1133
1352
|
useEmbeddableConfig as c,
|
|
1134
1353
|
useEmbeddableConfigSafe as d,
|
|
1135
1354
|
useEmbeddableData as e,
|
|
1136
|
-
|
|
1355
|
+
useFormSubmission as f,
|
|
1356
|
+
useLocalStorage as g,
|
|
1357
|
+
useVote as h,
|
|
1358
|
+
useVoteAggregations as i,
|
|
1137
1359
|
useEmbeddableContext as u
|
|
1138
1360
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,iCAAiC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("react"),r=require("./storage-3dk6ww91.cjs");var t,n={exports:{}},o={};var a,i={};
|
|
2
|
-
/**
|
|
3
|
-
* @license React
|
|
4
|
-
* react-jsx-runtime.development.js
|
|
5
|
-
*
|
|
6
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
7
|
-
*
|
|
8
|
-
* This source code is licensed under the MIT license found in the
|
|
9
|
-
* LICENSE file in the root directory of this source tree.
|
|
10
|
-
*/"production"===process.env.NODE_ENV?n.exports=function(){if(t)return o;t=1;var r=e,n=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function u(e,r,t){var o,a={},u=null,l=null;for(o in void 0!==t&&(u=""+t),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(l=r.ref),r)i.call(r,o)&&!c.hasOwnProperty(o)&&(a[o]=r[o]);if(e&&e.defaultProps)for(o in r=e.defaultProps)void 0===a[o]&&(a[o]=r[o]);return{$$typeof:n,type:e,key:u,ref:l,props:a,_owner:s.current}}return o.Fragment=a,o.jsx=u,o.jsxs=u,o}():n.exports=(a||(a=1,"production"!==process.env.NODE_ENV&&function(){var r,t=e,n=Symbol.for("react.element"),o=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),l=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),y=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),b=Symbol.for("react.offscreen"),g=Symbol.iterator,m=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function h(e){for(var r=arguments.length,t=new Array(r>1?r-1:0),n=1;n<r;n++)t[n-1]=arguments[n];!function(e,r,t){var n=m.ReactDebugCurrentFrame.getStackAddendum();""!==n&&(r+="%s",t=t.concat([n]));var o=t.map((function(e){return String(e)}));o.unshift("Warning: "+r),Function.prototype.apply.call(console[e],console,o)}("error",e,t)}function w(e){return e.displayName||"Context"}function k(e){if(null==e)return null;if("number"==typeof e.tag&&h("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),"function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case a:return"Fragment";case o:return"Portal";case c:return"Profiler";case s:return"StrictMode";case p:return"Suspense";case d:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case l:return w(e)+".Consumer";case u:return w(e._context)+".Provider";case f:return function(e,r,t){var n=e.displayName;if(n)return n;var o=r.displayName||r.name||"";return""!==o?t+"("+o+")":t}(e,e.render,"ForwardRef");case y:var r=e.displayName||null;return null!==r?r:k(e.type)||"Memo";case v:var t=e,n=t._payload,i=t._init;try{return k(i(n))}catch(b){return null}}return null}r=Symbol.for("react.module.reference");var _,E,S,O,j,R,x,C=Object.assign,P=0;function T(){}T.__reactDisabledLog=!0;var $,D=m.ReactCurrentDispatcher;function N(e,r,t){if(void 0===$)try{throw Error()}catch(o){var n=o.stack.trim().match(/\n( *(at )?)/);$=n&&n[1]||""}return"\n"+$+e}var F,I=!1,L="function"==typeof WeakMap?WeakMap:Map;function U(e,r){if(!e||I)return"";var t,n=F.get(e);if(void 0!==n)return n;I=!0;var o,a=Error.prepareStackTrace;Error.prepareStackTrace=void 0,o=D.current,D.current=null,function(){if(0===P){_=console.log,E=console.info,S=console.warn,O=console.error,j=console.group,R=console.groupCollapsed,x=console.groupEnd;var e={configurable:!0,enumerable:!0,value:T,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}P++}();try{if(r){var i=function(){throw Error()};if(Object.defineProperty(i.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(i,[])}catch(y){t=y}Reflect.construct(e,[],i)}else{try{i.call()}catch(y){t=y}e.call(i.prototype)}}else{try{throw Error()}catch(y){t=y}e()}}catch(v){if(v&&t&&"string"==typeof v.stack){for(var s=v.stack.split("\n"),c=t.stack.split("\n"),u=s.length-1,l=c.length-1;u>=1&&l>=0&&s[u]!==c[l];)l--;for(;u>=1&&l>=0;u--,l--)if(s[u]!==c[l]){if(1!==u||1!==l)do{if(u--,--l<0||s[u]!==c[l]){var f="\n"+s[u].replace(" at new "," at ");return e.displayName&&f.includes("<anonymous>")&&(f=f.replace("<anonymous>",e.displayName)),"function"==typeof e&&F.set(e,f),f}}while(u>=1&&l>=0);break}}}finally{I=!1,D.current=o,function(){if(0===--P){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:C({},e,{value:_}),info:C({},e,{value:E}),warn:C({},e,{value:S}),error:C({},e,{value:O}),group:C({},e,{value:j}),groupCollapsed:C({},e,{value:R}),groupEnd:C({},e,{value:x})})}P<0&&h("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}(),Error.prepareStackTrace=a}var p=e?e.displayName||e.name:"",d=p?N(p):"";return"function"==typeof e&&F.set(e,d),d}function A(e,r,t){if(null==e)return"";if("function"==typeof e)return U(e,!(!(n=e.prototype)||!n.isReactComponent));var n;if("string"==typeof e)return N(e);switch(e){case p:return N("Suspense");case d:return N("SuspenseList")}if("object"==typeof e)switch(e.$$typeof){case f:return U(e.render,!1);case y:return A(e.type,r,t);case v:var o=e,a=o._payload,i=o._init;try{return A(i(a),r,t)}catch(s){}}return""}F=new L;var W=Object.prototype.hasOwnProperty,z={},M=m.ReactDebugCurrentFrame;function V(e){if(e){var r=e._owner,t=A(e.type,e._source,r?r.type:null);M.setExtraStackFrame(t)}else M.setExtraStackFrame(null)}var Y=Array.isArray;function q(e){return Y(e)}function B(e){return""+e}function J(e){if(function(e){try{return B(e),!1}catch(r){return!0}}(e))return h("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",function(e){return"function"==typeof Symbol&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object"}(e)),B(e)}var K,X,H=m.ReactCurrentOwner,G={key:!0,ref:!0,__self:!0,__source:!0};function Q(e,r,t,o,a){var i,s={},c=null,u=null;for(i in void 0!==t&&(J(t),c=""+t),function(e){if(W.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return void 0!==e.key}(r)&&(J(r.key),c=""+r.key),function(e){if(W.call(e,"ref")){var r=Object.getOwnPropertyDescriptor(e,"ref").get;if(r&&r.isReactWarning)return!1}return void 0!==e.ref}(r)&&(u=r.ref,function(e){"string"==typeof e.ref&&H.current}(r)),r)W.call(r,i)&&!G.hasOwnProperty(i)&&(s[i]=r[i]);if(e&&e.defaultProps){var l=e.defaultProps;for(i in l)void 0===s[i]&&(s[i]=l[i])}if(c||u){var f="function"==typeof e?e.displayName||e.name||"Unknown":e;c&&function(e,r){var t=function(){K||(K=!0,h("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}(s,f),u&&function(e,r){var t=function(){X||(X=!0,h("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"ref",{get:t,configurable:!0})}(s,f)}return function(e,r,t,o,a,i,s){var c={$$typeof:n,type:e,key:r,ref:t,props:s,_owner:i,_store:{}};return Object.defineProperty(c._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(c,"_self",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.defineProperty(c,"_source",{configurable:!1,enumerable:!1,writable:!1,value:a}),Object.freeze&&(Object.freeze(c.props),Object.freeze(c)),c}(e,c,u,a,o,H.current,s)}var Z,ee=m.ReactCurrentOwner,re=m.ReactDebugCurrentFrame;function te(e){if(e){var r=e._owner,t=A(e.type,e._source,r?r.type:null);re.setExtraStackFrame(t)}else re.setExtraStackFrame(null)}function ne(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}function oe(){if(ee.current){var e=k(ee.current.type);if(e)return"\n\nCheck the render method of `"+e+"`."}return""}Z=!1;var ae={};function ie(e,r){if(e._store&&!e._store.validated&&null==e.key){e._store.validated=!0;var t=function(e){var r=oe();if(!r){var t="string"==typeof e?e:e.displayName||e.name;t&&(r="\n\nCheck the top-level render call using <"+t+">.")}return r}(r);if(!ae[t]){ae[t]=!0;var n="";e&&e._owner&&e._owner!==ee.current&&(n=" It was passed a child from "+k(e._owner.type)+"."),te(e),h('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',t,n),te(null)}}}function se(e,r){if("object"==typeof e)if(q(e))for(var t=0;t<e.length;t++){var n=e[t];ne(n)&&ie(n,r)}else if(ne(e))e._store&&(e._store.validated=!0);else if(e){var o=function(e){if(null===e||"object"!=typeof e)return null;var r=g&&e[g]||e["@@iterator"];return"function"==typeof r?r:null}(e);if("function"==typeof o&&o!==e.entries)for(var a,i=o.call(e);!(a=i.next()).done;)ne(a.value)&&ie(a.value,r)}}function ce(e){var r,t=e.type;if(null!=t&&"string"!=typeof t){if("function"==typeof t)r=t.propTypes;else{if("object"!=typeof t||t.$$typeof!==f&&t.$$typeof!==y)return;r=t.propTypes}if(r){var n=k(t);!function(e,r,t,n,o){var a=Function.call.bind(W);for(var i in e)if(a(e,i)){var s=void 0;try{if("function"!=typeof e[i]){var c=Error((n||"React class")+": "+t+" type `"+i+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[i]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw c.name="Invariant Violation",c}s=e[i](r,i,n,t,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(u){s=u}!s||s instanceof Error||(V(o),h("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",n||"React class",t,i,typeof s),V(null)),s instanceof Error&&!(s.message in z)&&(z[s.message]=!0,V(o),h("Failed %s type: %s",t,s.message),V(null))}}(r,e.props,"prop",n,e)}else void 0===t.PropTypes||Z||(Z=!0,h("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",k(t)||"Unknown"));"function"!=typeof t.getDefaultProps||t.getDefaultProps.isReactClassApproved||h("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}var ue={};function le(e,t,o,i,g,m){var w=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===c||e===s||e===p||e===d||e===b||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===y||e.$$typeof===u||e.$$typeof===l||e.$$typeof===f||e.$$typeof===r||void 0!==e.getModuleId)}(e);if(!w){var _,E="";(void 0===e||"object"==typeof e&&null!==e&&0===Object.keys(e).length)&&(E+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."),E+=oe(),null===e?_="null":q(e)?_="array":void 0!==e&&e.$$typeof===n?(_="<"+(k(e.type)||"Unknown")+" />",E=" Did you accidentally export a JSX literal instead of a component?"):_=typeof e,h("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",_,E)}var S=Q(e,t,o,g,m);if(null==S)return S;if(w){var O=t.children;if(void 0!==O)if(i)if(q(O)){for(var j=0;j<O.length;j++)se(O[j],e);Object.freeze&&Object.freeze(O)}else h("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else se(O,e)}if(W.call(t,"key")){var R=k(e),x=Object.keys(t).filter((function(e){return"key"!==e})),C=x.length>0?"{key: someKey, "+x.join(": ..., ")+": ...}":"{key: someKey}";ue[R+C]||(h('A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',C,R,x.length>0?"{"+x.join(": ..., ")+": ...}":"{}",R),ue[R+C]=!0)}return e===a?function(e){for(var r=Object.keys(e.props),t=0;t<r.length;t++){var n=r[t];if("children"!==n&&"key"!==n){te(e),h("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",n),te(null);break}}null!==e.ref&&(te(e),h("Invalid attribute `ref` supplied to `React.Fragment`."),te(null))}(S):ce(S),S}var fe=function(e,r,t){return le(e,r,t,!1)},pe=function(e,r,t){return le(e,r,t,!0)};i.Fragment=a,i.jsx=fe,i.jsxs=pe}()),i);var s=n.exports;const c={version:"latest",mode:"embeddable",ignoreCache:!1,lazyLoad:!1,loader:!0,widgetId:"",_containerId:"",_shadowRoot:void 0},u=e.createContext({config:{...c},setConfig:()=>{},data:{},setData:()=>{}});function l(){const r=e.useContext(u);if(!r)throw new Error("useEmbeddableContext must be used within an EmbeddableProvider");return r}exports.EmbeddableProvider=function({config:r,data:t,children:n}){const[o,a]=e.useState(c),[i,l]=e.useState(t||{});return e.useEffect((()=>{a({...c,...r})}),[r]),e.useEffect((()=>{const e=e=>{("https://embeddable.co"===e.origin||e.origin.includes("localhost"))&&e.data&&"object"==typeof e.data&&"embeddable-update-data"===e.data.type&&l(e.data.data||{})};return window.addEventListener("message",e),()=>{window.removeEventListener("message",e)}}),[]),s.jsx(u.Provider,{value:{config:o,setConfig:a,data:i,setData:l},children:n})},exports.useApi=function(t){const n=t;if(!n)throw new Error("No API configuration provided. Either pass a config parameter or wrap your app with EmbeddableProvider.");const[o,a]=e.useState({data:null,loading:!1,error:null}),i=r.createApiClient(n),s=e.useCallback((async(e,r,t)=>{a((e=>({...e,loading:!0,error:null})));try{let n;switch(e){case"get":n=await i.get(r);break;case"post":n=await i.post(r,t);break;case"put":n=await i.put(r,t);break;case"delete":n=await i.delete(r);break;default:throw new Error(`Unsupported method: ${e}`)}return a({data:n.data,loading:!1,error:n.success?null:n.error||"Unknown error"}),n}catch(n){const e=n instanceof Error?n.message:"Unknown error";return a({data:null,loading:!1,error:e}),{data:null,success:!1,error:e}}}),[i]);return{...o,get:e.useCallback((e=>s("get",e)),[s]),post:e.useCallback(((e,r)=>s("post",e,r)),[s]),put:e.useCallback(((e,r)=>s("put",e,r)),[s]),delete:e.useCallback((e=>s("delete",e)),[s]),reset:e.useCallback((()=>{a({data:null,loading:!1,error:null})}),[])}},exports.useDebounce=function(r,t){const[n,o]=e.useState(r);return e.useEffect((()=>{const e=setTimeout((()=>{o(r)}),t);return()=>{clearTimeout(e)}}),[r,t]),n},exports.useEmbeddableConfig=function(){const{config:e}=l();if(!e)throw new Error("No Embeddable configuration found. Make sure to wrap your app with EmbeddableProvider and provide a valid config.");return e},exports.useEmbeddableConfigSafe=function(){const{config:e}=l();return e},exports.useEmbeddableContext=l,exports.useEmbeddableData=function(){const{data:e}=l();return{data:e}},exports.useLocalStorage=function(t,n,o={}){const[a,i]=e.useState((()=>{const e=r.storage.get(t,o);return null!==e?e:n})),s=e.useCallback((e=>{try{const n=e instanceof Function?e(a):e;i(n),r.storage.set(t,n,o)}catch(n){}}),[t,a,o]),c=e.useCallback((()=>{try{i(n),r.storage.remove(t,o)}catch(e){}}),[t,n,o]);return e.useEffect((()=>{const e=e=>{const{prefix:r=""}=o,n=r+t;if(e.key===n&&null!==e.newValue)try{const{deserialize:r=JSON.parse}=o,t=r(e.newValue);i(t)}catch(a){}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,o]),[a,s,c]};
|