@dxtmisha/functional-basic 1.6.3 → 1.6.4

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.
Files changed (2) hide show
  1. package/ai-doc.md +74 -280
  2. package/package.json +1 -1
package/ai-doc.md CHANGED
@@ -1,347 +1,141 @@
1
- This is the basic functional library (@dxtmisha/functional-basic). It contains framework-agnostic algorithms, utilities, and classes.
1
+ # @dxtmisha/functional-basic Reference
2
2
 
3
- ATTENTION FOR VUE ENVIRONMENT:
4
- If you are developing in Vue, ALWAYS look for the required functionality (composables, reactive wrappers) inside the `@dxtmisha/functional` library FIRST.
5
- And ONLY if there is no reactive or Vue-specific analog there, you may use the functionality directly from this library (@dxtmisha/functional-basic).
3
+ Framework-agnostic utility library. **Vue developers MUST search `@dxtmisha/functional` first**; use this ONLY if no reactive/Vue-specific analog exists.
6
4
 
7
- =============================================================================
8
- CLASS STRUCTURE & CODING STANDARDS (RULES FOR AI)
9
- =============================================================================
10
-
11
- To maintain consistency and high industrial quality across the dxt-ui codebase, all TypeScript classes inside `@dxtmisha/functional-basic` must strictly adhere to the following rules regarding structure, member ordering, and styles.
12
-
13
- 1. ORDER OF MEMBERS WITHIN A CLASS
14
- Members in every class MUST be ordered in the following sequence:
15
-
16
- A. Class Properties / Member Variables:
17
- - Placed at the very top of the class body.
18
- - Ordered by visibility: Public first, then Protected, and Private last.
19
- - Within each visibility level, group by logical connection or alphabetically.
20
- - Initialize default values directly on declaration when possible.
21
-
22
- B. Constructor:
23
- - Placed immediately after all property declarations.
24
- - Parameter properties (e.g., `protected url: string`) are allowed to simplify declaration.
25
-
26
- C. Public Methods:
27
- - Placed after the constructor.
28
- - Grouped logically:
29
- 1. Getters, checkers, and status-check methods (e.g., `is*`, `get*`).
30
- 2. Setters and configuration methods (e.g., `set*`).
31
- 3. Core executors and action methods (e.g., `request()`, `fetch()`, `show()`).
32
-
33
- D. Protected Methods:
34
- - Placed after all public methods.
35
- - Contain internal utility and helper logic accessible to subclasses.
36
-
37
- E. Private Methods:
38
- - Placed at the very end of the class.
39
- - Strict encapsulation of internal logic.
40
-
41
- 2. CODING & STYLE CONVENTIONS
42
- - Naming:
43
- * Classes: PascalCase (e.g., `LoadingInstance`).
44
- * Methods & Properties: camelCase (e.g., `registrationEvent`, `registrationList`).
45
- * Constants inside files: UPPER_SNAKE_CASE (e.g., `LOADING_EVENT_NAME`).
46
- - TypeScript Safety:
47
- * Never use `any`. Use generic parameters or `unknown` if the type is dynamic/undefined.
48
- * Explicitly declare return types for ALL public, protected, and private methods (including `void`).
49
- * Use interfaces/types to define structural contracts for complex inputs and outputs.
50
- - SSR Isolation (Server-Side Rendering):
51
- * The library must be fully isomorphic and safe for SSR.
52
- * Avoid storing request-specific state in global/static class properties directly.
53
- * Use `ServerStorage.get('key', () => new Instance())` for request-isolated singletons.
54
- * Use `isDomRuntime()` checks before accessing browser-only APIs like `window`, `document`, or `location`.
5
+ ---
55
6
 
56
- 3. TYPES, INTERFACES, AND ENUMS
57
- - Location: All types, interfaces, and enums must be located in the `src/types` directory if it exists in the project. If the `src/types` directory does not exist, they must be defined in the same file where they are used.
58
- - Naming: All files containing types must have the suffix `Types` in their name (e.g., `*Types.ts` or `*Types.d.ts`).
59
- - Export: All types, interfaces, and enums must be explicitly exported.
60
- - API Types/Schemas: All types and interfaces for working with APIs must be defined/generated using the `@effect/schema` library if it is present in the project's dependencies (if the project is a monorepo, also check root dependencies).
7
+ ## Coding Standards & Class Structure
61
8
 
