@demicodes/utils 0.14.0 → 0.14.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/dist/index.d.mts +18 -1
- package/dist/index.mjs +35 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -90,6 +90,23 @@ declare function base64ToBytes(base64: string): Uint8Array;
|
|
|
90
90
|
declare function clamp(value: number, min: number, max: number): number;
|
|
91
91
|
/** Strips trailing slashes from a base URL so paths can be appended consistently. */
|
|
92
92
|
declare function normalizeBaseUrl(baseUrl: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Slices the first `maxChars` UTF-16 units of `text` without splitting a
|
|
95
|
+
* surrogate pair: a cut that would leave a trailing lone high surrogate moves
|
|
96
|
+
* back one unit instead.
|
|
97
|
+
*/
|
|
98
|
+
declare function sliceHead(text: string, maxChars: number): string;
|
|
99
|
+
/**
|
|
100
|
+
* Slices the last `maxChars` UTF-16 units of `text` without splitting a
|
|
101
|
+
* surrogate pair: a cut that would leave a leading lone low surrogate moves
|
|
102
|
+
* forward one unit instead.
|
|
103
|
+
*/
|
|
104
|
+
declare function sliceTail(text: string, maxChars: number): string;
|
|
105
|
+
/**
|
|
106
|
+
* Replaces lone UTF-16 surrogates with U+FFFD so the string is well-formed
|
|
107
|
+
* Unicode and can be serialized into any wire payload.
|
|
108
|
+
*/
|
|
109
|
+
declare function toWellFormedText(text: string): string;
|
|
93
110
|
/** Truncates `text` to at most `maxChars` characters, appending `ellipsis` when shortened. */
|
|
94
111
|
declare function truncate(text: string, maxChars: number, ellipsis?: string): string;
|
|
95
112
|
/** Returns the last `maxChars` characters of `text`. */
|
|
@@ -137,4 +154,4 @@ declare function isAbsolutePath(path: string): boolean;
|
|
|
137
154
|
/** Generates a random UUID. */
|
|
138
155
|
declare function createId(): string;
|
|
139
156
|
//#endregion
|
|
140
|
-
export { AbortError, Deferred, PortableJsonValue, abortable, asError, asRecord, asString, base64ToBytes, bytesToBase64, clamp, concatBytes, createId, decodeLatin1, decodeUtf8, decodeUtf8Strict, deferred, delay, dirnamePath, encodeLatin1, encodeUtf8, errorCode, errorMessage, isAbortError, isAbsolutePath, isFileNotFoundError, isRecord, nonEmptyString, noop, normalizeBaseUrl, normalizePath, numberOrNull, numberOrZero, parseJsonObject, parseJsonOrString, parsePortableJson, safeJsonStringify, shortHash, stringOrNull, stringifyPortableJson, tail, throwIfAborted, truncate, utf8Bytes, utf8Slice, waitFor, withTimeout };
|
|
157
|
+
export { AbortError, Deferred, PortableJsonValue, abortable, asError, asRecord, asString, base64ToBytes, bytesToBase64, clamp, concatBytes, createId, decodeLatin1, decodeUtf8, decodeUtf8Strict, deferred, delay, dirnamePath, encodeLatin1, encodeUtf8, errorCode, errorMessage, isAbortError, isAbsolutePath, isFileNotFoundError, isRecord, nonEmptyString, noop, normalizeBaseUrl, normalizePath, numberOrNull, numberOrZero, parseJsonObject, parseJsonOrString, parsePortableJson, safeJsonStringify, shortHash, sliceHead, sliceTail, stringOrNull, stringifyPortableJson, tail, throwIfAborted, toWellFormedText, truncate, utf8Bytes, utf8Slice, waitFor, withTimeout };
|
package/dist/index.mjs
CHANGED
|
@@ -248,15 +248,46 @@ function clamp(value, min, max) {
|
|
|
248
248
|
function normalizeBaseUrl(baseUrl) {
|
|
249
249
|
return baseUrl.replace(/\/+$/, "");
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Slices the first `maxChars` UTF-16 units of `text` without splitting a
|
|
253
|
+
* surrogate pair: a cut that would leave a trailing lone high surrogate moves
|
|
254
|
+
* back one unit instead.
|
|
255
|
+
*/
|
|
256
|
+
function sliceHead(text, maxChars) {
|
|
257
|
+
if (maxChars <= 0) return "";
|
|
258
|
+
if (text.length <= maxChars) return text;
|
|
259
|
+
const cut = text.charCodeAt(maxChars - 1);
|
|
260
|
+
return text.slice(0, cut >= 55296 && cut <= 56319 ? maxChars - 1 : maxChars);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Slices the last `maxChars` UTF-16 units of `text` without splitting a
|
|
264
|
+
* surrogate pair: a cut that would leave a leading lone low surrogate moves
|
|
265
|
+
* forward one unit instead.
|
|
266
|
+
*/
|
|
267
|
+
function sliceTail(text, maxChars) {
|
|
268
|
+
if (maxChars <= 0) return "";
|
|
269
|
+
if (text.length <= maxChars) return text;
|
|
270
|
+
const start = text.length - maxChars;
|
|
271
|
+
const cut = text.charCodeAt(start);
|
|
272
|
+
return text.slice(cut >= 56320 && cut <= 57343 ? start + 1 : start);
|
|
273
|
+
}
|
|
274
|
+
const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
275
|
+
/**
|
|
276
|
+
* Replaces lone UTF-16 surrogates with U+FFFD so the string is well-formed
|
|
277
|
+
* Unicode and can be serialized into any wire payload.
|
|
278
|
+
*/
|
|
279
|
+
function toWellFormedText(text) {
|
|
280
|
+
return text.replace(LONE_SURROGATE, "�");
|
|
281
|
+
}
|
|
251
282
|
/** Truncates `text` to at most `maxChars` characters, appending `ellipsis` when shortened. */
|
|
252
283
|
function truncate(text, maxChars, ellipsis = "…") {
|
|
253
284
|
if (text.length <= maxChars) return text;
|
|
254
|
-
if (maxChars <= ellipsis.length) return text
|
|
255
|
-
return text
|
|
285
|
+
if (maxChars <= ellipsis.length) return sliceHead(text, maxChars);
|
|
286
|
+
return sliceHead(text, maxChars - ellipsis.length) + ellipsis;
|
|
256
287
|
}
|
|
257
288
|
/** Returns the last `maxChars` characters of `text`. */
|
|
258
289
|
function tail(text, maxChars) {
|
|
259
|
-
return
|
|
290
|
+
return sliceTail(text, maxChars);
|
|
260
291
|
}
|
|
261
292
|
/** A short, stable hex hash of a string (32-bit FNV-1a). Not cryptographic. */
|
|
262
293
|
function shortHash(value) {
|
|
@@ -389,4 +420,4 @@ function createId() {
|
|
|
389
420
|
return globalThis.crypto.randomUUID();
|
|
390
421
|
}
|
|
391
422
|
//#endregion
|
|
392
|
-
export { AbortError, abortable, asError, asRecord, asString, base64ToBytes, bytesToBase64, clamp, concatBytes, createId, decodeLatin1, decodeUtf8, decodeUtf8Strict, deferred, delay, dirnamePath, encodeLatin1, encodeUtf8, errorCode, errorMessage, isAbortError, isAbsolutePath, isFileNotFoundError, isRecord, nonEmptyString, noop, normalizeBaseUrl, normalizePath, numberOrNull, numberOrZero, parseJsonObject, parseJsonOrString, parsePortableJson, safeJsonStringify, shortHash, stringOrNull, stringifyPortableJson, tail, throwIfAborted, truncate, utf8Bytes, utf8Slice, waitFor, withTimeout };
|
|
423
|
+
export { AbortError, abortable, asError, asRecord, asString, base64ToBytes, bytesToBase64, clamp, concatBytes, createId, decodeLatin1, decodeUtf8, decodeUtf8Strict, deferred, delay, dirnamePath, encodeLatin1, encodeUtf8, errorCode, errorMessage, isAbortError, isAbsolutePath, isFileNotFoundError, isRecord, nonEmptyString, noop, normalizeBaseUrl, normalizePath, numberOrNull, numberOrZero, parseJsonObject, parseJsonOrString, parsePortableJson, safeJsonStringify, shortHash, sliceHead, sliceTail, stringOrNull, stringifyPortableJson, tail, throwIfAborted, toWellFormedText, truncate, utf8Bytes, utf8Slice, waitFor, withTimeout };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@demicodes/utils",
|
|
3
3
|
"description": "Shared zero-dependency utilities for Demi (type guards, errors, async, bytes, strings, paths, JSON).",
|
|
4
|
-
"version": "0.14.
|
|
4
|
+
"version": "0.14.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.mjs",
|