@dxtmisha/functional-basic 1.3.12 → 1.3.15
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/CHANGELOG.md +17 -0
- package/ai-description.md +18 -0
- package/ai-doc.md +341 -0
- package/{ai-types.txt → ai-types.md} +357 -171
- package/dist/library.js +33 -12
- package/dist/src/classes/Geo.d.ts +14 -0
- package/dist/src/classes/GeoInstance.d.ts +16 -1
- package/dist/src/types/geoTypes.d.ts +6 -0
- package/package.json +4 -4
- package/ai-description.txt +0 -18
- package/ai-doc.txt +0 -54
package/CHANGELOG.md
CHANGED
|
@@ -2,8 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.3.15] - 2026-06-19
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **GeoInstance**: Introduced `getLocationCountry(): string` and `getLocationLanguage(): string` methods to directly retrieve country and language codes from the current location string.
|
|
9
|
+
- **Geo**: Added static `getLocationCountry()` and `getLocationLanguage()` wrappers.
|
|
10
|
+
- **geoTypes**: Extended `GeoItemFull` interface to include `location`, `locationCountry`, and `locationLanguage` properties.
|
|
11
|
+
|
|
12
|
+
### Changed / Improved
|
|
13
|
+
- **GeoInstance**: Refactored `toFull` helper to populate `location`, `locationCountry`, and `locationLanguage` fields dynamically on the resolved `GeoItemFull`.
|
|
14
|
+
- **GeoInstance**: Re-arranged matching logic order in `getByCode` to prioritize country matching (`getByCountry`) before language matching (`getByLanguage`).
|
|
15
|
+
- **GeoInstance**: Updated `toStandard` method signature to accept an optional `language` override.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- **Tests**: Adjusted `Geo.test.ts` and `GeoIntl.test.ts` fallback expectations to align with the country-first matching behavior (e.g. `'en-VN'` resolving to `vi-VN` / country `'VN'`).
|
|
19
|
+
- **Tests**: Fixed `UrlItem.test.ts` `getInstance` tests to follow the correct argumentless static `UrlItem.getInstance()` API signature.
|
|
20
|
+
|
|
5
21
|
## [1.3.11] - 2026-06-18
|
|
6
22
|
|
|
23
|
+
|
|
7
24
|
### Changed / Improved
|
|
8
25
|
- **ErrorCenterHandler**: Integrated server-side error stack tracing (`console.trace`) when logging causes in non-browser (SSR) environments.
|
|
9
26
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Core Purpose: This library provides a comprehensive, isomorphic toolkit for web applications, specifically focusing on SSR-ready API interaction, state-consistent storage (Cookies, Local/SessionStorage, ServerStorage), internationalization (i18n), and robust DOM event/UI management.
|
|
2
|
+
|
|
3
|
+
Key Expositions:
|
|
4
|
+
- Api: Centralized HTTP client managing requests, hydration, caching (ApiCache), and centralized error handling (ApiErrorStorage).
|
|
5
|
+
- Storage: Persistent utilities including DataStorage (local/session), CookieStorage, and ServerStorage (SSR-aware).
|
|
6
|
+
- Geo & Locale: GeoInstance, GeoIntl, and GeoFlag provide location-aware formatting (currencies, dates, numbers, units, phone masks).
|
|
7
|
+
- UI/Utility: Meta management (Meta, MetaOg, MetaTwitter), event handling (EventItem), icon management (Icons), and search utilities (SearchList).
|
|
8
|
+
- Formatting: Formatters class for templated data manipulation (currency, date, pluralization, unit conversion).
|
|
9
|
+
|
|
10
|
+
Triggers for Studying ai-types.md:
|
|
11
|
+
- When implementing API integration (Api, ApiFetch, ApiMethod).
|
|
12
|
+
- When configuring global error handling (ErrorCenter, ApiError).
|
|
13
|
+
- When managing SSR state or hydration (ServerStorage, ApiHydration).
|
|
14
|
+
- When handling localization (Geo, GeoIntl, Translate, Formatters).
|
|
15
|
+
- When configuring complex data search logic (SearchList, SearchColumns).
|
|
16
|
+
- When defining custom meta-tags or Twitter/Open Graph cards (Meta, MetaOg, MetaTwitter).
|
|
17
|
+
|
|
18
|
+
Integration Context: This library acts as a foundational service layer. It is designed to be injected or used as a singleton across the application stack, bridging client-side DOM operations with server-side context in SSR frameworks. It manages the lifecycle of data, authentication headers, and global configuration, serving as an abstraction layer over native Browser/Node.js APIs like fetch, Cookies, and BroadcastChannel.
|
package/ai-doc.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
This is the basic functional library (@dxtmisha/functional-basic). It contains framework-agnostic algorithms, utilities, and classes.
|
|
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).
|
|
6
|
+
|
|
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`.
|
|
55
|
+
|
|
56
|
+
=============================================================================
|
|
57
|
+
DEVELOPER GUIDE: USING `@dxtmisha/functional-basic` AS A LIBRARY
|
|
58
|
+
=============================================================================
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### 1. HTTP Client (`Api` and `ApiInstance`)
|
|
65
|
+
|
|
66
|
+
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.
|
|
67
|
+
|
|
68
|
+
#### Configuration
|
|
69
|
+
```typescript
|
|
70
|
+
import { Api } from '@dxtmisha/functional-basic';
|
|
71
|
+
|
|
72
|
+
// Set base origin and API path
|
|
73
|
+
Api.setOrigin('https://api.example.com');
|
|
74
|
+
Api.setUrl('/api/v1');
|
|
75
|
+
|
|
76
|
+
// Setup global request defaults (e.g., query params sent with every request)
|
|
77
|
+
Api.setRequestDefault({ client: 'web' });
|
|
78
|
+
|
|
79
|
+
// Setup global headers (can pass a callback for dynamic values)
|
|
80
|
+
Api.setHeaders(() => ({
|
|
81
|
+
Authorization: `Bearer ${localStorage.getItem('token') || ''}`,
|
|
82
|
+
}));
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Making Requests
|
|
86
|
+
```typescript
|
|
87
|
+
// Simple request: defaults to GET
|
|
88
|
+
const users = await Api.request<User[]>('users');
|
|
89
|
+
|
|
90
|
+
// Explicit methods
|
|
91
|
+
const profile = await Api.get<User>({ path: 'profile' });
|
|
92
|
+
const updated = await Api.post<User>({
|
|
93
|
+
path: 'profile',
|
|
94
|
+
request: { name: 'New Name' }, // Request payload
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Interceptors (Preparation and End Lifecycle Hooks)
|
|
99
|
+
```typescript
|
|
100
|
+
// Preparation hook: runs before fetch executes
|
|
101
|
+
Api.setPreparation(async (apiFetch) => {
|
|
102
|
+
// Can mutate apiFetch settings or inject headers
|
|
103
|
+
if (apiFetch.auth) {
|
|
104
|
+
apiFetch.headers = { ...apiFetch.headers, 'X-Auth-Required': 'true' };
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// End hook: runs after response is received
|
|
109
|
+
Api.setEnd(async (response, apiFetch) => {
|
|
110
|
+
if (response.status === 401) {
|
|
111
|
+
// Perform token refresh or trigger sign-out
|
|
112
|
+
return { reset: true }; // Resets request/attempts or signals failure
|
|
113
|
+
}
|
|
114
|
+
return {};
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Local caching with `ApiCache`
|
|
119
|
+
```typescript
|
|
120
|
+
import { ApiCache } from '@dxtmisha/functional-basic';
|
|
121
|
+
|
|
122
|
+
// Cache responses client-side
|
|
123
|
+
await ApiCache.set('custom-cache-key', data, 60000); // age in ms
|
|
124
|
+
const cached = await ApiCache.get<MyDataType>('custom-cache-key');
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### 2. State & Storage Management
|
|
130
|
+
|
|
131
|
+
The library features SSR-safe classes to manipulate `localStorage`/`sessionStorage`, cookies, and server-side contexts.
|
|
132
|
+
|
|
133
|
+
#### `DataStorage` (localStorage / sessionStorage)
|
|
134
|
+
Safely wraps storage with optional namespace prefixes, fallback defaults, and expiration cache.
|
|
135
|
+
```typescript
|
|
136
|
+
import { DataStorage } from '@dxtmisha/functional-basic';
|
|
137
|
+
|
|
138
|
+
// Set global namespace prefix to avoid storage collisions
|
|
139
|
+
DataStorage.setPrefix('my_app_');
|
|
140
|
+
|
|
141
|
+
// Instantiate a persistent storage item (sessionStorage if 2nd arg is true)
|
|
142
|
+
const userStorage = new DataStorage<{ id: string }>('user_session', false);
|
|
143
|
+
|
|
144
|
+
// Save value
|
|
145
|
+
userStorage.set({ id: '123' });
|
|
146
|
+
|
|
147
|
+
// Get value (with default value fallback and optional cache limit in ms)
|
|
148
|
+
const user = userStorage.get({ id: 'guest' });
|
|
149
|
+
|
|
150
|
+
// Remove item
|
|
151
|
+
userStorage.remove();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### `CookieStorage` & `Cookie`
|
|
155
|
+
Standard cookie manager.
|
|
156
|
+
```typescript
|
|
157
|
+
import { CookieStorage, Cookie } from '@dxtmisha/functional-basic';
|
|
158
|
+
|
|
159
|
+
// Global Cookie usage
|
|
160
|
+
CookieStorage.set('theme', 'dark', { age: 31536000, secure: true, sameSite: 'lax' });
|
|
161
|
+
const theme = CookieStorage.get<string>('theme', 'light');
|
|
162
|
+
CookieStorage.remove('theme');
|
|
163
|
+
|
|
164
|
+
// Instance-based Cookie manager
|
|
165
|
+
const tokenCookie = new Cookie<string>('auth_token');
|
|
166
|
+
tokenCookie.set('xyz123', { secure: true });
|
|
167
|
+
const token = tokenCookie.get();
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### `ServerStorage` (SSR Request-Isolated Storage)
|
|
171
|
+
Used to share and isolate singleton states safely across concurrent asynchronous server-side render requests.
|
|
172
|
+
```typescript
|
|
173
|
+
import { ServerStorage } from '@dxtmisha/functional-basic';
|
|
174
|
+
|
|
175
|
+
// Fetch or create a request-isolated instance singleton
|
|
176
|
+
const myServiceInstance = ServerStorage.get('myService', () => new MyService());
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### 3. Geolocation & Localization (`GeoIntl`, `Geo`, `GeoFlag`, `GeoPhone`)
|
|
182
|
+
|
|
183
|
+
Standardizes localization using the native browser/Node `Intl` API.
|
|
184
|
+
|
|
185
|
+
#### `Geo`
|
|
186
|
+
Used to track and modify country, language, standard, and timezone information.
|
|
187
|
+
```typescript
|
|
188
|
+
import { Geo } from '@dxtmisha/functional-basic';
|
|
189
|
+
|
|
190
|
+
// Get current geo details
|
|
191
|
+
const currentCountry = Geo.getCountry(); // e.g., 'VN'
|
|
192
|
+
const currentLang = Geo.getLanguage(); // e.g., 'vi'
|
|
193
|
+
|
|
194
|
+
// Change locale configuration
|
|
195
|
+
Geo.set('en-US');
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### `GeoIntl`
|
|
199
|
+
Used for localized numbers, currencies, percentages, dates, relative times, and file sizes.
|
|
200
|
+
```typescript
|
|
201
|
+
import { GeoIntl } from '@dxtmisha/functional-basic';
|
|
202
|
+
|
|
203
|
+
const intl = new GeoIntl('en-US');
|
|
204
|
+
|
|
205
|
+
// Numbers
|
|
206
|
+
intl.number(123456.78); // '123,456.78'
|
|
207
|
+
|
|
208
|
+
// Currencies
|
|
209
|
+
intl.currency(99.99, 'USD'); // '$99.99'
|
|
210
|
+
|
|
211
|
+
// File Sizes
|
|
212
|
+
intl.sizeFile(1024 * 1024 * 5); // '5.00 MB'
|
|
213
|
+
|
|
214
|
+
// Dates & Time
|
|
215
|
+
intl.date(new Date(), 'date'); // 'Jun 18, 2026'
|
|
216
|
+
intl.date(new Date(), 'time'); // '10:48 PM'
|
|
217
|
+
|
|
218
|
+
// Relative time formatting
|
|
219
|
+
intl.relative(new Date(Date.now() - 3600000)); // '1 hour ago'
|
|
220
|
+
|
|
221
|
+
// Pluralization rules
|
|
222
|
+
// Words are passed as a string delimited by '|' (e.g. 'one|other' or 'one|few|many|other')
|
|
223
|
+
intl.plural(3, 'apple|apples'); // '3 apples'
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Country Flags (`GeoFlag`) and Phone Masks (`GeoPhone`)
|
|
227
|
+
```typescript
|
|
228
|
+
import { GeoFlag, GeoPhone } from '@dxtmisha/functional-basic';
|
|
229
|
+
|
|
230
|
+
// Flags
|
|
231
|
+
const flagHelper = new GeoFlag();
|
|
232
|
+
const flagIcon = flagHelper.getFlag('VN'); // Vietnam flag emoji/svg code
|
|
233
|
+
|
|
234
|
+
// Phones
|
|
235
|
+
const phoneInfo = GeoPhone.getByPhone('+84900000000');
|
|
236
|
+
console.log(phoneInfo.phone); // Cleaned phone string
|
|
237
|
+
const mask = GeoPhone.toMask('84900000000'); // Returns formatted phone mask
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### 4. DOM and Safe Event Management (`EventItem`)
|
|
243
|
+
|
|
244
|
+
`EventItem` provides memory-leak proof DOM event management by automating listener binding and unbinding.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { EventItem } from '@dxtmisha/functional-basic';
|
|
248
|
+
|
|
249
|
+
// Initialize the event listener (attached to element selector or Window)
|
|
250
|
+
const clickListener = new EventItem(
|
|
251
|
+
window,
|
|
252
|
+
'click',
|
|
253
|
+
(event) => {
|
|
254
|
+
console.log('Window clicked', event);
|
|
255
|
+
},
|
|
256
|
+
{ passive: true }
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// Start listening
|
|
260
|
+
clickListener.start();
|
|
261
|
+
|
|
262
|
+
// Stop listening (always call when cleaning up/destroying component contexts!)
|
|
263
|
+
clickListener.stop();
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### Scrolling & Clipboard Helpers
|
|
267
|
+
```typescript
|
|
268
|
+
import { goScrollSmooth, writeClipboardData, getClipboardData } from '@dxtmisha/functional-basic';
|
|
269
|
+
|
|
270
|
+
// Scroll element into view smoothly
|
|
271
|
+
goScrollSmooth(document.getElementById('target'));
|
|
272
|
+
|
|
273
|
+
// Copy text to clipboard
|
|
274
|
+
await writeClipboardData('Text to copy');
|
|
275
|
+
|
|
276
|
+
// Read from clipboard
|
|
277
|
+
const text = await getClipboardData();
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### 5. Search & Formatting Utilities
|
|
283
|
+
|
|
284
|
+
#### `SearchList`
|
|
285
|
+
A highly-optimized client-side text searching class featuring search highlights.
|
|
286
|
+
```typescript
|
|
287
|
+
import { SearchList } from '@dxtmisha/functional-basic';
|
|
288
|
+
|
|
289
|
+
const users = [
|
|
290
|
+
{ name: 'John Doe', email: 'john@example.com' },
|
|
291
|
+
{ name: 'Jane Smith', email: 'jane@example.com' },
|
|
292
|
+
];
|
|
293
|
+
|
|
294
|
+
// Instantiation: items, fields to search in, current search query, search options
|
|
295
|
+
const searcher = new SearchList(users, ['name', 'email'], 'john');
|
|
296
|
+
|
|
297
|
+
// Execute and retrieve filtered results with highlight match markup
|
|
298
|
+
const results = searcher.to();
|
|
299
|
+
// returns: Array of results with exact matching highlights in matching keys
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
#### `Formatters`
|
|
303
|
+
Automates schema-based transformations of structured lists or objects.
|
|
304
|
+
```typescript
|
|
305
|
+
import { Formatters, FormattersType } from '@dxtmisha/functional-basic';
|
|
306
|
+
|
|
307
|
+
const rawData = { price: 12000, date: '2026-06-18' };
|
|
308
|
+
|
|
309
|
+
const formatter = new Formatters({
|
|
310
|
+
price: { type: FormattersType.currency, options: 'USD' },
|
|
311
|
+
date: { type: FormattersType.date, options: { month: 'long', year: 'numeric' } }
|
|
312
|
+
}, rawData);
|
|
313
|
+
|
|
314
|
+
const formatted = formatter.to();
|
|
315
|
+
// { price: '$12,000.00', date: 'June 2026' }
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
### 6. General Utility Functions
|
|
321
|
+
|
|
322
|
+
Core lightweight utilities:
|
|
323
|
+
- `isFilled(value)`: Checks if string, array, object, boolean or number has filled content. Returns `false` for `[]`, `{}`, `''`, `null`, `undefined`.
|
|
324
|
+
- `isDomRuntime()`: Safe isomorphic environment check. Returns `true` if code is running in a browser runtime.
|
|
325
|
+
- `copyObject(value)`: Performs a quick, deep object clone.
|
|
326
|
+
- `anyToString(value)`: Converts any type to its clean string representation.
|
|
327
|
+
- `sleep(ms)`: Promisified setTimeout wrapper for async delay.
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
import { isFilled, isDomRuntime, copyObject, sleep } from '@dxtmisha/functional-basic';
|
|
331
|
+
|
|
332
|
+
if (isDomRuntime()) {
|
|
333
|
+
console.log('Running in browser');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (isFilled(myArray)) {
|
|
337
|
+
const cloned = copyObject(myArray);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
await sleep(500);
|
|
341
|
+
```
|