62
- =============================================================================
63
- DEVELOPER GUIDE: USING `@dxtmisha/functional-basic` AS A LIBRARY
64
- =============================================================================
9
+ ### 1. Class Member Order
10
+ 1. **Properties/Variables**: Top of class, ordered by visibility (`public` -> `protected` -> `private`). Initialize inline if possible.
11
+ 2. **Constructor**: Follows properties. Parameter properties (e.g. `protected url: string`) allowed.
12
+ 3. **Public Methods**:
13
+ 1. Getters, checkers, status methods (`is*`, `get*`).
14
+ 2. Setters & configuration (`set*`).
15
+ 3. Core executors & actions (`request()`, `fetch()`, `show()`).
16
+ 4. **Protected Methods**: Internal helpers for subclasses.
17
+ 5. **Private Methods**: Internal helper logic at the very bottom.
65
18
 
66
- This section contains instructions and code guidelines for AI models on how to import and use the framework-agnostic utilities, classes, and helper functions provided by this library in client packages or applications.
19
+ ### 2. Style & Type Conventions
20
+ - **Naming**: Classes = `PascalCase`, Methods/Properties = `camelCase`, Constants = `UPPER_SNAKE_CASE`.
21
+ - **TypeScript**: No `any` (use `unknown`/generics). Explicit return types on ALL methods (including `void`). Export all types/interfaces. Suffix type files with `Types` (e.g., `*Types.ts`). Use `@effect/schema` for API schemas if present.
22
+ - **SSR Safety**: Isomorphic code. Do not store request-specific state in static/global variables. Use `isDomRuntime()` before accessing `window`/`document`/`location`. Use `ServerStorage.get(key, () => new Instance())` for request-isolated singletons.
67
23
 
68
24
  ---
69
25
 
70
- ### 1. HTTP Client (`Api` and `ApiInstance`)
71
-
72
- The library provides both a static global class `Api` and an instantiable `ApiInstance` wrapper around the native `fetch` API. They support cancellation, caching, interceptors, error handling, and loading states.
26
+ ## API Reference & Examples
73
27
 
74
- #### Configuration
28
+ ### 1. HTTP Client (`Api`, `ApiInstance`, `ApiCache`)
75
29
  ```typescript
76
- import { Api } from '@dxtmisha/functional-basic';
30
+ import { Api, ApiCache } from '@dxtmisha/functional-basic';
77
31
 
78
- // Set base origin and API path
32
+ // Config
79
33
  Api.setOrigin('https://api.example.com');
80
34
  Api.setUrl('/api/v1');
81
-
82
- // Setup global request defaults (e.g., query params sent with every request)
83
35
  Api.setRequestDefault({ client: 'web' });
36
+ Api.setHeaders(() => ({ Authorization: `Bearer ${localStorage.getItem('token') || ''}` }));
84
37
 
85
- // Setup global headers (can pass a callback for dynamic values)
86
- Api.setHeaders(() => ({
87
- Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
88
- }));
89
- ```
38
+ // Interceptors
39
+ Api.setPreparation(async (fetchOpts) => { if (fetchOpts.auth) fetchOpts.headers['X-Auth'] = '1'; });
40
+ Api.setEnd(async (res, fetchOpts) => res.status === 401 ? { reset: true } : {});
90
41
 
91
- #### Making Requests
92
- ```typescript
93
- // Simple request: defaults to GET
94
- const users = await Api.request<User[]>('users');
95
-
96
- // Explicit methods
42
+ // Requests
43
+ const users = await Api.request<User[]>('users'); // default GET
97
44
  const profile = await Api.get<User>({ path: 'profile' });
98
- const updated = await Api.post<User>({
99
- path: 'profile',
100
- request: { name: 'New Name' }, // Request payload
101
- });
102
- ```
103
-
104
- #### Interceptors (Preparation and End Lifecycle Hooks)
105
- ```typescript
106
- // Preparation hook: runs before fetch executes
107
- Api.setPreparation(async (apiFetch) => {
108
- // Can mutate apiFetch settings or inject headers
109
- if (apiFetch.auth) {
110
- apiFetch.headers = { ...apiFetch.headers, 'X-Auth-Required': 'true' };
111
- }
112
- });
113
-
114
- // End hook: runs after response is received
115
- Api.setEnd(async (response, apiFetch) => {
116
- if (response.status === 401) {
117
- // Perform token refresh or trigger sign-out
118
- return { reset: true }; // Resets request/attempts or signals failure
119
- }
120
- return {};
121
- });
122
- ```
123
-
124
- #### Local caching with `ApiCache`
125
- ```typescript
126
- import { ApiCache } from '@dxtmisha/functional-basic';
45
+ const updated = await Api.post<User>({ path: 'profile', request: { name: 'New' } });
127
46
 
128
- // Cache responses client-side
129
- await ApiCache.set('custom-cache-key', data, 60000); // age in ms
130
- const cached = await ApiCache.get<MyDataType>('custom-cache-key');
47
+ // Cache
48
+ await ApiCache.set('key', { data: 1 }, 60000); // ms age
49
+ const cached = await ApiCache.get<{ data: number }>('key');
131
50
  ```
