ranuts 0.5.0 → 0.5.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/CLAUDE.md +1 -1
- package/README.de.md +4 -4
- package/README.es.md +4 -4
- package/README.fa.md +4 -4
- package/README.ja.md +4 -4
- package/README.ko.md +4 -4
- package/README.md +4 -4
- package/README.pt.md +4 -4
- package/README.zh-CN.md +4 -4
- package/dist/iife/index.iife.js +1 -1
- package/dist/iife/utils.iife.js +1 -1
- package/dist/index.js +294 -293
- package/dist/src/utils/charset.d.ts +15 -0
- package/dist/src/utils/charset.js +21 -0
- package/dist/src/utils/index.d.ts +4 -2
- package/dist/src/utils/index.js +294 -293
- package/dist/src/utils/script.d.ts +3 -1
- package/dist/src/utils/script.js +33 -34
- package/dist/src/utils/scroll.d.ts +2 -0
- package/dist/src/utils/scroll.js +25 -25
- package/dist/src/utils/str.d.ts +0 -15
- package/dist/src/utils/str.js +70 -88
- package/package.json +4 -4
package/dist/src/utils/script.js
CHANGED
|
@@ -1,46 +1,45 @@
|
|
|
1
|
-
var
|
|
2
|
-
const
|
|
3
|
-
if (
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
var a = /* @__PURE__ */ new Map(), m = ({ type: s, content: o }) => {
|
|
2
|
+
const r = `${s}:${o}`, c = a.get(r);
|
|
3
|
+
if (c) return c;
|
|
4
|
+
const e = document.createElement("script");
|
|
5
|
+
if (s === "content") {
|
|
6
|
+
e.textContent = o, document.body.append(e);
|
|
7
|
+
const t = Promise.resolve({ success: !0 });
|
|
8
|
+
return a.set(r, t), t;
|
|
6
9
|
}
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let s;
|
|
25
|
-
if (n) {
|
|
26
|
-
const c = document.createElement("link");
|
|
27
|
-
c.type = "text/css", c.rel = "stylesheet", c.href = e, s = c;
|
|
10
|
+
const i = new Promise((t, d) => {
|
|
11
|
+
e.onload = () => t({ success: !0 }), e.onerror = (n) => {
|
|
12
|
+
a.delete(r), e.remove(), d({
|
|
13
|
+
success: !1,
|
|
14
|
+
error: n
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
return a.set(r, i), e.src = o, document.body.append(e), i;
|
|
19
|
+
}, p = (s, o, r) => {
|
|
20
|
+
s = Array.isArray(s) ? s : [s];
|
|
21
|
+
const c = s.map((e) => {
|
|
22
|
+
const i = e.toLowerCase().endsWith(".css");
|
|
23
|
+
let t;
|
|
24
|
+
if (i) {
|
|
25
|
+
const n = document.createElement("link");
|
|
26
|
+
n.type = "text/css", n.rel = "stylesheet", n.href = e, t = n;
|
|
28
27
|
} else
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
return (o ||
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
t = document.createElement("script"), t.type = "text/javascript", t.src = e;
|
|
29
|
+
const d = document.getElementsByTagName("body")[0];
|
|
30
|
+
return (o || d).appendChild(t), new Promise((n) => {
|
|
31
|
+
t.onload = () => {
|
|
32
|
+
n();
|
|
34
33
|
};
|
|
35
34
|
});
|
|
36
35
|
});
|
|
37
36
|
return new Promise((e) => {
|
|
38
|
-
Promise.all(
|
|
37
|
+
Promise.all(c).then(() => {
|
|
39
38
|
r && r(), e();
|
|
40
39
|
});
|
|
41
40
|
});
|
|
42
41
|
};
|
|
43
42
|
export {
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
m as loadScript,
|
|
44
|
+
p as scriptOnLoad
|
|
46
45
|
};
|
|
@@ -41,6 +41,8 @@ export interface BottomFollowerOptions {
|
|
|
41
41
|
observe?: readonly HTMLElement[];
|
|
42
42
|
/** Distance from the floor still counted as pinned. Defaults to 24. */
|
|
43
43
|
threshold?: number;
|
|
44
|
+
/** Current intent for automatic following; explicit navigation remains available. */
|
|
45
|
+
enabled?: () => boolean;
|
|
44
46
|
/**
|
|
45
47
|
* Called when the pinned state flips, so a caller can show or hide a "jump to latest"
|
|
46
48
|
* affordance. Never called for a change the caller itself just made synchronously.
|
package/dist/src/utils/scroll.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
var b = 24;
|
|
2
|
-
function H(
|
|
3
|
-
return Math.max(0,
|
|
2
|
+
function H(l) {
|
|
3
|
+
return Math.max(0, l.scrollHeight - l.clientHeight);
|
|
4
4
|
}
|
|
5
|
-
function h(
|
|
6
|
-
return
|
|
5
|
+
function h(l, e) {
|
|
6
|
+
return l.getBoundingClientRect().top - e.getBoundingClientRect().top;
|
|
7
7
|
}
|
|
8
|
-
function m(
|
|
9
|
-
const { scrollport: e, observe:
|
|
10
|
-
let
|
|
11
|
-
const
|
|
12
|
-
o !==
|
|
8
|
+
function m(l) {
|
|
9
|
+
const { scrollport: e, observe: f = [], threshold: g = b, onPinnedChange: T } = l;
|
|
10
|
+
let r = !0, n = e.scrollTop, t = null, c = !1;
|
|
11
|
+
const a = (o) => {
|
|
12
|
+
o !== r && (r = o, T?.(o));
|
|
13
13
|
}, s = (o) => {
|
|
14
14
|
e.scrollTop = o, n = e.scrollTop;
|
|
15
|
-
}, a = () => {
|
|
16
|
-
t = null, s(e.scrollHeight), p(!0);
|
|
17
15
|
}, d = () => {
|
|
16
|
+
t = null, s(e.scrollHeight), a(!0);
|
|
17
|
+
}, p = () => {
|
|
18
18
|
const o = H(e);
|
|
19
19
|
if (!(Math.abs(e.scrollTop - Math.min(n, o)) > 0.5)) {
|
|
20
|
-
l ?
|
|
20
|
+
r && l.enabled?.() !== !1 ? d() : n = e.scrollTop;
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
n = e.scrollTop,
|
|
23
|
+
n = e.scrollTop, a(o - e.scrollTop <= g);
|
|
24
24
|
};
|
|
25
|
-
e.addEventListener("scroll",
|
|
26
|
-
let
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
e.addEventListener("scroll", p, { passive: !0 });
|
|
26
|
+
let i = null;
|
|
27
|
+
if (f.length > 0 && typeof ResizeObserver < "u") {
|
|
28
|
+
i = new ResizeObserver(() => {
|
|
29
|
+
r && !c && l.enabled?.() !== !1 && s(e.scrollHeight);
|
|
30
30
|
});
|
|
31
|
-
for (const o of
|
|
31
|
+
for (const o of f) i.observe(o);
|
|
32
32
|
}
|
|
33
33
|
return {
|
|
34
34
|
get pinned() {
|
|
35
|
-
return
|
|
35
|
+
return r;
|
|
36
36
|
},
|
|
37
|
-
toBottom:
|
|
37
|
+
toBottom: d,
|
|
38
38
|
follow() {
|
|
39
|
-
l && s(e.scrollHeight);
|
|
39
|
+
r && !c && l.enabled?.() !== !1 && s(e.scrollHeight);
|
|
40
40
|
},
|
|
41
41
|
captureAnchor(o) {
|
|
42
42
|
t = {
|
|
@@ -46,14 +46,14 @@ function m(r) {
|
|
|
46
46
|
},
|
|
47
47
|
restoreAnchor(o) {
|
|
48
48
|
if (t === null) return !1;
|
|
49
|
-
const
|
|
50
|
-
return t = null,
|
|
49
|
+
const u = o === void 0 ? t.row : o(), { top: v } = t;
|
|
50
|
+
return t = null, u === null || !e.contains(u) ? !1 : (s(e.scrollTop + h(u, e) - v), !0);
|
|
51
51
|
},
|
|
52
52
|
releaseAnchor() {
|
|
53
53
|
t = null;
|
|
54
54
|
},
|
|
55
55
|
destroy() {
|
|
56
|
-
|
|
56
|
+
c = !0, e.removeEventListener("scroll", p), i?.disconnect();
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
}
|
package/dist/src/utils/str.d.ts
CHANGED
|
@@ -43,16 +43,6 @@ export declare const clearStr: (str: string, options?: ClearStrOption) => string
|
|
|
43
43
|
*/
|
|
44
44
|
export declare function getMatchingSentences(text: string, searchValue: string): string[];
|
|
45
45
|
export declare const toString: (value: string | number) => string;
|
|
46
|
-
export declare const checkEncoding: (uint8Array: Uint8Array) => string;
|
|
47
|
-
/**
|
|
48
|
-
* @description: Decode bytes into a string using the sniffed encoding. Required when reading
|
|
49
|
-
* text files of unknown provenance (a user-uploaded txt, content scraped off an old site) —
|
|
50
|
-
* a plain `new TextDecoder().decode()` turns GBK/Big5 into mojibake, and such files are a
|
|
51
|
-
* sizeable share of Chinese-language content.
|
|
52
|
-
* @param {ArrayBuffer | Uint8Array} buffer
|
|
53
|
-
* @return {string}
|
|
54
|
-
*/
|
|
55
|
-
export declare const arrayBufferToString: (buffer: ArrayBuffer | Uint8Array) => string;
|
|
56
46
|
/**
|
|
57
47
|
* @description: Convert full-width characters to half-width (digits, letters, punctuation and
|
|
58
48
|
* the ideographic space). Full-width digits produced by a Chinese IME are not equivalent to
|
|
@@ -102,11 +92,6 @@ export interface TruncateOptions {
|
|
|
102
92
|
* ```
|
|
103
93
|
*/
|
|
104
94
|
export declare const truncate: (value: string, options: TruncateOptions | number) => string;
|
|
105
|
-
export interface TransformText {
|
|
106
|
-
encoding: string;
|
|
107
|
-
content: string;
|
|
108
|
-
}
|
|
109
|
-
export declare const transformText: (content: string | ArrayBuffer) => TransformText | undefined;
|
|
110
95
|
/**
|
|
111
96
|
* @description: A short random-ish base-36 string.
|
|
112
97
|
*
|
package/dist/src/utils/str.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
var m = (r = "", e = "", t = "") => {
|
|
1
|
+
var w = (r = "", e = "", t = "") => {
|
|
3
2
|
const n = {}, o = r.split(e);
|
|
4
|
-
return o.length > 0 && o.forEach((
|
|
5
|
-
const [h = "", s = ""] =
|
|
3
|
+
return o.length > 0 && o.forEach((c) => {
|
|
4
|
+
const [h = "", s = ""] = c.split(t);
|
|
6
5
|
u(h) && (n[u(h)] = u(s));
|
|
7
6
|
}), n;
|
|
8
|
-
},
|
|
7
|
+
}, g = (r = "") => {
|
|
9
8
|
if (r.length === 0) return "";
|
|
10
9
|
let e = "", t = 0;
|
|
11
10
|
for (const n of r)
|
|
@@ -21,8 +20,8 @@ var m = (r = "", e = "", t = "") => {
|
|
|
21
20
|
t === 0 && (e += n);
|
|
22
21
|
}
|
|
23
22
|
return e;
|
|
24
|
-
},
|
|
25
|
-
function
|
|
23
|
+
}, p = (r) => window.toString.call(r) === "[object String]";
|
|
24
|
+
function m(r = 8) {
|
|
26
25
|
const e = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
|
|
27
26
|
let n = "";
|
|
28
27
|
for (let o = 0; o < r; o++) n += e.charAt(Math.floor(Math.random() * 48));
|
|
@@ -32,83 +31,69 @@ var u = (r, e = {}) => {
|
|
|
32
31
|
const { urlencoded: t = !0 } = e, n = String.prototype.trim.call(r);
|
|
33
32
|
return t ? decodeURIComponent(n).replace(/"|'/g, "") : n.replace(/"|'/g, "");
|
|
34
33
|
};
|
|
35
|
-
function
|
|
34
|
+
function E(r, e) {
|
|
36
35
|
if (!r || !e) return [];
|
|
37
36
|
const t = [], n = new RegExp(e, "gi");
|
|
38
37
|
let o;
|
|
39
38
|
for (; (o = n.exec(r)) !== null; ) {
|
|
40
39
|
const s = o.index;
|
|
41
|
-
let
|
|
42
|
-
for (;
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
` ||
|
|
46
|
-
|
|
40
|
+
let a = s;
|
|
41
|
+
for (; a > 0; ) {
|
|
42
|
+
const d = r[a - 1];
|
|
43
|
+
if (d === "。" || d === "." || d === `
|
|
44
|
+
` || d === "!" || d === "?" || d === "?") break;
|
|
45
|
+
a--;
|
|
47
46
|
}
|
|
48
47
|
let l = s + e.length;
|
|
49
48
|
for (; l < r.length; ) {
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
52
|
-
` ||
|
|
49
|
+
const d = r[l];
|
|
50
|
+
if (d === "。" || d === "." || d === `
|
|
51
|
+
` || d === "!" || d === "?" || d === "?") {
|
|
53
52
|
l++;
|
|
54
53
|
break;
|
|
55
54
|
}
|
|
56
55
|
l++;
|
|
57
56
|
}
|
|
58
|
-
const f = r.slice(
|
|
57
|
+
const f = r.slice(a, l).trim();
|
|
59
58
|
f && t.push({
|
|
60
59
|
sentence: f,
|
|
61
|
-
start:
|
|
60
|
+
start: a,
|
|
62
61
|
end: l
|
|
63
62
|
});
|
|
64
63
|
}
|
|
65
|
-
const
|
|
66
|
-
t.sort((s,
|
|
67
|
-
for (const s of t) h.some((
|
|
64
|
+
const c = [], h = [];
|
|
65
|
+
t.sort((s, a) => a.sentence.length - s.sentence.length);
|
|
66
|
+
for (const s of t) h.some((a) => !(s.end <= a.start || s.start >= a.end)) || (c.push(s.sentence), h.push({
|
|
68
67
|
start: s.start,
|
|
69
68
|
end: s.end
|
|
70
69
|
}));
|
|
71
|
-
return [...new Set(
|
|
70
|
+
return [...new Set(c)];
|
|
72
71
|
}
|
|
73
|
-
var
|
|
74
|
-
const e = Array.from(r).map((t) => String.fromCharCode(t)).join("");
|
|
75
|
-
return w(e).encoding || "utf-8";
|
|
76
|
-
}, R = (r) => {
|
|
77
|
-
const e = r instanceof Uint8Array ? r : new Uint8Array(r);
|
|
78
|
-
return new TextDecoder(g(e)).decode(e);
|
|
79
|
-
}, I = (r) => r.replace(/[!-~]/g, (e) => String.fromCharCode(e.charCodeAt(0) - 65248)).replace(/\u3000/g, " "), b = (r) => r.replace(/[!-~]/g, (e) => String.fromCharCode(e.charCodeAt(0) + 65248)).replace(/ /g, " "), M = (r, e) => {
|
|
72
|
+
var C = (r) => String(r), A = (r) => r.replace(/[!-~]/g, (e) => String.fromCharCode(e.charCodeAt(0) - 65248)).replace(/\u3000/g, " "), S = (r) => r.replace(/[!-~]/g, (e) => String.fromCharCode(e.charCodeAt(0) + 65248)).replace(/ /g, " "), R = (r, e) => {
|
|
80
73
|
const { length: t, position: n = "end", ellipsis: o = "…" } = typeof e == "number" ? { length: e } : e;
|
|
81
74
|
if (!r) return r;
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
75
|
+
const c = Array.from(r), h = Array.from(o);
|
|
76
|
+
if (c.length <= t) return r;
|
|
84
77
|
if (t <= h.length) return h.slice(0, Math.max(0, t)).join("");
|
|
85
78
|
const s = t - h.length;
|
|
86
|
-
if (n === "start") return o +
|
|
79
|
+
if (n === "start") return o + c.slice(c.length - s).join("");
|
|
87
80
|
if (n === "middle") {
|
|
88
|
-
const
|
|
89
|
-
return
|
|
81
|
+
const a = Math.ceil(s / 2);
|
|
82
|
+
return c.slice(0, a).join("") + o + c.slice(c.length - (s - a)).join("");
|
|
90
83
|
}
|
|
91
|
-
return
|
|
92
|
-
},
|
|
93
|
-
if (r instanceof ArrayBuffer) {
|
|
94
|
-
const e = new Uint8Array(r), t = String.fromCharCode.apply(null, e), n = w(t), o = n.encoding || "utf-8", a = new TextDecoder(o).decode(r);
|
|
95
|
-
if (n.encoding && a) return {
|
|
96
|
-
encoding: n.encoding,
|
|
97
|
-
content: a
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}, U = (r = 8) => Math.random().toString(36).substring(2, r + 2), d = class extends Error {
|
|
84
|
+
return c.slice(0, s).join("") + o;
|
|
85
|
+
}, b = (r = 8) => Math.random().toString(36).substring(2, r + 2), i = class extends Error {
|
|
101
86
|
code;
|
|
102
87
|
constructor(r, e) {
|
|
103
88
|
super(r), this.code = e, this.name = "MessageCodecError";
|
|
104
89
|
}
|
|
105
|
-
},
|
|
90
|
+
}, v = {
|
|
106
91
|
encode(r) {
|
|
107
92
|
try {
|
|
108
93
|
const e = JSON.stringify(r), t = new TextEncoder().encode(e);
|
|
109
94
|
let n = "";
|
|
110
95
|
const o = 32768;
|
|
111
|
-
for (let
|
|
96
|
+
for (let c = 0; c < t.length; c += o) n += String.fromCharCode.apply(null, Array.from(t.subarray(c, c + o)));
|
|
112
97
|
return btoa(n);
|
|
113
98
|
} catch {
|
|
114
99
|
return "";
|
|
@@ -136,20 +121,20 @@ var v = (r) => String(r), g = (r) => {
|
|
|
136
121
|
content: new Uint8Array(e)
|
|
137
122
|
});
|
|
138
123
|
} catch (e) {
|
|
139
|
-
throw new
|
|
124
|
+
throw new i(`Failed to encode file: ${e instanceof Error ? e.message : "Unknown error"}`, "FILE_ENCODE_ERROR");
|
|
140
125
|
}
|
|
141
126
|
},
|
|
142
127
|
decodeFile(r) {
|
|
143
128
|
try {
|
|
144
129
|
const e = this.decode(r);
|
|
145
|
-
if (e.type !== "File") throw new
|
|
130
|
+
if (e.type !== "File") throw new i(`Expected File type but got ${e.type}`, "INVALID_FILE_TYPE");
|
|
146
131
|
const t = e, n = t.content instanceof Uint8Array ? t.content.buffer.slice(0) : t.content;
|
|
147
132
|
return new File([n], t.name, {
|
|
148
133
|
type: t.mimeType,
|
|
149
134
|
lastModified: t.lastModified
|
|
150
135
|
});
|
|
151
136
|
} catch (e) {
|
|
152
|
-
throw e instanceof
|
|
137
|
+
throw e instanceof i ? e : new i(`Failed to decode file: ${e instanceof Error ? e.message : "Unknown error"}`, "FILE_DECODE_ERROR");
|
|
153
138
|
}
|
|
154
139
|
},
|
|
155
140
|
async encodeBlob(r) {
|
|
@@ -162,17 +147,17 @@ var v = (r) => String(r), g = (r) => {
|
|
|
162
147
|
content: new Uint8Array(e)
|
|
163
148
|
});
|
|
164
149
|
} catch (e) {
|
|
165
|
-
throw new
|
|
150
|
+
throw new i(`Failed to encode blob: ${e instanceof Error ? e.message : "Unknown error"}`, "BLOB_ENCODE_ERROR");
|
|
166
151
|
}
|
|
167
152
|
},
|
|
168
153
|
decodeBlob(r) {
|
|
169
154
|
try {
|
|
170
155
|
const e = this.decode(r);
|
|
171
|
-
if (e.type !== "Blob") throw new
|
|
156
|
+
if (e.type !== "Blob") throw new i(`Expected Blob type but got ${e.type}`, "INVALID_BLOB_TYPE");
|
|
172
157
|
const t = e, n = t.content instanceof Uint8Array ? t.content.buffer.slice(0) : t.content;
|
|
173
158
|
return new Blob([n], { type: t.mimeType });
|
|
174
159
|
} catch (e) {
|
|
175
|
-
throw e instanceof
|
|
160
|
+
throw e instanceof i ? e : new i(`Failed to decode blob: ${e instanceof Error ? e.message : "Unknown error"}`, "BLOB_DECODE_ERROR");
|
|
176
161
|
}
|
|
177
162
|
},
|
|
178
163
|
encodeDate(r) {
|
|
@@ -316,10 +301,10 @@ var v = (r) => String(r), g = (r) => {
|
|
|
316
301
|
},
|
|
317
302
|
async encodeFileChunked(r, e = 16384) {
|
|
318
303
|
try {
|
|
319
|
-
if (e <= 0) throw new
|
|
304
|
+
if (e <= 0) throw new i("Chunk size must be greater than 0", "INVALID_CHUNK_SIZE");
|
|
320
305
|
const t = Math.ceil(r.size / e), n = [];
|
|
321
306
|
for (let o = 0; o < t; o++) {
|
|
322
|
-
const
|
|
307
|
+
const c = o * e, h = Math.min(c + e, r.size), s = await r.slice(c, h).arrayBuffer(), a = String.fromCharCode.apply(null, Array.from(new Uint8Array(s)));
|
|
323
308
|
n.push({
|
|
324
309
|
name: r.name,
|
|
325
310
|
type: r.type,
|
|
@@ -327,38 +312,38 @@ var v = (r) => String(r), g = (r) => {
|
|
|
327
312
|
lastModified: r.lastModified,
|
|
328
313
|
totalChunks: t,
|
|
329
314
|
chunkIndex: o,
|
|
330
|
-
data:
|
|
315
|
+
data: a
|
|
331
316
|
});
|
|
332
317
|
}
|
|
333
318
|
return n;
|
|
334
319
|
} catch (t) {
|
|
335
|
-
throw t instanceof
|
|
320
|
+
throw t instanceof i ? t : new i(`Failed to encode file chunks: ${t instanceof Error ? t.message : "Unknown error"}`, "FILE_CHUNK_ENCODE_ERROR");
|
|
336
321
|
}
|
|
337
322
|
},
|
|
338
323
|
async decodeFileChunked(r) {
|
|
339
324
|
try {
|
|
340
|
-
if (!r.length) throw new
|
|
325
|
+
if (!r.length) throw new i("No chunks provided", "NO_CHUNKS");
|
|
341
326
|
const { type: e, lastModified: t, totalChunks: n } = r[0];
|
|
342
|
-
if (r.length !== n) throw new
|
|
343
|
-
r.sort((
|
|
344
|
-
for (let
|
|
345
|
-
const o = await Promise.all(r.map(async (
|
|
346
|
-
const l =
|
|
347
|
-
for (let
|
|
327
|
+
if (r.length !== n) throw new i(`Missing chunks. Expected ${n}, got ${r.length}`, "INCOMPLETE_CHUNKS");
|
|
328
|
+
r.sort((a, l) => a.chunkIndex - l.chunkIndex);
|
|
329
|
+
for (let a = 0; a < r.length; a++) if (r[a].chunkIndex !== a) throw new i(`Invalid chunk index at position ${a}`, "INVALID_CHUNK_ORDER");
|
|
330
|
+
const o = await Promise.all(r.map(async (a) => {
|
|
331
|
+
const l = a.data, f = new Uint8Array(l.length);
|
|
332
|
+
for (let d = 0; d < l.length; d++) f[d] = l.charCodeAt(d);
|
|
348
333
|
return f;
|
|
349
|
-
})),
|
|
334
|
+
})), c = r.reduce((a, l) => a + l.data.length, 0), h = new Uint8Array(c);
|
|
350
335
|
let s = 0;
|
|
351
|
-
for (const
|
|
352
|
-
h.set(
|
|
336
|
+
for (const a of o)
|
|
337
|
+
h.set(a, s), s += a.length;
|
|
353
338
|
return new File([h.buffer.slice(0)], r[0].name, {
|
|
354
339
|
type: e,
|
|
355
340
|
lastModified: t
|
|
356
341
|
});
|
|
357
342
|
} catch (e) {
|
|
358
|
-
throw e instanceof
|
|
343
|
+
throw e instanceof i ? e : new i(`Failed to decode file chunks: ${e instanceof Error ? e.message : "Unknown error"}`, "FILE_CHUNK_DECODE_ERROR");
|
|
359
344
|
}
|
|
360
345
|
}
|
|
361
|
-
},
|
|
346
|
+
}, I = (r, e, t = "…[truncated]") => r.length > e ? r.slice(0, e) + t : r, M = (r, e = "") => {
|
|
362
347
|
const t = Math.max(0, ...Array.from(r.matchAll(/`+/g), (o) => o[0].length)), n = "`".repeat(Math.max(3, t + 1));
|
|
363
348
|
return `${n}${e}
|
|
364
349
|
${r}
|
|
@@ -368,28 +353,25 @@ ${n}`;
|
|
|
368
353
|
for (; e < t && r[e] === "-"; ) e++;
|
|
369
354
|
for (; t > e && r[t - 1] === "-"; ) t--;
|
|
370
355
|
return r.slice(e, t);
|
|
371
|
-
},
|
|
356
|
+
}, D = (r, e = 60) => y(y(r.toLowerCase().replace(/[^a-z0-9]+/g, "-")).slice(0, e)), B = (r) => {
|
|
372
357
|
const e = String(r), t = /^[=+\-@]/.test(e) ? `'${e}` : e;
|
|
373
358
|
return /[",\n\r]/.test(t) ? `"${t.replace(/"/g, '""')}"` : t;
|
|
374
359
|
};
|
|
375
360
|
export {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
g as checkEncoding,
|
|
379
|
-
E as clearBr,
|
|
361
|
+
v as MessageCodec,
|
|
362
|
+
g as clearBr,
|
|
380
363
|
u as clearStr,
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
_ as truncateWithMarker
|
|
364
|
+
B as csvEscape,
|
|
365
|
+
M as fenceCode,
|
|
366
|
+
E as getMatchingSentences,
|
|
367
|
+
b as getRandomString,
|
|
368
|
+
p as isString,
|
|
369
|
+
m as randomString,
|
|
370
|
+
D as slugify,
|
|
371
|
+
w as strParse,
|
|
372
|
+
S as toFullWidth,
|
|
373
|
+
A as toHalfWidth,
|
|
374
|
+
C as toString,
|
|
375
|
+
R as truncate,
|
|
376
|
+
I as truncateWithMarker
|
|
395
377
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ranuts",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Tree-shakeable TypeScript utility library: DOM/BOM helpers, string/object/number/color utils, debounce/throttle/compose, a 2D rendering engine and a virtual DOM.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -95,11 +95,11 @@
|
|
|
95
95
|
"@types/node": "26.1.2",
|
|
96
96
|
"@vitest/coverage-v8": "4.1.11",
|
|
97
97
|
"@webgpu/types": "0.1.71",
|
|
98
|
-
"jsdom": "
|
|
98
|
+
"jsdom": "30.0.1",
|
|
99
99
|
"terser": "5.49.2",
|
|
100
100
|
"tsx": "4.23.10",
|
|
101
101
|
"typescript": "7.0.2",
|
|
102
|
-
"vite": "8.2.
|
|
102
|
+
"vite": "8.2.4",
|
|
103
103
|
"vitest": "4.1.11"
|
|
104
104
|
},
|
|
105
105
|
"dependencies": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"build": "sh ./bin/build.sh",
|
|
110
110
|
"test": "vitest run",
|
|
111
111
|
"test:coverage": "vitest run --coverage",
|
|
112
|
-
"verify:package": "node bin/verify-package.
|
|
112
|
+
"verify:package": "node bin/verify-package.ts",
|
|
113
113
|
"tsc": "tsc --noEmit",
|
|
114
114
|
"dev": "vite --host",
|
|
115
115
|
"doc:api": "tsx ./bin/generate-api-docs.ts",
|