@dxtmisha/wiki 0.24.0 → 0.24.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.
@@ -0,0 +1,248 @@
1
+ import {Meta} from '@storybook/addon-docs/blocks'
2
+
3
+ <Meta title='@dxtmisha/functional/en/Composables/useSessionRef'/>
4
+
5
+ # Composable useSessionRef
6
+
7
+ Composable for creating a reactive variable synchronized with sessionStorage. Automatically manages reading and writing values to browser session storage with singleton pattern. Data persists only within the current tab/window and is deleted when it closes.
8
+
9
+ ## Key Features
10
+
11
+ - **Two-way synchronization** — automatic sync between ref and sessionStorage
12
+ - **Automatic persistence** — ref changes automatically saved to sessionStorage
13
+ - **Tab isolation** — data not synchronized between tabs (unlike localStorage)
14
+ - **Temporary storage** — data deleted when tab/browser closes
15
+ - **Singleton pattern** — reuses ref for same keys
16
+ - **Type safety** — full TypeScript support with generics
17
+ - **Default values** — supports initial values and factory functions
18
+ - **DataStorage integration** — uses DataStorage class for storage management
19
+
20
+ ## Function
21
+
22
+ ### `useSessionRef`
23
+
24
+ Creates a reactive variable synchronized with sessionStorage.
25
+
26
+ **Parameters:**
27
+ - `name: string` — key name in sessionStorage
28
+ - `defaultValue?: T | (() => T)` — default value or function to generate it (optional)
29
+
30
+ **Returns:** `Ref<T | undefined>` — Vue reactive variable linked to sessionStorage
31
+
32
+ ```javascript
33
+ import { useSessionRef } from '@dxtmisha/functional'
34
+
35
+ // Simple usage
36
+ const wizardStep = useSessionRef('wizard-step')
37
+
38
+ // With default value
39
+ const currentStep = useSessionRef('current-step', 1)
40
+
41
+ // With factory function
42
+ const sessionId = useSessionRef('session-id', () => Math.random().toString(36))
43
+ ```
44
+
45
+ ## Basic Usage
46
+
47
+ ### Basic Synchronization
48
+
49
+ ```javascript
50
+ import { useSessionRef } from '@dxtmisha/functional'
51
+
52
+ // Create ref synchronized with sessionStorage
53
+ const wizardProgress = useSessionRef('wizard-progress', { step: 1 })
54
+
55
+ // When ref changes - sessionStorage automatically updates
56
+ wizardProgress.value = { step: 2, data: { name: 'John' } }
57
+
58
+ // On page reload (in same tab) value is restored
59
+ console.log(wizardProgress.value) // { step: 2, data: { name: 'John' } }
60
+
61
+ // When tab closes, data is deleted
62
+ ```
63
+
64
+ ### Singleton Pattern
65
+
66
+ ```javascript
67
+ // Repeated calls with same name return existing ref
68
+ const step1 = useSessionRef('wizard-step', 1)
69
+ const step2 = useSessionRef('wizard-step', 2)
70
+
71
+ console.log(step1 === step2) // true - same ref
72
+
73
+ step1.value = 3
74
+ console.log(step2.value) // 3 - both point to same ref
75
+ ```
76
+
77
+ ## Usage in Components
78
+
79
+ ### Multi-step Wizard
80
+
81
+ ```javascript
82
+ import { useSessionRef } from '@dxtmisha/functional'
83
+
84
+ export default {
85
+ setup() {
86
+ const currentStep = useSessionRef('wizard-step', 1)
87
+ const formData = useSessionRef('wizard-data', {
88
+ name: '',
89
+ email: '',
90
+ phone: ''
91
+ })
92
+
93
+ const nextStep = () => {
94
+ currentStep.value++
95
+ }
96
+
97
+ const prevStep = () => {
98
+ if (currentStep.value > 1) {
99
+ currentStep.value--
100
+ }
101
+ }
102
+
103
+ return {
104
+ currentStep,
105
+ formData,
106
+ nextStep,
107
+ prevStep
108
+ }
109
+ }
110
+ }
111
+
112
+ // Template:
113
+ // <div>
114
+ // <div v-if="currentStep === 1">
115
+ // <input v-model="formData.name" placeholder="Name" />
116
+ // </div>
117
+ // <div v-if="currentStep === 2">
118
+ // <input v-model="formData.email" placeholder="Email" />
119
+ // </div>
120
+ // <button @click="prevStep">Back</button>
121
+ // <button @click="nextStep">Next</button>
122
+ // </div>
123
+ ```
124
+
125
+ ### Temporary Filter State
126
+
127
+ ```javascript
128
+ import { useSessionRef } from '@dxtmisha/functional'
129
+
130
+ export default {
131
+ setup() {
132
+ const filters = useSessionRef('search-filters', {
133
+ category: 'all',
134
+ priceMin: 0,
135
+ priceMax: 10000,
136
+ sortBy: 'name'
137
+ })
138
+
139
+ const resetFilters = () => {
140
+ filters.value = {
141
+ category: 'all',
142
+ priceMin: 0,
143
+ priceMax: 10000,
144
+ sortBy: 'name'
145
+ }
146
+ }
147
+
148
+ return { filters, resetFilters }
149
+ }
150
+ }
151
+ ```
152
+
153
+ ## Differences from useStorageRef
154
+
155
+ ```javascript
156
+ // useStorageRef - data persists between browser sessions
157
+ const persistentTheme = useStorageRef('theme', 'light')
158
+ // Data remains even after browser closes
159
+
160
+ // useSessionRef - data deleted when tab closes
161
+ const temporaryFilters = useSessionRef('filters', {})
162
+ // Data deleted when tab/browser closes
163
+
164
+ // useStorageRef syncs between tabs
165
+ // useSessionRef isolated per tab
166
+ ```
167
+
168
+ ## Working with Data Types
169
+
170
+ ```javascript
171
+ // Numbers
172
+ const step = useSessionRef<number>('step', 1)
173
+ step.value = 2
174
+
175
+ // Booleans
176
+ const isCompleted = useSessionRef<boolean>('completed', false)
177
+ isCompleted.value = true
178
+
179
+ // Objects
180
+ const wizardData = useSessionRef('wizard-data', {
181
+ step: 1,
182
+ userData: {},
183
+ timestamp: Date.now()
184
+ })
185
+
186
+ // Arrays
187
+ const selectedItems = useSessionRef<number[]>('selected', [])
188
+ selectedItems.value.push(42)
189
+ ```
190
+
191
+ ## Usage Examples
192
+
193
+ ### Form Progress Persistence
194
+
195
+ ```javascript
196
+ const registrationForm = useSessionRef('registration', {
197
+ step: 1,
198
+ personal: { name: '', email: '' },
199
+ address: { street: '', city: '' },
200
+ completed: false
201
+ })
202
+
203
+ // Data saved as form is filled
204
+ registrationForm.value.personal.name = 'John'
205
+ registrationForm.value.step = 2
206
+
207
+ // On page reload (F5) data is restored
208
+ // On tab close - everything is deleted
209
+ ```
210
+
211
+ ### Temporary Modal State
212
+
213
+ ```javascript
214
+ const modalState = useSessionRef('modal', {
215
+ isOpen: false,
216
+ activeTab: 'details',
217
+ scrollPosition: 0
218
+ })
219
+
220
+ const openModal = () => {
221
+ modalState.value.isOpen = true
222
+ }
223
+
224
+ const closeModal = () => {
225
+ modalState.value.isOpen = false
226
+ }
227
+ ```
228
+
229
+ ### Shopping Cart (Temporary)
230
+
231
+ ```javascript
232
+ const cart = useSessionRef<CartItem[]>('temp-cart', [])
233
+
234
+ const addToCart = (item: CartItem) => {
235
+ cart.value = [...cart.value, item]
236
+ }
237
+
238
+ const removeFromCart = (itemId: number) => {
239
+ cart.value = cart.value.filter(item => item.id !== itemId)
240
+ }
241
+
242
+ const clearCart = () => {
243
+ cart.value = []
244
+ }
245
+
246
+ // Cart is automatically cleared when tab closes
247
+ ```
248
+
@@ -0,0 +1,242 @@
1
+ import {Meta} from '@storybook/addon-docs/blocks'
2
+
3
+ <Meta title='@dxtmisha/functional/en/Composables/useStorageRef'/>
4
+
5
+ # Composable useStorageRef
6
+
7
+ Composable for creating a reactive variable synchronized with localStorage. Automatically manages reading and writing values to browser local storage with caching support, cross-tab synchronization, and singleton pattern for efficient reuse.
8
+
9
+ ## Key Features
10
+
11
+ - **Two-way synchronization** — automatic sync between ref and localStorage
12
+ - **Automatic persistence** — ref changes automatically saved to localStorage
13
+ - **Caching with TTL** — optional cache lifetime in seconds
14
+ - **Cross-tab synchronization** — automatic updates when changes occur in other tabs
15
+ - **Singleton pattern** — reuses ref for same keys
16
+ - **Type safety** — full TypeScript support with generics
17
+ - **Default values** — supports initial values and factory functions
18
+ - **DataStorage integration** — uses DataStorage class for storage management
19
+
20
+ ## Function
21
+
22
+ ### `useStorageRef`
23
+
24
+ Creates a reactive variable synchronized with localStorage.
25
+
26
+ **Parameters:**
27
+ - `name: string` — key name in localStorage
28
+ - `defaultValue?: T | (() => T)` — default value or function to generate it (optional)
29
+ - `cache?: number` — cache time in seconds (optional)
30
+
31
+ **Returns:** `Ref<T | undefined>` — Vue reactive variable linked to localStorage
32
+
33
+ ```javascript
34
+ import { useStorageRef } from '@dxtmisha/functional'
35
+
36
+ // Simple usage
37
+ const theme = useStorageRef('app-theme')
38
+
39
+ // With default value
40
+ const language = useStorageRef('app-language', 'en')
41
+
42
+ // With factory function
43
+ const userId = useStorageRef('user-id', () => Math.random().toString(36))
44
+
45
+ // With caching (600 seconds = 10 minutes)
46
+ const cachedData = useStorageRef('cached-data', null, 600)
47
+ ```
48
+
49
+ ## Basic Usage
50
+
51
+ ### Basic Synchronization
52
+
53
+ ```javascript
54
+ import { useStorageRef } from '@dxtmisha/functional'
55
+
56
+ // Create ref synchronized with localStorage
57
+ const userTheme = useStorageRef('theme', 'light')
58
+
59
+ // When ref changes - localStorage automatically updates
60
+ userTheme.value = 'dark'
61
+ // localStorage: { 'ui-storage__theme': '{"value":"dark","age":1234567890}' }
62
+
63
+ // On page reload, value is restored
64
+ console.log(userTheme.value) // 'dark'
65
+ ```
66
+
67
+ ### Singleton Pattern
68
+
69
+ ```javascript
70
+ // Repeated calls with same name return existing ref
71
+ const theme1 = useStorageRef('app-theme', 'light')
72
+ const theme2 = useStorageRef('app-theme', 'dark')
73
+
74
+ console.log(theme1 === theme2) // true - same ref
75
+
76
+ theme1.value = 'blue'
77
+ console.log(theme2.value) // 'blue' - both point to same ref
78
+ ```
79
+
80
+ ## Usage in Components
81
+
82
+ ### User Settings
83
+
84
+ ```javascript
85
+ import { useStorageRef } from '@dxtmisha/functional'
86
+
87
+ export default {
88
+ setup() {
89
+ const theme = useStorageRef('user-theme', 'light')
90
+ const fontSize = useStorageRef('font-size', 16)
91
+ const notifications = useStorageRef('notifications', true)
92
+
93
+ return {
94
+ theme,
95
+ fontSize,
96
+ notifications
97
+ }
98
+ }
99
+ }
100
+
101
+ // Template:
102
+ // <div>
103
+ // <select v-model="theme">
104
+ // <option value="light">Light</option>
105
+ // <option value="dark">Dark</option>
106
+ // </select>
107
+ // <input v-model.number="fontSize" type="number" />
108
+ // <input v-model="notifications" type="checkbox" />
109
+ // </div>
110
+ ```
111
+
112
+ ### API Data Caching
113
+
114
+ ```javascript
115
+ import { useStorageRef } from '@dxtmisha/functional'
116
+
117
+ export default {
118
+ setup() {
119
+ // Cache for 10 minutes (600 seconds)
120
+ const userData = useStorageRef('user-data', null, 600)
121
+
122
+ const loadUserData = async () => {
123
+ if (userData.value) {
124
+ console.log('Data from cache')
125
+ return userData.value
126
+ }
127
+
128
+ console.log('Loading from server')
129
+ const response = await fetch('/api/user')
130
+ userData.value = await response.json()
131
+ return userData.value
132
+ }
133
+
134
+ return { userData, loadUserData }
135
+ }
136
+ }
137
+ ```
138
+
139
+ ## Cross-tab Synchronization
140
+
141
+ ```javascript
142
+ import { useStorageRef } from '@dxtmisha/functional'
143
+
144
+ // In first tab
145
+ const counter = useStorageRef('counter', 0)
146
+ counter.value = 5
147
+
148
+ // In second tab automatically updates
149
+ // counter.value === 5 (thanks to storage event)
150
+
151
+ // In third tab
152
+ const sameCounter = useStorageRef('counter', 0)
153
+ console.log(sameCounter.value) // 5
154
+
155
+ // Changes in any tab update all others
156
+ sameCounter.value = 10
157
+ // All open tabs will have counter.value === 10
158
+ ```
159
+
160
+ ## Working with Data Types
161
+
162
+ ```javascript
163
+ // Numbers
164
+ const count = useStorageRef<number>('count', 0)
165
+ count.value = 42
166
+
167
+ // Booleans
168
+ const isActive = useStorageRef<boolean>('active', false)
169
+ isActive.value = true
170
+
171
+ // Objects
172
+ const settings = useStorageRef('settings', {
173
+ theme: 'dark',
174
+ language: 'en',
175
+ notifications: true
176
+ })
177
+ settings.value.theme = 'light'
178
+
179
+ // Arrays
180
+ const items = useStorageRef<string[]>('items', [])
181
+ items.value.push('new item')
182
+ ```
183
+
184
+ ## Usage Examples
185
+
186
+ ### Form State Persistence
187
+
188
+ ```javascript
189
+ const formData = useStorageRef('contact-form', {
190
+ name: '',
191
+ email: '',
192
+ message: ''
193
+ })
194
+
195
+ // When filling form, data is automatically saved
196
+ formData.value.name = 'John'
197
+ formData.value.email = 'john@example.com'
198
+
199
+ // On page reload, data is restored
200
+ ```
201
+
202
+ ### User Favorites
203
+
204
+ ```javascript
205
+ const favorites = useStorageRef<number[]>('favorites', [])
206
+
207
+ const addToFavorites = (id: number) => {
208
+ if (!favorites.value.includes(id)) {
209
+ favorites.value = [...favorites.value, id]
210
+ }
211
+ }
212
+
213
+ const removeFromFavorites = (id: number) => {
214
+ favorites.value = favorites.value.filter(fav => fav !== id)
215
+ }
216
+ ```
217
+
218
+ ### Cache with Auto-refresh
219
+
220
+ ```javascript
221
+ // Cache for 5 minutes
222
+ const newsData = useStorageRef('news', null, 300)
223
+
224
+ const fetchNews = async () => {
225
+ // If cache is valid - return saved data
226
+ if (newsData.value) return newsData.value
227
+
228
+ // Otherwise load fresh data
229
+ const response = await fetch('/api/news')
230
+ newsData.value = await response.json()
231
+ return newsData.value
232
+ }
233
+
234
+ // First call - loads from server
235
+ await fetchNews()
236
+
237
+ // Subsequent calls within 5 minutes - use cache
238
+ await fetchNews() // From cache
239
+
240
+ // After 5+ minutes - loads from server again
241
+ ```
242
+