@h-ai/capacitor 0.1.0-alpha9 → 1.0.0-beta.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/dist/index.js CHANGED
@@ -8,15 +8,39 @@ var en_US_default = {
8
8
  capacitor_initFailed: "Capacitor initialization failed",
9
9
  capacitor_initInProgress: "Capacitor initialization is already in progress",
10
10
  capacitor_notAvailable: "Capacitor is not available in this environment",
11
+ capacitor_secureStorageClearFailed: "Could not fully clear sign-in credentials from secure storage; retry signing out",
11
12
  capacitor_preferencesGetFailed: "Failed to read from Capacitor Preferences",
12
13
  capacitor_preferencesSetFailed: "Failed to write to Capacitor Preferences",
13
14
  capacitor_preferencesRemoveFailed: "Failed to remove from Capacitor Preferences",
14
15
  capacitor_deviceInfoFailed: "Failed to get device info",
16
+ capacitor_appVersionFailed: "Failed to get app version",
15
17
  capacitor_pushRegisterFailed: "Failed to register push notifications",
16
18
  capacitor_pushListenFailed: "Failed to listen for push notifications",
17
19
  capacitor_cameraFailed: "Failed to access camera",
18
20
  capacitor_statusBarFailed: "Failed to configure status bar",
19
- capacitor_notInitialized: "Capacitor module is not initialized"
21
+ capacitor_notInitialized: "Capacitor module is not initialized",
22
+ capacitor_pushCancelled: "The push operation was cancelled, timed out or the module was closed",
23
+ capacitor_pushCleanupFailed: "Push listeners could not be fully removed; retry cleanup or close the module"
24
+ };
25
+
26
+ // messages/ja-JP.json
27
+ var ja_JP_default = {
28
+ capacitor_initFailed: "Capacitor\u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
29
+ capacitor_initInProgress: "Capacitor\u306E\u521D\u671F\u5316\u306F\u65E2\u306B\u5B9F\u884C\u4E2D\u3067\u3059",
30
+ capacitor_notAvailable: "\u3053\u306E\u74B0\u5883\u3067\u306FCapacitor\u3092\u5229\u7528\u3067\u304D\u307E\u305B\u3093",
31
+ capacitor_secureStorageClearFailed: "\u5B89\u5168\u306A\u30B9\u30C8\u30EC\u30FC\u30B8\u306E\u30ED\u30B0\u30A4\u30F3\u8A8D\u8A3C\u60C5\u5831\u3092\u5B8C\u5168\u306B\u524A\u9664\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30ED\u30B0\u30A2\u30A6\u30C8\u3092\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044",
32
+ capacitor_preferencesGetFailed: "Capacitor Preferences\u304B\u3089\u306E\u8AAD\u307F\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
33
+ capacitor_preferencesSetFailed: "Capacitor Preferences\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
34
+ capacitor_preferencesRemoveFailed: "Capacitor Preferences\u304B\u3089\u306E\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
35
+ capacitor_deviceInfoFailed: "\u30C7\u30D0\u30A4\u30B9\u60C5\u5831\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
36
+ capacitor_appVersionFailed: "\u30A2\u30D7\u30EA\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
37
+ capacitor_pushRegisterFailed: "\u30D7\u30C3\u30B7\u30E5\u901A\u77E5\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
38
+ capacitor_pushListenFailed: "\u30D7\u30C3\u30B7\u30E5\u901A\u77E5\u306E\u53D7\u4FE1\u8A2D\u5B9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
39
+ capacitor_cameraFailed: "\u30AB\u30E1\u30E9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
40
+ capacitor_statusBarFailed: "\u30B9\u30C6\u30FC\u30BF\u30B9\u30D0\u30FC\u306E\u8A2D\u5B9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
41
+ capacitor_notInitialized: "Capacitor\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093",
42
+ capacitor_pushCancelled: "\u30D7\u30C3\u30B7\u30E5\u64CD\u4F5C\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u305F\u304B\u3001\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u305F\u304B\u3001\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u7D42\u4E86\u3057\u307E\u3057\u305F",
43
+ capacitor_pushCleanupFailed: "\u30D7\u30C3\u30B7\u30E5\u30EA\u30B9\u30CA\u30FC\u3092\u5B8C\u5168\u306B\u524A\u9664\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7\u3092\u518D\u8A66\u884C\u3059\u308B\u304B\u3001\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u7D42\u4E86\u3057\u3066\u304F\u3060\u3055\u3044"
20
44
  };
