@pancakeswap/token-lists 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js ADDED
@@ -0,0 +1,781 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // ../utils/uriToHttp.ts
30
+ function uriToHttp(uri) {
31
+ var _a, _b;
32
+ const protocol = uri.split(":")[0].toLowerCase();
33
+ switch (protocol) {
34
+ case "https":
35
+ return [uri];
36
+ case "http":
37
+ return [`https${uri.substring(4)}`, uri];
38
+ case "ipfs":
39
+ const hash = (_a = uri.match(/^ipfs:(\/\/)?(.*)$/i)) == null ? void 0 : _a[2];
40
+ return [`https://cloudflare-ipfs.com/ipfs/${hash}/`, `https://ipfs.io/ipfs/${hash}/`];
41
+ case "ipns":
42
+ const name = (_b = uri.match(/^ipns:(\/\/)?(.*)$/i)) == null ? void 0 : _b[2];
43
+ return [`https://cloudflare-ipfs.com/ipns/${name}/`, `https://ipfs.io/ipns/${name}/`];
44
+ default:
45
+ return [];
46
+ }
47
+ }
48
+ var init_uriToHttp = __esm({
49
+ "../utils/uriToHttp.ts"() {
50
+ }
51
+ });
52
+
53
+ // schema/pancakeswap.json
54
+ var pancakeswap_default;
55
+ var init_pancakeswap = __esm({
56
+ "schema/pancakeswap.json"() {
57
+ pancakeswap_default = {
58
+ $schema: "http://json-schema.org/draft-07/schema#",
59
+ $id: "pancakeswap",
60
+ title: "PancakeSwap Token List",
61
+ description: "Schema for lists of tokens compatible with the PancakeSwap Interface, including Uniswap standard and PancakeSwap Aptos",
62
+ definitions: {
63
+ Version: {
64
+ type: "object",
65
+ description: "The version of the list, used in change detection",
66
+ examples: [
67
+ {
68
+ major: 1,
69
+ minor: 0,
70
+ patch: 0
71
+ }
72
+ ],
73
+ additionalProperties: false,
74
+ properties: {
75
+ major: {
76
+ type: "integer",
77
+ description: "The major version of the list. Must be incremented when tokens are removed from the list or token addresses are changed.",
78
+ minimum: 0,
79
+ examples: [1, 2]
80
+ },
81
+ minor: {
82
+ type: "integer",
83
+ description: "The minor version of the list. Must be incremented when tokens are added to the list.",
84
+ minimum: 0,
85
+ examples: [0, 1]
86
+ },
87
+ patch: {
88
+ type: "integer",
89
+ description: "The patch version of the list. Must be incremented for any changes to the list.",
90
+ minimum: 0,
91
+ examples: [0, 1]
92
+ }
93
+ },
94
+ required: ["major", "minor", "patch"]
95
+ },
96
+ TagIdentifier: {
97
+ type: "string",
98
+ description: "The unique identifier of a tag",
99
+ minLength: 1,
100
+ maxLength: 10,
101
+ pattern: "^[\\w]+$",
102
+ examples: ["compound", "stablecoin"]
103
+ },
104
+ ExtensionIdentifier: {
105
+ type: "string",
106
+ description: "The name of a token extension property",
107
+ minLength: 1,
108
+ maxLength: 40,
109
+ pattern: "^[\\w]+$",
110
+ examples: ["color", "is_fee_on_transfer", "aliases"]
111
+ },
112
+ ExtensionMap: {
113
+ type: "object",
114
+ description: "An object containing any arbitrary or vendor-specific token metadata",
115
+ maxProperties: 10,
116
+ propertyNames: {
117
+ $ref: "#/definitions/ExtensionIdentifier"
118
+ },
119
+ additionalProperties: {
120
+ $ref: "#/definitions/ExtensionValue"
121
+ },
122
+ examples: [
123
+ {
124
+ color: "#000000",
125
+ is_verified_by_me: true
126
+ },
127
+ {
128
+ "x-bridged-addresses-by-chain": {
129
+ "1": {
130
+ bridgeAddress: "0x4200000000000000000000000000000000000010",
131
+ tokenAddress: "0x4200000000000000000000000000000000000010"
132
+ }
133
+ }
134
+ }
135
+ ]
136
+ },
137
+ ExtensionPrimitiveValue: {
138
+ anyOf: [
139
+ {
140
+ type: "string",
141
+ minLength: 1,
142
+ maxLength: 42,
143
+ examples: ["#00000"]
144
+ },
145
+ {
146
+ type: "boolean",
147
+ examples: [true]
148
+ },
149
+ {
150
+ type: "number",
151
+ examples: [15]
152
+ },
153
+ {
154
+ type: "null"
155
+ }
156
+ ]
157
+ },
158
+ ExtensionValue: {
159
+ anyOf: [
160
+ {
161
+ $ref: "#/definitions/ExtensionPrimitiveValue"
162
+ },
163
+ {
164
+ type: "object",
165
+ maxProperties: 10,
166
+ propertyNames: {
167
+ $ref: "#/definitions/ExtensionIdentifier"
168
+ },
169
+ additionalProperties: {
170
+ $ref: "#/definitions/ExtensionValueInner0"
171
+ }
172
+ }
173
+ ]
174
+ },
175
+ ExtensionValueInner0: {
176
+ anyOf: [
177
+ {
178
+ $ref: "#/definitions/ExtensionPrimitiveValue"
179
+ },
180
+ {
181
+ type: "object",
182
+ maxProperties: 10,
183
+ propertyNames: {
184
+ $ref: "#/definitions/ExtensionIdentifier"
185
+ },
186
+ additionalProperties: {
187
+ $ref: "#/definitions/ExtensionValueInner1"
188
+ }
189
+ }
190
+ ]
191
+ },
192
+ ExtensionValueInner1: {
193
+ anyOf: [
194
+ {
195
+ $ref: "#/definitions/ExtensionPrimitiveValue"
196
+ }
197
+ ]
198
+ },
199
+ TagDefinition: {
200
+ type: "object",
201
+ description: "Definition of a tag that can be associated with a token via its identifier",
202
+ additionalProperties: false,
203
+ properties: {
204
+ name: {
205
+ type: "string",
206
+ description: "The name of the tag",
207
+ pattern: "^[ \\w]+$",
208
+ minLength: 1,
209
+ maxLength: 20
210
+ },
211
+ description: {
212
+ type: "string",
213
+ description: "A user-friendly description of the tag",
214
+ pattern: "^[ \\w\\.,:]+$",
215
+ minLength: 1,
216
+ maxLength: 200
217
+ }
218
+ },
219
+ required: ["name", "description"],
220
+ examples: [
221
+ {
222
+ name: "Stablecoin",
223
+ description: "A token with value pegged to another asset"
224
+ }
225
+ ]
226
+ },
227
+ TokenInfo: {
228
+ type: "object",
229
+ description: "Metadata for a single token in a token list",
230
+ additionalProperties: false,
231
+ properties: {
232
+ chainId: {
233
+ type: "integer",
234
+ description: "The chain ID of the Ethereum network where this token is deployed",
235
+ minimum: 1,
236
+ examples: [1, 42]
237
+ },
238
+ address: {
239
+ type: "string",
240
+ description: "The checksummed address of the token on the specified chain ID",
241
+ pattern: "^0x[a-fA-F0-9]{40}$",
242
+ examples: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"]
243
+ },
244
+ decimals: {
245
+ type: "integer",
246
+ description: "The number of decimals for the token balance",
247
+ minimum: 0,
248
+ maximum: 255,
249
+ examples: [18]
250
+ },
251
+ name: {
252
+ type: "string",
253
+ description: "The name of the token",
254
+ minLength: 1,
255
+ maxLength: 40,
256
+ pattern: "^[ \\w.'+\\-%/\xC0-\xD6\xD8-\xF6\xF8-\xFF:&\\[\\]\\(\\)]+$",
257
+ examples: ["USD Coin"]
258
+ },
259
+ symbol: {
260
+ type: "string",
261
+ description: "The symbol for the token; must be alphanumeric",
262
+ pattern: "^[a-zA-Z0-9+\\-%/$.]+$",
263
+ minLength: 1,
264
+ maxLength: 20,
265
+ examples: ["USDC"]
266
+ },
267
+ logoURI: {
268
+ type: "string",
269
+ description: "A URI to the token logo asset; if not set, interface will attempt to find a logo based on the token address; suggest SVG or PNG of size 64x64",
270
+ format: "uri",
271
+ examples: ["ipfs://QmXfzKRvjZz3u5JRgC4v5mGVbm9ahrUiB4DgzHBsnWbTMM"]
272
+ },
273
+ tags: {
274
+ type: "array",
275
+ description: "An array of tag identifiers associated with the token; tags are defined at the list level",
276
+ items: {
277
+ $ref: "#/definitions/TagIdentifier"
278
+ },
279
+ maxItems: 10,
280
+ examples: ["stablecoin", "compound"]
281
+ },
282
+ extensions: {
283
+ $ref: "#/definitions/ExtensionMap"
284
+ }
285
+ },
286
+ required: ["chainId", "address", "decimals", "name", "symbol"]
287
+ },
288
+ AptosTokenInfo: {
289
+ type: "object",
290
+ description: "Metadata for a single token in a token list",
291
+ additionalProperties: false,
292
+ properties: {
293
+ chainId: {
294
+ type: "integer",
295
+ description: "The chain ID of the Aptos network where this token is deployed, 0 is devent",
296
+ minimum: 0,
297
+ examples: [1, 42]
298
+ },
299
+ address: {
300
+ type: "string",
301
+ description: "The address of the coin on the specified chain ID",
302
+ examples: ["0x1::aptos_coin::AptosCoin"]
303
+ },
304
+ decimals: {
305
+ type: "integer",
306
+ description: "The number of decimals for the token balance",
307
+ minimum: 0,
308
+ maximum: 255,
309
+ examples: [18]
310
+ },
311
+ name: {
312
+ type: "string",
313
+ description: "The name of the token",
314
+ minLength: 1,
315
+ maxLength: 40,
316
+ pattern: "^[ \\w.'+\\-%/\xC0-\xD6\xD8-\xF6\xF8-\xFF:&\\[\\]\\(\\)]+$",
317
+ examples: ["USD Coin"]
318
+ },
319
+ symbol: {
320
+ type: "string",
321
+ description: "The symbol for the token; must be alphanumeric",
322
+ pattern: "^[a-zA-Z0-9+\\-%/$.]+$",
323
+ minLength: 1,
324
+ maxLength: 20,
325
+ examples: ["USDC"]
326
+ },
327
+ logoURI: {
328
+ type: "string",
329
+ description: "A URI to the token logo asset; if not set, interface will attempt to find a logo based on the token address; suggest SVG or PNG of size 64x64",
330
+ format: "uri",
331
+ examples: ["ipfs://QmXfzKRvjZz3u5JRgC4v5mGVbm9ahrUiB4DgzHBsnWbTMM"]
332
+ },
333
+ tags: {
334
+ type: "array",
335
+ description: "An array of tag identifiers associated with the token; tags are defined at the list level",
336
+ items: {
337
+ $ref: "#/definitions/TagIdentifier"
338
+ },
339
+ maxItems: 10,
340
+ examples: ["stablecoin", "compound"]
341
+ },
342
+ extensions: {
343
+ $ref: "#/definitions/ExtensionMap"
344
+ }
345
+ },
346
+ required: ["chainId", "address", "decimals", "name", "symbol"]
347
+ }
348
+ },
349
+ type: "object",
350
+ additionalProperties: false,
351
+ properties: {
352
+ name: {
353
+ type: "string",
354
+ description: "The name of the token list",
355
+ minLength: 1,
356
+ maxLength: 30,
357
+ pattern: "^[\\w ]+$",
358
+ examples: ["My Token List"]
359
+ },
360
+ timestamp: {
361
+ type: "string",
362
+ format: "date-time",
363
+ description: "The timestamp of this list version; i.e. when this immutable version of the list was created"
364
+ },
365
+ schema: {
366
+ type: "string"
367
+ },
368
+ version: {
369
+ $ref: "#/definitions/Version"
370
+ },
371
+ tokens: {
372
+ type: "array",
373
+ description: "The list of tokens included in the list",
374
+ minItems: 1,
375
+ maxItems: 1e4
376
+ },
377
+ keywords: {
378
+ type: "array",
379
+ description: "Keywords associated with the contents of the list; may be used in list discoverability",
380
+ items: {
381
+ type: "string",
382
+ description: "A keyword to describe the contents of the list",
383
+ minLength: 1,
384
+ maxLength: 20,
385
+ pattern: "^[\\w ]+$",
386
+ examples: ["compound", "lending", "personal tokens"]
387
+ },
388
+ maxItems: 20,
389
+ uniqueItems: true
390
+ },
391
+ tags: {
392
+ type: "object",
393
+ description: "A mapping of tag identifiers to their name and description",
394
+ propertyNames: {
395
+ $ref: "#/definitions/TagIdentifier"
396
+ },
397
+ additionalProperties: {
398
+ $ref: "#/definitions/TagDefinition"
399
+ },
400
+ maxProperties: 20,
401
+ examples: [
402
+ {
403
+ stablecoin: {
404
+ name: "Stablecoin",
405
+ description: "A token with value pegged to another asset"
406
+ }
407
+ }
408
+ ]
409
+ },
410
+ logoURI: {
411
+ type: "string",
412
+ description: "A URI for the logo of the token list; prefer SVG or PNG of size 256x256",
413
+ format: "uri",
414
+ examples: ["ipfs://QmXfzKRvjZz3u5JRgC4v5mGVbm9ahrUiB4DgzHBsnWbTMM"]
415
+ }
416
+ },
417
+ if: {
418
+ properties: { schema: { const: "aptos" } },
419
+ required: ["name", "timestamp", "version", "tokens", "schema"]
420
+ },
421
+ then: {
422
+ properties: {
423
+ tokens: {
424
+ items: {
425
+ $ref: "#/definitions/AptosTokenInfo"
426
+ },
427
+ type: "array",
428
+ description: "The list of tokens included in the list",
429
+ minItems: 1,
430
+ maxItems: 1e4
431
+ }
432
+ }
433
+ },
434
+ else: {
435
+ properties: {
436
+ tokens: {
437
+ items: {
438
+ $ref: "#/definitions/TokenInfo"
439
+ },
440
+ type: "array",
441
+ description: "The list of tokens included in the list",
442
+ minItems: 1,
443
+ maxItems: 1e4
444
+ }
445
+ }
446
+ },
447
+ required: ["name", "timestamp", "version", "tokens"]
448
+ };
449
+ }
450
+ });
451
+
452
+ // react/getTokenList.ts
453
+ var getTokenList_exports = {};
454
+ __export(getTokenList_exports, {
455
+ default: () => getTokenList,
456
+ tokenListValidator: () => tokenListValidator
457
+ });
458
+ async function getTokenList(listUrl) {
459
+ var _a;
460
+ const urls = uriToHttp(listUrl);
461
+ for (let i = 0; i < urls.length; i++) {
462
+ const url = urls[i];
463
+ const isLast = i === urls.length - 1;
464
+ let response;
465
+ try {
466
+ response = await fetch(url);
467
+ } catch (error) {
468
+ console.error("Failed to fetch list", listUrl, error);
469
+ if (isLast)
470
+ throw new Error(`Failed to download list ${listUrl}`);
471
+ continue;
472
+ }
473
+ if (!response.ok) {
474
+ if (isLast)
475
+ throw new Error(`Failed to download list ${listUrl}`);
476
+ continue;
477
+ }
478
+ const json = await response.json();
479
+ if (!tokenListValidator(json)) {
480
+ const validationErrors = ((_a = tokenListValidator.errors) == null ? void 0 : _a.reduce((memo, error) => {
481
+ const add = `${error.dataPath} ${error.message ?? ""}`;
482
+ return memo.length > 0 ? `${memo}; ${add}` : `${add}`;
483
+ }, "")) ?? "unknown error";
484
+ throw new Error(`Token list failed validation: ${validationErrors}`);
485
+ }
486
+ return json;
487
+ }
488
+ throw new Error("Unrecognized list URL protocol.");
489
+ }
490
+ var import_ajv, tokenListValidator;
491
+ var init_getTokenList = __esm({
492
+ "react/getTokenList.ts"() {
493
+ "use strict";
494
+ init_uriToHttp();
495
+ import_ajv = __toESM(require("ajv"));
496
+ init_pancakeswap();
497
+ tokenListValidator = new import_ajv.default({ allErrors: true }).compile(pancakeswap_default);
498
+ }
499
+ });
500
+
501
+ // react/index.ts
502
+ var react_exports = {};
503
+ __export(react_exports, {
504
+ NEW_LIST_STATE: () => NEW_LIST_STATE,
505
+ acceptListUpdate: () => acceptListUpdate,
506
+ addList: () => addList,
507
+ createListsAtom: () => createListsAtom,
508
+ createTokenListReducer: () => createTokenListReducer,
509
+ disableList: () => disableList,
510
+ enableList: () => enableList,
511
+ fetchTokenList: () => fetchTokenList,
512
+ rejectVersionUpdate: () => rejectVersionUpdate,
513
+ removeList: () => removeList,
514
+ updateListVersion: () => updateListVersion,
515
+ useFetchListCallback: () => useFetchListCallback_default
516
+ });
517
+ module.exports = __toCommonJS(react_exports);
518
+
519
+ // react/reducer.ts
520
+ var import_toolkit2 = require("@reduxjs/toolkit");
521
+
522
+ // react/actions.ts
523
+ var import_toolkit = require("@reduxjs/toolkit");
524
+ var fetchTokenList = {
525
+ pending: (0, import_toolkit.createAction)("lists/fetchTokenList/pending"),
526
+ fulfilled: (0, import_toolkit.createAction)("lists/fetchTokenList/fulfilled"),
527
+ rejected: (0, import_toolkit.createAction)("lists/fetchTokenList/rejected")
528
+ };
529
+ var addList = (0, import_toolkit.createAction)("lists/addList");
530
+ var removeList = (0, import_toolkit.createAction)("lists/removeList");
531
+ var enableList = (0, import_toolkit.createAction)("lists/enableList");
532
+ var disableList = (0, import_toolkit.createAction)("lists/disableList");
533
+ var acceptListUpdate = (0, import_toolkit.createAction)("lists/acceptListUpdate");
534
+ var rejectVersionUpdate = (0, import_toolkit.createAction)("lists/rejectVersionUpdate");
535
+ var updateListVersion = (0, import_toolkit.createAction)("lists/updateListVersion");
536
+
537
+ // src/getVersionUpgrade.ts
538
+ function getVersionUpgrade(base, update) {
539
+ if (update.major > base.major) {
540
+ return 3 /* MAJOR */;
541
+ }
542
+ if (update.major < base.major) {
543
+ return 0 /* NONE */;
544
+ }
545
+ if (update.minor > base.minor) {
546
+ return 2 /* MINOR */;
547
+ }
548
+ if (update.minor < base.minor) {
549
+ return 0 /* NONE */;
550
+ }
551
+ return update.patch > base.patch ? 1 /* PATCH */ : 0 /* NONE */;
552
+ }
553
+
554
+ // react/reducer.ts
555
+ var NEW_LIST_STATE = {
556
+ error: null,
557
+ current: null,
558
+ loadingRequestId: null,
559
+ pendingUpdate: null
560
+ };
561
+ var createTokenListReducer = (initialState, DEFAULT_LIST_OF_LISTS, DEFAULT_ACTIVE_LIST_URLS) => (0, import_toolkit2.createReducer)(
562
+ initialState,
563
+ (builder) => builder.addCase(fetchTokenList.pending, (state, { payload: { requestId, url } }) => {
564
+ var _a, _b;
565
+ const current = ((_a = state.byUrl[url]) == null ? void 0 : _a.current) ?? null;
566
+ const pendingUpdate = ((_b = state.byUrl[url]) == null ? void 0 : _b.pendingUpdate) ?? null;
567
+ state.byUrl[url] = {
568
+ current,
569
+ pendingUpdate,
570
+ loadingRequestId: requestId,
571
+ error: null
572
+ };
573
+ }).addCase(fetchTokenList.fulfilled, (state, { payload: { requestId, tokenList, url } }) => {
574
+ var _a, _b, _c;
575
+ const current = (_a = state.byUrl[url]) == null ? void 0 : _a.current;
576
+ const loadingRequestId = (_b = state.byUrl[url]) == null ? void 0 : _b.loadingRequestId;
577
+ if (current) {
578
+ const upgradeType = getVersionUpgrade(current.version, tokenList.version);
579
+ if (upgradeType === 0 /* NONE */)
580
+ return;
581
+ if (loadingRequestId === null || loadingRequestId === requestId) {
582
+ state.byUrl[url] = {
583
+ ...state.byUrl[url],
584
+ loadingRequestId: null,
585
+ error: null,
586
+ current,
587
+ pendingUpdate: tokenList
588
+ };
589
+ }
590
+ } else {
591
+ if (DEFAULT_ACTIVE_LIST_URLS.includes(url)) {
592
+ (_c = state.activeListUrls) == null ? void 0 : _c.push(url);
593
+ }
594
+ state.byUrl[url] = {
595
+ ...state.byUrl[url],
596
+ loadingRequestId: null,
597
+ error: null,
598
+ current: tokenList,
599
+ pendingUpdate: null
600
+ };
601
+ }
602
+ }).addCase(fetchTokenList.rejected, (state, { payload: { url, requestId, errorMessage } }) => {
603
+ var _a;
604
+ if (((_a = state.byUrl[url]) == null ? void 0 : _a.loadingRequestId) !== requestId) {
605
+ return;
606
+ }
607
+ state.byUrl[url] = {
608
+ ...state.byUrl[url],
609
+ loadingRequestId: null,
610
+ error: errorMessage,
611
+ current: null,
612
+ pendingUpdate: null
613
+ };
614
+ }).addCase(addList, (state, { payload: url }) => {
615
+ if (!state.byUrl[url]) {
616
+ state.byUrl[url] = NEW_LIST_STATE;
617
+ }
618
+ }).addCase(removeList, (state, { payload: url }) => {
619
+ if (state.byUrl[url]) {
620
+ delete state.byUrl[url];
621
+ }
622
+ if (state.activeListUrls && state.activeListUrls.includes(url)) {
623
+ state.activeListUrls = state.activeListUrls.filter((u) => u !== url);
624
+ }
625
+ }).addCase(enableList, (state, { payload: url }) => {
626
+ if (!state.byUrl[url]) {
627
+ state.byUrl[url] = NEW_LIST_STATE;
628
+ }
629
+ if (state.activeListUrls && !state.activeListUrls.includes(url)) {
630
+ state.activeListUrls.push(url);
631
+ }
632
+ if (!state.activeListUrls) {
633
+ state.activeListUrls = [url];
634
+ }
635
+ }).addCase(disableList, (state, { payload: url }) => {
636
+ if (state.activeListUrls && state.activeListUrls.includes(url)) {
637
+ state.activeListUrls = state.activeListUrls.filter((u) => u !== url);
638
+ }
639
+ }).addCase(acceptListUpdate, (state, { payload: url }) => {
640
+ var _a;
641
+ if (!((_a = state.byUrl[url]) == null ? void 0 : _a.pendingUpdate)) {
642
+ throw new Error("accept list update called without pending update");
643
+ }
644
+ state.byUrl[url] = {
645
+ ...state.byUrl[url],
646
+ pendingUpdate: null,
647
+ current: state.byUrl[url].pendingUpdate
648
+ };
649
+ }).addCase(updateListVersion, (state) => {
650
+ if (!state.lastInitializedDefaultListOfLists) {
651
+ state.byUrl = initialState.byUrl;
652
+ state.activeListUrls = initialState.activeListUrls;
653
+ } else if (state.lastInitializedDefaultListOfLists) {
654
+ const lastInitializedSet = state.lastInitializedDefaultListOfLists.reduce(
655
+ (s, l) => s.add(l),
656
+ /* @__PURE__ */ new Set()
657
+ );
658
+ const newListOfListsSet = DEFAULT_LIST_OF_LISTS.reduce((s, l) => s.add(l), /* @__PURE__ */ new Set());
659
+ DEFAULT_LIST_OF_LISTS.forEach((listUrl) => {
660
+ if (!lastInitializedSet.has(listUrl)) {
661
+ state.byUrl[listUrl] = NEW_LIST_STATE;
662
+ }
663
+ });
664
+ state.lastInitializedDefaultListOfLists.forEach((listUrl) => {
665
+ if (!newListOfListsSet.has(listUrl)) {
666
+ delete state.byUrl[listUrl];
667
+ }
668
+ });
669
+ }
670
+ state.lastInitializedDefaultListOfLists = DEFAULT_LIST_OF_LISTS;
671
+ if (!state.activeListUrls) {
672
+ state.activeListUrls = DEFAULT_ACTIVE_LIST_URLS;
673
+ DEFAULT_ACTIVE_LIST_URLS.forEach((listUrl) => {
674
+ if (!state.byUrl[listUrl]) {
675
+ state.byUrl[listUrl] = NEW_LIST_STATE;
676
+ }
677
+ return true;
678
+ });
679
+ }
680
+ })
681
+ );
682
+
683
+ // react/lists.ts
684
+ var import_utils = require("jotai/utils");
685
+ var import_localforage = __toESM(require("localforage"));
686
+ function noop() {
687
+ }
688
+ var noopStorage = {
689
+ getItem: noop,
690
+ setItem: noop,
691
+ removeItem: noop,
692
+ keys: [],
693
+ getAllKeys: noop
694
+ };
695
+ var createListsAtom = (storeName, reducer, initialState) => {
696
+ let gotOnce = false;
697
+ function IndexedDBStorage(dbName) {
698
+ if (typeof window !== "undefined") {
699
+ const db = import_localforage.default.createInstance({
700
+ name: dbName,
701
+ storeName
702
+ });
703
+ return {
704
+ db,
705
+ getItem: async (key) => {
706
+ const value = await db.getItem(key);
707
+ gotOnce = true;
708
+ if (value) {
709
+ return value;
710
+ }
711
+ return initialState;
712
+ },
713
+ setItem: (k, v) => {
714
+ if (gotOnce) {
715
+ return db.setItem(k, v);
716
+ }
717
+ return void 0;
718
+ },
719
+ removeItem: db.removeItem,
720
+ delayInit: true
721
+ };
722
+ }
723
+ return noopStorage;
724
+ }
725
+ const listsAtom = (0, import_utils.atomWithStorage)(
726
+ "lists",
727
+ initialState,
728
+ IndexedDBStorage("lists")
729
+ );
730
+ function useListState() {
731
+ return (0, import_utils.useReducerAtom)(listsAtom, reducer);
732
+ }
733
+ return {
734
+ listsAtom,
735
+ useListState
736
+ };
737
+ };
738
+
739
+ // react/useFetchListCallback.ts
740
+ var import_toolkit3 = require("@reduxjs/toolkit");
741
+ var import_react = require("react");
742
+ function useFetchListCallback(dispatch) {
743
+ return (0, import_react.useCallback)(
744
+ async (listUrl, sendDispatch = true) => {
745
+ const requestId = (0, import_toolkit3.nanoid)();
746
+ if (sendDispatch) {
747
+ dispatch(fetchTokenList.pending({ requestId, url: listUrl }));
748
+ }
749
+ const getTokenList2 = (await Promise.resolve().then(() => (init_getTokenList(), getTokenList_exports))).default;
750
+ return getTokenList2(listUrl).then((tokenList) => {
751
+ if (sendDispatch) {
752
+ dispatch(fetchTokenList.fulfilled({ url: listUrl, tokenList, requestId }));
753
+ }
754
+ return tokenList;
755
+ }).catch((error) => {
756
+ console.error(`Failed to get list at url ${listUrl}`, error);
757
+ if (sendDispatch) {
758
+ dispatch(fetchTokenList.rejected({ url: listUrl, requestId, errorMessage: error.message }));
759
+ }
760
+ throw error;
761
+ });
762
+ },
763
+ [dispatch]
764
+ );
765
+ }
766
+ var useFetchListCallback_default = useFetchListCallback;
767
+ // Annotate the CommonJS export names for ESM import in node:
768
+ 0 && (module.exports = {
769
+ NEW_LIST_STATE,
770
+ acceptListUpdate,
771
+ addList,
772
+ createListsAtom,
773
+ createTokenListReducer,
774
+ disableList,
775
+ enableList,
776
+ fetchTokenList,
777
+ rejectVersionUpdate,
778
+ removeList,
779
+ updateListVersion,
780
+ useFetchListCallback
781
+ });