132
51
 
133
- ---
134
-
135
52
  ### 2. State & Storage Management
136
-
137
- The library features SSR-safe classes to manipulate `localStorage`/`sessionStorage`, cookies, and server-side contexts.
138
-
139
- #### `DataStorage` (localStorage / sessionStorage)
140
- Safely wraps storage with optional namespace prefixes, fallback defaults, and expiration cache.
141
53
  ```typescript
142
- import { DataStorage } from '@dxtmisha/functional-basic';
54
+ import { DataStorage, CookieStorage, Cookie, ServerStorage } from '@dxtmisha/functional-basic';
143
55
 
144
- // Set global namespace prefix to avoid storage collisions
56
+ // DataStorage (localStorage/sessionStorage)
145
57
  DataStorage.setPrefix('my_app_');
146
-
147
- // Instantiate a persistent storage item (sessionStorage if 2nd arg is true)
148
- const userStorage = new DataStorage<{ id: string }>('user_session', false);
149
-
150
- // Save value
58
+ const userStorage = new DataStorage<{ id: string }>('user_session', false); // true for sessionStorage
151
59
  userStorage.set({ id: '123' });
152
-
153
- // Get value (with default value fallback and optional cache limit in ms)
154
- const user = userStorage.get({ id: 'guest' });
155
-
156
- // Remove item
60
+ const user = userStorage.get({ id: 'guest' }); // fallback default
157
61
  userStorage.remove();
158
- ```
159
62
 
160
- #### `CookieStorage` & `Cookie`
161
- Standard cookie manager.
162
- ```typescript
163
- import { CookieStorage, Cookie } from '@dxtmisha/functional-basic';
164
-
165
- // Global Cookie usage
63
+ // Cookies
166
64
  CookieStorage.set('theme', 'dark', { age: 31536000, secure: true, sameSite: 'lax' });
167
65
  const theme = CookieStorage.get<string>('theme', 'light');
168
66
  CookieStorage.remove('theme');
169
67
 
170
- // Instance-based Cookie manager
171
68
  const tokenCookie = new Cookie<string>('auth_token');
172
69
  tokenCookie.set('xyz123', { secure: true });
173
70
  const token = tokenCookie.get();
174
- ```
175
-
176
- #### `ServerStorage` (SSR Request-Isolated Storage)
177
- Used to share and isolate singleton states safely across concurrent asynchronous server-side render requests.
178
- ```typescript
179
- import { ServerStorage } from '@dxtmisha/functional-basic';
180
71
 
181
- // Fetch or create a request-isolated instance singleton
182
- const myServiceInstance = ServerStorage.get('myService', () => new MyService());
72
+ // SSR Request-Isolated Storage
73
+ const myService = ServerStorage.get('myService', () => new MyService());
183
74
  ```
184
75
 