21
45
 
22
46
  // messages/zh-CN.json
@@ -24,21 +48,26 @@ var zh_CN_default = {
24
48
  capacitor_initFailed: "Capacitor \u521D\u59CB\u5316\u5931\u8D25",
25
49
  capacitor_initInProgress: "Capacitor \u6B63\u5728\u521D\u59CB\u5316\u4E2D",
26
50
  capacitor_notAvailable: "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 Capacitor",
51
+ capacitor_secureStorageClearFailed: "\u672A\u80FD\u5B8C\u5168\u6E05\u9664\u5B89\u5168\u5B58\u50A8\u4E2D\u7684\u767B\u5F55\u51ED\u636E\uFF0C\u8BF7\u91CD\u8BD5\u9000\u51FA",
27
52
  capacitor_preferencesGetFailed: "\u8BFB\u53D6 Capacitor Preferences \u5931\u8D25",
28
53
  capacitor_preferencesSetFailed: "\u5199\u5165 Capacitor Preferences \u5931\u8D25",
29
54
  capacitor_preferencesRemoveFailed: "\u5220\u9664 Capacitor Preferences \u5931\u8D25",
30
55
  capacitor_deviceInfoFailed: "\u83B7\u53D6\u8BBE\u5907\u4FE1\u606F\u5931\u8D25",
56
+ capacitor_appVersionFailed: "\u83B7\u53D6\u5E94\u7528\u7248\u672C\u5931\u8D25",
31
57
  capacitor_pushRegisterFailed: "\u6CE8\u518C\u63A8\u9001\u901A\u77E5\u5931\u8D25",
32
58
  capacitor_pushListenFailed: "\u76D1\u542C\u63A8\u9001\u901A\u77E5\u5931\u8D25",
33
59
  capacitor_cameraFailed: "\u8BBF\u95EE\u76F8\u673A\u5931\u8D25",
34
60
  capacitor_statusBarFailed: "\u914D\u7F6E\u72B6\u6001\u680F\u5931\u8D25",
35
- capacitor_notInitialized: "Capacitor \u6A21\u5757\u672A\u521D\u59CB\u5316"
61
+ capacitor_notInitialized: "Capacitor \u6A21\u5757\u672A\u521D\u59CB\u5316",
62
+ capacitor_pushCancelled: "\u63A8\u9001\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3001\u8D85\u65F6\u6216\u6A21\u5757\u5DF2\u5173\u95ED",
63
+ capacitor_pushCleanupFailed: "\u63A8\u9001\u76D1\u542C\u5668\u672A\u5B8C\u5168\u79FB\u9664\uFF0C\u8BF7\u91CD\u8BD5\u6E05\u7406\u6216\u5173\u95ED\u6A21\u5757"
36
64
  };
37
65
 
38
66
  // src/capacitor-i18n.ts
39
67
  var capacitorM = core.i18n.createMessageGetter({
40
68
  "zh-CN": zh_CN_default,
41
- "en-US": en_US_default
69
+ "en-US": en_US_default,
70
+ "ja-JP": ja_JP_default
42
71
  });
43
72
  var CapacitorErrorInfo = {
44
73
  INIT_FAILED: "001:500",
@@ -49,8 +78,10 @@ var CapacitorErrorInfo = {
49
78
  PREFERENCES_SET_FAILED: "012:500",
50
79
  PREFERENCES_REMOVE_FAILED: "013:500",
51
80
  DEVICE_INFO_FAILED: "020:500",
81
+ APP_VERSION_FAILED: "021:500",
52
82
  PUSH_REGISTER_FAILED: "030:500",
53
83
  PUSH_LISTEN_FAILED: "031:500",
84
+ PUSH_CLEANUP_FAILED: "032:500",
54
85
  CAMERA_FAILED: "040:500",
55
86
  STATUS_BAR_FAILED: "050:500"
56
87
  };
@@ -128,100 +159,188 @@ async function getAppVersion() {
128
159
  });
