@dxtmisha/wiki 0.39.7 → 0.39.8
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/dist/{defineProperty-DblGXmzD.js → defineProperty-Bjg6wMoX.js} +4 -4
- package/dist/library.js +1 -1
- package/dist/media.js +12 -0
- package/dist/storybook.js +1 -1
- package/package.json +1 -1
- package/src/media/functional/functional-basic/api/api.en.mdx +45 -0
- package/src/media/functional/functional-basic/api/api.ru.mdx +45 -0
- package/src/media/functional/functional-basic/api/api.vi.mdx +45 -0
- package/src/media/functional/functional-basic/classes/Api/Api.en.mdx +54 -54
- package/src/media/functional/functional-basic/classes/Api/Api.ru.mdx +54 -54
- package/src/media/functional/functional-basic/classes/Api/Api.vi.mdx +54 -54
- package/src/media/functional/functional-basic/classes/ApiCache/ApiCache.en.mdx +111 -0
- package/src/media/functional/functional-basic/classes/ApiCache/ApiCache.ru.mdx +111 -0
- package/src/media/functional/functional-basic/classes/ApiCache/ApiCache.vi.mdx +111 -0
- package/src/media/functional/functional-basic/classes/ApiDataReturn/ApiDataReturn.en.mdx +32 -0
- package/src/media/functional/functional-basic/classes/ApiDataReturn/ApiDataReturn.ru.mdx +32 -0
- package/src/media/functional/functional-basic/classes/ApiDataReturn/ApiDataReturn.vi.mdx +32 -0
- package/src/media/functional/functional-basic/classes/ApiDefault/ApiDefault.en.mdx +24 -28
- package/src/media/functional/functional-basic/classes/ApiDefault/ApiDefault.ru.mdx +24 -28
- package/src/media/functional/functional-basic/classes/ApiDefault/ApiDefault.vi.mdx +24 -28
- package/src/media/functional/functional-basic/classes/ApiHeaders/ApiHeaders.en.mdx +28 -14
- package/src/media/functional/functional-basic/classes/ApiHeaders/ApiHeaders.ru.mdx +33 -19
- package/src/media/functional/functional-basic/classes/ApiHeaders/ApiHeaders.vi.mdx +33 -19
- package/src/media/functional/functional-basic/classes/ApiHydration/ApiHydration.en.mdx +56 -0
- package/src/media/functional/functional-basic/classes/ApiHydration/ApiHydration.ru.mdx +56 -0
- package/src/media/functional/functional-basic/classes/ApiHydration/ApiHydration.vi.mdx +55 -0
- package/src/media/functional/functional-basic/classes/ApiInstance/ApiInstance.en.mdx +101 -49
- package/src/media/functional/functional-basic/classes/ApiInstance/ApiInstance.ru.mdx +101 -49
- package/src/media/functional/functional-basic/classes/ApiInstance/ApiInstance.vi.mdx +98 -47
- package/src/media/functional/functional-basic/classes/ApiPreparation/ApiPreparation.en.mdx +44 -26
- package/src/media/functional/functional-basic/classes/ApiPreparation/ApiPreparation.ru.mdx +45 -27
- package/src/media/functional/functional-basic/classes/ApiPreparation/ApiPreparation.vi.mdx +44 -26
- package/src/media/functional/functional-basic/classes/ApiResponse/ApiResponse.en.mdx +50 -21
- package/src/media/functional/functional-basic/classes/ApiResponse/ApiResponse.ru.mdx +54 -25
- package/src/media/functional/functional-basic/classes/ApiResponse/ApiResponse.vi.mdx +55 -26
- package/src/media/functional/functional-basic/classes/ApiStatus/ApiStatus.en.mdx +29 -32
- package/src/media/functional/functional-basic/classes/ApiStatus/ApiStatus.ru.mdx +33 -36
- package/src/media/functional/functional-basic/classes/ApiStatus/ApiStatus.vi.mdx +33 -36
- package/src/media/functional/functional-basic/classes/BroadcastMessage/BroadcastMessage.en.mdx +34 -53
- package/src/media/functional/functional-basic/classes/BroadcastMessage/BroadcastMessage.ru.mdx +33 -52
- package/src/media/functional/functional-basic/classes/BroadcastMessage/BroadcastMessage.vi.mdx +39 -58
- package/src/media/functional/functional-basic/classes/Cache/Cache.en.mdx +7 -4
- package/src/media/functional/functional-basic/classes/Cache/Cache.ru.mdx +7 -4
- package/src/media/functional/functional-basic/classes/Cache/Cache.vi.mdx +28 -25
- package/src/media/functional/functional-basic/classes/CacheItem/CacheItem.en.mdx +45 -53
- package/src/media/functional/functional-basic/classes/CacheItem/CacheItem.ru.mdx +46 -54
- package/src/media/functional/functional-basic/classes/CacheItem/CacheItem.vi.mdx +47 -55
- package/src/media/functional/functional-basic/classes/CacheStatic/CacheStatic.en.mdx +13 -1
- package/src/media/functional/functional-basic/classes/CacheStatic/CacheStatic.ru.mdx +13 -1
- package/src/media/functional/functional-basic/classes/CacheStatic/CacheStatic.vi.mdx +13 -0
- package/src/media/functional/functional-basic/classes/Cookie/Cookie.en.mdx +88 -44
- package/src/media/functional/functional-basic/classes/Cookie/Cookie.ru.mdx +88 -44
- package/src/media/functional/functional-basic/classes/Cookie/Cookie.vi.mdx +85 -41
- package/src/media/functional/functional-basic/classes/CookieBlock/CookieBlock.en.mdx +43 -22
- package/src/media/functional/functional-basic/classes/CookieBlock/CookieBlock.ru.mdx +46 -25
- package/src/media/functional/functional-basic/classes/CookieBlock/CookieBlock.vi.mdx +43 -22
- package/src/media/functional/functional-basic/classes/CookieBlockInstance/CookieBlockInstance.en.mdx +84 -0
- package/src/media/functional/functional-basic/classes/CookieBlockInstance/CookieBlockInstance.ru.mdx +84 -0
- package/src/media/functional/functional-basic/classes/CookieBlockInstance/CookieBlockInstance.vi.mdx +100 -0
- package/src/media/functional/functional-basic/classes/CookieStorage/CookieStorage.en.mdx +153 -0
- package/src/media/functional/functional-basic/classes/CookieStorage/CookieStorage.ru.mdx +153 -0
- package/src/media/functional/functional-basic/classes/CookieStorage/CookieStorage.vi.mdx +153 -0
- package/src/media/functional/functional-basic/classes/DataStorage/DataStorage.en.mdx +32 -25
- package/src/media/functional/functional-basic/classes/DataStorage/DataStorage.ru.mdx +32 -25
- package/src/media/functional/functional-basic/classes/DataStorage/DataStorage.vi.mdx +32 -27
- package/src/media/functional/functional-basic/classes/Datetime/Datetime.en.mdx +36 -4
- package/src/media/functional/functional-basic/classes/Datetime/Datetime.ru.mdx +36 -4
- package/src/media/functional/functional-basic/classes/Datetime/Datetime.vi.mdx +36 -4
- package/src/media/functional/functional-basic/classes/ErrorCenter/ErrorCenter.en.mdx +101 -70
- package/src/media/functional/functional-basic/classes/ErrorCenter/ErrorCenter.ru.mdx +100 -69
- package/src/media/functional/functional-basic/classes/ErrorCenter/ErrorCenter.vi.mdx +101 -70
- package/src/media/functional/functional-basic/classes/ErrorCenterHandler/ErrorCenterHandler.en.mdx +46 -42
- package/src/media/functional/functional-basic/classes/ErrorCenterHandler/ErrorCenterHandler.ru.mdx +46 -42
- package/src/media/functional/functional-basic/classes/ErrorCenterHandler/ErrorCenterHandler.vi.mdx +46 -42
- package/src/media/functional/functional-basic/classes/ErrorCenterInstance/ErrorCenterInstance.en.mdx +44 -96
- package/src/media/functional/functional-basic/classes/ErrorCenterInstance/ErrorCenterInstance.ru.mdx +44 -96
- package/src/media/functional/functional-basic/classes/ErrorCenterInstance/ErrorCenterInstance.vi.mdx +44 -96
- package/src/media/functional/functional-basic/classes/EventItem/EventItem.en.mdx +49 -28
- package/src/media/functional/functional-basic/classes/EventItem/EventItem.ru.mdx +21 -0
- package/src/media/functional/functional-basic/classes/EventItem/EventItem.vi.mdx +63 -42
- package/src/media/functional/functional-basic/classes/Formatters/Formatters.en.mdx +97 -109
- package/src/media/functional/functional-basic/classes/Formatters/Formatters.ru.mdx +86 -98
- package/src/media/functional/functional-basic/classes/Formatters/Formatters.vi.mdx +99 -111
- package/src/media/functional/functional-basic/classes/Geo/Geo.en.mdx +3 -3
- package/src/media/functional/functional-basic/classes/Geo/Geo.ru.mdx +5 -5
- package/src/media/functional/functional-basic/classes/Geo/Geo.vi.mdx +5 -5
- package/src/media/functional/functional-basic/classes/GeoFlag/GeoFlag.en.mdx +83 -40
- package/src/media/functional/functional-basic/classes/GeoFlag/GeoFlag.ru.mdx +83 -40
- package/src/media/functional/functional-basic/classes/GeoFlag/GeoFlag.vi.mdx +87 -44
- package/src/media/functional/functional-basic/classes/GeoInstance/GeoInstance.en.mdx +81 -0
- package/src/media/functional/functional-basic/classes/GeoInstance/GeoInstance.ru.mdx +81 -0
- package/src/media/functional/functional-basic/classes/GeoInstance/GeoInstance.vi.mdx +81 -0
- package/src/media/functional/functional-basic/classes/GeoPhone/GeoPhone.en.mdx +56 -105
- package/src/media/functional/functional-basic/classes/GeoPhone/GeoPhone.ru.mdx +53 -102
- package/src/media/functional/functional-basic/classes/GeoPhone/GeoPhone.vi.mdx +55 -105
- package/src/media/functional/functional-basic/classes/Hash/Hash.en.mdx +18 -7
- package/src/media/functional/functional-basic/classes/Hash/Hash.ru.mdx +18 -7
- package/src/media/functional/functional-basic/classes/Hash/Hash.vi.mdx +18 -7
- package/src/media/functional/functional-basic/classes/HashInstance/HashInstance.en.mdx +54 -0
- package/src/media/functional/functional-basic/classes/HashInstance/HashInstance.ru.mdx +54 -0
- package/src/media/functional/functional-basic/classes/HashInstance/HashInstance.vi.mdx +54 -0
- package/src/media/functional/functional-basic/classes/MetaStatic/MetaStatic.en.mdx +78 -0
- package/src/media/functional/functional-basic/classes/MetaStatic/MetaStatic.ru.mdx +78 -0
- package/src/media/functional/functional-basic/classes/MetaStatic/MetaStatic.vi.mdx +78 -0
- package/src/media/functional/functional-basic/classes/ResumableTimer/ResumableTimer.en.mdx +50 -0
- package/src/media/functional/functional-basic/classes/ResumableTimer/ResumableTimer.ru.mdx +50 -0
- package/src/media/functional/functional-basic/classes/ResumableTimer/ResumableTimer.vi.mdx +50 -0
- package/src/media/functional/functional-basic/classes/ServerStorage/ServerStorage.en.mdx +131 -0
- package/src/media/functional/functional-basic/classes/ServerStorage/ServerStorage.ru.mdx +131 -0
- package/src/media/functional/functional-basic/classes/ServerStorage/ServerStorage.vi.mdx +131 -0
- package/src/media/functional/functional-basic/classes/StorageCallback/StorageCallback.en.mdx +97 -0
- package/src/media/functional/functional-basic/classes/StorageCallback/StorageCallback.ru.mdx +97 -0
- package/src/media/functional/functional-basic/classes/StorageCallback/StorageCallback.vi.mdx +97 -0
- package/src/media/functional/functional-basic/functions/addTagHighlightMatch/addTagHighlightMatch.en.mdx +13 -5
- package/src/media/functional/functional-basic/functions/addTagHighlightMatch/addTagHighlightMatch.ru.mdx +13 -5
- package/src/media/functional/functional-basic/functions/addTagHighlightMatch/addTagHighlightMatch.vi.mdx +13 -5
- package/src/media/functional/functional-basic/functions/anyToString/anyToString.en.mdx +37 -19
- package/src/media/functional/functional-basic/functions/anyToString/anyToString.ru.mdx +37 -19
- package/src/media/functional/functional-basic/functions/anyToString/anyToString.vi.mdx +35 -17
- package/src/media/functional/functional-basic/functions/applyTemplate/applyTemplate.en.mdx +31 -19
- package/src/media/functional/functional-basic/functions/applyTemplate/applyTemplate.ru.mdx +31 -19
- package/src/media/functional/functional-basic/functions/applyTemplate/applyTemplate.vi.mdx +32 -20
- package/src/media/functional/functional-basic/functions/blobToBase64/blobToBase64.en.mdx +29 -15
- package/src/media/functional/functional-basic/functions/blobToBase64/blobToBase64.ru.mdx +28 -14
- package/src/media/functional/functional-basic/functions/blobToBase64/blobToBase64.vi.mdx +28 -14
- package/src/media/functional/functional-basic/functions/capitalize/capitalize.en.mdx +7 -3
- package/src/media/functional/functional-basic/functions/capitalize/capitalize.ru.mdx +7 -3
- package/src/media/functional/functional-basic/functions/capitalize/capitalize.vi.mdx +7 -3
- package/src/media/functional/functional-basic/functions/copyObject/copyObject.en.mdx +17 -13
- package/src/media/functional/functional-basic/functions/copyObject/copyObject.ru.mdx +17 -13
- package/src/media/functional/functional-basic/functions/copyObject/copyObject.vi.mdx +17 -13
- package/src/media/functional/functional-basic/functions/createElement/createElement.en.mdx +2 -0
- package/src/media/functional/functional-basic/functions/createElement/createElement.ru.mdx +2 -0
- package/src/media/functional/functional-basic/functions/createElement/createElement.vi.mdx +2 -0
- package/src/media/functional/functional-basic/functions/encodeAttribute/encodeAttribute.en.mdx +1 -3
- package/src/media/functional/functional-basic/functions/encodeAttribute/encodeAttribute.ru.mdx +1 -3
- package/src/media/functional/functional-basic/functions/encodeAttribute/encodeAttribute.vi.mdx +1 -3
- package/src/media/functional/functional-basic/functions/executeFunction/executeFunction.en.mdx +13 -10
- package/src/media/functional/functional-basic/functions/executeFunction/executeFunction.ru.mdx +14 -11
- package/src/media/functional/functional-basic/functions/executeFunction/executeFunction.vi.mdx +12 -9
- package/src/media/functional/functional-basic/functions/executePromise/executePromise.en.mdx +14 -13
- package/src/media/functional/functional-basic/functions/executePromise/executePromise.ru.mdx +15 -14
- package/src/media/functional/functional-basic/functions/executePromise/executePromise.vi.mdx +14 -13
- package/src/media/functional/functional-basic/functions/forEach/forEach.en.mdx +1 -1
- package/src/media/functional/functional-basic/functions/forEach/forEach.ru.mdx +1 -1
- package/src/media/functional/functional-basic/functions/forEach/forEach.vi.mdx +1 -1
- package/src/media/functional/functional-basic/functions/frame/frame.en.mdx +7 -4
- package/src/media/functional/functional-basic/functions/frame/frame.ru.mdx +6 -3
- package/src/media/functional/functional-basic/functions/frame/frame.vi.mdx +7 -4
- package/src/media/functional/functional-basic/functions/getArrayHighlightMatch/getArrayHighlightMatch.en.mdx +34 -0
- package/src/media/functional/functional-basic/functions/getArrayHighlightMatch/getArrayHighlightMatch.ru.mdx +34 -0
- package/src/media/functional/functional-basic/functions/getArrayHighlightMatch/getArrayHighlightMatch.vi.mdx +35 -0
- package/src/media/functional/functional-basic/functions/getCurrentDate/getCurrentDate.en.mdx +2 -0
- package/src/media/functional/functional-basic/functions/getCurrentDate/getCurrentDate.ru.mdx +2 -0
- package/src/media/functional/functional-basic/functions/getCurrentDate/getCurrentDate.vi.mdx +2 -0
- package/src/media/functional/functional-basic/functions/getCurrentTime/getCurrentTime.en.mdx +21 -0
- package/src/media/functional/functional-basic/functions/getCurrentTime/getCurrentTime.ru.mdx +21 -0
- package/src/media/functional/functional-basic/functions/getCurrentTime/getCurrentTime.vi.mdx +21 -0
- package/src/media/functional/functional-basic/functions/getElementId/getElementId.en.mdx +17 -3
- package/src/media/functional/functional-basic/functions/getElementId/getElementId.ru.mdx +17 -3
- package/src/media/functional/functional-basic/functions/getElementId/getElementId.vi.mdx +18 -4
- package/src/media/functional/functional-basic/functions/getElementSafeScript/getElementSafeScript.en.mdx +31 -0
- package/src/media/functional/functional-basic/functions/getElementSafeScript/getElementSafeScript.ru.mdx +31 -0
- package/src/media/functional/functional-basic/functions/getElementSafeScript/getElementSafeScript.vi.mdx +31 -0
- package/src/media/functional/functional-basic/functions/getOnlyText/getOnlyText.en.mdx +25 -0
- package/src/media/functional/functional-basic/functions/getOnlyText/getOnlyText.ru.mdx +25 -0
- package/src/media/functional/functional-basic/functions/getOnlyText/getOnlyText.vi.mdx +25 -0
- package/src/media/functional/functional-basic/functions/getSearchExp/getSearchExp.en.mdx +11 -4
- package/src/media/functional/functional-basic/functions/getSearchExp/getSearchExp.ru.mdx +14 -7
- package/src/media/functional/functional-basic/functions/getSearchExp/getSearchExp.vi.mdx +13 -6
- package/src/media/functional/functional-basic/functions/getSeparatingSearchExp/getSeparatingSearchExp.en.mdx +3 -2
- package/src/media/functional/functional-basic/functions/getSeparatingSearchExp/getSeparatingSearchExp.ru.mdx +3 -2
- package/src/media/functional/functional-basic/functions/getSeparatingSearchExp/getSeparatingSearchExp.vi.mdx +3 -2
- package/src/media/functional/functional-basic/functions/toNumber/toNumber.en.mdx +25 -9
- package/src/media/functional/functional-basic/functions/toNumber/toNumber.ru.mdx +25 -9
- package/src/media/functional/functional-basic/functions/toNumber/toNumber.vi.mdx +25 -9
- package/src/media/functional/functional-basic/functions/toString/toString.en.mdx +28 -0
- package/src/media/functional/functional-basic/functions/toString/toString.ru.mdx +28 -0
- package/src/media/functional/functional-basic/functions/toString/toString.vi.mdx +28 -0
- package/src/media/functional/ui/about/about.en.mdx +45 -0
- package/src/media/functional/ui/about/about.ru.mdx +45 -0
- package/src/media/functional/ui/about/about.vi.mdx +45 -0
- package/src/media/functional/ui/component/component.en.mdx +104 -0
- package/src/media/functional/ui/component/component.ru.mdx +106 -0
- package/src/media/functional/ui/component/component.vi.mdx +104 -0
- package/src/media/functional/ui/setup/setup.en.mdx +72 -0
- package/src/media/functional/ui/setup/setup.ru.mdx +72 -0
- package/src/media/functional/ui/setup/setup.vi.mdx +72 -0
- package/src/media/functional/ui/wiki-data.en.mdx +114 -0
- package/src/media/functional/ui/wiki-data.ru.mdx +114 -0
- package/src/media/functional/ui/wiki-data.vi.mdx +114 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/vi/functional-basic/Classes/ServerStorage - Cách ly dữ liệu trong SSR'/>
|
|
4
|
+
|
|
5
|
+
# Lớp ServerStorage
|
|
6
|
+
|
|
7
|
+
`ServerStorage` là một cơ chế để quản lý **trạng thái toàn cục được cách ly** trong các ứng dụng hỗ trợ SSR (Server-Side Rendering).
|
|
8
|
+
|
|
9
|
+
Lớp này cho phép bạn làm việc với dữ liệu dễ dàng như với các biến tĩnh (static), nhưng đảm bảo rằng dữ liệu người dùng trên máy chủ không bị trộn lẫn giữa các yêu cầu song song.
|
|
10
|
+
|
|
11
|
+
## Các tính năng chính
|
|
12
|
+
|
|
13
|
+
- **Cách ly yêu cầu** — dữ liệu trên máy chủ được liên kết với ngữ cảnh của yêu cầu hiện tại.
|
|
14
|
+
- **Hydration** — khả năng tự động chuyển trạng thái từ máy chủ sang máy khách thông qua JSON.
|
|
15
|
+
- **Bảo mật** — tự động thoát (escape) XSS trong quá trình truyền dữ liệu.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { ServerStorage } from '@dxtmisha/functional-basic'
|
|
19
|
+
|
|
20
|
+
// Lưu dữ liệu với cờ hydration (sẽ có sẵn trên máy khách)
|
|
21
|
+
ServerStorage.set('theme', () => 'dark', true)
|
|
22
|
+
|
|
23
|
+
// Truy xuất dữ liệu
|
|
24
|
+
const theme = ServerStorage.get('theme') // 'dark'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Các phương thức truy cập dữ liệu
|
|
28
|
+
|
|
29
|
+
### `get`
|
|
30
|
+
|
|
31
|
+
Truy xuất giá trị theo khóa. Nếu không tìm thấy, nó sẽ tạo giá trị mới bằng cách sử dụng factory giá trị mặc định.
|
|
32
|
+
|
|
33
|
+
**Tham số:**
|
|
34
|
+
- `key: string` — khóa lưu trữ duy nhất.
|
|
35
|
+
- `defaultValue?: () => T` — hàm trả về giá trị mặc định nếu không tìm thấy.
|
|
36
|
+
- `hydration: boolean` — nếu là `true`, giá trị sẽ được bao gồm trong JSON cho máy khách (mặc định: `false`).
|
|
37
|
+
|
|
38
|
+
**Trả về:** `T`
|
|
39
|
+
|
|
40
|
+
### `set`
|
|
41
|
+
|
|
42
|
+
Lưu một giá trị vào kho lưu trữ.
|
|
43
|
+
|
|
44
|
+
**Tham số:**
|
|
45
|
+
- `key: string` — khóa lưu trữ duy nhất.
|
|
46
|
+
- `value: () => T` — hàm trả về giá trị để lưu.
|
|
47
|
+
- `hydration: boolean` — nếu là `true`, giá trị sẽ được bao gồm trong JSON cho máy khách (mặc định: `false`).
|
|
48
|
+
|
|
49
|
+
**Trả về:** `T`
|
|
50
|
+
|
|
51
|
+
## Các phương thức tiện ích và vòng đời
|
|
52
|
+
|
|
53
|
+
- `init(listener: () => Record<string, any>): typeof ServerStorage` — Khởi tạo kho lưu trữ với bộ lắng nghe ngữ cảnh. Trên máy chủ, bộ lắng nghe này sẽ trả về một đối tượng duy nhất cho mỗi yêu cầu.
|
|
54
|
+
- `has(key: string): boolean` — Kiếm tra sự tồn tại của một khóa trong ngữ cảnh hiện tại.
|
|
55
|
+
- `reset(): void` — Đặt lại kho lưu trữ, xóa tất cả dữ liệu đã lưu và bộ lắng nghe. Hữu ích cho việc dọn dẹp.
|
|
56
|
+
- `toString(): string` — Tạo một thẻ HTML `<script type="application/json">` chứa tất cả dữ liệu được đánh dấu để hydration.
|
|
57
|
+
|
|
58
|
+
## Cách ly trong SSR
|
|
59
|
+
|
|
60
|
+
Trong các ứng dụng phía máy khách thông thường, trạng thái toàn cục thuộc về một người dùng duy nhất. Tuy nhiên, trong môi trường SSR, một quy trình Node.js xử lý nhiều yêu cầu đồng thời. Để ngăn chặn dữ liệu của người dùng này "rò rỉ" sang yêu cầu của người dùng khác (Ô nhiễm trạng thái), `ServerStorage` phải được cách ly chính xác.
|
|
61
|
+
|
|
62
|
+
Để đạt được điều này, bạn phải khởi tạo `ServerStorage` bằng phương thức `init`. Phương thức này chấp nhận một hàm lắng nghe trả về một đối tượng dữ liệu duy nhất cho ngữ cảnh yêu cầu hiện tại.
|
|
63
|
+
|
|
64
|
+
> Quan trọng: Việc cách ly chính xác là cực kỳ quan trọng đối với bảo mật. Nếu không được cấu hình, dữ liệu từ người dùng này có thể được cung cấp cho người dùng khác.
|
|
65
|
+
|
|
66
|
+
### Node.js (AsyncLocalStorage)
|
|
67
|
+
|
|
68
|
+
Cách được khuyến nghị cho Node.js là sử dụng `AsyncLocalStorage` để lưu trữ ngữ cảnh trong suốt một yêu cầu không đồng bộ.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
72
|
+
import { ServerStorage } from '@dxtmisha/functional-basic'
|
|
73
|
+
|
|
74
|
+
const als = new AsyncLocalStorage<Record<string, any>>()
|
|
75
|
+
|
|
76
|
+
// Khởi tạo
|
|
77
|
+
ServerStorage.init(() => als.getStore() || {})
|
|
78
|
+
|
|
79
|
+
// Sử dụng trong máy chủ
|
|
80
|
+
http.createServer((req, res) => {
|
|
81
|
+
als.run({}, () => {
|
|
82
|
+
// Tất cả các lệnh gọi đến ServerStorage bên trong khối này sẽ được cách ly
|
|
83
|
+
ServerStorage.set('requestId', () => req.id)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Nuxt / Nitro
|
|
89
|
+
|
|
90
|
+
Trong Nuxt/Nitro, việc cách ly được quản lý thông qua ngữ cảnh sự kiện `h3` bằng cách sử dụng `useEvent()` bên trong một plugin máy chủ.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// server/plugins/server-storage.ts
|
|
94
|
+
import { ServerStorage } from '@dxtmisha/functional-basic'
|
|
95
|
+
|
|
96
|
+
export default defineNitroPlugin(() => {
|
|
97
|
+
ServerStorage.init(() => {
|
|
98
|
+
try {
|
|
99
|
+
return useEvent().context
|
|
100
|
+
} catch {
|
|
101
|
+
return {}
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Hydration (Chuyển dữ liệu sang máy khách)
|
|
108
|
+
|
|
109
|
+
Hydration là quá trình chuyển trạng thái ứng dụng được thiết lập trên máy chủ sang máy khách. Điều này cho phép trình duyệt tiếp tục công việc từ nơi máy chủ dừng lại, đảm bảo tính nhất quán và ngăn chặn việc tìm kiếm dữ liệu thừa hoặc hiện tượng "nhấp nháy" (flickering) trong quá trình tải trang.
|
|
110
|
+
|
|
111
|
+
### 1. Xác định dữ liệu để Hydration
|
|
112
|
+
|
|
113
|
+
Khi sử dụng `set()` hoặc `get()`, hãy truyền `true` làm tham số thứ ba (`hydration`). Chỉ những giá trị được đánh dấu theo cách này mới được chuyển sang máy khách.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Thiết lập trên máy chủ
|
|
117
|
+
ServerStorage.set('userSettings', () => ({ fontSize: 16 }), true)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 2. Chèn trạng thái vào HTML
|
|
121
|
+
|
|
122
|
+
Trên máy chủ, bạn phải gọi `ServerStorage.toString()` và chèn kết quả của nó vào mẫu trang của bạn (thường ở cuối thẻ `<body>`, trước các tập lệnh ứng dụng của bạn).
|
|
123
|
+
|
|
124
|
+
Phương thức này tạo ra một thẻ script đặc biệt:
|
|
125
|
+
```html
|
|
126
|
+
<script id="__ui:server:storage:id__" type="application/json">
|
|
127
|
+
{"userSettings":{"fontSize":16}}
|
|
128
|
+
</script>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/en/functional-basic/Classes/StorageCallback - Storage Callbacks'/>
|
|
4
|
+
|
|
5
|
+
# StorageCallback Class
|
|
6
|
+
|
|
7
|
+
A utility class for managing groups of callback functions associated with specific storage keys. It ensures that multiple components or functions can react to storage changes or triggers in a coordinated, asynchronous manner.
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- **Named Instances** — facilitates a singleton-like pattern where instances are retrieved by name and group, ensuring different parts of the application share the same callback list for the same resource.
|
|
12
|
+
- **Group Separation** — allows segregating callback lists by group (e.g., 'main', 'global', 'local'), preventing name collisions between different modules.
|
|
13
|
+
- **Asynchronous Execution** — supports `Promise`-based callbacks and executes them sequentially during the `run` process.
|
|
14
|
+
- **Loading State Tracking** — provides a built-in `loading` flag that is automatically managed during the callback execution phase.
|
|
15
|
+
|
|
16
|
+
## Initialization
|
|
17
|
+
|
|
18
|
+
To initialize the object, call the `StorageCallback(name, group)` constructor or use the static method `getInstance(name, group)`.
|
|
19
|
+
|
|
20
|
+
### Generic Constraints
|
|
21
|
+
|
|
22
|
+
To ensure strict typing, the class supports the following generics:
|
|
23
|
+
- `T = any` — The type of data passed to callbacks.
|
|
24
|
+
- `Callback = (value: T) => void | Promise<void>` — The structure of the callback function.
|
|
25
|
+
|
|
26
|
+
**Parameters:**
|
|
27
|
+
- `name: string` — a unique identifier for the storage entry.
|
|
28
|
+
- `group: string = 'main'` — optional category to prevent name collisions.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { StorageCallback } from '@dxtmisha/functional-basic'
|
|
32
|
+
|
|
33
|
+
// 1. Simple initialization (group defaults to 'main')
|
|
34
|
+
const storage = new StorageCallback('user-data')
|
|
35
|
+
|
|
36
|
+
// 2. Using the singleton-like getInstance method
|
|
37
|
+
const sharedStorage = StorageCallback.getInstance('settings', 'global')
|
|
38
|
+
|
|
39
|
+
// 3. Using generics for strict typing
|
|
40
|
+
const numberStorage = new StorageCallback<number>('counter')
|
|
41
|
+
numberStorage.addCallback((val) => console.log(val + 1))
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Methods
|
|
45
|
+
|
|
46
|
+
### Information
|
|
47
|
+
|
|
48
|
+
- `getName(): string` — returns the storage instance name.
|
|
49
|
+
- `isLoading(): boolean` — returns the current loading state.
|
|
50
|
+
- `getLoading(): boolean` — returns the current loading state (alias for `isLoading`).
|
|
51
|
+
|
|
52
|
+
### Management
|
|
53
|
+
|
|
54
|
+
- `addCallback(callback: Callback, isOnce?: boolean): this` — adds a new callback to the execution list. If `isOnce: true`, the callback will be removed after the first execution.
|
|
55
|
+
- `removeCallback(callback: Callback): this` — removes a specific callback from the list.
|
|
56
|
+
|
|
57
|
+
### Control
|
|
58
|
+
|
|
59
|
+
- `preparation(): this` — prepares the state before execution (sets `loading` to `true`). Should be called manually when starting an asynchronous process.
|
|
60
|
+
- `run(value: T): Promise<this>` — executes all callbacks sequentially with the provided value. Sets `loading` back to `false` at the start of execution.
|
|
61
|
+
|
|
62
|
+
## Usage Examples
|
|
63
|
+
|
|
64
|
+
### Manual Loading Management
|
|
65
|
+
|
|
66
|
+
When data is fetched asynchronously from an external source (e.g., Figma storage), you can manage the `loading` state manually to coordinate multiple requests.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const storage = new StorageCallback('figma-data')
|
|
70
|
+
|
|
71
|
+
// 1. Check if it is not already loading
|
|
72
|
+
if (!storage.isLoading()) {
|
|
73
|
+
// 2. Set loading state to true
|
|
74
|
+
storage.preparation()
|
|
75
|
+
|
|
76
|
+
// 3. Request the data
|
|
77
|
+
fetchFromFigma((data) => {
|
|
78
|
+
// 4. Run callbacks (run will reset loading to false)
|
|
79
|
+
storage.run(data)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### One-time Callback
|
|
85
|
+
|
|
86
|
+
If you only need a function to trigger once (e.g., for initial data hydration), use the `isOnce` flag.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const storage = new StorageCallback('initial-data')
|
|
90
|
+
|
|
91
|
+
storage.addCallback((data) => {
|
|
92
|
+
console.log('Executed once:', data)
|
|
93
|
+
}, true)
|
|
94
|
+
|
|
95
|
+
await storage.run('update 1') // 'Executed once: update 1'
|
|
96
|
+
await storage.run('update 2') // (no output, callback removed)
|
|
97
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/ru/functional-basic/Classes/StorageCallback - Обратные вызовы хранилища'/>
|
|
4
|
+
|
|
5
|
+
# Класс StorageCallback
|
|
6
|
+
|
|
7
|
+
Вспомогательный класс для управления группами функций обратного вызова, связанных с конкретными ключами хранилища. Он позволяет нескольким компонентам или функциям реагировать на изменения или триггеры хранилища согласованно и асинхронно.
|
|
8
|
+
|
|
9
|
+
## Основные особенности
|
|
10
|
+
|
|
11
|
+
- **Именованные экземпляры** — реализует паттерн, похожий на синглтон, где экземпляры извлекаются по имени и группе, гарантируя, что разные части приложения используют один и тот же список обратных вызовов для одного и того же ресурса.
|
|
12
|
+
- **Разделение по группам** — позволяет разделять списки обратных вызовов по группам (например, 'main', 'global', 'local'), предотвращая конфликты имен между различными модулями.
|
|
13
|
+
- **Асинхронное выполнение** — поддерживает асинхронные обратные вызовы и выполняет их последовательно в процессе вызова `run`.
|
|
14
|
+
- **Отслеживание состояния загрузки** — предоставляет встроенный флаг `loading`, который автоматически переключается во время фазы выполнения обратных вызовов.
|
|
15
|
+
|
|
16
|
+
## Инициализация
|
|
17
|
+
|
|
18
|
+
Для инициализации объекта вызовите конструктор `StorageCallback(name, group)` или используйте статический метод `getInstance(name, group)`.
|
|
19
|
+
|
|
20
|
+
### Ограничения типов (Generics)
|
|
21
|
+
|
|
22
|
+
Для обеспечения строгой типизации класс поддерживает следующие параметры:
|
|
23
|
+
- `T = any` — тип данных, передаваемых в обратные вызовы.
|
|
24
|
+
- `Callback = (value: T) => void | Promise<void>` — структура функции обратного вызова.
|
|
25
|
+
|
|
26
|
+
**Параметры:**
|
|
27
|
+
- `name: string` — уникальный идентификатор для записи в хранилище.
|
|
28
|
+
- `group: string = 'main'` — необязательная категория для предотвращения конфликтов имен.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { StorageCallback } from '@dxtmisha/functional-basic'
|
|
32
|
+
|
|
33
|
+
// 1. Простая инициализация (группа по умолчанию 'main')
|
|
34
|
+
const storage = new StorageCallback('user-data')
|
|
35
|
+
|
|
36
|
+
// 2. Использование статического метода getInstance
|
|
37
|
+
const sharedStorage = StorageCallback.getInstance('settings', 'global')
|
|
38
|
+
|
|
39
|
+
// 3. Использование generic-типов для строгой типизации
|
|
40
|
+
const numberStorage = new StorageCallback<number>('counter')
|
|
41
|
+
numberStorage.addCallback((val) => console.log(val + 1))
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Методы
|
|
45
|
+
|
|
46
|
+
### Информация
|
|
47
|
+
|
|
48
|
+
- `getName(): string` — возвращает имя экземпляра хранилища.
|
|
49
|
+
- `isLoading(): boolean` — возвращает текущее состояние загрузки.
|
|
50
|
+
- `getLoading(): boolean` — возвращает текущее состояние загрузки (аналог `isLoading`).
|
|
51
|
+
|
|
52
|
+
### Управление
|
|
53
|
+
|
|
54
|
+
- `addCallback(callback: Callback, isOnce?: boolean): this` — добавляет новый обратный вызов в список выполнения. При `isOnce: true` callback будет удален после первого выполнения.
|
|
55
|
+
- `removeCallback(callback: Callback): this` — удаляет конкретный обратный вызов из списка.
|
|
56
|
+
|
|
57
|
+
### Управление процессом (Control)
|
|
58
|
+
|
|
59
|
+
- `preparation(): this` — подготавливает состояние перед выполнением (устанавливает `loading` в `true`). Используется вручную при запуске асинхронных операций.
|
|
60
|
+
- `run(value: T): Promise<this>` — последовательно выполняет все обратные вызовы с переданным значением. В начале выполнения устанавливает `loading` в `false`.
|
|
61
|
+
|
|
62
|
+
## Примеры использования
|
|
63
|
+
|
|
64
|
+
### Ручное управление состоянием загрузки
|
|
65
|
+
|
|
66
|
+
Если данные загружаются асинхронно из внешнего источника (например, Figma storage), вы можете управлять состоянием `loading` вручную.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const storage = new StorageCallback('figma-data')
|
|
70
|
+
|
|
71
|
+
// 1. Проверяем, не идет ли уже загрузка
|
|
72
|
+
if (!storage.isLoading()) {
|
|
73
|
+
// 2. Устанавливаем состояние загрузки
|
|
74
|
+
storage.preparation()
|
|
75
|
+
|
|
76
|
+
// 3. Запрашиваем данные
|
|
77
|
+
fetchFromFigma((data) => {
|
|
78
|
+
// 4. Выполняем колбэки (run сбросит loading в false)
|
|
79
|
+
storage.run(data)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Одноразовый обратный вызов
|
|
85
|
+
|
|
86
|
+
Если вам нужно, чтобы функция сработала только один раз (например, для начальной загрузки данных), используйте флаг `isOnce`.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const storage = new StorageCallback('initial-data')
|
|
90
|
+
|
|
91
|
+
storage.addCallback((data) => {
|
|
92
|
+
console.log('Выполнено один раз:', data)
|
|
93
|
+
}, true)
|
|
94
|
+
|
|
95
|
+
await storage.run('update 1') // 'Выполнено один раз: update 1'
|
|
96
|
+
await storage.run('update 2') // (ничего не выводится, callback удален)
|
|
97
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/vi/functional-basic/Classes/StorageCallback - Storage Callbacks'/>
|
|
4
|
+
|
|
5
|
+
# Lớp StorageCallback
|
|
6
|
+
|
|
7
|
+
Một lớp tiện ích để quản lý các nhóm hàm callback liên kết với các khóa lưu trữ cụ thể. Nó cho phép nhiều thành phần hoặc chức năng phản hồi các thay đổi hoặc kích hoạt lưu trữ một cách phối hợp, bất đồng bộ.
|
|
8
|
+
|
|
9
|
+
## Các đặc điểm chính
|
|
10
|
+
|
|
11
|
+
- **Các thực thể có tên** — thực hiện mô hình singleton, trong đó các thực thể được truy xuất theo tên và nhóm, đảm bảo rằng các phần khác nhau của ứng dụng chia sẻ cùng một danh sách callback cho cùng một tài nguyên.
|
|
12
|
+
- **Phân tách theo nhóm** — cho phép tách biệt các danh sách callback theo nhóm (ví dụ: 'main', 'global', 'local'), ngăn chặn xung đột tên giữa các mô-đun khác nhau.
|
|
13
|
+
- **Thực thi bất đồng bộ** — hỗ trợ các callback dựa trên `Promise` và thực thi chúng theo trình tự trong quá trình `run`.
|
|
14
|
+
- **Theo dõi trạng thái tải** — cung cấp cờ `loading` có sẵn, được quản lý tự động trong giai đoạn thực thi callback.
|
|
15
|
+
|
|
16
|
+
## Khởi tạo
|
|
17
|
+
|
|
18
|
+
Để khởi tạo đối tượng, hãy gọi hàm tạo `StorageCallback(name, group)` hoặc sử dụng phương thức tĩnh `getInstance(name, group)`.
|
|
19
|
+
|
|
20
|
+
### Các ràng buộc Generic
|
|
21
|
+
|
|
22
|
+
Để đảm bảo kiểu dữ liệu nghiêm ngặt, lớp hỗ trợ các generic sau:
|
|
23
|
+
- `T = any` — Kiểu dữ liệu được truyền cho các callback.
|
|
24
|
+
- `Callback = (value: T) => void | Promise<void>` — Cấu trúc hàm callback.
|
|
25
|
+
|
|
26
|
+
**Tham số:**
|
|
27
|
+
- `name: string` — định danh duy nhất cho mục nhập lưu trữ.
|
|
28
|
+
- `group: string = 'main'` — phân loại tùy chọn để ngăn chặn xung đột tên.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { StorageCallback } from '@dxtmisha/functional-basic'
|
|
32
|
+
|
|
33
|
+
// 1. Khởi tạo đơn giản (nhóm mặc định là 'main')
|
|
34
|
+
const storage = new StorageCallback('user-data')
|
|
35
|
+
|
|
36
|
+
// 2. Sử dụng phương thức tĩnh getInstance
|
|
37
|
+
const sharedStorage = StorageCallback.getInstance('settings', 'global')
|
|
38
|
+
|
|
39
|
+
// 3. Sử dụng generic để kiểm soát kiểu dữ liệu
|
|
40
|
+
const numberStorage = new StorageCallback<number>('counter')
|
|
41
|
+
numberStorage.addCallback((val) => console.log(val + 1))
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Các phương thức
|
|
45
|
+
|
|
46
|
+
### Thông tin
|
|
47
|
+
|
|
48
|
+
- `getName(): string` — trả về tên của thực thể lưu trữ.
|
|
49
|
+
- `isLoading(): boolean` — trả về trạng thái tải hiện tại.
|
|
50
|
+
- `getLoading(): boolean` — trả về trạng thái tải hiện tại (tương tự `isLoading`).
|
|
51
|
+
|
|
52
|
+
### Quản lý
|
|
53
|
+
|
|
54
|
+
- `addCallback(callback: Callback, isOnce?: boolean): this` — thêm một callback mới vào danh sách thực thi. Nếu `isOnce: true`, callback sẽ bị xóa sau lần thực thi đầu tiên.
|
|
55
|
+
- `removeCallback(callback: Callback): this` — xóa một callback cụ thể khỏi danh sách.
|
|
56
|
+
|
|
57
|
+
### Điều khiển (Control)
|
|
58
|
+
|
|
59
|
+
- `preparation(): this` — chuẩn bị trạng thái trước khi thực thi (đặt `loading` thành `true`). Được sử dụng thủ công khi bắt đầu các hoạt động bất đồng bộ.
|
|
60
|
+
- `run(value: T): Promise<this>` — thực thi tất cả các callback theo trình tự với giá trị được cung cấp. Đặt `loading` về `false` khi bắt đầu thực thi.
|
|
61
|
+
|
|
62
|
+
## Ví dụ sử dụng
|
|
63
|
+
|
|
64
|
+
### Quản lý trạng thái tải thủ công
|
|
65
|
+
|
|
66
|
+
Khi dữ liệu được lấy bất đồng bộ từ nguồn bên ngoài (ví dụ: Figma storage), bạn có thể quản lý trạng thái `loading` thủ công để điều phối nhiều yêu cầu.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const storage = new StorageCallback('figma-data')
|
|
70
|
+
|
|
71
|
+
// 1. Kiểm tra nếu không phải đang tải
|
|
72
|
+
if (!storage.isLoading()) {
|
|
73
|
+
// 2. Thiết lập trạng thái đang tải
|
|
74
|
+
storage.preparation()
|
|
75
|
+
|
|
76
|
+
// 3. Yêu cầu dữ liệu
|
|
77
|
+
fetchFromFigma((data) => {
|
|
78
|
+
// 4. Thực thi callback (run sẽ đưa loading về false)
|
|
79
|
+
storage.run(data)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Callback một lần
|
|
85
|
+
|
|
86
|
+
Nếu bạn chỉ cần một hàm kích hoạt một lần (ví dụ: để nạp dữ liệu ban đầu), hãy sử dụng cờ `isOnce`.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const storage = new StorageCallback('initial-data')
|
|
90
|
+
|
|
91
|
+
storage.addCallback((data) => {
|
|
92
|
+
console.log('Đã thực thi một lần:', data)
|
|
93
|
+
}, true)
|
|
94
|
+
|
|
95
|
+
await storage.run('update 1') // 'Đã thực thi một lần: update 1'
|
|
96
|
+
await storage.run('update 2') // (không có đầu ra, callback đã bị xóa)
|
|
97
|
+
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meta } from '@storybook/addon-docs/blocks'
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks'
|
|
2
2
|
|
|
3
3
|
<Meta title='@dxtmisha/en/functional-basic/Functions/addTagHighlightMatch - Highlight matches in a string'/>
|
|
4
4
|
|
|
@@ -8,17 +8,20 @@ A utility for highlighting matches in a string by wrapping them in a `<span>` HT
|
|
|
8
8
|
|
|
9
9
|
**Parameters:**
|
|
10
10
|
- `value: string` — The initial string to process.
|
|
11
|
-
- `search?: string` — The search string (one or more words separated by spaces).
|
|
11
|
+
- `search?: string | RegExp` — The search string (one or more words separated by spaces) or a regular expression.
|
|
12
12
|
- `className: string = 'sys-highlight-match'` — The CSS class to be added to the `<span>` tag.
|
|
13
|
+
- `shouldEscape: boolean = false` — Whether to escape the string before adding highlighting.
|
|
13
14
|
|
|
14
15
|
**Returns:**
|
|
15
16
|
`string` — The string with HTML tags added for highlighting.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
<Source
|
|
19
|
+
language='typescript'
|
|
20
|
+
code={`
|
|
18
21
|
import { addTagHighlightMatch } from '@dxtmisha/functional-basic'
|
|
19
22
|
|
|
20
23
|
// Highlight a single word
|
|
21
|
-
addTagHighlightMatch('Hello world', 'hello')
|
|
24
|
+
addTagHighlightMatch('Hello world', 'hello')
|
|
22
25
|
// '<span class="sys-highlight-match">Hello</span> world'
|
|
23
26
|
|
|
24
27
|
// Highlight multiple words (OR logic)
|
|
@@ -28,4 +31,9 @@ addTagHighlightMatch('Apple and Banana', 'apple banana')
|
|
|
28
31
|
// Custom class
|
|
29
32
|
addTagHighlightMatch('Test', 'test', 'text-red')
|
|
30
33
|
// '<span class="text-red">Test</span>'
|
|
31
|
-
|
|
34
|
+
|
|
35
|
+
// With escaping
|
|
36
|
+
addTagHighlightMatch('<b>bold</b>', 'bold', 'sys-highlight-match', true)
|
|
37
|
+
// '<b><span class="sys-highlight-match">bold</span></b>'
|
|
38
|
+
`}
|
|
39
|
+
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meta } from '@storybook/addon-docs/blocks'
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks'
|
|
2
2
|
|
|
3
3
|
<Meta title='@dxtmisha/ru/functional-basic/Functions/addTagHighlightMatch - Подсветка совпадений в строке'/>
|
|
4
4
|
|
|
@@ -8,17 +8,20 @@ import { Meta } from '@storybook/addon-docs/blocks'
|
|
|
8
8
|
|
|
9
9
|
**Параметры:**
|
|
10
10
|
- `value: string` — Исходная строка для обработки.
|
|
11
|
-
- `search?: string` — Строка поиска (одно или несколько слов через пробел)
|
|
11
|
+
- `search?: string | RegExp` — Строка поиска (одно или несколько слов через пробел) или регулярное выражение.
|
|
12
12
|
- `className: string = 'sys-highlight-match'` — CSS-класс, который будет добавлен к тегу `<span>`.
|
|
13
|
+
- `shouldEscape: boolean = false` — Нужно ли экранировать строку перед добавлением подсветки.
|
|
13
14
|
|
|
14
15
|
**Возвращает:**
|
|
15
16
|
`string` — Строка с добавленными HTML-тегами для подсветки.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
<Source
|
|
19
|
+
language='typescript'
|
|
20
|
+
code={`
|
|
18
21
|
import { addTagHighlightMatch } from '@dxtmisha/functional-basic'
|
|
19
22
|
|
|
20
23
|
// Подсветка одного слова
|
|
21
|
-
addTagHighlightMatch('Hello world', 'hello')
|
|
24
|
+
addTagHighlightMatch('Hello world', 'hello')
|
|
22
25
|
// '<span class="sys-highlight-match">Hello</span> world'
|
|
23
26
|
|
|
24
27
|
// Подсветка нескольких слов (OR-логика)
|
|
@@ -28,4 +31,9 @@ addTagHighlightMatch('Apple and Banana', 'apple banana')
|
|
|
28
31
|
// Кастомный класс
|
|
29
32
|
addTagHighlightMatch('Test', 'test', 'text-red')
|
|
30
33
|
// '<span class="text-red">Test</span>'
|
|
31
|
-
|
|
34
|
+
|
|
35
|
+
// С экранированием
|
|
36
|
+
addTagHighlightMatch('<b>bold</b>', 'bold', 'sys-highlight-match', true)
|
|
37
|
+
// '<b><span class="sys-highlight-match">bold</span></b>'
|
|
38
|
+
`}
|
|
39
|
+
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meta } from '@storybook/addon-docs/blocks'
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks'
|
|
2
2
|
|
|
3
3
|
<Meta title='@dxtmisha/vi/functional-basic/Functions/addTagHighlightMatch - Làm nổi bật các kết quả khớp trong chuỗi'/>
|
|
4
4
|
|
|
@@ -8,17 +8,20 @@ Tiện ích để làm nổi bật các kết quả khớp trong một chuỗi b
|
|
|
8
8
|
|
|
9
9
|
**Tham số:**
|
|
10
10
|
- `value: string` — Chuỗi ban đầu để xử lý.
|
|
11
|
-
- `search?: string` — Chuỗi tìm kiếm (một hoặc nhiều từ phân tách bằng dấu cách).
|
|
11
|
+
- `search?: string | RegExp` — Chuỗi tìm kiếm (một hoặc nhiều từ phân tách bằng dấu cách) hoặc biễu thức chính quy.
|
|
12
12
|
- `className: string = 'sys-highlight-match'` — Class CSS sẽ được thêm vào thẻ `<span>`.
|
|
13
|
+
- `shouldEscape: boolean = false` — Có nên thoát chuỗi trước khi thêm làm nổi bật hay không.
|
|
13
14
|
|
|
14
15
|
**Trả về:**
|
|
15
16
|
`string` — Chuỗi với các thẻ HTML được thêm vào để làm nổi bật.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
<Source
|
|
19
|
+
language='typescript'
|
|
20
|
+
code={`
|
|
18
21
|
import { addTagHighlightMatch } from '@dxtmisha/functional-basic'
|
|
19
22
|
|
|
20
23
|
// Làm nổi bật một từ đơn
|
|
21
|
-
addTagHighlightMatch('Hello world', 'hello')
|
|
24
|
+
addTagHighlightMatch('Hello world', 'hello')
|
|
22
25
|
// '<span class="sys-highlight-match">Hello</span> world'
|
|
23
26
|
|
|
24
27
|
// Làm nổi bật nhiều từ (logic OR)
|
|
@@ -28,4 +31,9 @@ addTagHighlightMatch('Apple and Banana', 'apple banana')
|
|
|
28
31
|
// Class tùy chỉnh
|
|
29
32
|
addTagHighlightMatch('Test', 'test', 'text-red')
|
|
30
33
|
// '<span class="text-red">Test</span>'
|
|
31
|
-
|
|
34
|
+
|
|
35
|
+
// Với thoát chuỗi (escaping)
|
|
36
|
+
addTagHighlightMatch('<b>bold</b>', 'bold', 'sys-highlight-match', true)
|
|
37
|
+
// '<b><span class="sys-highlight-match">bold</span></b>'
|
|
38
|
+
`}
|
|
39
|
+
/>
|
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import { Meta } from '@storybook/addon-docs/blocks'
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks'
|
|
2
2
|
|
|
3
3
|
<Meta title='@dxtmisha/en/functional-basic/Functions/anyToString - Conversion of a value to a string'/>
|
|
4
4
|
|
|
5
5
|
# `anyToString`
|
|
6
6
|
|
|
7
|
-
A utility
|
|
8
|
-
|
|
9
|
-
This is useful when outputting data to the interface when the variable type (object, array, boolean, or null) is not known in advance.
|
|
7
|
+
A utility for safely converting any input data into a string type.
|
|
10
8
|
|
|
11
9
|
**Parameters:**
|
|
12
|
-
- `value: V` —
|
|
13
|
-
- `isArrayString: boolean
|
|
10
|
+
- `value: V` — The value for conversion.
|
|
11
|
+
- `isArrayString: boolean = true` — If `true`, primitive arrays are joined by commas.
|
|
12
|
+
- `trim: boolean = true` — If `true`, trims leading and trailing whitespace (only for strings).
|
|
13
|
+
|
|
14
|
+
**Conversion Rules:**
|
|
15
|
+
- **Strings**: Returned as is (with `trim` if enabled).
|
|
16
|
+
- **Arrays**: If `isArrayString: true` and no objects are in the array, elements are joined by commas. Otherwise, JSON stringified.
|
|
17
|
+
- **Objects**: Converted to JSON. In case of error (e.g., circular reference), returns standard `toString()`.
|
|
18
|
+
- **Boolean**: `true` converts to `'1'`, `false` to `'0'`.
|
|
19
|
+
- **Other types**: `null` and `undefined` result in an empty string. Others call `toString()`.
|
|
14
20
|
|
|
15
21
|
**Returns:**
|
|
16
|
-
`string` — The string representation of the
|
|
22
|
+
`string` — The string representation of the value.
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
<Source
|
|
27
|
+
language='typescript'
|
|
28
|
+
code={`
|
|
19
29
|
import { anyToString } from '@dxtmisha/functional-basic'
|
|
20
30
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
// 1. Strings
|
|
32
|
+
anyToString(' Hello ') // 'Hello'
|
|
33
|
+
anyToString(' Hello ', true, false) // ' Hello '
|
|
34
|
+
|
|
35
|
+
// 2. Arrays
|
|
36
|
+
anyToString([1, 2, 3]) // '1,2,3'
|
|
37
|
+
anyToString([1, 2, 3], false) // '[1,2,3]'
|
|
38
|
+
|
|
39
|
+
// 3. Objects
|
|
40
|
+
anyToString({ a: 1 }) // '{"a":1}'
|
|
24
41
|
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
// 4. Boolean values (1/0 conversion)
|
|
43
|
+
anyToString(true) // '1'
|
|
44
|
+
anyToString(false) // '0'
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
// 5. Empty values and types
|
|
47
|
+
anyToString(null) // ''
|
|
48
|
+
anyToString(123) // '123'
|
|
49
|
+
anyToString(Symbol('test')) // 'Symbol(test)'
|
|
50
|
+
`}
|
|
51
|
+
/>
|