Skip to content

Commit 37cfc7f

Browse files
圧縮ライブラリを変更 (#5)
* fix open file * migrate svelte/stores to rune * Update src/routes/utils/read-text-file-on-tauri.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Coderabbitの修正で発生した問題を修正。 * update read-text-file-on-tauri * add error handling * add robots.txt etc... * add save file * 0.1.1 * bump version * fix error handling * Modify the string compression library. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 8af93d7 commit 37cfc7f

File tree

4 files changed

+126
-16
lines changed

4 files changed

+126
-16
lines changed

src/routes/+page.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ let preview = $derived.by(() => {
3636
3737
let urlSearchParams = $page.url.searchParams;
3838
if (urlSearchParams) {
39-
const result = generateSearchParamsToText(urlSearchParams);
40-
if (result) {
39+
generateSearchParamsToText(urlSearchParams).then((result) => {
4140
inputText = result;
42-
}
41+
});
4342
}
4443
4544
function handleFileChange(event: Event) {
@@ -49,8 +48,9 @@ function handleFileChange(event: Event) {
4948
}
5049
5150
function CopyUrlToClipboard(inputText: string) {
52-
const url = generateCompressedNovelUrl(inputText);
53-
navigator.clipboard.writeText(url);
51+
generateCompressedNovelUrl(inputText).then((url) => {
52+
navigator.clipboard.writeText(url);
53+
});
5454
}
5555
5656
if (isTauriApp()) {

src/routes/utils/compression.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const textEncoder = new TextEncoder();
2+
const textDecoder = new TextDecoder();
3+
4+
const createUpstream = (value: unknown) => {
5+
return new ReadableStream({
6+
start(controller) {
7+
controller.enqueue(value);
8+
controller.close();
9+
},
10+
});
11+
};
12+
13+
export async function compressToBase64(input: string): Promise<string> {
14+
const upstream = createUpstream(textEncoder.encode(input));
15+
const compression = new CompressionStream("deflate");
16+
const stream = upstream.pipeThrough(compression);
17+
const compressed = await new Response(stream).arrayBuffer();
18+
return btoa(
19+
new Uint8Array(compressed).reduce(
20+
(acc, c) => acc + String.fromCharCode(c),
21+
"",
22+
),
23+
);
24+
}
25+
26+
export async function decompressFromBase64(input: string): Promise<string> {
27+
const compressedBytes = Uint8Array.from(atob(input), (c) => c.charCodeAt(0));
28+
const upstream = createUpstream(compressedBytes);
29+
const decompression = new DecompressionStream("deflate");
30+
const stream = upstream.pipeThrough(decompression);
31+
const decompressed = await new Response(stream).arrayBuffer();
32+
return textDecoder.decode(decompressed);
33+
}
34+
35+
export async function compressToUTF16(input: string): Promise<string> {
36+
const upstream = createUpstream(textEncoder.encode(input));
37+
const compression = new CompressionStream("deflate");
38+
const stream = upstream.pipeThrough(compression);
39+
const compressed = await new Response(stream).arrayBuffer();
40+
41+
let compressedBytes = new Uint8Array(compressed);
42+
43+
if (compressedBytes.length % 2 !== 0) {
44+
const paddedBytes = new Uint8Array(compressedBytes.length + 1);
45+
paddedBytes.set(compressedBytes);
46+
paddedBytes[compressedBytes.length] = 0; // 奇数個配列の場合、最後のバイトに 0 をパディング
47+
compressedBytes = paddedBytes;
48+
}
49+
50+
const compressedUint16Array = new Uint16Array(compressedBytes.buffer);
51+
return String.fromCharCode(...compressedUint16Array);
52+
}
53+
54+
export async function decompressFromUTF16(input: string): Promise<string> {
55+
const compressedUint16Array = new Uint16Array(
56+
input.split("").map((c) => c.charCodeAt(0)),
57+
);
58+
let compressedBytes = new Uint8Array(compressedUint16Array.buffer);
59+
60+
if (compressedBytes[compressedBytes.length - 1] === 0) {
61+
compressedBytes = compressedBytes.slice(0, compressedBytes.length - 1); // パディングされた 0 を削除
62+
}
63+
64+
const upstream = createUpstream(compressedBytes);
65+
const decompression = new DecompressionStream("deflate");
66+
const stream = upstream.pipeThrough(decompression);
67+
const decompressed = await new Response(stream).arrayBuffer();
68+
return textDecoder.decode(decompressed);
69+
}
70+
71+
export async function compressToUint8Array(input: string): Promise<Uint8Array> {
72+
const upstream = createUpstream(textEncoder.encode(input));
73+
const compression = new CompressionStream("deflate");
74+
const stream = upstream.pipeThrough(compression);
75+
const compressed = await new Response(stream).arrayBuffer();
76+
return new Uint8Array(compressed);
77+
}
78+
79+
export async function decompressFromUint8Array(
80+
input: Uint8Array,
81+
): Promise<string> {
82+
const upstream = createUpstream(input);
83+
const decompression = new DecompressionStream("deflate");
84+
const stream = upstream.pipeThrough(decompression);
85+
const decompressed = await new Response(stream).arrayBuffer();
86+
return textDecoder.decode(decompressed);
87+
}
88+
89+
export async function compressToEncodedURIComponent(
90+
input: string,
91+
): Promise<string> {
92+
const withBase64 = await compressToBase64(input);
93+
return withBase64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
94+
}
95+
96+
export async function decompressFromEncodedURIComponent(
97+
input: string,
98+
): Promise<string> {
99+
let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
100+
while (base64.length % 4) {
101+
base64 += "=";
102+
}
103+
return decompressFromBase64(base64);
104+
}
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import { page } from "$app/stores";
2-
import { compressToEncodedURIComponent } from "lz-string";
2+
import { compressToEncodedURIComponent } from "./compression";
33
import { get } from "svelte/store";
44

5-
export function generateCompressedNovelUrl(text: string): string {
6-
const compressedText = compressToEncodedURIComponent(text);
7-
return `${get(page).url.origin}?novel=${compressedText}`;
5+
export async function generateCompressedNovelUrl(
6+
text: string,
7+
): Promise<string> {
8+
const compressedText = await compressToEncodedURIComponent(text);
9+
console.log(compressedText);
10+
const url = `${get(page).url.origin}?novel=${compressedText}`;
11+
console.log(url);
12+
return url;
813
}
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { decompressFromEncodedURIComponent } from "lz-string";
1+
import { decompressFromEncodedURIComponent } from "./compression";
22

3-
export function generateSearchParamsToText(
3+
export async function generateSearchParamsToText(
44
urlSearchParams: URLSearchParams,
5-
): string | null {
5+
): Promise<string> {
66
const compressedText = urlSearchParams.get("novel");
7-
if (!compressedText) return null; // undefinedの代わりにnullを返す
7+
if (!compressedText) {
8+
return "";
9+
}
810

9-
const result: string = decompressFromEncodedURIComponent(compressedText);
10-
11-
return result || null;
11+
const result = decompressFromEncodedURIComponent(compressedText);
12+
return result ?? ""; // resultがnullの場合は空文字を返す
1213
}

0 commit comments

Comments
 (0)