129
160
  } catch (cause) {
130
161
  return err(
131
- HaiCapacitorError.DEVICE_INFO_FAILED,
132
- capacitorM("capacitor_deviceInfoFailed"),
162
+ HaiCapacitorError.APP_VERSION_FAILED,
163
+ capacitorM("capacitor_appVersionFailed"),
133
164
  cause
134
165
  );
135
166
  }
136
167
  }
137
- async function registerPush() {
138
- try {
139
- const { PushNotifications } = await import('@capacitor/push-notifications');
140
- const permResult = await PushNotifications.requestPermissions();
141
- if (permResult.receive !== "granted") {
142
- return err(
143
- HaiCapacitorError.PUSH_REGISTER_FAILED,
144
- capacitorM("capacitor_pushRegisterFailed")
145
- );
168
+ var logger = core.logger.child({ module: "capacitor", scope: "push" });
169
+ var activeScopes = /* @__PURE__ */ new Set();
170
+ function createPushScope(options) {
171
+ let scope;
172
+ const controller = new AbortController();
173
+ const handles = /* @__PURE__ */ new Set();
174
+ const removals = /* @__PURE__ */ new Map();
175
+ let pending = 0;
176
+ let closing;
177
+ let timer;
178
+ const cancelled = () => new Error(capacitorM("capacitor_pushCancelled"));
179
+ function releaseIfComplete() {
180
+ if (controller.signal.aborted && pending === 0 && handles.size === 0)
181
+ activeScopes.delete(scope);
182
+ }
183
+ function remove(handle) {
184
+ const current = removals.get(handle);
185
+ if (current)
186
+ return current;
187
+ const removal = Promise.resolve().then(() => handle.remove()).then(() => {
188
+ handles.delete(handle);
189
+ }).finally(() => {
190
+ removals.delete(handle);
191
+ releaseIfComplete();
192
+ });
193
+ removals.set(handle, removal);
194
+ return removal;
195
+ }
196
+ function finishSetup() {
197
+ if (timer !== void 0) {
198
+ clearTimeout(timer);
199
+ timer = void 0;
146
200
  }
147
- const REGISTER_TIMEOUT_MS = 3e4;
148
- const token = await new Promise((resolve, reject) => {
149
- let regListener;
150
- let errListener;
151
- const timer = setTimeout(() => {
152
- cleanup();
153
- reject(new Error("Push registration timed out"));
154
- }, REGISTER_TIMEOUT_MS);
155
- function cleanup() {
156
- clearTimeout(timer);
157
- regListener?.remove();
158
- errListener?.remove();
201
+ }
202
+ function dispose() {
203
+ controller.abort();
204
+ finishSetup();
205
+ options?.signal?.removeEventListener("abort", onAbort);
206
+ if (closing)
207
+ return closing;
208
+ closing = Promise.allSettled([...handles].map(remove)).then((results) => {
209
+ releaseIfComplete();
210
+ if (results.some((result) => result.status === "rejected"))
211
+ throw new Error(capacitorM("capacitor_pushCleanupFailed"));
212
+ }).finally(() => {
213
+ closing = void 0;
214
+ });
215
+ return closing;
216
+ }
217
+ function onAbort() {
218
+ void dispose().catch(() => logger.warn("Push listener cleanup failed; retry cleanup or capacitor.close"));
219
+ }
220
+ scope = {
221
+ signal: controller.signal,
222
+ assertOpen() {
223
+ if (controller.signal.aborted)
224
+ throw cancelled();
225
+ },
226
+ async attach(add) {
227
+ scope.assertOpen();
228
+ pending++;
229
+ try {
230
+ const handle = await add();
231
+ handles.add(handle);
232
+ if (controller.signal.aborted) {
233
+ await remove(handle);
234
+ throw cancelled();
235
+ }
236
+ } finally {
237
+ pending--;
238
+ releaseIfComplete();
159
239
  }
160
- PushNotifications.addListener("registration", (t) => {
161
- cleanup();
162
- resolve(t.value);
163
- }).then((l) => {
164
- regListener = l;
240
+ },
241
+ async wait(operation) {
242
+ scope.assertOpen();
243
+ let interrupt;
244
+ const aborted = new Promise((_, reject) => {
245
+ interrupt = () => reject(cancelled());
246
+ controller.signal.addEventListener("abort", interrupt, { once: true });
165
247
  });
166
- PushNotifications.addListener("registrationError", (error) => {
167
- cleanup();
168
- reject(error);
169
- }).then((l) => {
170
- errListener = l;
248
+ try {
249
+ return await Promise.race([Promise.resolve().then(operation), aborted]);
250
+ } finally {
251
+ if (interrupt)
252
+ controller.signal.removeEventListener("abort", interrupt);
253
+ }
254
+ },
255
+ finishSetup,
256
+ dispose
257
+ };
258
+ activeScopes.add(scope);
259
+ timer = setTimeout(onAbort, 3e4);
260
+ options?.signal?.addEventListener("abort", onAbort, { once: true });
261
+ if (options?.signal?.aborted)
262
+ onAbort();
263
+ return scope;
264
+ }
265
+ async function loadPushPlugin() {
266
+ const { Capacitor } = await import('@capacitor/core');
267
+ if (!Capacitor.isNativePlatform())
268
+ throw new Error(capacitorM("capacitor_notAvailable"));
269
+ return (await import('@capacitor/push-notifications')).PushNotifications;
270
+ }
271
+ async function closePushListeners() {
272
+ const results = await Promise.allSettled([...activeScopes].map((scope) => scope.dispose()));
273
+ return results.some((result) => result.status === "rejected") ? err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM("capacitor_pushCleanupFailed")) : ok(void 0);
274
+ }
275
+ async function registerPush(options) {
276
+ const scope = createPushScope(options);
277
+ try {
278
+ const token = await scope.wait(async () => {
279
+ const push = await loadPushPlugin();
280
+ scope.assertOpen();
281
+ const permission = await push.requestPermissions();
282
+ scope.assertOpen();
283
+ if (permission.receive !== "granted")
284
+ throw new Error(capacitorM("capacitor_pushRegisterFailed"));
285
+ let resolveToken;
286
+ let rejectToken;
287
+ const tokenResult = new Promise((resolve, reject) => {
288
+ resolveToken = resolve;
289
+ rejectToken = reject;
171
290
  });
172
- PushNotifications.register();
291
+ const setup = async () => {
292
+ await scope.attach(() => push.addListener("registration", (result) => {
293
+ if (!scope.signal.aborted)
294
+ resolveToken(result.value);
295
+ }));
296
+ await scope.attach(() => push.addListener("registrationError", () => {
297
+ if (!scope.signal.aborted)
298
+ rejectToken(new Error(capacitorM("capacitor_pushRegisterFailed")));
299
+ }));
300
+ scope.assertOpen();
301
+ await push.register();
302
+ };
303
+ return (await Promise.all([setup(), tokenResult]))[1];
173
304
  });
305
+ await scope.dispose();
174
306
  return ok({ token });
175
307
  } catch (cause) {
176
- return err(
177
- HaiCapacitorError.PUSH_REGISTER_FAILED,
178
- capacitorM("capacitor_pushRegisterFailed"),
179
- cause
180
- );
308
+ await scope.dispose().catch(() => logger.warn("Push registration cleanup failed; retry capacitor.close"));
309
+ return err(HaiCapacitorError.PUSH_REGISTER_FAILED, capacitorM("capacitor_pushRegisterFailed"), cause);
181
310
  }
182
311
  }
183
- async function listenPush(callbacks) {
312
+ async function listenPush(callbacks, options) {
313
+ const scope = createPushScope(options);
184
314
  try {
185
- const { PushNotifications } = await import('@capacitor/push-notifications');
186
- const listeners = [];
187
- if (callbacks.onReceived) {
188
- const listener = await PushNotifications.addListener(
189
- "pushNotificationReceived",
190
- (notification) => {
191
- callbacks.onReceived?.({
192
- id: notification.id,
193
- title: notification.title,
194
- body: notification.body,
195
- data: notification.data
196
- });
197
- }
198
- );
199
- listeners.push(listener);
200
- }
201
- if (callbacks.onActionPerformed) {
202
- const listener = await PushNotifications.addListener(
203
- "pushNotificationActionPerformed",
204
- (action) => {
205
- callbacks.onActionPerformed?.({
206
- id: action.notification.id,
207
- title: action.notification.title,
208
- body: action.notification.body,
209
- data: action.notification.data
210
- });
211
- }
212
- );
213
- listeners.push(listener);
214
- }
215
- const cleanup = async () => {
216
- await Promise.all(listeners.map((l) => l.remove()));
217
- };
218
- return ok(cleanup);
315
+ await scope.wait(async () => {
316
+ const push = await loadPushPlugin();
317
+ scope.assertOpen();
318
+ if (callbacks.onReceived) {
319
+ await scope.attach(() => push.addListener("pushNotificationReceived", (notification) => {
320
+ if (!scope.signal.aborted)
321
+ callbacks.onReceived?.({ id: notification.id, title: notification.title, body: notification.body, data: notification.data });
322
+ }));
323
+ }
324
+ if (callbacks.onActionPerformed) {
325
+ await scope.attach(() => push.addListener("pushNotificationActionPerformed", (action) => {
326
+ if (!scope.signal.aborted)
327
+ callbacks.onActionPerformed?.({ id: action.notification.id, title: action.notification.title, body: action.notification.body, data: action.notification.data });
328
+ }));
329
+ }
330
+ });
331
+ scope.assertOpen();
332
+ scope.finishSetup();
333
+ return ok(async () => {
334
+ try {
335
+ await scope.dispose();
336
+ return ok(void 0);
337
+ } catch (cause) {
338
+ return err(HaiCapacitorError.PUSH_CLEANUP_FAILED, capacitorM("capacitor_pushCleanupFailed"), cause);
339
+ }
340
+ });
219
341
  } catch (cause) {
220
- return err(
221
- HaiCapacitorError.PUSH_LISTEN_FAILED,
222
- capacitorM("capacitor_pushListenFailed"),
223
- cause
224
- );
342
+ await scope.dispose().catch(() => logger.warn("Push setup cleanup failed; retry capacitor.close"));
343
+ return err(HaiCapacitorError.PUSH_LISTEN_FAILED, capacitorM("capacitor_pushListenFailed"), cause);
225
344
  }
226
345
  }
227
346
  async function configureStatusBar(config) {
@@ -276,52 +395,74 @@ async function hideStatusBar() {
276
395
  );
277
396
  }
278
397
  }
279
- var logger = core.logger.child({ module: "capacitor", scope: "token-storage" });
280
398
  var PREF_ACCESS_TOKEN = "hai_access_token";
281
399
  var PREF_REFRESH_TOKEN = "hai_refresh_token";
400
+ async function loadSecureStoragePlugin() {
401
+ const { Capacitor } = await import('@capacitor/core');
402
+ if (!Capacitor.isNativePlatform())
403
+ throw new Error(capacitorM("capacitor_notAvailable"));
404
+ const { SecureStorage } = await import('@aparajita/capacitor-secure-storage');
405
+ return SecureStorage;
406
+ }
282
407
  function createCapacitorTokenStorage() {
408
+ let credentialGeneration = 0;
409
+ let accessBlocked = false;
410
+ let refreshBlocked = false;
411
+ function blockCredentials() {
412
+ credentialGeneration++;
413
+ accessBlocked = true;
414
+ refreshBlocked = true;
415
+ }
416
+ async function writeToken(key, token) {
417
+ const writeGeneration = credentialGeneration;
418
+ try {
419
+ const storage = await loadSecureStoragePlugin();
420
+ await storage.setItem(key, token);
421
+ if (writeGeneration === credentialGeneration) {
422
+ if (key === PREF_ACCESS_TOKEN)
423
+ accessBlocked = false;
424
+ else
425
+ refreshBlocked = false;
426
+ }
427
+ } catch (error) {
428
+ if (writeGeneration === credentialGeneration)
429
+ blockCredentials();
430
+ throw error;
431
+ }
432
+ }
283
433
  return {
284
434
  async getAccessToken() {
285
- try {
286
- const { value } = await Preferences.get({ key: PREF_ACCESS_TOKEN });
287
- return value;
288
- } catch (error) {
289
- logger.error("Failed to get access token from Preferences", { error });
435
+ const readGeneration = credentialGeneration;
436
+ const storage = await loadSecureStoragePlugin();
437
+ if (accessBlocked)
290
438
  return null;
291
- }
439
+ const token = await storage.getItem(PREF_ACCESS_TOKEN);
440
+ return accessBlocked || readGeneration !== credentialGeneration ? null : token;
292
441
  },
293
442
  async getRefreshToken() {
294
- try {
295
- const { value } = await Preferences.get({ key: PREF_REFRESH_TOKEN });
296
- return value;
297
- } catch (error) {
298
- logger.error("Failed to get refresh token from Preferences", { error });
443
+ const readGeneration = credentialGeneration;
444
+ const storage = await loadSecureStoragePlugin();
445
+ if (refreshBlocked)
299
446
  return null;
300
- }
447
+ const token = await storage.getItem(PREF_REFRESH_TOKEN);
448
+ return refreshBlocked || readGeneration !== credentialGeneration ? null : token;
301
449
  },
302
450
  async setAccessToken(token) {
303
- try {
304
- await Preferences.set({ key: PREF_ACCESS_TOKEN, value: token });
305
- } catch (error) {
306
- logger.error("Failed to set access token in Preferences", { error });
307
- }
451
+ await writeToken(PREF_ACCESS_TOKEN, token);
308
452
  },
309
453
  async setRefreshToken(token) {
310
- try {
311
- await Preferences.set({ key: PREF_REFRESH_TOKEN, value: token });
312
- } catch (error) {
313
- logger.error("Failed to set refresh token in Preferences", { error });
314
- }
454
+ await writeToken(PREF_REFRESH_TOKEN, token);
315
455
  },
316
456
  async clear() {
317
- try {
318
- await Promise.all([
319
- Preferences.remove({ key: PREF_ACCESS_TOKEN }),
320
- Preferences.remove({ key: PREF_REFRESH_TOKEN })
321
- ]);
322
- } catch (error) {
323
- logger.error("Failed to clear tokens from Preferences", { error });
324
- }
457
+ blockCredentials();
458
+ const storage = await loadSecureStoragePlugin();
459
+ const results = await Promise.allSettled([
460
+ storage.removeItem(PREF_ACCESS_TOKEN),
461
+ storage.removeItem(PREF_REFRESH_TOKEN)
462
+ ]);
463
+ const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
464
+ if (errors.length > 0)
465
+ throw new AggregateError(errors, capacitorM("capacitor_secureStorageClearFailed"));
325
466
  }
326
467
  };
327
468
  }
@@ -417,8 +558,13 @@ var capacitor = {
417
558
  try {
418
559
  if (initialized) {
419
560
  logger2.warn("Capacitor module is already initialized, reinitializing");
420
- await capacitor.close();
561
+ const closed = await capacitor.close();
562
+ if (!closed.success)
563
+ return closed;
421
564
  }
565
+ const cleaned = await closePushListeners();
566
+ if (!cleaned.success)
567
+ return cleaned;
422
568
  logger2.info("Initializing capacitor module");
423
569
  if (!isCapacitorAvailable()) {
424
570
  logger2.error("Capacitor is not available in current environment");
@@ -452,14 +598,14 @@ var capacitor = {
452
598
  }
453
599
  },
454
600
  async close() {
455
- if (!initialized) {
456
- logger2.info("Capacitor module is already closed, skipping");
457
- return;
458
- }
459
601
  logger2.info("Closing capacitor module");
460
602
  initialized = false;
461
603
  cachedPlatform = null;
604
+ const cleaned = await closePushListeners();
605
+ if (!cleaned.success)
606
+ return cleaned;
462
607
  logger2.info("Capacitor module closed");
608
+ return ok(void 0);
463
609
  },
464
610
  getPlatform() {
465
611
  if (cachedPlatform) {