usewagen 0.0.0 → 0.2.0

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.
@@ -0,0 +1,278 @@
1
+ import { _ as warnDev, g as warn, h as ErrorCodes } from "./parsers-CA8aZuF-.mjs";
2
+ import { hasInjectionContext, inject, markRaw } from "vue";
3
+ //#region src/storage/create-storage.ts
4
+ const ALL_KEYS = Symbol("all-keys");
5
+ function createStorage$1(name, options) {
6
+ const { prefix = "", crossTab = false, onError } = options;
7
+ const fullKey = (key) => prefix + key;
8
+ const isOwn = (key) => key.startsWith(prefix);
9
+ const listeners = /* @__PURE__ */ new Map();
10
+ function notify(key) {
11
+ if (key === null) {
12
+ for (const set of listeners.values()) for (const listener of set) listener(null);
13
+ return;
14
+ }
15
+ const own = key.slice(prefix.length);
16
+ for (const listener of listeners.get(key) ?? []) listener(own);
17
+ for (const listener of listeners.get(ALL_KEYS) ?? []) listener(own);
18
+ }
19
+ const stopSync = crossTab ? options.watch?.((key) => {
20
+ if (key === null || isOwn(key)) notify(key);
21
+ }) : void 0;
22
+ return {
23
+ name,
24
+ prefix,
25
+ getItem(key) {
26
+ try {
27
+ return options.getItem(fullKey(key));
28
+ } catch (error) {
29
+ onError?.(error);
30
+ return null;
31
+ }
32
+ },
33
+ setItem(key, value) {
34
+ const target = fullKey(key);
35
+ try {
36
+ if (options.getItem(target) === value) return;
37
+ options.setItem(target, value);
38
+ notify(target);
39
+ } catch (error) {
40
+ onError?.(error);
41
+ notify(target);
42
+ }
43
+ },
44
+ removeItem(key) {
45
+ const target = fullKey(key);
46
+ try {
47
+ if (options.getItem(target) === null) return;
48
+ options.removeItem(target);
49
+ notify(target);
50
+ } catch (error) {
51
+ onError?.(error);
52
+ notify(target);
53
+ }
54
+ },
55
+ has(key) {
56
+ try {
57
+ return options.getItem(fullKey(key)) !== null;
58
+ } catch (error) {
59
+ onError?.(error);
60
+ return false;
61
+ }
62
+ },
63
+ keys() {
64
+ try {
65
+ return options.keys().filter(isOwn).map((key) => key.slice(prefix.length));
66
+ } catch (error) {
67
+ onError?.(error);
68
+ return [];
69
+ }
70
+ },
71
+ clear(clearOptions) {
72
+ try {
73
+ const except = new Set((clearOptions?.except ?? []).map(fullKey));
74
+ const targets = options.keys().filter((key) => isOwn(key) && !except.has(key));
75
+ if (targets.length === 0) return;
76
+ for (const target of targets) {
77
+ options.removeItem(target);
78
+ notify(target);
79
+ }
80
+ } catch (error) {
81
+ onError?.(error);
82
+ }
83
+ },
84
+ subscribe(key, listener) {
85
+ const target = typeof key === "function" ? ALL_KEYS : fullKey(key);
86
+ const handler = typeof key === "function" ? key : listener;
87
+ let set = listeners.get(target);
88
+ if (!set) {
89
+ set = /* @__PURE__ */ new Set();
90
+ listeners.set(target, set);
91
+ }
92
+ set.add(handler);
93
+ return () => {
94
+ const current = listeners.get(target);
95
+ if (!current) return;
96
+ current.delete(handler);
97
+ if (current.size === 0) listeners.delete(target);
98
+ };
99
+ },
100
+ destroy() {
101
+ stopSync?.();
102
+ listeners.clear();
103
+ }
104
+ };
105
+ }
106
+ //#endregion
107
+ //#region src/storage/presets.ts
108
+ function memoryAdapter() {
109
+ const store = /* @__PURE__ */ new Map();
110
+ return {
111
+ getItem: (key) => store.get(key) ?? null,
112
+ setItem: (key, value) => {
113
+ store.set(key, value);
114
+ },
115
+ removeItem: (key) => {
116
+ store.delete(key);
117
+ },
118
+ keys: () => [...store.keys()]
119
+ };
120
+ }
121
+ function noopAdapter() {
122
+ return {
123
+ getItem: () => null,
124
+ setItem: () => {},
125
+ removeItem: () => {},
126
+ keys: () => []
127
+ };
128
+ }
129
+ function webAdapter(name) {
130
+ let area;
131
+ try {
132
+ area = name === "local" ? window.localStorage : window.sessionStorage;
133
+ } catch {
134
+ return null;
135
+ }
136
+ return {
137
+ getItem: (key) => area.getItem(key),
138
+ setItem: (key, value) => area.setItem(key, value),
139
+ removeItem: (key) => area.removeItem(key),
140
+ keys: () => {
141
+ const result = [];
142
+ for (let i = 0; i < area.length; i++) {
143
+ const key = area.key(i);
144
+ if (key !== null) result.push(key);
145
+ }
146
+ return result;
147
+ },
148
+ watch(onChange) {
149
+ const handleStorage = (event) => {
150
+ if (event.storageArea && event.storageArea !== area) return;
151
+ if (event.key === null) return onChange(null);
152
+ if (typeof event.key === "string") onChange(event.key);
153
+ };
154
+ const target = window;
155
+ target.addEventListener("storage", handleStorage);
156
+ return () => target.removeEventListener("storage", handleStorage);
157
+ }
158
+ };
159
+ }
160
+ function createWebStorage(name, config) {
161
+ if (typeof window === "undefined") return createStorage$1(name, {
162
+ ...noopAdapter(),
163
+ ...config
164
+ });
165
+ const adapter = webAdapter(name);
166
+ if (!adapter) {
167
+ warn(ErrorCodes.WEB_STORAGE_UNAVAILABLE, `${name}Storage`);
168
+ return createStorage$1(name, {
169
+ ...memoryAdapter(),
170
+ ...config,
171
+ crossTab: false
172
+ });
173
+ }
174
+ return createStorage$1(name, {
175
+ ...adapter,
176
+ ...config
177
+ });
178
+ }
179
+ function createMemoryStorage(config = {}) {
180
+ return createStorage$1("memory", {
181
+ ...memoryAdapter(),
182
+ ...config
183
+ });
184
+ }
185
+ function createLocalStorage(config = {}) {
186
+ return createWebStorage("local", {
187
+ ...config,
188
+ crossTab: config.crossTab ?? true
189
+ });
190
+ }
191
+ function createSessionStorage(config = {}) {
192
+ return createWebStorage("session", config);
193
+ }
194
+ //#endregion
195
+ //#region src/wagen.ts
196
+ const WAGEN_KEY = Symbol.for("usewagen");
197
+ const ROUTER_DEFAULTS = {
198
+ history: "replace",
199
+ source: "query",
200
+ clearOnDefault: true,
201
+ mode: "optimistic"
202
+ };
203
+ let activeWagen = null;
204
+ function createStorage(options) {
205
+ const { prefix, crossTab, onError } = options;
206
+ const created = [];
207
+ function own(instance) {
208
+ created.push(instance);
209
+ return instance;
210
+ }
211
+ let local;
212
+ let session;
213
+ const storage = {
214
+ get local() {
215
+ local ??= options.local ?? own(createLocalStorage({
216
+ prefix,
217
+ crossTab,
218
+ onError
219
+ }));
220
+ return local;
221
+ },
222
+ get session() {
223
+ session ??= options.session ?? own(createSessionStorage({
224
+ prefix,
225
+ crossTab,
226
+ onError
227
+ }));
228
+ return session;
229
+ },
230
+ get default() {
231
+ return options.default === "session" ? storage.session : storage.local;
232
+ },
233
+ mode: options.mode ?? "optimistic"
234
+ };
235
+ function destroy() {
236
+ for (const instance of created) instance.destroy();
237
+ created.length = 0;
238
+ }
239
+ return {
240
+ storage,
241
+ destroy
242
+ };
243
+ }
244
+ function defineWagenConfig(config) {
245
+ return config;
246
+ }
247
+ function createWagen(config = {}) {
248
+ const { storage, destroy } = createStorage(config.storage ?? {});
249
+ const wagen = markRaw({
250
+ parsers: { ...config.parsers },
251
+ storage,
252
+ router: {
253
+ ...ROUTER_DEFAULTS,
254
+ ...config.router
255
+ },
256
+ install(app) {
257
+ app.provide(WAGEN_KEY, wagen);
258
+ activeWagen = wagen;
259
+ },
260
+ destroy() {
261
+ destroy();
262
+ if (activeWagen === wagen) activeWagen = null;
263
+ }
264
+ });
265
+ return wagen;
266
+ }
267
+ function getActiveWagen() {
268
+ const injected = hasInjectionContext() ? inject(WAGEN_KEY, null) : null;
269
+ if (injected) return injected;
270
+ activeWagen ??= createWagen();
271
+ return activeWagen;
272
+ }
273
+ function useWagen() {
274
+ if (!hasInjectionContext()) warnDev(ErrorCodes.NO_INJECTION_CONTEXT);
275
+ return getActiveWagen();
276
+ }
277
+ //#endregion
278
+ export { createLocalStorage as a, createStorage$1 as c, useWagen as i, defineWagenConfig as n, createMemoryStorage as o, getActiveWagen as r, createSessionStorage as s, createWagen as t };
package/package.json CHANGED
@@ -1,8 +1,81 @@
1
1
  {
2
2
  "name": "usewagen",
3
- "version": "0.0.0",
4
- "description": "Sync and transform Vue state across router, storage and beyond.",
3
+ "version": "0.2.0",
4
+ "description": "Reactive state for URL and storage in Vue.",
5
+ "keywords": [
6
+ "composables",
7
+ "localstorage",
8
+ "query-params",
9
+ "search-params",
10
+ "sessionstorage",
11
+ "storage",
12
+ "type-safe",
13
+ "url-state",
14
+ "vue",
15
+ "vue-router"
16
+ ],
17
+ "homepage": "https://usewagen.dev",
18
+ "bugs": {
19
+ "url": "https://github.com/tinas/usewagen/issues"
20
+ },
21
+ "license": "MIT",
5
22
  "author": "Ahmet Tinastepe <ahmettinastepe0@gmail.com>",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/tinas/usewagen.git"
26
+ },
27
+ "files": [
28
+ "client.d.ts",
29
+ "dist"
30
+ ],
6
31
  "type": "module",