185
- ---
186
-
187
- ### 3. Geolocation & Localization (`GeoIntl`, `Geo`, `GeoFlag`, `GeoPhone`)
188
-
189
- Standardizes localization using the native browser/Node `Intl` API.
190
-
191
- #### `Geo`
192
- Used to track and modify country, language, standard, and timezone information.
76
+ ### 3. Geolocation & Localization
193
77
  ```typescript
194
- import { Geo } from '@dxtmisha/functional-basic';
195
-
196
- // Get current geo details
197
- const currentCountry = Geo.getCountry(); // e.g., 'VN'
198
- const currentLang = Geo.getLanguage(); // e.g., 'vi'
78
+ import { Geo, GeoIntl, GeoFlag, GeoPhone } from '@dxtmisha/functional-basic';
199
79
 
200
- // Change locale configuration
80
+ // Geo state
81
+ const country = Geo.getCountry(); // e.g., 'VN'
82
+ const lang = Geo.getLanguage(); // e.g., 'vi'
201
83
  Geo.set('en-US');
202
- ```
203
-
204
- #### `GeoIntl`
205
- Used for localized numbers, currencies, percentages, dates, relative times, and file sizes.
206
- ```typescript
207
- import { GeoIntl } from '@dxtmisha/functional-basic';
208
84
 
85
+ // Formatters (Intl)
209
86
  const intl = new GeoIntl('en-US');
210
-
211
- // Numbers
212
- intl.number(123456.78); // '123,456.78'
213
-
214
- // Currencies
215
- intl.currency(99.99, 'USD'); // '$99.99'
216
-
217
- // File Sizes
218
- intl.sizeFile(1024 * 1024 * 5); // '5.00 MB'
219
-
220
- // Dates & Time
221
- intl.date(new Date(), 'date'); // 'Jun 18, 2026'
222
- intl.date(new Date(), 'time'); // '10:48 PM'
223
-
224
- // Relative time formatting
87
+ intl.number(123456.78); // '123,456.78'
88
+ intl.currency(99.99, 'USD'); // '$99.99'
89
+ intl.sizeFile(1024 * 1024 * 5); // '5.00 MB'
90
+ intl.date(new Date(), 'date'); // 'Jun 18, 2026'
91
+ intl.date(new Date(), 'time'); // '10:48 PM'
225
92
  intl.relative(new Date(Date.now() - 3600000)); // '1 hour ago'
93
+ intl.plural(3, 'apple|apples'); // '3 apples' ('one|other' or 'one|few|many|other')
226
94
 
227
- // Pluralization rules
228
- // Words are passed as a string delimited by '|' (e.g. 'one|other' or 'one|few|many|other')
229
- intl.plural(3, 'apple|apples'); // '3 apples'
230
- ```
231
-
232
- #### Country Flags (`GeoFlag`) and Phone Masks (`GeoPhone`)
233
- ```typescript
234
- import { GeoFlag, GeoPhone } from '@dxtmisha/functional-basic';
235
-
236
- // Flags
237
- const flagHelper = new GeoFlag();
238
- const flagIcon = flagHelper.getFlag('VN'); // Vietnam flag emoji/svg code
239
-
240
- // Phones
241
- const phoneInfo = GeoPhone.getByPhone('+84900000000');
242
- console.log(phoneInfo.phone); // Cleaned phone string
243
- const mask = GeoPhone.toMask('84900000000'); // Returns formatted phone mask
95
+ // Flags & Phones
96
+ const flag = new GeoFlag().getFlag('VN');
97
+ const phoneInfo = GeoPhone.getByPhone('+84900000000'); // .phone = cleaned string
98
+ const mask = GeoPhone.toMask('84900000000');
244
99
  ```
245
100
 
246
- ---
247
-
248
- ### 4. DOM and Safe Event Management (`EventItem`)
249
-
250
- `EventItem` provides memory-leak proof DOM event management by automating listener binding and unbinding.
251
-
101
+ ### 4. DOM, Safe Events & Helpers
252
102
  ```typescript
253
- import { EventItem } from '@dxtmisha/functional-basic';
254
-
255
- // Initialize the event listener (attached to element selector or Window)
256
- const clickListener = new EventItem(
257
- window,
258
- 'click',
259
- (event) => {
260
- console.log('Window clicked', event);
261
- },
262
- { passive: true }
263
- );
103
+ import { EventItem, goScrollSmooth, writeClipboardData, getClipboardData } from '@dxtmisha/functional-basic';
264
104
 
265
- // Start listening
105
+ // Leak-proof Event management
106
+ const clickListener = new EventItem(window, 'click', (e) => console.log(e), { passive: true });
266
107
  clickListener.start();
108
+ clickListener.stop(); // Call on destroy/cleanup!
267
109
 
268
- // Stop listening (always call when cleaning up/destroying component contexts!)
269
- clickListener.stop();
270
- ```
271
-
272
- #### Scrolling & Clipboard Helpers
273
- ```typescript
274
- import { goScrollSmooth, writeClipboardData, getClipboardData } from '@dxtmisha/functional-basic';
275
-
276
- // Scroll element into view smoothly
110
+ // DOM / Clipboard
277
111
  goScrollSmooth(document.getElementById('target'));
278
-
279
- // Copy text to clipboard
280
- await writeClipboardData('Text to copy');
281
-
282
- // Read from clipboard
112
+ await writeClipboardData('text');
283
113
  const text = await getClipboardData();
284
114
  ```
