@thezelijah/majik-message 1.0.3 → 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
- const compressed = zstdCompress(data, level); // synchronous
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
- const decompressed = zstdDecompress(compressedData); // synchronous
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"}`);
@@ -1,5 +1,6 @@
1
1
  import { autogenerateID } from "./utils";
2
2
  import { hash } from "@stablelib/sha256";
3
+ import { arrayToBase64 } from "../../utils/utilities";
3
4
  /**
4
5
  * Utility assertions
5
6
  */
@@ -16,7 +17,7 @@ function assertISODate(value, field) {
16
17
  }
17
18
  function sha256(input) {
18
19
  const hashed = hash(new TextEncoder().encode(input));
19
- return hashed.toString();
20
+ return arrayToBase64(hashed);
20
21
  }
21
22
  /**
22
23
  * MajikMessageIdentity
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.3",
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
  },