vue-router-query-sync 1.0.1 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,213 +1,123 @@
1
1
  # vue-router-query-sync
2
2
 
3
- ![demo](src/assets/demo.gif)
3
+ > Draft docs for `2.0.0-alpha.0`. API only — no tests, migration guide or final docs yet.
4
4
 
5
- > Effortlessly sync Vue Router query parameters with your store or local refs — no boilerplate.
5
+ A reactive, typed view of the Vue Router query string. The URL (`route.query`) is the
6
+ single source of truth: reads parse `route.query`, writes navigate the router. The library
7
+ holds no state of its own and never throws because of URL contents.
6
8
 
7
- [![npm version](https://img.shields.io/npm/v/vue-router-query-sync.svg)](https://www.npmjs.com/package/vue-router-query-sync)
8
- [![license](https://img.shields.io/npm/l/vue-router-query-sync.svg)](LICENSE)
9
+ - Vue 3 + Vue Router 4 (peer dependencies).
10
+ - Codecs + defaults per param; defaults never appear in the URL.
11
+ - Arrays use native repeated keys (`?a=1&a=2`).
12
+ - Batched navigation: several writes in one tick collapse into one `push`/`replace`.
13
+ - SSR-safe: router is read via `useRouter()`/`useRoute()`, no global/module state.
9
14
 
10
- ---
11
-
12
- ## ✨ What is this?
13
-
14
- `vue-router-query-sync` is a tiny, fully-typed Vue 3 utility that keeps your reactive state
15
- (Pinia store fields or local refs) in sync with the current URL query string — both ways.
16
-
17
- - Changes in your store update the URL query.
18
- - Changes in the URL query update your store.
19
- - Batched updates prevent excessive `router.replace` calls.
20
-
21
- ---
22
-
23
- ## 💡 Why use this plugin?
24
-
25
- - 🔄 Keeps your app state and URL perfectly in sync — no more manual watchers or `router.replace` logic.
26
- - 🧠 Works with **Pinia**, **local refs**, or any reactive source.
27
- - 🧩 Handles multiple query keys and isolated contexts safely.
28
- - ⚙️ Fully typed with TypeScript and designed for Vue 3’s Composition API.
29
- - 🚀 Tiny footprint — optimized for production.
30
-
31
- ## ✅ Requirements
32
-
33
- - Vue 3
34
- - Vue Router 4
35
-
36
- ---
37
-
38
- ## 🚀 Installation
15
+ ## Install
39
16
 
40
17
  ```bash
41
18
  npm install vue-router-query-sync
42
- # or
43
- yarn add vue-router-query-sync
44
- # or
45
- pnpm add vue-router-query-sync
46
19
  ```
47
20
 
48
- ---
21
+ ## `useQueryFilters(schema)`
49
22
 
50
- ## ⚙️ Setup
23
+ Returns `{ filters, patch, reset }`. `filters` is a reactive object of schema fields only
24
+ (no methods on it); access fields without `.value`. The type is inferred from the schema.
51
25
 
52
26
  ```ts
53
- // main.ts
54
- import { createApp } from 'vue'
55
- import { createRouter, createWebHistory } from 'vue-router'
56
- import routerQuerySync from 'vue-router-query-sync'
57
- import App from './App.vue'
58
-
59
- const router = createRouter({
60
- history: createWebHistory(),
61
- routes: []
62
- })
27
+ import { useQueryFilters, param } from 'vue-router-query-sync'
63
28
 
64
- createApp(App)
65
- .use(router)
66
- .use(routerQuerySync, { router })
67
- .mount('#app')
68
- ```
29
+ enum SortType { Popular = 'popular', New = 'new' }
69
30
 
70
- ---
71
-
72
- ## 🧩 Basic Usage
73
-
74
- You can use `useQuerySync` several times in one component.
75
-
76
- #### Sync a value with a query param named `tab`:
77
-
78
- - Visiting `?tab=favorite` sets `tab.value = 'favorite'`.
79
- - Changing `tab.value = 'all'` updates the URL to `?tab=all`.
80
-
81
- ```ts
82
- import { useQuerySync } from 'vue-router-query-sync'
83
-
84
- const tab = ref<'favorite' | 'all'>('all')
31
+ const { filters, patch, reset } = useQueryFilters({
32
+ sort: param.enum(SortType, { default: SortType.Popular, history: 'push' }),
33
+ brands: param.stringArray(), // default: []
34
+ page: param.number({ default: 1 }),
35
+ from: param.custom(dateCodec), // default: null
36
+ })
85
37
 
86
- useQuerySync(
87
- 'tab',
88
- () => tab.value,
89
- (val) => (tab.value = val)
90
- )
38
+ filters.sort = SortType.New // write -> router navigation
39
+ filters.brands // read -> parses route.query (or pending write)
40
+ patch({ brands: ['lg'], page: 2 }) // several fields, ONE navigation
41
+ reset() // all fields back to defaults (keys removed)
91
42
  ```
92
43
 
93
- ### Multiple values
94
- #### Sync a value with a query param named `brands`:
95
-
96
- - Visiting `?brands=lg%samsung` sets `brands.value = ['lg', 'samsung']`.
97
- - Changing `brands.value = ['lg']` updates the URL to `?brands=lg`.
44
+ - **Read**: pending write (same tick) → else `route.query[key]` → `deserialize` → on
45
+ `undefined`/throw `default`. Reading a field right after writing it returns the new value.
46
+ - **Write**: `serialize` → if `null` or equal to `serialize(default)` → the key is removed.
47
+ - Query keys not described in the schema are left untouched.
48
+ - Destructuring `filters` loses reactivity use Vue's `toRefs(filters)`.
98
49
 
99
- ```ts
100
- import { useQuerySync } from 'vue-router-query-sync'
101
-
102
- const brands = [
103
- { value: 'lg', label: 'LG' },
104
- { value: 'samsung', label: 'Samsung' }
105
- ]
106
-
107
- const selectedBrands = ref<string[]>([])
108
-
109
- useQuerySync(
110
- 'brands',
111
- () => {
112
- return selectedBrands.value.length > 0 ? selectedBrands.value.join('%') : null
113
- },
114
- (val) => {
115
- if (typeof val === 'string' && val) {
116
- selectedBrands.value = val.includes('%') ? val.split('%') : [val]
117
- } else {
118
- selectedBrands.value = []
119
- }
120
- }
121
- )
122
- ```
123
- ---
50
+ ### Single parameter
124
51
 
125
- ## 🔧 API
52
+ There is no separate single-param helper: use a one-key schema and `toRef`.
126
53
 
127
54
  ```ts
128
- function useQuerySync<T extends string | number>(
129
- key: string,
130
- get: () => T | null,
131
- set: (val: T) => void,
132
- options?: QuerySyncOptions
133
- ): void
134
-
135
- type QuerySyncOptions = {
136
- deps?: Ref<unknown>[]
137
- context?: string
138
- }
139
- ```
140
-
141
- - **key**: Query parameter name, e.g., `'tab'`.
142
- - **get**: Function returning the current value from your store/ref. Return `null` to indicate “no value”.
143
- - **set**: Function that writes the value to your store/ref.
144
- - **options.deps**: Array of refs. If provided, the initial sync runs after any of these deps change (useful when state is populated asynchronously).
145
- - **options.context**: If the same query key may be used multiple times on the same page, provide a unique context to avoid collisions. The actual query key becomes `${context}_${key}`.
146
-
147
- ---
148
-
149
- ## ❗ Important
150
-
151
- If a page can have multiple components with the same query key, pass a unique `context` to avoid conflicts.
152
- The real key used in the URL will be `${context}_${key}`. Otherwise, use unique keys per component.
55
+ import { toRef } from 'vue'
56
+ import { useQueryFilters, param } from 'vue-router-query-sync'
153
57
 
154
- ---
155
-
156
- ## 🏷️ Context Example
157
-
158
- If two widgets on the same page need a `tab` param, use unique contexts:
159
-
160
- ```ts
161
- useQuerySync('tab', () => usersStore.tab, (v) => (usersStore.tab = v), { context: 'users' })
162
- useQuerySync('tab', () => ordersStore.tab, (v) => (ordersStore.tab = v), { context: 'orders' })
163
- // URL keys will be: users_tab and orders_tab
58
+ const { filters } = useQueryFilters({ tab: param.enum(['all', 'favorite'] as const) })
59
+ const tab = toRef(filters, 'tab') // WritableComputedRef<'all' | 'favorite' | null>
60
+ tab.value = 'favorite'
164
61
  ```
165
62
 
166
- ---
63
+ ## `param`
167
64
 
168
- ## Delayed/Dependent Initialization
65
+ All options are shared: `{ default?: T; history?: 'push' | 'replace' }` (`history` defaults to
66
+ `'replace'`). Passing `default` narrows the field type from `T | null` to `T`.
169
67
 
170
- If your state becomes available later (e.g., after a request), delay the initial sync with `deps`:
68
+ | Factory | Field type | Notes |
69
+ | --- | --- | --- |
70
+ | `param.string(options?)` | `string \| null` | |
71
+ | `param.number(options?)` | `number \| null` | |
72
+ | `param.boolean(options?)` | `boolean \| null` | URL is `'true'` / `'false'` |
73
+ | `param.stringArray(options?)` | `string[]` | repeated keys; default always `[]` |
74
+ | `param.enum(input, options?)` | member of `input` | see below |
75
+ | `param.custom(codec, options?)` | `T` from codec | default `null` if unset |
171
76
 
172
- ```ts
173
- const isReady = ref(false)
77
+ `param.enum` accepts either a readonly string array or a TS enum object (string or numeric).
78
+ Numeric enums have their reverse mapping filtered out and URL strings are coerced to numbers.
79
+ A value outside the set becomes `undefined` → `default` (behaviour mirrors `z.enum`).
174
80
 
175
- useQuerySync('sort', () => store.sort, (v) => (store.sort = v), { deps: [isReady] })
81
+ ## Codecs
176
82
 
177
- // Later when data is loaded:
178
- isReady.value = true
179
- ```
180
-
181
- ---
83
+ ```ts
84
+ import { defineCodec, type QueryCodec } from 'vue-router-query-sync'
182
85
 
183
- ## 📦 Exports
86
+ interface QueryCodec<T> {
87
+ serialize(value: T): string | string[] | null // null = remove key
88
+ deserialize(raw: string | string[]): T | undefined // undefined = use default
89
+ }
184
90
 
185
- ```ts
186
- import routerQuerySync, { useQuerySync, replaceRouterQueue } from 'vue-router-query-sync'
91
+ const dateCodec = defineCodec<Date | null>({
92
+ serialize: (d) => (d ? d.toISOString().slice(0, 10) : null),
93
+ deserialize: (raw) => {
94
+ const t = Date.parse(Array.isArray(raw) ? raw[0] : raw)
95
+ return Number.isNaN(t) ? undefined : new Date(t)
96
+ },
97
+ })
187
98
  ```
188
99
 
189
- - **default**: Vue plugin to register with `app.use(routerQuerySync, { router })`.
190
- - **useQuerySync**: The composable described above.
191
- - **replaceRouterQueue**: Internal helper that batches query updates (exported in case you need manual batching).
192
-
193
- Note: `setRouter/getRouter` are internal; prefer using the plugin install.
100
+ `defineCodec` is an identity helper for type inference. All built-in `param.*` types are codecs.
194
101
 
195
- ---
102
+ ## Batching & history
196
103
 
197
- ## 🔒 TypeScript
104
+ All writes in the same tick — field assignments, `patch`, `reset` — accumulate into one
105
+ pending batch (kept per router instance) and are applied as a **single** navigation via
106
+ `queueMicrotask`. The batch is layered over the last *scheduled* state, so reads within the
107
+ same tick see pending writes. If any changed param in the batch has `history: 'push'`, the
108
+ whole batch uses `router.push`; otherwise `router.replace`. Query keys are sorted for a
109
+ deterministic URL.
198
110
 
199
- `useQuerySync` is fully typed. You can annotate the expected type if needed:
111
+ ## Playground
200
112
 
201
- ```ts
202
- useQuerySync<number>('page', () => page.value, (v) => (page.value = v))
113
+ ```bash
114
+ npm run dev
203
115
  ```
204
116
 
205
- Values must be `string` or `number`.
206
-
207
- ---
117
+ A catalog page exercises every param type plus `reset`/`patch`, and a second route shows the
118
+ single-parameter pattern (`toRef` over a one-key schema). The current `route.query` is
119
+ rendered on screen.
208
120
 
209
- ## 📄 License
121
+ ## License
210
122
 
211
123
  MIT © Ivan Chikachev
212
-
213
-
@@ -0,0 +1,3 @@
1
+ import { QueryCodec } from './types';
2
+ export declare function defineCodec<T>(codec: QueryCodec<T>): QueryCodec<T>;
3
+ //# sourceMappingURL=defineCodec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineCodec.d.ts","sourceRoot":"","sources":["../src/defineCodec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAElE"}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,5 @@
1
- import { App } from 'vue';
2
- import { Router } from 'vue-router';
3
- export * from './composables/useQuerySync';
4
- export * from './utils/replaceRouterQueue';
5
- export * from './router';
6
- export * from './types/index';
7
- declare const _default: {
8
- install(app: App, options: {
9
- router: Router;
10
- }): void;
11
- };
12
- export default _default;
1
+ export { useQueryFilters } from './useQueryFilters';
2
+ export { param } from './param';
3
+ export { defineCodec } from './defineCodec';
4
+ export type { QueryCodec, ParamOptions, Param, FilterSchema, InferFilters, UseQueryFiltersReturn } from './types';
13
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;;iBAGd,GAAG,WAAW;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE;;AAD/C,wBAIC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EACV,UAAU,EACV,YAAY,EACZ,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACtB,MAAM,SAAS,CAAA"}
package/dist/index.mjs CHANGED
@@ -1,77 +1,193 @@
1
- import { onBeforeMount as b, watch as y, onBeforeUnmount as g } from "vue";
2
- let v = null;
3
- function x(e) {
4
- v = e;
5
- }
6
- function S() {
7
- if (!v)
8
- throw new Error(
9
- "[vue-router-query-sync] Router instance not set. Call setRouter(router) before using composables."
10
- );
11
- return v;
12
- }
13
- let f = {};
14
- const a = /* @__PURE__ */ new Set();
15
- let Q = !1;
16
- function l(e, t) {
17
- const s = S();
18
- t === null ? e in f || a.add(e) : (f[e] = t, a.delete(e)), Q || (Q = !0, queueMicrotask(() => {
19
- const c = { ...s.currentRoute.value.query };
20
- a.forEach((o) => {
21
- delete c[o];
22
- });
23
- const R = {
24
- ...c,
25
- ...f
26
- };
27
- s.replace({ query: R }), f = {}, a.clear(), Q = !1;
28
- }));
29
- }
30
- function N(e) {
31
- if (e === "")
32
- return e;
33
- const t = Number(e);
34
- return isNaN(t) ? e : t;
35
- }
36
- function B(e, t, s, c = {}) {
37
- const o = S().currentRoute, { deps: m = [], context: q } = c, r = q ? `${q}_${e}` : e, d = (u, i = !1) => {
38
- if (typeof u == "string") {
39
- const n = N(u);
40
- if (i || n !== t()) {
41
- s(n);
42
- const p = t();
43
- p !== n && p !== null && l(r, p);
44
- }
45
- } else if (u === void 0) {
46
- const n = t();
47
- n !== null && l(r, n);
48
- }
49
- }, h = (u) => {
50
- const i = o.value.query[r];
51
- if (u === null)
52
- i !== void 0 && l(r, null);
53
- else {
54
- const n = String(u);
55
- i !== n && l(r, u);
1
+ import { reactive as A, computed as N } from "vue";
2
+ import { useRoute as v, useRouter as S } from "vue-router";
3
+ function g(e) {
4
+ if (e != null)
5
+ return Array.isArray(e) ? e.filter((r) => r !== null) : e;
6
+ }
7
+ function o(e, r) {
8
+ return e === r ? !0 : Array.isArray(e) && Array.isArray(r) ? e.length !== r.length ? !1 : e.every((t, u) => t === r[u]) : !1;
9
+ }
10
+ const h = /* @__PURE__ */ new WeakMap();
11
+ function m(e) {
12
+ let r = h.get(e);
13
+ return r || (r = {
14
+ patch: A(/* @__PURE__ */ new Map()),
15
+ usePush: !1,
16
+ scheduled: !1
17
+ }, h.set(e, r)), r;
18
+ }
19
+ function P(e, r) {
20
+ const t = m(e);
21
+ return t.patch.has(r) ? { pending: !0, value: t.patch.get(r) ?? null } : { pending: !1, value: null };
22
+ }
23
+ function z(e, r, t, u) {
24
+ const l = m(e);
25
+ l.patch.set(r, t), u === "push" && (l.usePush = !0), l.scheduled || (l.scheduled = !0, queueMicrotask(() => q(e)));
26
+ }
27
+ function j(e, r) {
28
+ const t = Object.keys(e), u = Object.keys(r);
29
+ if (t.length !== u.length)
30
+ return !1;
31
+ const l = (n, c) => {
32
+ if (Array.isArray(n) || Array.isArray(c)) {
33
+ const a = Array.isArray(n) ? n : [n], s = Array.isArray(c) ? c : [c];
34
+ return a.length === s.length && a.every((i, f) => String(i) === String(s[f]));
56
35
  }
36
+ return String(n) === String(c);
57
37
  };
58
- b(() => {
59
- m.length > 0 ? y(m, () => d(o.value.query[r])) : d(o.value.query[r]);
60
- }), y(t, h), y(
61
- () => o.value.query[r],
62
- (u) => d(u)
63
- ), g(() => {
64
- l(r, null);
38
+ return t.every((n) => n in r && l(e[n], r[n]));
39
+ }
40
+ function q(e) {
41
+ const r = h.get(e);
42
+ if (!r)
43
+ return;
44
+ if (r.scheduled = !1, r.patch.size === 0) {
45
+ r.usePush = !1;
46
+ return;
47
+ }
48
+ const t = r.usePush;
49
+ r.usePush = !1;
50
+ const u = e.currentRoute.value.query, l = {};
51
+ for (const [i, f] of Object.entries(u))
52
+ f !== null && (l[i] = Array.isArray(f) ? f.filter((b) => b !== null) : f);
53
+ const n = new Map(r.patch);
54
+ n.forEach((i, f) => {
55
+ i === null ? delete l[f] : l[f] = i;
65
56
  });
57
+ const c = {};
58
+ for (const i of Object.keys(l).sort())
59
+ c[i] = l[i];
60
+ const a = () => {
61
+ n.forEach((i, f) => {
62
+ r.patch.get(f) === i && r.patch.delete(f);
63
+ });
64
+ };
65
+ if (j(u, c)) {
66
+ a();
67
+ return;
68
+ }
69
+ (t ? e.push({ query: c }) : e.replace({ query: c })).then(a, a);
66
70
  }
67
- const E = {
68
- install(e, t) {
69
- x(t.router);
71
+ function O(e, r, t, u) {
72
+ const l = P(r, t);
73
+ let n;
74
+ if (l.pending) {
75
+ if (l.value === null)
76
+ return u.default;
77
+ n = g(l.value);
78
+ } else
79
+ n = g(e.query[t]);
80
+ if (n === void 0)
81
+ return u.default;
82
+ try {
83
+ const c = u.codec.deserialize(n);
84
+ return c === void 0 ? u.default : c;
85
+ } catch {
86
+ return u.default;
70
87
  }
88
+ }
89
+ function y(e, r, t, u) {
90
+ const l = t.codec.serialize(u), n = t.codec.serialize(t.default);
91
+ l === null || o(l, n) ? z(e, r, null, t.history) : z(e, r, l, t.history);
92
+ }
93
+ function k(e, r, t, u) {
94
+ let l = !1, n, c;
95
+ return N({
96
+ get: () => {
97
+ const a = O(e, r, t, u), s = u.codec.serialize(a);
98
+ return l && o(s, c) ? n : (l = !0, n = a, c = s, a);
99
+ },
100
+ set: (a) => y(r, t, u, a)
101
+ });
102
+ }
103
+ function W(e) {
104
+ const r = v(), t = S(), u = Object.keys(e), l = {};
105
+ for (const s of u)
106
+ l[s] = k(r, t, s, e[s]);
107
+ return { filters: A(l), patch: (s) => {
108
+ for (const i of Object.keys(s))
109
+ i in e && y(t, i, e[i], s[i]);
110
+ }, reset: () => {
111
+ for (const s of u)
112
+ y(t, s, e[s], e[s].default);
113
+ } };
114
+ }
115
+ function d(e) {
116
+ return Array.isArray(e) ? e[0] ?? "" : e;
117
+ }
118
+ function w(e) {
119
+ return { codec: {
120
+ serialize: (t) => t === null || t === "" ? null : t,
121
+ deserialize: (t) => d(t)
122
+ }, default: (e == null ? void 0 : e.default) ?? null, history: (e == null ? void 0 : e.history) ?? "replace" };
123
+ }
124
+ function F(e) {
125
+ return { codec: {
126
+ serialize: (t) => t === null ? null : String(t),
127
+ deserialize: (t) => {
128
+ const u = d(t), l = Number(u);
129
+ return u === "" || Number.isNaN(l) ? void 0 : l;
130
+ }
131
+ }, default: (e == null ? void 0 : e.default) ?? null, history: (e == null ? void 0 : e.history) ?? "replace" };
132
+ }
133
+ function M(e) {
134
+ return { codec: {
135
+ serialize: (t) => t === null ? null : t ? "true" : "false",
136
+ deserialize: (t) => {
137
+ const u = d(t);
138
+ if (u === "true")
139
+ return !0;
140
+ if (u === "false")
141
+ return !1;
142
+ }
143
+ }, default: (e == null ? void 0 : e.default) ?? null, history: (e == null ? void 0 : e.history) ?? "replace" };
144
+ }
145
+ function R(e) {
146
+ return { codec: {
147
+ serialize: (t) => t.length === 0 ? null : [...t],
148
+ deserialize: (t) => Array.isArray(t) ? [...t] : [t]
149
+ }, default: (e == null ? void 0 : e.default) ?? [], history: (e == null ? void 0 : e.history) ?? "replace" };
150
+ }
151
+ function E(e) {
152
+ return Object.entries(e).filter(([r]) => Number.isNaN(Number(r))).map(([, r]) => r);
153
+ }
154
+ function C(e, r) {
155
+ const t = Array.isArray(e) ? [...e] : E(e), u = new Set(t);
156
+ return { codec: {
157
+ serialize: (n) => n === null ? null : String(n),
158
+ deserialize: (n) => {
159
+ const c = d(n);
160
+ if (u.has(c))
161
+ return c;
162
+ const a = Number(c);
163
+ if (c !== "" && !Number.isNaN(a) && u.has(a))
164
+ return a;
165
+ }
166
+ }, default: (r == null ? void 0 : r.default) ?? null, history: (r == null ? void 0 : r.history) ?? "replace" };
167
+ }
168
+ function K(e, r) {
169
+ return {
170
+ codec: {
171
+ serialize: (u) => u === null ? null : e.serialize(u),
172
+ deserialize: (u) => e.deserialize(u)
173
+ },
174
+ default: (r == null ? void 0 : r.default) ?? null,
175
+ history: (r == null ? void 0 : r.history) ?? "replace"
176
+ };
177
+ }
178
+ const B = {
179
+ string: w,
180
+ number: F,
181
+ boolean: M,
182
+ stringArray: R,
183
+ enum: C,
184
+ custom: K
71
185
  };
186
+ function D(e) {
187
+ return e;
188
+ }
72
189
  export {
73
- E as default,
74
- S as getRouter,
75
- x as setRouter,
76
- B as useQuerySync
190
+ D as defineCodec,
191
+ B as param,
192
+ W as useQueryFilters
77
193
  };
@@ -0,0 +1,10 @@
1
+ import { Router } from 'vue-router';
2
+ type Serialized = string | string[];
3
+ export interface PendingRead {
4
+ pending: boolean;
5
+ value: Serialized | null;
6
+ }
7
+ export declare function readPending(router: Router, key: string): PendingRead;
8
+ export declare function scheduleWrite(router: Router, key: string, value: Serialized | null, history: 'push' | 'replace'): void;
9
+ export {};
10
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/internal/batch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmC,MAAM,EAAE,MAAM,YAAY,CAAA;AAEzE,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;AA2BnC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CACzB;AAGD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAMpE;AAGD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,IAAI,CAUN"}
@@ -0,0 +1,2 @@
1
+ export declare function serializedEqual(a: string | string[] | null, b: string | string[] | null): boolean;
2
+ //# sourceMappingURL=equal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equal.d.ts","sourceRoot":"","sources":["../../src/internal/equal.ts"],"names":[],"mappings":"AACA,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,OAAO,CAWjG"}
@@ -0,0 +1,5 @@
1
+ import { RouteLocationNormalizedLoaded, Router } from 'vue-router';
2
+ import { Param } from '../types';
3
+ export declare function readField<Out>(route: RouteLocationNormalizedLoaded, router: Router, key: string, p: Param<Out>): Out;
4
+ export declare function writeField<Out>(router: Router, key: string, p: Param<Out>, value: Out): void;
5
+ //# sourceMappingURL=field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/internal/field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAOrC,wBAAgB,SAAS,CAAC,GAAG,EAC3B,KAAK,EAAE,6BAA6B,EACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,GACZ,GAAG,CAoBL;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAQ5F"}
@@ -0,0 +1,3 @@
1
+ import { LocationQuery } from 'vue-router';
2
+ export declare function normalizeRaw(value: LocationQuery[string]): string | string[] | undefined;
3
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/internal/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAQxF"}
@@ -0,0 +1,39 @@
1
+ import { Param, ParamOptions, QueryCodec } from './types';
2
+ declare function string(): Param<string | null>;
3
+ declare function string(options: ParamOptions<string> & {
4
+ default: string;
5
+ }): Param<string>;
6
+ declare function string(options?: ParamOptions<string>): Param<string | null>;
7
+ declare function number(): Param<number | null>;
8
+ declare function number(options: ParamOptions<number> & {
9
+ default: number;
10
+ }): Param<number>;
11
+ declare function number(options?: ParamOptions<number>): Param<number | null>;
12
+ declare function boolean(): Param<boolean | null>;
13
+ declare function boolean(options: ParamOptions<boolean> & {
14
+ default: boolean;
15
+ }): Param<boolean>;
16
+ declare function boolean(options?: ParamOptions<boolean>): Param<boolean | null>;
17
+ declare function stringArray(options?: ParamOptions<string[]>): Param<string[]>;
18
+ declare function enumParam<const T extends readonly string[]>(values: T, options: ParamOptions<T[number]> & {
19
+ default: T[number];
20
+ }): Param<T[number]>;
21
+ declare function enumParam<const T extends readonly string[]>(values: T, options?: ParamOptions<T[number]>): Param<T[number] | null>;
22
+ declare function enumParam<T extends Record<string, string | number>>(enumObj: T, options: ParamOptions<T[keyof T]> & {
23
+ default: T[keyof T];
24
+ }): Param<T[keyof T]>;
25
+ declare function enumParam<T extends Record<string, string | number>>(enumObj: T, options?: ParamOptions<T[keyof T]>): Param<T[keyof T] | null>;
26
+ declare function custom<T>(codec: QueryCodec<T>, options: ParamOptions<T> & {
27
+ default: T;
28
+ }): Param<T>;
29
+ declare function custom<T>(codec: QueryCodec<T>, options?: ParamOptions<T>): Param<T | null>;
30
+ export declare const param: {
31
+ string: typeof string;
32
+ number: typeof number;
33
+ boolean: typeof boolean;
34
+ stringArray: typeof stringArray;
35
+ enum: typeof enumParam;
36
+ custom: typeof custom;
37
+ };
38
+ export {};
39
+ //# sourceMappingURL=param.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"param.d.ts","sourceRoot":"","sources":["../src/param.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface QueryCodec<T> {
2
+ serialize(value: T): string | string[] | null;
3
+ deserialize(raw: string | string[]): T | undefined;
4
+ }
5
+ export type ParamOptions<T> = {
6
+ default?: T;
7
+ history?: 'push' | 'replace';
8
+ };
9
+ export interface Param<Out> {
10
+ codec: QueryCodec<Out>;
11
+ default: Out;
12
+ history: 'push' | 'replace';
13
+ }
14
+ export type FilterSchema = Record<string, Param<unknown>>;
15
+ export type InferFilters<S extends FilterSchema> = {
16
+ [K in keyof S]: S[K] extends Param<infer O> ? O : never;
17
+ };
18
+ export interface UseQueryFiltersReturn<S extends FilterSchema> {
19
+ filters: InferFilters<S>;
20
+ patch(partial: Partial<InferFilters<S>>): void;
21
+ reset(): void;
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,UAAU,CAAC,CAAC;IAE3B,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IAE7C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAA;CACnD;AAGD,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,OAAO,CAAC,EAAE,CAAC,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B,CAAA;AAGD,MAAM,WAAW,KAAK,CAAC,GAAG;IACxB,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAA;IACtB,OAAO,EAAE,GAAG,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B;AAGD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;AAGzD,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,IAAI;KAChD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACxD,CAAA;AAGD,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,YAAY;IAC3D,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IACxB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC9C,KAAK,IAAI,IAAI,CAAA;CACd"}
@@ -0,0 +1,3 @@
1
+ import { FilterSchema, UseQueryFiltersReturn } from './types';
2
+ export declare function useQueryFilters<S extends FilterSchema>(schema: S): UseQueryFiltersReturn<S>;
3
+ //# sourceMappingURL=useQueryFilters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useQueryFilters.d.ts","sourceRoot":"","sources":["../src/useQueryFilters.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAuB,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAiCvF,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,MAAM,EAAE,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CA0B3F"}
package/package.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "vue-router-query-sync",
3
- "version": "1.0.1",
4
- "description": "Vue composable for syncing router query params with store",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
3
+ "version": "2.0.0-alpha.2",
4
+ "description": "Reactive, typed view of Vue Router query params with codecs and defaults",
5
+ "type": "module",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "vite build"
9
+ "dev": "vite --config vite.dev.config.ts",
10
+ "build": "vite build",
11
+ "typecheck": "tsc --noEmit",
12
+ "lint": "eslint ."
10
13
  },
11
14
  "exports": {
12
15
  ".": {
13
16
  "types": "./dist/index.d.ts",
14
- "import": "./dist/index.mjs",
15
- "require": "./dist/index.js"
17
+ "import": "./dist/index.mjs"
16
18
  }
17
19
  },
18
20
  "files": [
@@ -35,7 +37,7 @@
35
37
  "license": "MIT",
36
38
  "repository": {
37
39
  "type": "git",
38
- "url": "https://github.com/Ivan-Chikachev/vue-router-query-sync"
40
+ "url": "git+https://github.com/Ivan-Chikachev/vue-router-query-sync.git"
39
41
  },
40
42
  "peerDependencies": {
41
43
  "vue": "^3.3.13",
@@ -43,16 +45,18 @@
43
45
  },
44
46
  "devDependencies": {
45
47
  "vite-plugin-dts": "^4.5.4",
48
+ "@eslint/js": "^9.36.0",
46
49
  "@types/node": "^20.1.0",
47
- "@typescript-eslint/eslint-plugin": "^8.4.0",
48
50
  "@vitejs/plugin-vue": "^5.2.3",
49
- "@vue/eslint-config-typescript": "^12.0.0",
50
- "eslint": "^8.57.0",
51
+ "eslint": "^9.36.0",
51
52
  "eslint-config-prettier": "^9.1.0",
52
53
  "eslint-plugin-import": "^2.30.0",
53
54
  "eslint-plugin-prettier": "^5.2.1",
54
- "eslint-plugin-vue": "^9.28.0",
55
+ "eslint-plugin-vue": "^9.33.0",
56
+ "globals": "^15.15.0",
57
+ "prettier": "^3.6.2",
55
58
  "typescript": "^5.2.0",
59
+ "typescript-eslint": "^8.45.0",
56
60
  "vite": "^6.3.6"
57
61
  }
58
62
  }
@@ -1,17 +0,0 @@
1
- import { QuerySyncOptions } from '../types';
2
- /**
3
- * Synchronizes a store value with a query parameter in the URL.
4
- *
5
- * @param key - The name of the query parameter, e.g. "tab".
6
- * @param get - A function that returns the current value from the store.
7
- * @param set - A function that updates the value in the store.
8
- * @param options.deps - A list of reactive dependencies that must change before synchronization occurs.
9
- * @param options.context - A unique context identifier, required when multiple instances use the same query key on the same page.
10
- *
11
- * ⚠️ Important:
12
- * If multiple components on the same page use the same query key,
13
- * you must provide a unique `context` to prevent conflicts.
14
- * Alternatively, always use unique query keys (for example, instead of "page", use "usersPage").
15
- */
16
- export declare function useQuerySync<T extends string | number>(key: string, get: () => T | null, set: (val: T) => void, options?: QuerySyncOptions): void;
17
- //# sourceMappingURL=useQuerySync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useQuerySync.d.ts","sourceRoot":"","sources":["../../src/composables/useQuerySync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAgB1C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACpD,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EACnB,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EACrB,OAAO,GAAE,gBAAqB,QAiE/B"}
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- (function(u,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(u=typeof globalThis<"u"?globalThis:u||self,n(u.VueRouterQuerySync={},u.Vue))})(this,(function(u,n){"use strict";let p=null;function m(e){p=e}function Q(){if(!p)throw new Error("[vue-router-query-sync] Router instance not set. Call setRouter(router) before using composables.");return p}let c={};const f=new Set;let R=!1;function l(e,t){const a=Q();t===null?e in c||f.add(e):(c[e]=t,f.delete(e)),R||(R=!0,queueMicrotask(()=>{const d={...a.currentRoute.value.query};f.forEach(i=>{delete d[i]});const q={...d,...c};a.replace({query:q}),c={},f.clear(),R=!1}))}function g(e){if(e==="")return e;const t=Number(e);return isNaN(t)?e:t}function T(e,t,a,d={}){const i=Q().currentRoute,{deps:v=[],context:b}=d,r=b?`${b}_${e}`:e,S=(o,y=!1)=>{if(typeof o=="string"){const s=g(o);if(y||s!==t()){a(s);const h=t();h!==s&&h!==null&&l(r,h)}}else if(o===void 0){const s=t();s!==null&&l(r,s)}},M=o=>{const y=i.value.query[r];if(o===null)y!==void 0&&l(r,null);else{const s=String(o);y!==s&&l(r,o)}};n.onBeforeMount(()=>{v.length>0?n.watch(v,()=>S(i.value.query[r])):S(i.value.query[r])}),n.watch(t,M),n.watch(()=>i.value.query[r],o=>S(o)),n.onBeforeUnmount(()=>{l(r,null)})}const w={install(e,t){m(t.router)}};u.default=w,u.getRouter=Q,u.setRouter=m,u.useQuerySync=T,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/dist/router.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import { Router } from 'vue-router';
2
- export declare function setRouter(router: Router): void;
3
- export declare function getRouter(): Router;
4
- //# sourceMappingURL=router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAIxC,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,QAEvC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAOlC"}
@@ -1,6 +0,0 @@
1
- import { Ref } from 'vue';
2
- export type QuerySyncOptions = {
3
- deps?: Ref<unknown>[];
4
- context?: string;
5
- };
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA"}
@@ -1,2 +0,0 @@
1
- export default function replaceRouterQueue(key: string, value: string | number | null): void;
2
- //# sourceMappingURL=replaceRouterQueue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"replaceRouterQueue.d.ts","sourceRoot":"","sources":["../../src/utils/replaceRouterQueue.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,QAiCpF"}