285
115
 
286
- ---
287
-
288
116
  ### 5. Search & Formatting Utilities
289
-
290
- #### `SearchList`
291
- A highly-optimized client-side text searching class featuring search highlights.
292
- ```typescript
293
- import { SearchList } from '@dxtmisha/functional-basic';
294
-
295
- const users = [
296
- { name: 'John Doe', email: 'john@example.com' },
297
- { name: 'Jane Smith', email: 'jane@example.com' },
298
- ];
299
-
300
- // Instantiation: items, fields to search in, current search query, search options
301
- const searcher = new SearchList(users, ['name', 'email'], 'john');
302
-
303
- // Execute and retrieve filtered results with highlight match markup
304
- const results = searcher.to();
305
- // returns: Array of results with exact matching highlights in matching keys
306
- ```
307
-
308
- #### `Formatters`
309
- Automates schema-based transformations of structured lists or objects.
310
117
  ```typescript
311
- import { Formatters, FormattersType } from '@dxtmisha/functional-basic';
118
+ import { SearchList, Formatters, FormattersType } from '@dxtmisha/functional-basic';
312
119
 
313
- const rawData = { price: 12000, date: '2026-06-18' };
120
+ // Search List with highlights
121
+ const searcher = new SearchList([{ name: 'John Doe' }], ['name'], 'john');
122
+ const results = searcher.to(); // returns matching items with highlighted markup in matching keys
314
123
 
124
+ // Object Formatter
315
125
  const formatter = new Formatters({
316
126
  price: { type: FormattersType.currency, options: 'USD' },
317
127
  date: { type: FormattersType.date, options: { month: 'long', year: 'numeric' } }
318
- }, rawData);
319
-
320
- const formatted = formatter.to();
321
- // { price: '$12,000.00', date: 'June 2026' }
128
+ }, { price: 12000, date: '2026-06-18' });
129
+ const formatted = formatter.to(); // { price: '$12,000.00', date: 'June 2026' }
322
130
  ```
323
131
 
324
- ---
325
-
326
- ### 6. General Utility Functions
327
-
328
- Core lightweight utilities:
329
- - `isFilled(value)`: Checks if string, array, object, boolean or number has filled content. Returns `false` for `[]`, `{}`, `''`, `null`, `undefined`.
330
- - `isDomRuntime()`: Safe isomorphic environment check. Returns `true` if code is running in a browser runtime.
331
- - `copyObject(value)`: Performs a quick, deep object clone.
332
- - `anyToString(value)`: Converts any type to its clean string representation.
333
- - `sleep(ms)`: Promisified setTimeout wrapper for async delay.
334
-
132
+ ### 6. General Helpers
335
133
  ```typescript
336
- import { isFilled, isDomRuntime, copyObject, sleep } from '@dxtmisha/functional-basic';
337
-
338
- if (isDomRuntime()) {
339
- console.log('Running in browser');
340
- }
341
-
342
- if (isFilled(myArray)) {
343
- const cloned = copyObject(myArray);
344
- }
134
+ import { isFilled, isDomRuntime, copyObject, anyToString, sleep } from '@dxtmisha/functional-basic';
345
135
 
136
+ isFilled([]); // false (works for strings, arrays, objects, numbers, booleans)
137
+ isDomRuntime(); // true if in browser
138
+ const cloned = copyObject({ a: 1 });
139
+ const str = anyToString(123);
346
140
  await sleep(500);
347
141
  ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dxtmisha/functional-basic",
3
3
  "private": false,
4
- "version": "1.6.3",
4
+ "version": "1.6.4",
5
5
  "type": "module",
6
6
  "description": "Foundational utility library for modern web development — HTTP client, geolocation, i18n, SEO meta tags, caching, storage, DOM utilities, and more. Framework-agnostic, zero dependencies, TypeScript-first.",
7
7
  "keywords": [