@thezelijah/majik-message 1.0.20 → 1.0.21

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.
@@ -6,7 +6,7 @@ import { MajikContactDirectory, type MajikContactDirectoryData } from "./core/co
6
6
  import type { MAJIK_API_RESPONSE } from "./core/types";
7
7
  import { MajikMessageChat } from "./core/database/chat/majik-message-chat";
8
8
  import { MajikMessageIdentity } from "./core/database/system/identity";
9
- type MajikMessageEvents = "message" | "envelope" | "untrusted" | "error";
9
+ type MajikMessageEvents = "message" | "envelope" | "untrusted" | "error" | "active-account-change";
10
10
  interface MajikMessageStatic<T extends MajikMessage> {
11
11
  new (config: MajikMessageConfig, id?: string): T;
12
12
  fromJSON(json: MajikMessageJSON): Promise<T>;
@@ -87,7 +87,7 @@ export declare class MajikMessage {
87
87
  /**
88
88
  * Set an active account (moves it to index 0)
89
89
  */
90
- setActiveAccount(id: string): Promise<boolean>;
90
+ setActiveAccount(id: string, bypassIdentity?: boolean): Promise<boolean>;
91
91
  getActiveAccount(): MajikContact | null;
92
92
  isAccountActive(id: string): boolean;
93
93
  /**
@@ -197,6 +197,11 @@ export declare class MajikMessage {
197
197
  startDOMObserver(rootNode: Node): void;
198
198
  stopDOMObserver(): void;
199
199
  on(event: MajikMessageEvents, callback: EventCallback): void;
200
+ /**
201
+ * Remove a previously registered event listener.
202
+ * If `callback` is omitted, all listeners for the event are removed.
203
+ */
204
+ off(event: MajikMessageEvents, callback?: EventCallback): void;
200
205
  private emit;
201
206
  private handleEnvelope;
202
207
  /**
@@ -43,7 +43,13 @@ export class MajikMessage {
43
43
  onError: (err, ctx) => this.emit("error", err, ctx),
44
44
  });
45
45
  // Prepare listeners map
46
- ["message", "envelope", "untrusted", "error"].forEach((e) => this.listeners.set(e, []));
46
+ [
47
+ "message",
48
+ "envelope",
49
+ "untrusted",
50
+ "error",
51
+ "active-account-change",
52
+ ].forEach((e) => this.listeners.set(e, []));
47
53
  // Attach autosave handlers so state is persisted automatically
48
54
  this.attachAutosaveHandlers();
49
55
  }
@@ -171,17 +177,20 @@ export class MajikMessage {
171
177
  /**
172
178
  * Set an active account (moves it to index 0)
173
179
  */
174
- async setActiveAccount(id) {
180
+ async setActiveAccount(id, bypassIdentity = false) {
175
181
  if (!this.ownAccounts.has(id))
176
182
  return false;
177
- // Ensure identity is unlocked
178
- try {
179
- await this.ensureIdentityUnlocked(id);
180
- }
181
- catch (err) {
182
- console.warn("Failed to unlock account:", err);
183
- return false; // don't set as active if unlock fails
183
+ if (!bypassIdentity) {
184
+ // Ensure identity is unlocked
185
+ try {
186
+ await this.ensureIdentityUnlocked(id);
187
+ }
188
+ catch (err) {
189
+ console.warn("Failed to unlock account:", err);
190
+ return false; // don't set as active if unlock fails
191
+ }
184
192
  }
193
+ const previousActive = this.getActiveAccount()?.id;
185
194
  // Remove ID from current position
186
195
  const index = this.ownAccountsOrder.indexOf(id);
187
196
  if (index > -1)
@@ -189,6 +198,11 @@ export class MajikMessage {
189
198
  // Add to the front
190
199
  this.ownAccountsOrder.unshift(id);
191
200
  this.scheduleAutosave();
201
+ // 🔔 Emit the active account changed event
202
+ if (previousActive !== id) {
203
+ const newActive = this.getActiveAccount();
204
+ this.emit("active-account-change", newActive, previousActive);
205
+ }
192
206
  return true;
193
207
  }
194
208
  getActiveAccount() {
@@ -762,6 +776,25 @@ export class MajikMessage {
762
776
  on(event, callback) {
763
777
  this.listeners.get(event)?.push(callback);
764
778
  }
779
+ /**
780
+ * Remove a previously registered event listener.
781
+ * If `callback` is omitted, all listeners for the event are removed.
782
+ */
783
+ off(event, callback) {
784
+ const callbacks = this.listeners.get(event);
785
+ if (!callbacks || callbacks.length === 0)
786
+ return;
787
+ if (callback) {
788
+ // Remove only the specific callback
789
+ const index = callbacks.indexOf(callback);
790
+ if (index !== -1)
791
+ callbacks.splice(index, 1);
792
+ }
793
+ else {
794
+ // Remove all callbacks for this event
795
+ this.listeners.set(event, []);
796
+ }
797
+ }
765
798
  emit(event, ...args) {
766
799
  this.listeners.get(event)?.forEach((cb) => cb(...args));
767
800
  }
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.20",
5
+ "version": "1.0.21",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Zelijah",
8
8
  "main": "./dist/index.js",