vue3-router-tab 1.0.9 → 1.1.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.
package/lib/pinia.ts DELETED
@@ -1,149 +0,0 @@
1
- import { defineStore, type StoreDefinition } from 'pinia'
2
- import { onMounted, ref, watch } from 'vue'
3
- import type { RouteLocationRaw } from 'vue-router'
4
- import { useRouterTabs } from './useRouterTabs'
5
- import type { RouterTabsSnapshot } from './core/types'
6
-
7
- export interface RouterTabsPiniaOptions {
8
- /** Pinia store id. Defaults to 'routerTabs'. */
9
- storeId?: string
10
- /** Storage key used when persisting snapshots. Defaults to 'router-tabs:persistent'. */
11
- storageKey?: string
12
- /** Custom storage implementation (e.g. localStorage, sessionStorage). Defaults to window.localStorage. */
13
- storage?: Storage | null
14
- /** Fallback route to open when no snapshot exists. Defaults to RouterTab's default route. */
15
- fallbackRoute?: RouteLocationRaw
16
- /** Provide a custom store definition if you want to control persistence yourself. */
17
- store?: StoreDefinition<'routerTabs', { snapshot: RouterTabsSnapshot | null }, {}, { load(): void; setSnapshot(snapshot: RouterTabsSnapshot | null): void; clear(): void }>
18
- }
19
-
20
- const defaultStorageKey = 'router-tabs:persistent'
21
-
22
- function resolveStorage(storage?: Storage | null): Storage | null {
23
- if (typeof window === 'undefined') return null
24
- if (storage === undefined) return window.localStorage ?? null
25
- return storage
26
- }
27
-
28
- function createDefaultStore(options: RouterTabsPiniaOptions) {
29
- const storage = resolveStorage(options.storage)
30
- const key = options.storageKey ?? defaultStorageKey
31
-
32
- return defineStore(options.storeId ?? 'routerTabs', {
33
- state: () => ({
34
- snapshot: null as RouterTabsSnapshot | null
35
- }),
36
- actions: {
37
- load() {
38
- if (!storage || this.snapshot) return
39
- try {
40
- const raw = storage.getItem(key)
41
- if (raw) {
42
- this.snapshot = JSON.parse(raw)
43
- }
44
- } catch (error) {
45
- if (import.meta.env?.DEV) {
46
- console.warn('[RouterTabs] Failed to load snapshot from storage', error)
47
- }
48
- }
49
- },
50
- setSnapshot(snapshot: RouterTabsSnapshot | null) {
51
- this.snapshot = snapshot
52
- if (!storage) return
53
-
54
- try {
55
- if (snapshot && snapshot.tabs.length) {
56
- storage.setItem(key, JSON.stringify(snapshot))
57
- } else {
58
- storage.removeItem(key)
59
- }
60
- } catch (error) {
61
- if (import.meta.env?.DEV) {
62
- console.warn('[RouterTabs] Failed to persist snapshot to storage', error)
63
- }
64
- }
65
- },
66
- clear() {
67
- this.setSnapshot(null)
68
- }
69
- }
70
- })
71
- }
72
-
73
- /**
74
- * Synchronise RouterTab state with a Pinia store so tab snapshots persist across reloads.
75
- *
76
- * ```ts
77
- * const store = useRouterTabsPiniaPersistence()
78
- * ```
79
- */
80
- export function useRouterTabsPiniaPersistence(options: RouterTabsPiniaOptions = {}) {
81
- const Store = options.store ?? createDefaultStore(options)
82
- const store = Store()
83
- const hydrating = ref(false)
84
- let initialized = false
85
-
86
- const attemptSetup = (controller: NonNullable<ReturnType<typeof useRouterTabs>>) => {
87
- if (!controller || initialized) return
88
- initialized = true
89
-
90
- onMounted(async () => {
91
- store.load()
92
- const snapshot = store.snapshot
93
-
94
- if (snapshot && snapshot.tabs?.length) {
95
- try {
96
- hydrating.value = true
97
- await controller.hydrate(snapshot)
98
- } finally {
99
- hydrating.value = false
100
- }
101
- } else {
102
- try {
103
- hydrating.value = true
104
- const fallback = options.fallbackRoute ?? controller.options.defaultRoute
105
- await controller.reset(fallback)
106
- } finally {
107
- hydrating.value = false
108
- }
109
- }
110
-
111
- store.setSnapshot(controller.snapshot())
112
- })
113
-
114
- watch(
115
- () => ({
116
- tabs: controller.tabs.map(tab => ({
117
- to: tab.to,
118
- title: tab.title,
119
- tips: tab.tips,
120
- icon: tab.icon,
121
- tabClass: tab.tabClass,
122
- closable: tab.closable
123
- })),
124
- active: controller.activeId.value
125
- }),
126
- () => {
127
- if (hydrating.value) return
128
- store.setSnapshot(controller.snapshot())
129
- },
130
- { deep: true }
131
- )
132
- }
133
-
134
- const controller = useRouterTabs({ optional: true })
135
- if (controller) {
136
- attemptSetup(controller)
137
- } else {
138
- onMounted(() => {
139
- const lateController = useRouterTabs({ optional: true })
140
- if (lateController) {
141
- attemptSetup(lateController)
142
- } else if (import.meta.env?.DEV) {
143
- console.warn('[RouterTabs] Pinia helper must be used inside <router-tab>.')
144
- }
145
- })
146
- }
147
-
148
- return store
149
- }