7
- "license": "MIT"
32
+ "exports": {
33
+ ".": "./dist/index.mjs",
34
+ "./router": "./dist/router/index.mjs",
35
+ "./storage": "./dist/storage/index.mjs",
36
+ "./vite": "./dist/vite/index.mjs",
37
+ "./package.json": "./package.json",
38
+ "./client": {
39
+ "types": "./client.d.ts"
40
+ }
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^26.1.1",
47
+ "typescript": "^7.0.2",
48
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
49
+ "vite-plus": "latest"
50
+ },
51
+ "peerDependencies": {
52
+ "vite": "^7.3.0 || ^8.0.0",
53
+ "vue": "^3.5.0 || ^4.0.0",
54
+ "vue-router": "^4.0.0 || ^5.0.0"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "vite": {
58
+ "optional": true
59
+ },
60
+ "vue-router": {
61
+ "optional": true
62
+ }
63
+ },
64
+ "devEngines": {
65
+ "packageManager": {
66
+ "name": "pnpm",
67
+ "version": "11.25.0",
68
+ "onFail": "download"
69
+ }
70
+ },
71
+ "scripts": {
72
+ "build": "vp pack",
73
+ "dev": "vp pack --watch",
74
+ "lint:fix": "vp lint --fix && vp fmt",
75
+ "test": "vp test",
76
+ "check": "vp check",
77
+ "docs:dev": "pnpm --filter docs dev",
78
+ "docs:build": "pnpm --filter docs build",
79
+ "docs:preview": "pnpm --filter docs preview"
80
+ }
8
81
  }