@thezelijah/majik-message 1.0.4 → 1.0.5
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.
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
type SupportedInput = string | object | ArrayBuffer | Uint8Array;
|
|
2
2
|
export type MajikCompressorType = "str" | "json" | "blob";
|
|
3
|
+
export type CompressionMode = "binary" | "plaintext";
|
|
3
4
|
export declare class MajikCompressor {
|
|
4
5
|
private static PREFIX;
|
|
5
6
|
private static initialized;
|
|
6
7
|
private static ensureInit;
|
|
7
8
|
private static encodeInput;
|
|
8
9
|
private static decodeOutput;
|
|
9
|
-
static compress(input: SupportedInput, level?: number): Promise<string>;
|
|
10
|
-
static decompress(compressedStr: string): Promise<string | Record<string, any> | Uint8Array>;
|
|
10
|
+
static compress(mode: CompressionMode, input: SupportedInput, level?: number): Promise<string>;
|
|
11
|
+
static decompress(mode: CompressionMode, compressedStr: string): Promise<string | Record<string, any> | Uint8Array>;
|
|
11
12
|
static decompressJSON(compressedStr: string): Promise<Record<string, any>>;
|
|
12
13
|
static decompressString(compressedStr: string): Promise<string>;
|
|
13
14
|
static decompressBlob(compressedStr: string): Promise<Uint8Array>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { init, compress as zstdCompress, decompress as zstdDecompress, } from "@bokuweb/zstd-wasm";
|
|
2
|
+
import { gzipSync, gunzipSync } from "fflate";
|
|
2
3
|
export class MajikCompressor {
|
|
3
4
|
static PREFIX = "mjkcmp";
|
|
4
5
|
static initialized = false;
|
|
5
6
|
static async ensureInit() {
|
|
6
7
|
if (!this.initialized) {
|
|
7
|
-
await init();
|
|
8
|
+
await init(); // only init Zstd for binary mode
|
|
8
9
|
this.initialized = true;
|
|
9
10
|
}
|
|
10
11
|
}
|
|
@@ -32,37 +33,50 @@ export class MajikCompressor {
|
|
|
32
33
|
throw new Error(`Unsupported type for decoding: ${type}`);
|
|
33
34
|
}
|
|
34
35
|
// --- Compress input and return string ---
|
|
35
|
-
static async compress(input, level = 9) {
|
|
36
|
-
await this.ensureInit();
|
|
36
|
+
static async compress(mode, input, level = 9) {
|
|
37
37
|
const { type, data } = this.encodeInput(input);
|
|
38
|
-
|
|
38
|
+
let compressed;
|
|
39
|
+
if (mode === "binary") {
|
|
40
|
+
await this.ensureInit();
|
|
41
|
+
compressed = zstdCompress(data, level);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// plaintext mode → fflate gzip
|
|
45
|
+
compressed = gzipSync(data);
|
|
46
|
+
}
|
|
39
47
|
const b64 = this.uint8ArrayToBase64(compressed);
|
|
40
48
|
return `${this.PREFIX}:${type}:${b64}`;
|
|
41
49
|
}
|
|
42
50
|
// --- Decompress string with prefix ---
|
|
43
|
-
static async decompress(compressedStr) {
|
|
44
|
-
await this.ensureInit();
|
|
51
|
+
static async decompress(mode, compressedStr) {
|
|
45
52
|
if (!compressedStr.startsWith(`${this.PREFIX}:`))
|
|
46
53
|
throw new Error("Invalid MajikCompressor string format");
|
|
47
54
|
const [, type, b64] = compressedStr.split(":", 3);
|
|
48
55
|
const compressedData = this.base64ToUint8Array(b64);
|
|
49
|
-
|
|
56
|
+
let decompressed;
|
|
57
|
+
if (mode === "binary") {
|
|
58
|
+
await this.ensureInit();
|
|
59
|
+
decompressed = zstdDecompress(compressedData);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
decompressed = gunzipSync(compressedData);
|
|
63
|
+
}
|
|
50
64
|
return this.decodeOutput(type, decompressed);
|
|
51
65
|
}
|
|
52
66
|
static async decompressJSON(compressedStr) {
|
|
53
|
-
const result = await this.decompress(compressedStr);
|
|
67
|
+
const result = await this.decompress("binary", compressedStr);
|
|
54
68
|
if (typeof result === "object" && !(result instanceof Uint8Array))
|
|
55
69
|
return result;
|
|
56
70
|
throw new Error("Decompressed data is not JSON");
|
|
57
71
|
}
|
|
58
72
|
static async decompressString(compressedStr) {
|
|
59
|
-
const result = await this.decompress(compressedStr);
|
|
73
|
+
const result = await this.decompress("binary", compressedStr);
|
|
60
74
|
if (typeof result === "string")
|
|
61
75
|
return result;
|
|
62
76
|
throw new Error("Decompressed data is not a string");
|
|
63
77
|
}
|
|
64
78
|
static async decompressBlob(compressedStr) {
|
|
65
|
-
const result = await this.decompress(compressedStr);
|
|
79
|
+
const result = await this.decompress("binary", compressedStr);
|
|
66
80
|
if (result instanceof Uint8Array)
|
|
67
81
|
return result;
|
|
68
82
|
throw new Error("Decompressed data is not a blob");
|
|
@@ -142,7 +142,7 @@ export class MajikMessageChat {
|
|
|
142
142
|
// Compress the message before storing
|
|
143
143
|
let compressedMessage;
|
|
144
144
|
try {
|
|
145
|
-
compressedMessage = await MajikCompressor.compress(message.trim());
|
|
145
|
+
compressedMessage = await MajikCompressor.compress("plaintext", message.trim());
|
|
146
146
|
}
|
|
147
147
|
catch (error) {
|
|
148
148
|
throw new Error(`Failed to compress message: ${error instanceof Error ? error.message : "Unknown error"}`);
|
package/dist/index.d.ts
CHANGED
|
@@ -13,3 +13,5 @@ export * from "./core/utils/APITranscoder";
|
|
|
13
13
|
export * from "./core/utils/utilities";
|
|
14
14
|
export * from "./core/database/chat/majik-message-chat";
|
|
15
15
|
export type * from "./core/database/chat/types";
|
|
16
|
+
export * from "./core/database/system/identity";
|
|
17
|
+
export * from "./core/compressor/majik-compressor";
|
package/dist/index.js
CHANGED
|
@@ -11,3 +11,5 @@ export * from "./core/scanner/scanner-engine";
|
|
|
11
11
|
export * from "./core/utils/APITranscoder";
|
|
12
12
|
export * from "./core/utils/utilities";
|
|
13
13
|
export * from "./core/database/chat/majik-message-chat";
|
|
14
|
+
export * from "./core/database/system/identity";
|
|
15
|
+
export * from "./core/compressor/majik-compressor";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@thezelijah/majik-message",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Encrypt and decrypt messages on any website. Secure chats with keypairs and seed-based accounts. Open source.",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.5",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "Zelijah",
|
|
8
8
|
"main": "./dist/index.js",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"@stablelib/x25519": "^2.0.1",
|
|
87
87
|
"ed2curve": "^0.3.0",
|
|
88
88
|
"fernet": "^0.3.3",
|
|
89
|
+
"fflate": "^0.8.2",
|
|
89
90
|
"idb": "^8.0.3",
|
|
90
91
|
"nanoid": "^5.1.6"
|
|
91
92
|
},
|