@ahoo-wang/fetcher-storage 1.6.6
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/LICENSE +201 -0
- package/dist/browserListenableStorage.d.ts +51 -0
- package/dist/browserListenableStorage.d.ts.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/inMemoryListenableStorage.d.ts +52 -0
- package/dist/inMemoryListenableStorage.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +270 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/keyStorage.d.ts +66 -0
- package/dist/keyStorage.d.ts.map +1 -0
- package/dist/listenableStorage.d.ts +33 -0
- package/dist/listenableStorage.d.ts.map +1 -0
- package/dist/serializer.d.ts +96 -0
- package/dist/serializer.d.ts.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [2025] [ahoo wang <ahoowang@qq.com>]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ListenableStorage, RemoveStorageListener, StorageListener } from './listenableStorage';
|
|
2
|
+
/**
|
|
3
|
+
* A wrapper around the browser's native Storage (localStorage or sessionStorage)
|
|
4
|
+
* that implements the ListenableStorage interface by using the browser's native storage events.
|
|
5
|
+
*/
|
|
6
|
+
export declare class BrowserListenableStorage implements ListenableStorage {
|
|
7
|
+
private readonly storage;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new BrowserListenableStorage instance.
|
|
10
|
+
* @param storage - The native Storage object to wrap (e.g., localStorage or sessionStorage)
|
|
11
|
+
*/
|
|
12
|
+
constructor(storage: Storage);
|
|
13
|
+
/**
|
|
14
|
+
* Gets the number of items stored in the storage.
|
|
15
|
+
*/
|
|
16
|
+
get length(): number;
|
|
17
|
+
/**
|
|
18
|
+
* Adds a listener for storage changes.
|
|
19
|
+
* @param listener - The listener function to be called when storage changes
|
|
20
|
+
* @returns A function that can be called to remove the listener
|
|
21
|
+
*/
|
|
22
|
+
addListener(listener: StorageListener): RemoveStorageListener;
|
|
23
|
+
/**
|
|
24
|
+
* Clears all items from the storage.
|
|
25
|
+
*/
|
|
26
|
+
clear(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Gets an item from the storage.
|
|
29
|
+
* @param key - The key of the item to retrieve
|
|
30
|
+
* @returns The value of the item, or null if the item does not exist
|
|
31
|
+
*/
|
|
32
|
+
getItem(key: string): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Gets the key at the specified index.
|
|
35
|
+
* @param index - The index of the key to retrieve
|
|
36
|
+
* @returns The key at the specified index, or null if the index is out of bounds
|
|
37
|
+
*/
|
|
38
|
+
key(index: number): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Removes an item from the storage.
|
|
41
|
+
* @param key - The key of the item to remove
|
|
42
|
+
*/
|
|
43
|
+
removeItem(key: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Sets an item in the storage.
|
|
46
|
+
* @param key - The key of the item to set
|
|
47
|
+
* @param value - The value to set
|
|
48
|
+
*/
|
|
49
|
+
setItem(key: string, value: string): void;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=browserListenableStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserListenableStorage.d.ts","sourceRoot":"","sources":["../src/browserListenableStorage.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAsB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEpH;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAMpD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC;;;OAGG;gBAC0B,OAAO,EAAE,OAAO;IAG7C;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,qBAAqB;IAU7D;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIjC;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAG1C"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAaA,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ListenableStorage, RemoveStorageListener, StorageListener } from './listenableStorage';
|
|
2
|
+
/**
|
|
3
|
+
* An in-memory implementation of ListenableStorage that works in any environment.
|
|
4
|
+
* This implementation stores data in a Map and manually fires storage events when data changes.
|
|
5
|
+
*/
|
|
6
|
+
export declare class InMemoryListenableStorage implements ListenableStorage {
|
|
7
|
+
private readonly store;
|
|
8
|
+
private readonly listeners;
|
|
9
|
+
/**
|
|
10
|
+
* Gets the number of items stored in the storage.
|
|
11
|
+
*/
|
|
12
|
+
get length(): number;
|
|
13
|
+
/**
|
|
14
|
+
* Clears all items from the storage.
|
|
15
|
+
*/
|
|
16
|
+
clear(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Gets an item from the storage.
|
|
19
|
+
* @param key - The key of the item to retrieve
|
|
20
|
+
* @returns The value of the item, or null if the item does not exist
|
|
21
|
+
*/
|
|
22
|
+
getItem(key: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the key at the specified index.
|
|
25
|
+
* @param index - The index of the key to retrieve
|
|
26
|
+
* @returns The key at the specified index, or null if the index is out of bounds
|
|
27
|
+
*/
|
|
28
|
+
key(index: number): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Removes an item from the storage.
|
|
31
|
+
* @param key - The key of the item to remove
|
|
32
|
+
*/
|
|
33
|
+
removeItem(key: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Sets an item in the storage.
|
|
36
|
+
* @param key - The key of the item to set
|
|
37
|
+
* @param value - The value to set
|
|
38
|
+
*/
|
|
39
|
+
setItem(key: string, value: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Adds a listener for storage changes.
|
|
42
|
+
* @param listener - The listener function to be called when storage changes
|
|
43
|
+
* @returns A function that can be called to remove the listener
|
|
44
|
+
*/
|
|
45
|
+
addListener(listener: StorageListener): RemoveStorageListener;
|
|
46
|
+
/**
|
|
47
|
+
* Notifies all listeners of a storage change by creating and dispatching a StorageEvent.
|
|
48
|
+
* @param eventInit - The initialization object for the StorageEvent
|
|
49
|
+
*/
|
|
50
|
+
private notifyListeners;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=inMemoryListenableStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inMemoryListenableStorage.d.ts","sourceRoot":"","sources":["../src/inMemoryListenableStorage.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGhG;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAE7D;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKnC;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjC;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAY7B;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMzC;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,qBAAqB;IAK7D;;;OAGG;IACH,OAAO,CAAC,eAAe;CAexB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,OAAO,CAAC;AACtB,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
function a() {
|
|
2
|
+
return typeof window < "u";
|
|
3
|
+
}
|
|
4
|
+
class n {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.store = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Set();
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Gets the number of items stored in the storage.
|
|
10
|
+
*/
|
|
11
|
+
get length() {
|
|
12
|
+
return this.store.size;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Clears all items from the storage.
|
|
16
|
+
*/
|
|
17
|
+
clear() {
|
|
18
|
+
this.store.clear();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Gets an item from the storage.
|
|
22
|
+
* @param key - The key of the item to retrieve
|
|
23
|
+
* @returns The value of the item, or null if the item does not exist
|
|
24
|
+
*/
|
|
25
|
+
getItem(e) {
|
|
26
|
+
const t = this.store.get(e);
|
|
27
|
+
return t !== void 0 ? t : null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets the key at the specified index.
|
|
31
|
+
* @param index - The index of the key to retrieve
|
|
32
|
+
* @returns The key at the specified index, or null if the index is out of bounds
|
|
33
|
+
*/
|
|
34
|
+
key(e) {
|
|
35
|
+
return Array.from(this.store.keys())[e] || null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Removes an item from the storage.
|
|
39
|
+
* @param key - The key of the item to remove
|
|
40
|
+
*/
|
|
41
|
+
removeItem(e) {
|
|
42
|
+
const t = this.getItem(e);
|
|
43
|
+
this.store.has(e) && (this.store.delete(e), this.notifyListeners({
|
|
44
|
+
key: e,
|
|
45
|
+
oldValue: t,
|
|
46
|
+
newValue: null
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sets an item in the storage.
|
|
51
|
+
* @param key - The key of the item to set
|
|
52
|
+
* @param value - The value to set
|
|
53
|
+
*/
|
|
54
|
+
setItem(e, t) {
|
|
55
|
+
const r = this.getItem(e);
|
|
56
|
+
this.store.set(e, t), this.notifyListeners({ key: e, oldValue: r, newValue: t });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Adds a listener for storage changes.
|
|
60
|
+
* @param listener - The listener function to be called when storage changes
|
|
61
|
+
* @returns A function that can be called to remove the listener
|
|
62
|
+
*/
|
|
63
|
+
addListener(e) {
|
|
64
|
+
return this.listeners.add(e), () => this.listeners.delete(e);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Notifies all listeners of a storage change by creating and dispatching a StorageEvent.
|
|
68
|
+
* @param eventInit - The initialization object for the StorageEvent
|
|
69
|
+
*/
|
|
70
|
+
notifyListeners(e) {
|
|
71
|
+
a() && window.location && (e.url = e.url || window.location.href), e.storageArea = this, this.listeners.forEach((t) => {
|
|
72
|
+
try {
|
|
73
|
+
t(e);
|
|
74
|
+
} catch (r) {
|
|
75
|
+
console.error("Error in storage change listener:", r);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
class o {
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new BrowserListenableStorage instance.
|
|
83
|
+
* @param storage - The native Storage object to wrap (e.g., localStorage or sessionStorage)
|
|
84
|
+
*/
|
|
85
|
+
constructor(e) {
|
|
86
|
+
this.storage = e;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Gets the number of items stored in the storage.
|
|
90
|
+
*/
|
|
91
|
+
get length() {
|
|
92
|
+
return this.storage.length;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Adds a listener for storage changes.
|
|
96
|
+
* @param listener - The listener function to be called when storage changes
|
|
97
|
+
* @returns A function that can be called to remove the listener
|
|
98
|
+
*/
|
|
99
|
+
addListener(e) {
|
|
100
|
+
const t = (r) => {
|
|
101
|
+
r.storageArea === this.storage && e(r);
|
|
102
|
+
};
|
|
103
|
+
return window.addEventListener(i, t), () => window.removeEventListener(i, t);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Clears all items from the storage.
|
|
107
|
+
*/
|
|
108
|
+
clear() {
|
|
109
|
+
this.storage.clear();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Gets an item from the storage.
|
|
113
|
+
* @param key - The key of the item to retrieve
|
|
114
|
+
* @returns The value of the item, or null if the item does not exist
|
|
115
|
+
*/
|
|
116
|
+
getItem(e) {
|
|
117
|
+
return this.storage.getItem(e);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Gets the key at the specified index.
|
|
121
|
+
* @param index - The index of the key to retrieve
|
|
122
|
+
* @returns The key at the specified index, or null if the index is out of bounds
|
|
123
|
+
*/
|
|
124
|
+
key(e) {
|
|
125
|
+
return this.storage.key(e);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Removes an item from the storage.
|
|
129
|
+
* @param key - The key of the item to remove
|
|
130
|
+
*/
|
|
131
|
+
removeItem(e) {
|
|
132
|
+
this.storage.removeItem(e);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sets an item in the storage.
|
|
136
|
+
* @param key - The key of the item to set
|
|
137
|
+
* @param value - The value to set
|
|
138
|
+
*/
|
|
139
|
+
setItem(e, t) {
|
|
140
|
+
this.storage.setItem(e, t);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const i = "storage", h = () => a() ? new o(window.localStorage) : new n();
|
|
144
|
+
class l {
|
|
145
|
+
/**
|
|
146
|
+
* Serializes a value to a JSON string
|
|
147
|
+
* @param value The value to serialize
|
|
148
|
+
* @returns The JSON string representation of the value
|
|
149
|
+
*/
|
|
150
|
+
/**
|
|
151
|
+
* Serializes a value to a JSON string
|
|
152
|
+
* @param value The value to serialize
|
|
153
|
+
* @returns The JSON string representation of the value
|
|
154
|
+
*/
|
|
155
|
+
serialize(e) {
|
|
156
|
+
return JSON.stringify(e);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Deserializes a JSON string to a value
|
|
160
|
+
* @template V The type of the deserialized value
|
|
161
|
+
* @param value The JSON string to deserialize
|
|
162
|
+
* @returns The deserialized value
|
|
163
|
+
*/
|
|
164
|
+
/**
|
|
165
|
+
* Deserializes a JSON string to a value
|
|
166
|
+
* @param value The JSON string to deserialize
|
|
167
|
+
* @returns The deserialized value
|
|
168
|
+
*/
|
|
169
|
+
deserialize(e) {
|
|
170
|
+
return JSON.parse(e);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
class c {
|
|
174
|
+
/**
|
|
175
|
+
* Returns the value as-is without serialization
|
|
176
|
+
* @param value The value to pass through
|
|
177
|
+
* @returns The same value that was passed in
|
|
178
|
+
*/
|
|
179
|
+
/**
|
|
180
|
+
* Returns the value as-is without serialization
|
|
181
|
+
* @param value The value to pass through
|
|
182
|
+
* @returns The same value that was passed in
|
|
183
|
+
*/
|
|
184
|
+
serialize(e) {
|
|
185
|
+
return e;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Returns the value as-is without deserialization
|
|
189
|
+
* @template Deserialized The type of the deserialized value
|
|
190
|
+
* @param value The value to pass through
|
|
191
|
+
* @returns The same value that was passed in, cast to the target type
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* Returns the value as-is without deserialization
|
|
195
|
+
* @param value The value to pass through
|
|
196
|
+
* @returns The same value that was passed in
|
|
197
|
+
*/
|
|
198
|
+
deserialize(e) {
|
|
199
|
+
return e;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const d = new l(), u = new c();
|
|
203
|
+
function g() {
|
|
204
|
+
return u;
|
|
205
|
+
}
|
|
206
|
+
class w {
|
|
207
|
+
/**
|
|
208
|
+
* Creates a new KeyStorage instance
|
|
209
|
+
* @param options Configuration options for the storage
|
|
210
|
+
*/
|
|
211
|
+
constructor(e) {
|
|
212
|
+
this.cacheValue = null, this.refreshCacheListener = (t) => {
|
|
213
|
+
this.cacheValue = null, t.newValue && this.refreshCache(t.newValue);
|
|
214
|
+
}, this.key = e.key, this.serializer = e.serializer ?? g(), this.storage = e.storage ?? h(), this.addListener(this.refreshCacheListener);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Refreshes the cached value by deserializing the provided string
|
|
218
|
+
* @param value The serialized value to deserialize and cache
|
|
219
|
+
*/
|
|
220
|
+
refreshCache(e) {
|
|
221
|
+
this.cacheValue = this.serializer.deserialize(e);
|
|
222
|
+
}
|
|
223
|
+
addListener(e) {
|
|
224
|
+
const t = (r) => {
|
|
225
|
+
r.key === this.key && e(r);
|
|
226
|
+
};
|
|
227
|
+
return this.storage.addListener(t);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Gets the value associated with the key from storage
|
|
231
|
+
* Uses cached value if available, otherwise retrieves from storage and caches it
|
|
232
|
+
* @returns The deserialized value or null if no value is found
|
|
233
|
+
*/
|
|
234
|
+
get() {
|
|
235
|
+
if (this.cacheValue)
|
|
236
|
+
return this.cacheValue;
|
|
237
|
+
const e = this.storage.getItem(this.key);
|
|
238
|
+
return e ? (this.refreshCache(e), this.cacheValue) : null;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Sets the value associated with the key in storage
|
|
242
|
+
* Also updates the cached value
|
|
243
|
+
* @param value The value to serialize and store
|
|
244
|
+
*/
|
|
245
|
+
set(e) {
|
|
246
|
+
const t = this.serializer.serialize(e);
|
|
247
|
+
this.storage.setItem(this.key, t), this.cacheValue = e;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Removes the value associated with the key from storage
|
|
251
|
+
* Also clears the cached value
|
|
252
|
+
*/
|
|
253
|
+
remove() {
|
|
254
|
+
this.storage.removeItem(this.key), this.cacheValue = null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
export {
|
|
258
|
+
o as BrowserListenableStorage,
|
|
259
|
+
c as IdentitySerializer,
|
|
260
|
+
n as InMemoryListenableStorage,
|
|
261
|
+
l as JsonSerializer,
|
|
262
|
+
w as KeyStorage,
|
|
263
|
+
i as STORAGE_EVENT_TYPE,
|
|
264
|
+
h as createListenableStorage,
|
|
265
|
+
u as identitySerializer,
|
|
266
|
+
a as isBrowser,
|
|
267
|
+
d as jsonSerializer,
|
|
268
|
+
g as typedIdentitySerializer
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/env.ts","../src/inMemoryListenableStorage.ts","../src/browserListenableStorage.ts","../src/listenableStorage.ts","../src/serializer.ts","../src/keyStorage.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListenableStorage, RemoveStorageListener, StorageListener } from './listenableStorage';\nimport { isBrowser } from './env';\n\n/**\n * An in-memory implementation of ListenableStorage that works in any environment.\n * This implementation stores data in a Map and manually fires storage events when data changes.\n */\nexport class InMemoryListenableStorage implements ListenableStorage {\n private readonly store: Map<string, string> = new Map();\n private readonly listeners: Set<StorageListener> = new Set();\n\n /**\n * Gets the number of items stored in the storage.\n */\n get length(): number {\n return this.store.size;\n }\n\n /**\n * Clears all items from the storage.\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Gets an item from the storage.\n * @param key - The key of the item to retrieve\n * @returns The value of the item, or null if the item does not exist\n */\n getItem(key: string): string | null {\n const value = this.store.get(key);\n return value !== undefined ? value : null;\n }\n\n /**\n * Gets the key at the specified index.\n * @param index - The index of the key to retrieve\n * @returns The key at the specified index, or null if the index is out of bounds\n */\n key(index: number): string | null {\n const keys = Array.from(this.store.keys());\n return keys[index] || null;\n }\n\n /**\n * Removes an item from the storage.\n * @param key - The key of the item to remove\n */\n removeItem(key: string): void {\n const oldValue = this.getItem(key);\n if (this.store.has(key)) {\n this.store.delete(key);\n this.notifyListeners({\n key,\n oldValue,\n newValue: null,\n });\n }\n }\n\n /**\n * Sets an item in the storage.\n * @param key - The key of the item to set\n * @param value - The value to set\n */\n setItem(key: string, value: string): void {\n const oldValue = this.getItem(key);\n this.store.set(key, value);\n this.notifyListeners({ key, oldValue, newValue: value });\n }\n\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Notifies all listeners of a storage change by creating and dispatching a StorageEvent.\n * @param eventInit - The initialization object for the StorageEvent\n */\n private notifyListeners(\n eventInit: StorageEventInit,\n ): void {\n if (isBrowser() && window.location) {\n eventInit.url = eventInit.url || window.location.href;\n }\n eventInit.storageArea = this;\n this.listeners.forEach(listener => {\n try {\n listener(eventInit);\n } catch (error) {\n console.error('Error in storage change listener:', error);\n }\n });\n }\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListenableStorage, RemoveStorageListener, STORAGE_EVENT_TYPE, StorageListener } from './listenableStorage';\n\n/**\n * A wrapper around the browser's native Storage (localStorage or sessionStorage)\n * that implements the ListenableStorage interface by using the browser's native storage events.\n */\nexport class BrowserListenableStorage implements ListenableStorage {\n\n /**\n * Creates a new BrowserListenableStorage instance.\n * @param storage - The native Storage object to wrap (e.g., localStorage or sessionStorage)\n */\n constructor(private readonly storage: Storage) {\n }\n\n /**\n * Gets the number of items stored in the storage.\n */\n get length(): number {\n return this.storage.length;\n }\n\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener {\n const wrapper: StorageListener = (event: StorageEventInit) => {\n if (event.storageArea === this.storage) {\n listener(event);\n }\n };\n window.addEventListener(STORAGE_EVENT_TYPE, wrapper);\n return () => window.removeEventListener(STORAGE_EVENT_TYPE, wrapper);\n }\n\n /**\n * Clears all items from the storage.\n */\n clear(): void {\n this.storage.clear();\n }\n\n /**\n * Gets an item from the storage.\n * @param key - The key of the item to retrieve\n * @returns The value of the item, or null if the item does not exist\n */\n getItem(key: string): string | null {\n return this.storage.getItem(key);\n }\n\n /**\n * Gets the key at the specified index.\n * @param index - The index of the key to retrieve\n * @returns The key at the specified index, or null if the index is out of bounds\n */\n key(index: number): string | null {\n return this.storage.key(index);\n }\n\n /**\n * Removes an item from the storage.\n * @param key - The key of the item to remove\n */\n removeItem(key: string): void {\n this.storage.removeItem(key);\n }\n\n /**\n * Sets an item in the storage.\n * @param key - The key of the item to set\n * @param value - The value to set\n */\n setItem(key: string, value: string): void {\n this.storage.setItem(key, value);\n }\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InMemoryListenableStorage } from './inMemoryListenableStorage';\nimport { BrowserListenableStorage } from './browserListenableStorage';\nimport { isBrowser } from './env';\n\n/**\n * The type of storage event used for listening to storage changes.\n */\nexport const STORAGE_EVENT_TYPE = 'storage';\n\n/**\n * A function that handles storage change events.\n */\nexport type StorageListener = (event: StorageEventInit) => void;\n\n/**\n * A function that removes a storage listener when called.\n */\nexport type RemoveStorageListener = () => void;\n\nexport interface StorageListenable {\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener;\n}\n\n/**\n * An interface that extends the native Storage interface with the ability to listen for storage changes.\n */\nexport interface ListenableStorage extends Storage, StorageListenable {\n\n}\n\n/**\n * Factory function to get an appropriate ListenableStorage implementation based on the environment.\n * In a browser environment, it returns a BrowserListenableStorage wrapping localStorage.\n * In other environments, it returns an InMemoryListenableStorage.\n * @returns A ListenableStorage instance suitable for the current environment\n */\nexport const createListenableStorage = (): ListenableStorage => {\n if (isBrowser()) {\n return new BrowserListenableStorage(window.localStorage);\n }\n return new InMemoryListenableStorage();\n};","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Interface for serializing and deserializing values\n * @template Serialized The type of the serialized value\n */\n/**\n * Interface for serializing and deserializing values\n * @template Serialized The type of the serialized value\n * @template Deserialized The type of the deserialized value\n */\nexport interface Serializer<Serialized, Deserialized> {\n /**\n * Serializes a value to the specified format\n * @param value The value to serialize\n * @returns The serialized value\n */\n serialize(value: any): Serialized;\n\n /**\n * Deserializes a value from the specified format\n * @template Deserialized The type of the deserialized value\n * @param value The value to deserialize\n * @returns The deserialized value\n */\n /**\n * Deserializes a value from the specified format\n * @param value The value to deserialize\n * @returns The deserialized value\n */\n deserialize(value: Serialized): Deserialized;\n}\n\n/**\n * Implementation of Serializer that uses JSON for serialization\n */\nexport class JsonSerializer implements Serializer<string, any> {\n /**\n * Serializes a value to a JSON string\n * @param value The value to serialize\n * @returns The JSON string representation of the value\n */\n /**\n * Serializes a value to a JSON string\n * @param value The value to serialize\n * @returns The JSON string representation of the value\n */\n serialize(value: any): string {\n return JSON.stringify(value);\n }\n\n /**\n * Deserializes a JSON string to a value\n * @template V The type of the deserialized value\n * @param value The JSON string to deserialize\n * @returns The deserialized value\n */\n /**\n * Deserializes a JSON string to a value\n * @param value The JSON string to deserialize\n * @returns The deserialized value\n */\n deserialize<V>(value: string): V {\n return JSON.parse(value);\n }\n}\n\n/**\n * Implementation of Serializer that performs no actual serialization\n * @template T The type of the value to pass through\n */\nexport class IdentitySerializer<T> implements Serializer<T, T> {\n /**\n * Returns the value as-is without serialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n /**\n * Returns the value as-is without serialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n serialize(value: T): T {\n return value;\n }\n\n /**\n * Returns the value as-is without deserialization\n * @template Deserialized The type of the deserialized value\n * @param value The value to pass through\n * @returns The same value that was passed in, cast to the target type\n */\n /**\n * Returns the value as-is without deserialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n deserialize(value: T): T {\n return value;\n }\n}\n\n/**\n * Global instance of JsonSerializer\n */\nexport const jsonSerializer = new JsonSerializer();\n/**\n * Global instance of IdentitySerializer\n */\nexport const identitySerializer = new IdentitySerializer<any>();\n\nexport function typedIdentitySerializer<T>(): IdentitySerializer<T> {\n return identitySerializer as IdentitySerializer<T>;\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createListenableStorage,\n ListenableStorage,\n RemoveStorageListener,\n StorageListenable,\n StorageListener,\n} from './listenableStorage';\nimport { Serializer, typedIdentitySerializer } from './serializer';\n\n/**\n * Options for configuring KeyStorage\n */\nexport interface KeyStorageOptions<Deserialized> {\n /**\n * The key used to store and retrieve values from storage\n */\n key: string;\n\n /**\n * Optional serializer for converting values to and from storage format\n * Defaults to IdentitySerializer if not provided\n */\n serializer?: Serializer<string, Deserialized>;\n\n /**\n * Optional storage implementation\n * Defaults to the result of createListenableStorage() if not provided\n */\n storage?: ListenableStorage;\n}\n\n/**\n * A storage wrapper that manages a single value associated with a specific key\n * Provides caching and automatic cache invalidation when the storage value changes\n * @template Deserialized The type of the value being stored\n */\nexport class KeyStorage<Deserialized> implements StorageListenable {\n private readonly key: string;\n private readonly serializer: Serializer<string, Deserialized>;\n private readonly storage: ListenableStorage;\n private cacheValue: Deserialized | null = null;\n\n /**\n * Listener for storage change events\n * Invalidates the cache when the relevant key is modified\n */\n private readonly refreshCacheListener: StorageListener = (event) => {\n this.cacheValue = null;\n if (event.newValue) {\n this.refreshCache(event.newValue);\n }\n };\n\n /**\n * Refreshes the cached value by deserializing the provided string\n * @param value The serialized value to deserialize and cache\n */\n private refreshCache(value: string) {\n this.cacheValue = this.serializer.deserialize(value);\n }\n\n /**\n * Creates a new KeyStorage instance\n * @param options Configuration options for the storage\n */\n constructor(options: KeyStorageOptions<Deserialized>) {\n this.key = options.key;\n this.serializer = options.serializer ?? typedIdentitySerializer();\n this.storage = options.storage ?? createListenableStorage();\n this.addListener(this.refreshCacheListener);\n }\n\n addListener(listener: StorageListener): RemoveStorageListener {\n const wrapper: StorageListener = (event: StorageEventInit) => {\n if (event.key !== this.key) {\n return;\n }\n listener(event);\n };\n return this.storage.addListener(wrapper);\n }\n\n /**\n * Gets the value associated with the key from storage\n * Uses cached value if available, otherwise retrieves from storage and caches it\n * @returns The deserialized value or null if no value is found\n */\n get(): Deserialized | null {\n if (this.cacheValue) {\n return this.cacheValue;\n }\n const value = this.storage.getItem(this.key);\n if (!value) {\n return null;\n }\n this.refreshCache(value);\n return this.cacheValue;\n }\n\n /**\n * Sets the value associated with the key in storage\n * Also updates the cached value\n * @param value The value to serialize and store\n */\n set(value: Deserialized): void {\n const serialized = this.serializer.serialize(value);\n this.storage.setItem(this.key, serialized);\n this.cacheValue = value;\n }\n\n /**\n * Removes the value associated with the key from storage\n * Also clears the cached value\n */\n remove(): void {\n this.storage.removeItem(this.key);\n this.cacheValue = null;\n }\n}"],"names":["isBrowser","InMemoryListenableStorage","key","value","index","oldValue","listener","eventInit","error","BrowserListenableStorage","storage","wrapper","event","STORAGE_EVENT_TYPE","createListenableStorage","JsonSerializer","IdentitySerializer","jsonSerializer","identitySerializer","typedIdentitySerializer","KeyStorage","options","serialized"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(r,i){typeof exports=="object"&&typeof module<"u"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(r=typeof globalThis<"u"?globalThis:r||self,i(r.Fetcher={}))})(this,(function(r){"use strict";function i(){return typeof window<"u"}class o{constructor(){this.store=new Map,this.listeners=new Set}get length(){return this.store.size}clear(){this.store.clear()}getItem(e){const t=this.store.get(e);return t!==void 0?t:null}key(e){return Array.from(this.store.keys())[e]||null}removeItem(e){const t=this.getItem(e);this.store.has(e)&&(this.store.delete(e),this.notifyListeners({key:e,oldValue:t,newValue:null}))}setItem(e,t){const s=this.getItem(e);this.store.set(e,t),this.notifyListeners({key:e,oldValue:s,newValue:t})}addListener(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notifyListeners(e){i()&&window.location&&(e.url=e.url||window.location.href),e.storageArea=this,this.listeners.forEach(t=>{try{t(e)}catch(s){console.error("Error in storage change listener:",s)}})}}class l{constructor(e){this.storage=e}get length(){return this.storage.length}addListener(e){const t=s=>{s.storageArea===this.storage&&e(s)};return window.addEventListener(a,t),()=>window.removeEventListener(a,t)}clear(){this.storage.clear()}getItem(e){return this.storage.getItem(e)}key(e){return this.storage.key(e)}removeItem(e){this.storage.removeItem(e)}setItem(e,t){this.storage.setItem(e,t)}}const a="storage",h=()=>i()?new l(window.localStorage):new o;class c{serialize(e){return JSON.stringify(e)}deserialize(e){return JSON.parse(e)}}class u{serialize(e){return e}deserialize(e){return e}}const f=new c,d=new u;function g(){return d}class y{constructor(e){this.cacheValue=null,this.refreshCacheListener=t=>{this.cacheValue=null,t.newValue&&this.refreshCache(t.newValue)},this.key=e.key,this.serializer=e.serializer??g(),this.storage=e.storage??h(),this.addListener(this.refreshCacheListener)}refreshCache(e){this.cacheValue=this.serializer.deserialize(e)}addListener(e){const t=s=>{s.key===this.key&&e(s)};return this.storage.addListener(t)}get(){if(this.cacheValue)return this.cacheValue;const e=this.storage.getItem(this.key);return e?(this.refreshCache(e),this.cacheValue):null}set(e){const t=this.serializer.serialize(e);this.storage.setItem(this.key,t),this.cacheValue=e}remove(){this.storage.removeItem(this.key),this.cacheValue=null}}r.BrowserListenableStorage=l,r.IdentitySerializer=u,r.InMemoryListenableStorage=o,r.JsonSerializer=c,r.KeyStorage=y,r.STORAGE_EVENT_TYPE=a,r.createListenableStorage=h,r.identitySerializer=d,r.isBrowser=i,r.jsonSerializer=f,r.typedIdentitySerializer=g,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/env.ts","../src/inMemoryListenableStorage.ts","../src/browserListenableStorage.ts","../src/listenableStorage.ts","../src/serializer.ts","../src/keyStorage.ts"],"sourcesContent":["/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListenableStorage, RemoveStorageListener, StorageListener } from './listenableStorage';\nimport { isBrowser } from './env';\n\n/**\n * An in-memory implementation of ListenableStorage that works in any environment.\n * This implementation stores data in a Map and manually fires storage events when data changes.\n */\nexport class InMemoryListenableStorage implements ListenableStorage {\n private readonly store: Map<string, string> = new Map();\n private readonly listeners: Set<StorageListener> = new Set();\n\n /**\n * Gets the number of items stored in the storage.\n */\n get length(): number {\n return this.store.size;\n }\n\n /**\n * Clears all items from the storage.\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Gets an item from the storage.\n * @param key - The key of the item to retrieve\n * @returns The value of the item, or null if the item does not exist\n */\n getItem(key: string): string | null {\n const value = this.store.get(key);\n return value !== undefined ? value : null;\n }\n\n /**\n * Gets the key at the specified index.\n * @param index - The index of the key to retrieve\n * @returns The key at the specified index, or null if the index is out of bounds\n */\n key(index: number): string | null {\n const keys = Array.from(this.store.keys());\n return keys[index] || null;\n }\n\n /**\n * Removes an item from the storage.\n * @param key - The key of the item to remove\n */\n removeItem(key: string): void {\n const oldValue = this.getItem(key);\n if (this.store.has(key)) {\n this.store.delete(key);\n this.notifyListeners({\n key,\n oldValue,\n newValue: null,\n });\n }\n }\n\n /**\n * Sets an item in the storage.\n * @param key - The key of the item to set\n * @param value - The value to set\n */\n setItem(key: string, value: string): void {\n const oldValue = this.getItem(key);\n this.store.set(key, value);\n this.notifyListeners({ key, oldValue, newValue: value });\n }\n\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Notifies all listeners of a storage change by creating and dispatching a StorageEvent.\n * @param eventInit - The initialization object for the StorageEvent\n */\n private notifyListeners(\n eventInit: StorageEventInit,\n ): void {\n if (isBrowser() && window.location) {\n eventInit.url = eventInit.url || window.location.href;\n }\n eventInit.storageArea = this;\n this.listeners.forEach(listener => {\n try {\n listener(eventInit);\n } catch (error) {\n console.error('Error in storage change listener:', error);\n }\n });\n }\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ListenableStorage, RemoveStorageListener, STORAGE_EVENT_TYPE, StorageListener } from './listenableStorage';\n\n/**\n * A wrapper around the browser's native Storage (localStorage or sessionStorage)\n * that implements the ListenableStorage interface by using the browser's native storage events.\n */\nexport class BrowserListenableStorage implements ListenableStorage {\n\n /**\n * Creates a new BrowserListenableStorage instance.\n * @param storage - The native Storage object to wrap (e.g., localStorage or sessionStorage)\n */\n constructor(private readonly storage: Storage) {\n }\n\n /**\n * Gets the number of items stored in the storage.\n */\n get length(): number {\n return this.storage.length;\n }\n\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener {\n const wrapper: StorageListener = (event: StorageEventInit) => {\n if (event.storageArea === this.storage) {\n listener(event);\n }\n };\n window.addEventListener(STORAGE_EVENT_TYPE, wrapper);\n return () => window.removeEventListener(STORAGE_EVENT_TYPE, wrapper);\n }\n\n /**\n * Clears all items from the storage.\n */\n clear(): void {\n this.storage.clear();\n }\n\n /**\n * Gets an item from the storage.\n * @param key - The key of the item to retrieve\n * @returns The value of the item, or null if the item does not exist\n */\n getItem(key: string): string | null {\n return this.storage.getItem(key);\n }\n\n /**\n * Gets the key at the specified index.\n * @param index - The index of the key to retrieve\n * @returns The key at the specified index, or null if the index is out of bounds\n */\n key(index: number): string | null {\n return this.storage.key(index);\n }\n\n /**\n * Removes an item from the storage.\n * @param key - The key of the item to remove\n */\n removeItem(key: string): void {\n this.storage.removeItem(key);\n }\n\n /**\n * Sets an item in the storage.\n * @param key - The key of the item to set\n * @param value - The value to set\n */\n setItem(key: string, value: string): void {\n this.storage.setItem(key, value);\n }\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InMemoryListenableStorage } from './inMemoryListenableStorage';\nimport { BrowserListenableStorage } from './browserListenableStorage';\nimport { isBrowser } from './env';\n\n/**\n * The type of storage event used for listening to storage changes.\n */\nexport const STORAGE_EVENT_TYPE = 'storage';\n\n/**\n * A function that handles storage change events.\n */\nexport type StorageListener = (event: StorageEventInit) => void;\n\n/**\n * A function that removes a storage listener when called.\n */\nexport type RemoveStorageListener = () => void;\n\nexport interface StorageListenable {\n /**\n * Adds a listener for storage changes.\n * @param listener - The listener function to be called when storage changes\n * @returns A function that can be called to remove the listener\n */\n addListener(listener: StorageListener): RemoveStorageListener;\n}\n\n/**\n * An interface that extends the native Storage interface with the ability to listen for storage changes.\n */\nexport interface ListenableStorage extends Storage, StorageListenable {\n\n}\n\n/**\n * Factory function to get an appropriate ListenableStorage implementation based on the environment.\n * In a browser environment, it returns a BrowserListenableStorage wrapping localStorage.\n * In other environments, it returns an InMemoryListenableStorage.\n * @returns A ListenableStorage instance suitable for the current environment\n */\nexport const createListenableStorage = (): ListenableStorage => {\n if (isBrowser()) {\n return new BrowserListenableStorage(window.localStorage);\n }\n return new InMemoryListenableStorage();\n};","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Interface for serializing and deserializing values\n * @template Serialized The type of the serialized value\n */\n/**\n * Interface for serializing and deserializing values\n * @template Serialized The type of the serialized value\n * @template Deserialized The type of the deserialized value\n */\nexport interface Serializer<Serialized, Deserialized> {\n /**\n * Serializes a value to the specified format\n * @param value The value to serialize\n * @returns The serialized value\n */\n serialize(value: any): Serialized;\n\n /**\n * Deserializes a value from the specified format\n * @template Deserialized The type of the deserialized value\n * @param value The value to deserialize\n * @returns The deserialized value\n */\n /**\n * Deserializes a value from the specified format\n * @param value The value to deserialize\n * @returns The deserialized value\n */\n deserialize(value: Serialized): Deserialized;\n}\n\n/**\n * Implementation of Serializer that uses JSON for serialization\n */\nexport class JsonSerializer implements Serializer<string, any> {\n /**\n * Serializes a value to a JSON string\n * @param value The value to serialize\n * @returns The JSON string representation of the value\n */\n /**\n * Serializes a value to a JSON string\n * @param value The value to serialize\n * @returns The JSON string representation of the value\n */\n serialize(value: any): string {\n return JSON.stringify(value);\n }\n\n /**\n * Deserializes a JSON string to a value\n * @template V The type of the deserialized value\n * @param value The JSON string to deserialize\n * @returns The deserialized value\n */\n /**\n * Deserializes a JSON string to a value\n * @param value The JSON string to deserialize\n * @returns The deserialized value\n */\n deserialize<V>(value: string): V {\n return JSON.parse(value);\n }\n}\n\n/**\n * Implementation of Serializer that performs no actual serialization\n * @template T The type of the value to pass through\n */\nexport class IdentitySerializer<T> implements Serializer<T, T> {\n /**\n * Returns the value as-is without serialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n /**\n * Returns the value as-is without serialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n serialize(value: T): T {\n return value;\n }\n\n /**\n * Returns the value as-is without deserialization\n * @template Deserialized The type of the deserialized value\n * @param value The value to pass through\n * @returns The same value that was passed in, cast to the target type\n */\n /**\n * Returns the value as-is without deserialization\n * @param value The value to pass through\n * @returns The same value that was passed in\n */\n deserialize(value: T): T {\n return value;\n }\n}\n\n/**\n * Global instance of JsonSerializer\n */\nexport const jsonSerializer = new JsonSerializer();\n/**\n * Global instance of IdentitySerializer\n */\nexport const identitySerializer = new IdentitySerializer<any>();\n\nexport function typedIdentitySerializer<T>(): IdentitySerializer<T> {\n return identitySerializer as IdentitySerializer<T>;\n}","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createListenableStorage,\n ListenableStorage,\n RemoveStorageListener,\n StorageListenable,\n StorageListener,\n} from './listenableStorage';\nimport { Serializer, typedIdentitySerializer } from './serializer';\n\n/**\n * Options for configuring KeyStorage\n */\nexport interface KeyStorageOptions<Deserialized> {\n /**\n * The key used to store and retrieve values from storage\n */\n key: string;\n\n /**\n * Optional serializer for converting values to and from storage format\n * Defaults to IdentitySerializer if not provided\n */\n serializer?: Serializer<string, Deserialized>;\n\n /**\n * Optional storage implementation\n * Defaults to the result of createListenableStorage() if not provided\n */\n storage?: ListenableStorage;\n}\n\n/**\n * A storage wrapper that manages a single value associated with a specific key\n * Provides caching and automatic cache invalidation when the storage value changes\n * @template Deserialized The type of the value being stored\n */\nexport class KeyStorage<Deserialized> implements StorageListenable {\n private readonly key: string;\n private readonly serializer: Serializer<string, Deserialized>;\n private readonly storage: ListenableStorage;\n private cacheValue: Deserialized | null = null;\n\n /**\n * Listener for storage change events\n * Invalidates the cache when the relevant key is modified\n */\n private readonly refreshCacheListener: StorageListener = (event) => {\n this.cacheValue = null;\n if (event.newValue) {\n this.refreshCache(event.newValue);\n }\n };\n\n /**\n * Refreshes the cached value by deserializing the provided string\n * @param value The serialized value to deserialize and cache\n */\n private refreshCache(value: string) {\n this.cacheValue = this.serializer.deserialize(value);\n }\n\n /**\n * Creates a new KeyStorage instance\n * @param options Configuration options for the storage\n */\n constructor(options: KeyStorageOptions<Deserialized>) {\n this.key = options.key;\n this.serializer = options.serializer ?? typedIdentitySerializer();\n this.storage = options.storage ?? createListenableStorage();\n this.addListener(this.refreshCacheListener);\n }\n\n addListener(listener: StorageListener): RemoveStorageListener {\n const wrapper: StorageListener = (event: StorageEventInit) => {\n if (event.key !== this.key) {\n return;\n }\n listener(event);\n };\n return this.storage.addListener(wrapper);\n }\n\n /**\n * Gets the value associated with the key from storage\n * Uses cached value if available, otherwise retrieves from storage and caches it\n * @returns The deserialized value or null if no value is found\n */\n get(): Deserialized | null {\n if (this.cacheValue) {\n return this.cacheValue;\n }\n const value = this.storage.getItem(this.key);\n if (!value) {\n return null;\n }\n this.refreshCache(value);\n return this.cacheValue;\n }\n\n /**\n * Sets the value associated with the key in storage\n * Also updates the cached value\n * @param value The value to serialize and store\n */\n set(value: Deserialized): void {\n const serialized = this.serializer.serialize(value);\n this.storage.setItem(this.key, serialized);\n this.cacheValue = value;\n }\n\n /**\n * Removes the value associated with the key from storage\n * Also clears the cached value\n */\n remove(): void {\n this.storage.removeItem(this.key);\n this.cacheValue = null;\n }\n}"],"names":["isBrowser","InMemoryListenableStorage","key","value","index","oldValue","listener","eventInit","error","BrowserListenableStorage","storage","wrapper","event","STORAGE_EVENT_TYPE","createListenableStorage","JsonSerializer","IdentitySerializer","jsonSerializer","identitySerializer","typedIdentitySerializer","KeyStorage","options","serialized"],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ListenableStorage, RemoveStorageListener, StorageListenable, StorageListener } from './listenableStorage';
|
|
2
|
+
import { Serializer } from './serializer';
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring KeyStorage
|
|
5
|
+
*/
|
|
6
|
+
export interface KeyStorageOptions<Deserialized> {
|
|
7
|
+
/**
|
|
8
|
+
* The key used to store and retrieve values from storage
|
|
9
|
+
*/
|
|
10
|
+
key: string;
|
|
11
|
+
/**
|
|
12
|
+
* Optional serializer for converting values to and from storage format
|
|
13
|
+
* Defaults to IdentitySerializer if not provided
|
|
14
|
+
*/
|
|
15
|
+
serializer?: Serializer<string, Deserialized>;
|
|
16
|
+
/**
|
|
17
|
+
* Optional storage implementation
|
|
18
|
+
* Defaults to the result of createListenableStorage() if not provided
|
|
19
|
+
*/
|
|
20
|
+
storage?: ListenableStorage;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A storage wrapper that manages a single value associated with a specific key
|
|
24
|
+
* Provides caching and automatic cache invalidation when the storage value changes
|
|
25
|
+
* @template Deserialized The type of the value being stored
|
|
26
|
+
*/
|
|
27
|
+
export declare class KeyStorage<Deserialized> implements StorageListenable {
|
|
28
|
+
private readonly key;
|
|
29
|
+
private readonly serializer;
|
|
30
|
+
private readonly storage;
|
|
31
|
+
private cacheValue;
|
|
32
|
+
/**
|
|
33
|
+
* Listener for storage change events
|
|
34
|
+
* Invalidates the cache when the relevant key is modified
|
|
35
|
+
*/
|
|
36
|
+
private readonly refreshCacheListener;
|
|
37
|
+
/**
|
|
38
|
+
* Refreshes the cached value by deserializing the provided string
|
|
39
|
+
* @param value The serialized value to deserialize and cache
|
|
40
|
+
*/
|
|
41
|
+
private refreshCache;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new KeyStorage instance
|
|
44
|
+
* @param options Configuration options for the storage
|
|
45
|
+
*/
|
|
46
|
+
constructor(options: KeyStorageOptions<Deserialized>);
|
|
47
|
+
addListener(listener: StorageListener): RemoveStorageListener;
|
|
48
|
+
/**
|
|
49
|
+
* Gets the value associated with the key from storage
|
|
50
|
+
* Uses cached value if available, otherwise retrieves from storage and caches it
|
|
51
|
+
* @returns The deserialized value or null if no value is found
|
|
52
|
+
*/
|
|
53
|
+
get(): Deserialized | null;
|
|
54
|
+
/**
|
|
55
|
+
* Sets the value associated with the key in storage
|
|
56
|
+
* Also updates the cached value
|
|
57
|
+
* @param value The value to serialize and store
|
|
58
|
+
*/
|
|
59
|
+
set(value: Deserialized): void;
|
|
60
|
+
/**
|
|
61
|
+
* Removes the value associated with the key from storage
|
|
62
|
+
* Also clears the cached value
|
|
63
|
+
*/
|
|
64
|
+
remove(): void;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=keyStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyStorage.d.ts","sourceRoot":"","sources":["../src/keyStorage.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAA2B,MAAM,cAAc,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,YAAY;IAC7C;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAE9C;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,UAAU,CAAC,YAAY,CAAE,YAAW,iBAAiB;IAChE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,UAAU,CAA6B;IAE/C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAKnC;IAEF;;;OAGG;IACH,OAAO,CAAC,YAAY;IAIpB;;;OAGG;gBACS,OAAO,EAAE,iBAAiB,CAAC,YAAY,CAAC;IAOpD,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,qBAAqB;IAU7D;;;;OAIG;IACH,GAAG,IAAI,YAAY,GAAG,IAAI;IAY1B;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAM9B;;;OAGG;IACH,MAAM,IAAI,IAAI;CAIf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type of storage event used for listening to storage changes.
|
|
3
|
+
*/
|
|
4
|
+
export declare const STORAGE_EVENT_TYPE = "storage";
|
|
5
|
+
/**
|
|
6
|
+
* A function that handles storage change events.
|
|
7
|
+
*/
|
|
8
|
+
export type StorageListener = (event: StorageEventInit) => void;
|
|
9
|
+
/**
|
|
10
|
+
* A function that removes a storage listener when called.
|
|
11
|
+
*/
|
|
12
|
+
export type RemoveStorageListener = () => void;
|
|
13
|
+
export interface StorageListenable {
|
|
14
|
+
/**
|
|
15
|
+
* Adds a listener for storage changes.
|
|
16
|
+
* @param listener - The listener function to be called when storage changes
|
|
17
|
+
* @returns A function that can be called to remove the listener
|
|
18
|
+
*/
|
|
19
|
+
addListener(listener: StorageListener): RemoveStorageListener;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An interface that extends the native Storage interface with the ability to listen for storage changes.
|
|
23
|
+
*/
|
|
24
|
+
export interface ListenableStorage extends Storage, StorageListenable {
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Factory function to get an appropriate ListenableStorage implementation based on the environment.
|
|
28
|
+
* In a browser environment, it returns a BrowserListenableStorage wrapping localStorage.
|
|
29
|
+
* In other environments, it returns an InMemoryListenableStorage.
|
|
30
|
+
* @returns A ListenableStorage instance suitable for the current environment
|
|
31
|
+
*/
|
|
32
|
+
export declare const createListenableStorage: () => ListenableStorage;
|
|
33
|
+
//# sourceMappingURL=listenableStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listenableStorage.d.ts","sourceRoot":"","sources":["../src/listenableStorage.ts"],"names":[],"mappings":"AAiBA;;GAEG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,IAAI,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,qBAAqB,CAAC;CAC/D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO,EAAE,iBAAiB;CAEpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAO,iBAK1C,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for serializing and deserializing values
|
|
3
|
+
* @template Serialized The type of the serialized value
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Interface for serializing and deserializing values
|
|
7
|
+
* @template Serialized The type of the serialized value
|
|
8
|
+
* @template Deserialized The type of the deserialized value
|
|
9
|
+
*/
|
|
10
|
+
export interface Serializer<Serialized, Deserialized> {
|
|
11
|
+
/**
|
|
12
|
+
* Serializes a value to the specified format
|
|
13
|
+
* @param value The value to serialize
|
|
14
|
+
* @returns The serialized value
|
|
15
|
+
*/
|
|
16
|
+
serialize(value: any): Serialized;
|
|
17
|
+
/**
|
|
18
|
+
* Deserializes a value from the specified format
|
|
19
|
+
* @template Deserialized The type of the deserialized value
|
|
20
|
+
* @param value The value to deserialize
|
|
21
|
+
* @returns The deserialized value
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Deserializes a value from the specified format
|
|
25
|
+
* @param value The value to deserialize
|
|
26
|
+
* @returns The deserialized value
|
|
27
|
+
*/
|
|
28
|
+
deserialize(value: Serialized): Deserialized;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Implementation of Serializer that uses JSON for serialization
|
|
32
|
+
*/
|
|
33
|
+
export declare class JsonSerializer implements Serializer<string, any> {
|
|
34
|
+
/**
|
|
35
|
+
* Serializes a value to a JSON string
|
|
36
|
+
* @param value The value to serialize
|
|
37
|
+
* @returns The JSON string representation of the value
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Serializes a value to a JSON string
|
|
41
|
+
* @param value The value to serialize
|
|
42
|
+
* @returns The JSON string representation of the value
|
|
43
|
+
*/
|
|
44
|
+
serialize(value: any): string;
|
|
45
|
+
/**
|
|
46
|
+
* Deserializes a JSON string to a value
|
|
47
|
+
* @template V The type of the deserialized value
|
|
48
|
+
* @param value The JSON string to deserialize
|
|
49
|
+
* @returns The deserialized value
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* Deserializes a JSON string to a value
|
|
53
|
+
* @param value The JSON string to deserialize
|
|
54
|
+
* @returns The deserialized value
|
|
55
|
+
*/
|
|
56
|
+
deserialize<V>(value: string): V;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Implementation of Serializer that performs no actual serialization
|
|
60
|
+
* @template T The type of the value to pass through
|
|
61
|
+
*/
|
|
62
|
+
export declare class IdentitySerializer<T> implements Serializer<T, T> {
|
|
63
|
+
/**
|
|
64
|
+
* Returns the value as-is without serialization
|
|
65
|
+
* @param value The value to pass through
|
|
66
|
+
* @returns The same value that was passed in
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* Returns the value as-is without serialization
|
|
70
|
+
* @param value The value to pass through
|
|
71
|
+
* @returns The same value that was passed in
|
|
72
|
+
*/
|
|
73
|
+
serialize(value: T): T;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the value as-is without deserialization
|
|
76
|
+
* @template Deserialized The type of the deserialized value
|
|
77
|
+
* @param value The value to pass through
|
|
78
|
+
* @returns The same value that was passed in, cast to the target type
|
|
79
|
+
*/
|
|
80
|
+
/**
|
|
81
|
+
* Returns the value as-is without deserialization
|
|
82
|
+
* @param value The value to pass through
|
|
83
|
+
* @returns The same value that was passed in
|
|
84
|
+
*/
|
|
85
|
+
deserialize(value: T): T;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Global instance of JsonSerializer
|
|
89
|
+
*/
|
|
90
|
+
export declare const jsonSerializer: JsonSerializer;
|
|
91
|
+
/**
|
|
92
|
+
* Global instance of IdentitySerializer
|
|
93
|
+
*/
|
|
94
|
+
export declare const identitySerializer: IdentitySerializer<any>;
|
|
95
|
+
export declare function typedIdentitySerializer<T>(): IdentitySerializer<T>;
|
|
96
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,UAAU,EAAE,YAAY;IAClD;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,UAAU,CAAC;IAElC;;;;;OAKG;IACH;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CAAC;CAC9C;AAED;;GAEG;AACH,qBAAa,cAAe,YAAW,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D;;;;OAIG;IACH;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;IAI7B;;;;;OAKG;IACH;;;;OAIG;IACH,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC;CAGjC;AAED;;;GAGG;AACH,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5D;;;;OAIG;IACH;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;IAItB;;;;;OAKG;IACH;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;CAGzB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC;AACnD;;GAEG;AACH,eAAO,MAAM,kBAAkB,yBAAgC,CAAC;AAEhE,wBAAgB,uBAAuB,CAAC,CAAC,KAAK,kBAAkB,CAAC,CAAC,CAAC,CAElE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ahoo-wang/fetcher-storage",
|
|
3
|
+
"version": "1.6.6",
|
|
4
|
+
"description": "Ultra-lightweight HTTP client with built-in path parameters, query parameters, and Axios-like API. The foundation of the Fetcher ecosystem with powerful interceptor system and LLM streaming API support.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fetch",
|
|
7
|
+
"http",
|
|
8
|
+
"client",
|
|
9
|
+
"axios",
|
|
10
|
+
"ultra-lightweight",
|
|
11
|
+
"modular",
|
|
12
|
+
"typescript",
|
|
13
|
+
"interceptor",
|
|
14
|
+
"llm",
|
|
15
|
+
"streaming",
|
|
16
|
+
"sse",
|
|
17
|
+
"server-sent-events"
|
|
18
|
+
],
|
|
19
|
+
"author": "Ahoo-Wang",
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"homepage": "https://github.com/Ahoo-Wang/fetcher/tree/master/packages/fetcher",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/Ahoo-Wang/fetcher.git",
|
|
25
|
+
"directory": "packages/storage"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/Ahoo-Wang/fetcher/issues"
|
|
29
|
+
},
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "./dist/index.umd.js",
|
|
32
|
+
"module": "./dist/index.es.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.es.js",
|
|
38
|
+
"require": "./dist/index.umd.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist"
|
|
43
|
+
],
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
46
|
+
"eslint": "^9.33.0",
|
|
47
|
+
"prettier": "^3.6.2",
|
|
48
|
+
"typescript": "^5.9.2",
|
|
49
|
+
"unplugin-dts": "1.0.0-beta.6",
|
|
50
|
+
"vite": "^7.1.3",
|
|
51
|
+
"vitest": "^3.2.4"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "vite build",
|
|
55
|
+
"test": "vitest run --coverage",
|
|
56
|
+
"lint": "eslint . --fix",
|
|
57
|
+
"clean": "rm -rf dist",
|
|
58
|
+
"analyze": "npx vite-bundle-analyzer -p auto"
|
|
59
|
+
}
|
|
60
|
+
}
|