@dvirus-js/utils 0.0.1

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 ADDED
@@ -0,0 +1,69 @@
1
+ ## 1.1.7 (2026-05-06)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - utils readme ([e41a14e](https://github.com/Dvirus97/dvirus-js/commit/e41a14e))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Dvir Cohen
10
+
11
+ ## 1.1.6 (2026-05-06)
12
+
13
+ This was a version bump only for utils to align it with other projects, there were no code changes.
14
+
15
+ ## 1.1.5 (2026-05-06)
16
+
17
+ This was a version bump only for utils to align it with other projects, there were no code changes.
18
+
19
+ ## 1.1.4 (2026-05-05)
20
+
21
+ This was a version bump only for utils to align it with other projects, there were no code changes.
22
+
23
+ ## 1.1.3 (2026-05-05)
24
+
25
+ This was a version bump only for utils to align it with other projects, there were no code changes.
26
+
27
+ ## 1.1.2 (2026-05-05)
28
+
29
+ ### 🩹 Fixes
30
+
31
+ - **angular:** align peer range and signal utils ([d2dc230](https://github.com/Dvirus97/dvirus-js/commit/d2dc230))
32
+
33
+ ### ❤️ Thank You
34
+
35
+ - Dvir Cohen
36
+
37
+ ## 1.1.1 (2026-04-11)
38
+
39
+ This was a version bump only for utils to align it with other projects, there were no code changes.
40
+
41
+ ## 1.1.0 (2026-04-10)
42
+
43
+ ### 🚀 Features
44
+
45
+ - add signals implementation and controlSignal to angular ([58ea6f5](https://github.com/Dvirus97/dvirus-js/commit/58ea6f5))
46
+
47
+ ### 🩹 Fixes
48
+
49
+ - build ([5c87b77](https://github.com/Dvirus97/dvirus-js/commit/5c87b77))
50
+
51
+ ### ❤️ Thank You
52
+
53
+ - Dvir Cohen
54
+
55
+ ## 1.0.3 (2026-02-17)
56
+
57
+ This was a version bump only for utils to align it with other projects, there were no code changes.
58
+
59
+ ## 1.0.2 (2026-02-17)
60
+
61
+ This was a version bump only for utils to align it with other projects, there were no code changes.
62
+
63
+ ## 1.0.1 (2026-02-17)
64
+
65
+ This was a version bump only for utils to align it with other projects, there were no code changes.
66
+
67
+ # 1.0.0 (2026-02-17)
68
+
69
+ This was a version bump only for utils to align it with other projects, there were no code changes.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # Utils Library
2
+
3
+ Shared utility package for string transforms, async helpers, HTTP calls, typed accessors, lightweight signals, and branded types.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @dvirus-js/utils
9
+ ```
10
+
11
+ ## Exports
12
+
13
+ - `normalizeString`, `convertCase`: normalize text and convert between cases.
14
+ - `tryCatch`, `tryCatchAsync`, `Result`: tuple-style and object-style error handling.
15
+ - `http`: small `fetch` wrapper with `get`, `post`, `put`, `patch`, `delete`.
16
+ - `groupBy`, `toArray`, `getProp`: data shaping helpers.
17
+ - `delay`, `clamp`, `debounce`: async and timing utilities.
18
+ - `signal`, `computed`, `effect`, `linkedSignal`, `resource`: minimal reactive primitives.
19
+ - `parseRichText`: parse supported inline HTML tags into styled text segments.
20
+ - `createBrand`, `NumericString`: nominal typing helpers.
21
+
22
+ ## Examples
23
+
24
+ ### Cases and collections
25
+
26
+ ```ts
27
+ import { convertCase, groupBy, normalizeString, toArray } from '@dvirus-js/utils';
28
+
29
+ const value = 'HelloWorld_example-string';
30
+
31
+ normalizeString(value); // 'hello world example string'
32
+ convertCase(value, 'snake_case'); // 'hello_world_example_string'
33
+
34
+ groupBy(
35
+ [
36
+ { type: 'a', value: 1 },
37
+ { type: 'b', value: 2 },
38
+ { type: 'a', value: 3 },
39
+ ],
40
+ (item) => item.type,
41
+ );
42
+
43
+ toArray('item'); // ['item']
44
+ ```
45
+
46
+ ### Errors and HTTP
47
+
48
+ ```ts
49
+ import { Result, http, tryCatch, tryCatchAsync } from '@dvirus-js/utils';
50
+
51
+ const [parsed, parseError] = tryCatch(() => JSON.parse('{"ok":true}'));
52
+ const [todo, requestError] = await tryCatchAsync(http.get<{ id: number; title: string }>('/api/todo/1'));
53
+
54
+ const safeDivide = Result.func(
55
+ (a: number, b: number) => {
56
+ if (b === 0) throw new Error('Cannot divide by zero');
57
+ return a / b;
58
+ },
59
+ 10,
60
+ 2,
61
+ );
62
+
63
+ if (!parseError && !requestError && safeDivide.isOk()) {
64
+ console.log(parsed, todo, safeDivide.value);
65
+ }
66
+ ```
67
+
68
+ ### Paths, timing, and text parsing
69
+
70
+ ```ts
71
+ import { clamp, debounce, delay, getProp, parseRichText } from '@dvirus-js/utils';
72
+
73
+ const user = { profile: { name: 'Ada' } };
74
+ const name = getProp(user, 'profile.name'); // 'Ada'
75
+
76
+ await delay(200);
77
+ const page = clamp(1, 12, 10); // 10
78
+ const save = debounce(() => console.log('saved'), 300);
79
+
80
+ const segments = parseRichText('Hello <b>world</b>');
81
+ ```
82
+
83
+ ## Rich text parser (`parseRichText`)
84
+
85
+ `parseRichText` converts a string with a limited set of HTML-like tags into
86
+ structured text segments.
87
+
88
+ Each segment includes:
89
+
90
+ - `text`: plain text for the segment.
91
+ - `tagNames`: comma-separated active tag names (for quick display/debug).
92
+ - `tagNamesList`: active tag names as an array.
93
+ - `style`: inline CSS string built from active tags.
94
+
95
+ ### Supported tags
96
+
97
+ Default rich tags:
98
+
99
+ - `b`, `strong`
100
+ - `i`, `em`
101
+ - `u`
102
+ - `s`
103
+ - `mark`
104
+ - `small`
105
+ - `h1`, `h2`, `h3`, `h4`, `h5`, `h6`
106
+ - `div`
107
+ - `p`
108
+ - `code`
109
+
110
+ Default self-closing tags:
111
+
112
+ - `br`
113
+
114
+ Notes:
115
+
116
+ - Tag matching is case-insensitive.
117
+ - Nested tags are supported.
118
+ - Unsupported tags are treated as normal text.
119
+ - Tags with attributes are not parsed as tags (for example `<b class="x">`).
120
+
121
+ ### Basic example
122
+
123
+ ```ts
124
+ import { parseRichText } from '@dvirus-js/utils';
125
+
126
+ const input = 'Hello <b>world <i>now</i></b>!<br/>Done';
127
+ const segments = parseRichText(input);
128
+
129
+ /*
130
+ [
131
+ {
132
+ text: 'Hello ',
133
+ tagNames: '',
134
+ tagNamesList: [],
135
+ style: ''
136
+ },
137
+ {
138
+ text: 'world ',
139
+ tagNames: 'b',
140
+ tagNamesList: ['b'],
141
+ style: 'font-weight: bold'
142
+ },
143
+ {
144
+ text: 'now',
145
+ tagNames: 'b,i',
146
+ tagNamesList: ['b', 'i'],
147
+ style: 'font-weight: bold; font-style: italic'
148
+ },
149
+ {
150
+ text: '!',
151
+ tagNames: '',
152
+ tagNamesList: [],
153
+ style: ''
154
+ },
155
+ {
156
+ text: '',
157
+ tagNames: 'br',
158
+ tagNamesList: ['br'],
159
+ style: 'display: block'
160
+ },
161
+ {
162
+ text: 'Done',
163
+ tagNames: '',
164
+ tagNamesList: [],
165
+ style: ''
166
+ }
167
+ ]
168
+ */
169
+ ```
170
+
171
+ ### Add custom rich tags
172
+
173
+ You can register additional tags at runtime:
174
+
175
+ ```ts
176
+ import { parseRichText } from '@dvirus-js/utils';
177
+
178
+ parseRichText.addTag({
179
+ tag: 'newTag',
180
+ style: 'border:1px solid black, border-radius:1rem',
181
+ });
182
+
183
+ const out = parseRichText('Use <newTag>npm run build</newTag>');
184
+ ```
185
+
186
+ You can also register multiple tags in one call:
187
+
188
+ ```ts
189
+ import { parseRichText } from '@dvirus-js/utils';
190
+
191
+ parseRichText.addTag([
192
+ { tag: 'sub', style: 'vertical-align: sub; font-size: smaller' },
193
+ { tag: 'sup', style: 'vertical-align: super; font-size: smaller' },
194
+ ]);
195
+ ```
196
+
197
+ ### Add custom self-closing tags
198
+
199
+ ```ts
200
+ import { parseRichText } from '@dvirus-js/utils';
201
+
202
+ parseRichText.addSelfClosingTag({ tag: 'hr', style: 'display: block; border-top: 1px solid #ddd' });
203
+
204
+ const out = parseRichText('Line one<hr/>Line two');
205
+ ```
206
+
207
+ ### Alias tags to the same style key
208
+
209
+ Use `tagName` when you want multiple tags to map to the same style entry:
210
+
211
+ ```ts
212
+ import { addRichTextTag } from '@dvirus-js/utils';
213
+
214
+ addRichTextTag({ tag: 'strong', tagName: 'b' });
215
+ ```
216
+
217
+ This behaves like the built-in `strong` -> `b` and `em` -> `i` aliases.
218
+
219
+ ### Signals and branded types
220
+
221
+ ```ts
222
+ import { NumericString, computed, effect, signal } from '@dvirus-js/utils';
223
+
224
+ const count = signal(0);
225
+ const doubled = computed(() => count() * 2);
226
+
227
+ const ref = effect(() => {
228
+ console.log(count(), doubled());
229
+ });
230
+
231
+ count.set(2);
232
+
233
+ const userId = NumericString('12345');
234
+ console.log(userId);
235
+
236
+ ref.destroy();
237
+ ```
package/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export * from './lib/convert-cases';
2
+ export * from './lib/tryCatch';
3
+ export * from './lib/http';
4
+ export * from './lib/group-by';
5
+ export * from './lib/delay';
6
+ export * from './lib/getProp';
7
+ export * from './lib/Result';
8
+ export * from './lib/to-array';
9
+ export * from './lib/signals';
10
+ export * from './lib/html-text-parser';
11
+ export * from './lib/brand-type';