@agent-native/core 0.109.1 → 0.109.3

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.
Files changed (135) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +15 -0
  3. package/corpus/core/docs/content/integrations.mdx +87 -253
  4. package/corpus/core/package.json +1 -1
  5. package/corpus/core/src/cli/create.ts +18 -12
  6. package/corpus/core/src/client/blocks/library/diagram.config.ts +10 -1
  7. package/corpus/core/src/client/blocks/library/diagram.tsx +9 -4
  8. package/corpus/core/src/client/require-session.tsx +19 -3
  9. package/corpus/core/src/client/use-action.ts +145 -2
  10. package/corpus/core/src/client/use-session.ts +79 -48
  11. package/corpus/core/src/db/client.ts +13 -7
  12. package/corpus/core/src/db/create-get-db.ts +20 -13
  13. package/corpus/core/src/db/request-telemetry.ts +154 -0
  14. package/corpus/core/src/deploy/build.ts +63 -3
  15. package/corpus/core/src/integrations/index.ts +1 -0
  16. package/corpus/core/src/integrations/plugin.ts +9 -3
  17. package/corpus/core/src/integrations/remote-push-delivery-job.ts +48 -0
  18. package/corpus/core/src/integrations/remote-push-delivery.ts +370 -0
  19. package/corpus/core/src/integrations/remote-push-store.ts +275 -26
  20. package/corpus/core/src/server/better-auth-instance.ts +11 -3
  21. package/corpus/core/src/server/core-routes-plugin.ts +36 -14
  22. package/corpus/core/src/server/framework-request-handler.ts +11 -1
  23. package/corpus/core/src/server/http-response-telemetry.ts +233 -31
  24. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
  25. package/corpus/templates/clips/.agents/skills/dictate/SKILL.md +28 -5
  26. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -0
  27. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +23 -0
  28. package/corpus/templates/clips/AGENTS.md +10 -0
  29. package/corpus/templates/clips/actions/create-dictation.ts +29 -4
  30. package/corpus/templates/clips/actions/finalize-recording.ts +1 -1
  31. package/corpus/templates/clips/actions/get-recording-player-data.ts +16 -6
  32. package/corpus/templates/clips/actions/set-mobile-capture-state.ts +40 -0
  33. package/corpus/templates/clips/actions/update-dictation.ts +9 -1
  34. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -6
  35. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +13 -2
  36. package/corpus/templates/clips/app/routes/share.$shareId.tsx +13 -2
  37. package/corpus/templates/clips/changelog/2026-07-17-capture-dictation-background-meeting-audio-and-camera-videos.md +6 -0
  38. package/corpus/templates/clips/changelog/2026-07-17-delayed-upload-verification-keeps-local-backups-retryable.md +6 -0
  39. package/corpus/templates/clips/changelog/2026-07-18-new-recording-is-now-emphasized-as-the-primary-action-in-the.md +6 -0
  40. package/corpus/templates/clips/changelog/2026-07-18-recordings-now-remain-safely-recoverable-until-the-stored-me.md +6 -0
  41. package/corpus/templates/clips/desktop/src/app.tsx +17 -0
  42. package/corpus/templates/clips/desktop/src/lib/processing-backup-recovery.ts +19 -0
  43. package/corpus/templates/clips/desktop/src/lib/recorder.ts +60 -35
  44. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +12 -0
  45. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  46. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +14 -0
  47. package/corpus/templates/clips/server/db/schema.ts +9 -1
  48. package/corpus/templates/clips/server/lib/builder-media-compression.ts +59 -7
  49. package/corpus/templates/clips/server/lib/media-verification-state.ts +17 -0
  50. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +7 -0
  51. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +22 -1
  52. package/corpus/templates/plan/changelog/2026-07-17-diagrams-can-opt-into-a-polished-clean-rendering-mode-withou.md +6 -0
  53. package/corpus/templates/plan/shared/plan-content.ts +3 -0
  54. package/corpus/templates/tasks/AGENTS.md +3 -0
  55. package/corpus/templates/tasks/actions/render-task-list-inline.ts +202 -0
  56. package/corpus/templates/tasks/changelog/2026-07-18-task-lists-can-now-appear-as-interactive-widgets-inline-in-c.md +6 -0
  57. package/corpus/templates/tasks/docs/features/f8-chat.mdx +2 -0
  58. package/corpus/templates/tasks/server/plugins/agent-chat.ts +2 -0
  59. package/dist/cli/create.d.ts +10 -1
  60. package/dist/cli/create.d.ts.map +1 -1
  61. package/dist/cli/create.js +17 -13
  62. package/dist/cli/create.js.map +1 -1
  63. package/dist/client/blocks/library/diagram.config.d.ts +2 -0
  64. package/dist/client/blocks/library/diagram.config.d.ts.map +1 -1
  65. package/dist/client/blocks/library/diagram.config.js +8 -1
  66. package/dist/client/blocks/library/diagram.config.js.map +1 -1
  67. package/dist/client/blocks/library/diagram.d.ts.map +1 -1
  68. package/dist/client/blocks/library/diagram.js +9 -4
  69. package/dist/client/blocks/library/diagram.js.map +1 -1
  70. package/dist/client/require-session.d.ts.map +1 -1
  71. package/dist/client/require-session.js +6 -3
  72. package/dist/client/require-session.js.map +1 -1
  73. package/dist/client/use-action.d.ts.map +1 -1
  74. package/dist/client/use-action.js +117 -1
  75. package/dist/client/use-action.js.map +1 -1
  76. package/dist/client/use-session.d.ts.map +1 -1
  77. package/dist/client/use-session.js +72 -50
  78. package/dist/client/use-session.js.map +1 -1
  79. package/dist/collab/routes.d.ts +1 -1
  80. package/dist/db/client.d.ts.map +1 -1
  81. package/dist/db/client.js +7 -1
  82. package/dist/db/client.js.map +1 -1
  83. package/dist/db/create-get-db.d.ts +3 -6
  84. package/dist/db/create-get-db.d.ts.map +1 -1
  85. package/dist/db/create-get-db.js +9 -2
  86. package/dist/db/create-get-db.js.map +1 -1
  87. package/dist/db/request-telemetry.d.ts +23 -0
  88. package/dist/db/request-telemetry.d.ts.map +1 -0
  89. package/dist/db/request-telemetry.js +95 -0
  90. package/dist/db/request-telemetry.js.map +1 -0
  91. package/dist/deploy/build.d.ts +3 -0
  92. package/dist/deploy/build.d.ts.map +1 -1
  93. package/dist/deploy/build.js +45 -1
  94. package/dist/deploy/build.js.map +1 -1
  95. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  96. package/dist/integrations/index.d.ts +1 -0
  97. package/dist/integrations/index.d.ts.map +1 -1
  98. package/dist/integrations/index.js +1 -0
  99. package/dist/integrations/index.js.map +1 -1
  100. package/dist/integrations/plugin.d.ts.map +1 -1
  101. package/dist/integrations/plugin.js +8 -3
  102. package/dist/integrations/plugin.js.map +1 -1
  103. package/dist/integrations/remote-push-delivery-job.d.ts +4 -0
  104. package/dist/integrations/remote-push-delivery-job.d.ts.map +1 -0
  105. package/dist/integrations/remote-push-delivery-job.js +44 -0
  106. package/dist/integrations/remote-push-delivery-job.js.map +1 -0
  107. package/dist/integrations/remote-push-delivery.d.ts +11 -0
  108. package/dist/integrations/remote-push-delivery.d.ts.map +1 -0
  109. package/dist/integrations/remote-push-delivery.js +265 -0
  110. package/dist/integrations/remote-push-delivery.js.map +1 -0
  111. package/dist/integrations/remote-push-store.d.ts +33 -0
  112. package/dist/integrations/remote-push-store.d.ts.map +1 -1
  113. package/dist/integrations/remote-push-store.js +195 -26
  114. package/dist/integrations/remote-push-store.js.map +1 -1
  115. package/dist/observability/routes.d.ts +5 -5
  116. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  117. package/dist/resources/handlers.d.ts +1 -1
  118. package/dist/server/better-auth-instance.js +7 -3
  119. package/dist/server/better-auth-instance.js.map +1 -1
  120. package/dist/server/core-routes-plugin.d.ts +8 -0
  121. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  122. package/dist/server/core-routes-plugin.js +23 -8
  123. package/dist/server/core-routes-plugin.js.map +1 -1
  124. package/dist/server/framework-request-handler.d.ts.map +1 -1
  125. package/dist/server/framework-request-handler.js +9 -1
  126. package/dist/server/framework-request-handler.js.map +1 -1
  127. package/dist/server/http-response-telemetry.d.ts +3 -2
  128. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  129. package/dist/server/http-response-telemetry.js +160 -27
  130. package/dist/server/http-response-telemetry.js.map +1 -1
  131. package/dist/server/transcribe-voice.d.ts +1 -1
  132. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
  133. package/docs/content/integrations.mdx +87 -253
  134. package/package.json +1 -1
  135. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
@@ -0,0 +1,154 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ export type DatabaseOperationKind = "connect" | "query";
4
+
5
+ export interface DatabaseRequestTelemetry {
6
+ operationCount: number;
7
+ queryCount: number;
8
+ connectCount: number;
9
+ retryCount: number;
10
+ errorCount: number;
11
+ timeoutCount: number;
12
+ operationTotalMs: number;
13
+ operationWallMs: number;
14
+ queryTotalMs: number;
15
+ connectTotalMs: number;
16
+ slowestOperationMs: number;
17
+ activeOperationCount: number;
18
+ activeWindowStartedAt?: number;
19
+ }
20
+
21
+ const STORAGE_KEY = Symbol.for(
22
+ "@agent-native/core/db.request-telemetry-storage",
23
+ );
24
+ const STARTUP_STATE_KEY = Symbol.for(
25
+ "@agent-native/core/db.startup-telemetry-state",
26
+ );
27
+ const STARTUP_CAPTURE_WINDOW_MS = 120_000;
28
+ interface StartupDatabaseTelemetryState {
29
+ captureUntil: number;
30
+ claimed: boolean;
31
+ telemetry: DatabaseRequestTelemetry;
32
+ }
33
+ type GlobalWithDatabaseTelemetry = typeof globalThis & {
34
+ [STORAGE_KEY]?: AsyncLocalStorage<DatabaseRequestTelemetry>;
35
+ [STARTUP_STATE_KEY]?: StartupDatabaseTelemetryState;
36
+ };
37
+
38
+ const globalRef = globalThis as GlobalWithDatabaseTelemetry;
39
+ const storage =
40
+ globalRef[STORAGE_KEY] ??
41
+ (globalRef[STORAGE_KEY] = new AsyncLocalStorage<DatabaseRequestTelemetry>());
42
+
43
+ export function createDatabaseRequestTelemetry(): DatabaseRequestTelemetry {
44
+ return {
45
+ operationCount: 0,
46
+ queryCount: 0,
47
+ connectCount: 0,
48
+ retryCount: 0,
49
+ errorCount: 0,
50
+ timeoutCount: 0,
51
+ operationTotalMs: 0,
52
+ operationWallMs: 0,
53
+ queryTotalMs: 0,
54
+ connectTotalMs: 0,
55
+ slowestOperationMs: 0,
56
+ activeOperationCount: 0,
57
+ };
58
+ }
59
+
60
+ const startupState =
61
+ globalRef[STARTUP_STATE_KEY] ??
62
+ (globalRef[STARTUP_STATE_KEY] = {
63
+ captureUntil: Date.now() + STARTUP_CAPTURE_WINDOW_MS,
64
+ claimed: false,
65
+ telemetry: createDatabaseRequestTelemetry(),
66
+ });
67
+
68
+ function currentDatabaseTelemetry(): DatabaseRequestTelemetry | undefined {
69
+ const requestTelemetry = storage.getStore();
70
+ if (requestTelemetry) return requestTelemetry;
71
+ if (!startupState.claimed && Date.now() <= startupState.captureUntil) {
72
+ return startupState.telemetry;
73
+ }
74
+ return undefined;
75
+ }
76
+
77
+ export function claimStartupDatabaseTelemetry():
78
+ | DatabaseRequestTelemetry
79
+ | undefined {
80
+ if (startupState.claimed) return undefined;
81
+ startupState.claimed = true;
82
+ return startupState.telemetry;
83
+ }
84
+
85
+ export function runWithDatabaseRequestTelemetry<T>(
86
+ telemetry: DatabaseRequestTelemetry,
87
+ fn: () => T,
88
+ ): T {
89
+ return storage.run(telemetry, fn);
90
+ }
91
+
92
+ export function enterDatabaseRequestTelemetry(
93
+ telemetry: DatabaseRequestTelemetry,
94
+ ): void {
95
+ storage.enterWith(telemetry);
96
+ }
97
+
98
+ export function beginDatabaseOperation(
99
+ operation: DatabaseOperationKind,
100
+ ): (outcome: "success" | "error" | "timeout") => void {
101
+ const telemetry = currentDatabaseTelemetry();
102
+ if (!telemetry) return () => {};
103
+
104
+ const startedAt = Date.now();
105
+ if (telemetry.activeOperationCount === 0) {
106
+ telemetry.activeWindowStartedAt = startedAt;
107
+ }
108
+ telemetry.activeOperationCount += 1;
109
+ let completed = false;
110
+
111
+ return (outcome) => {
112
+ if (completed) return;
113
+ completed = true;
114
+ const completedAt = Date.now();
115
+ const duration = Math.max(0, completedAt - startedAt);
116
+ telemetry.operationCount += 1;
117
+ telemetry.operationTotalMs += duration;
118
+ telemetry.slowestOperationMs = Math.max(
119
+ telemetry.slowestOperationMs,
120
+ duration,
121
+ );
122
+
123
+ if (operation === "connect") {
124
+ telemetry.connectCount += 1;
125
+ telemetry.connectTotalMs += duration;
126
+ } else {
127
+ telemetry.queryCount += 1;
128
+ telemetry.queryTotalMs += duration;
129
+ }
130
+
131
+ if (outcome !== "success") telemetry.errorCount += 1;
132
+ if (outcome === "timeout") telemetry.timeoutCount += 1;
133
+
134
+ telemetry.activeOperationCount = Math.max(
135
+ 0,
136
+ telemetry.activeOperationCount - 1,
137
+ );
138
+ if (
139
+ telemetry.activeOperationCount === 0 &&
140
+ telemetry.activeWindowStartedAt !== undefined
141
+ ) {
142
+ telemetry.operationWallMs += Math.max(
143
+ 0,
144
+ completedAt - telemetry.activeWindowStartedAt,
145
+ );
146
+ telemetry.activeWindowStartedAt = undefined;
147
+ }
148
+ };
149
+ }
150
+
151
+ export function recordDatabaseRetry(): void {
152
+ const telemetry = currentDatabaseTelemetry();
153
+ if (telemetry) telemetry.retryCount += 1;
154
+ }
@@ -138,6 +138,14 @@ export const CLOUDFLARE_WORKER_STUB_MODULES: Record<string, string> = {
138
138
  "export default { Resvg };",
139
139
  "",
140
140
  ].join("\n"),
141
+ playwright: [
142
+ "const unavailable = async () => { throw new Error('playwright unavailable in Cloudflare Pages worker'); };",
143
+ "export const chromium = { launch: unavailable, connect: unavailable, connectOverCDP: unavailable };",
144
+ "export const firefox = { launch: unavailable, connect: unavailable };",
145
+ "export const webkit = { launch: unavailable, connect: unavailable };",
146
+ "export default { chromium, firefox, webkit };",
147
+ "",
148
+ ].join("\n"),
141
149
  "playwright-core": [
142
150
  "const unavailable = async () => { throw new Error('playwright-core unavailable in Cloudflare Pages worker'); };",
143
151
  "export const chromium = { launch: unavailable };",
@@ -187,6 +195,50 @@ export const CLOUDFLARE_WORKER_STUB_MODULES: Record<string, string> = {
187
195
  "export default async () => ({ elements: [], files: {} });\n",
188
196
  };
189
197
 
198
+ export const CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES: Record<string, string> = {
199
+ "pdf-parse/worker": [
200
+ "const unavailable = async () => { throw new Error('pdf-parse/worker unavailable in Cloudflare Pages worker'); };",
201
+ "export class CanvasFactory {}",
202
+ "export const getData = unavailable;",
203
+ "export default { CanvasFactory, getData };",
204
+ "",
205
+ ].join("\n"),
206
+ };
207
+
208
+ export function cloudflareWorkerStubAliasArgs(stubDir: string): string[] {
209
+ const subpathAliases = Object.keys(CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES)
210
+ .sort((a, b) => b.length - a.length)
211
+ .map(
212
+ (mod) =>
213
+ `--alias:${mod}=${path.join(stubDir, `${mod.replace(/\//g, "__")}.js`)}`,
214
+ );
215
+ const packageAliases = Object.keys(CLOUDFLARE_WORKER_STUB_MODULES)
216
+ .sort((a, b) => b.length - a.length)
217
+ .map((mod) => `--alias:${mod}=${path.join(stubDir, mod, "index.js")}`);
218
+ return [...subpathAliases, ...packageAliases];
219
+ }
220
+
221
+ export function assertNoCloudflareWorkerStubDynamicImports(
222
+ code: string,
223
+ sourceName: string,
224
+ ): void {
225
+ const stubbedModules = [
226
+ ...Object.keys(CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES),
227
+ ...Object.keys(CLOUDFLARE_WORKER_STUB_MODULES),
228
+ ];
229
+ const pattern = stubbedModules
230
+ .sort((a, b) => b.length - a.length)
231
+ .map((moduleName) => moduleName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
232
+ .join("|");
233
+ const unresolvedImport = code.match(
234
+ new RegExp(`\\bimport\\s*\\(\\s*(["'])(${pattern})\\1\\s*\\)`),
235
+ );
236
+ if (!unresolvedImport) return;
237
+ throw new Error(
238
+ `Cloudflare worker output ${sourceName} retained a dynamic import for stubbed module "${unresolvedImport[2]}". Use a literal import so the worker bundler can apply its fail-closed stub.`,
239
+ );
240
+ }
241
+
190
242
  function cloudflareNodeBuiltinStubSource(
191
243
  moduleName: string,
192
244
  namedExports: string[],
@@ -1666,9 +1718,15 @@ async function buildCloudflarePages() {
1666
1718
  JSON.stringify({ name: mod, main: "index.js", type: "module" }),
1667
1719
  );
1668
1720
  }
1669
- const stubAliases = Object.keys(CLOUDFLARE_WORKER_STUB_MODULES).map(
1670
- (mod) => `--alias:${mod}=${path.join(stubDir, mod, "index.js")}`,
1671
- );
1721
+ for (const [mod, source] of Object.entries(
1722
+ CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES,
1723
+ )) {
1724
+ fs.writeFileSync(
1725
+ path.join(stubDir, `${mod.replace(/\//g, "__")}.js`),
1726
+ source,
1727
+ );
1728
+ }
1729
+ const stubAliases = cloudflareWorkerStubAliasArgs(stubDir);
1672
1730
  const nodeBuiltinStubDir = path.join(tmpDir, "node-builtin-stubs");
1673
1731
  fs.mkdirSync(nodeBuiltinStubDir, { recursive: true });
1674
1732
  const nodeBuiltinStubAliases: string[] = [];
@@ -1850,6 +1908,8 @@ async function buildCloudflarePages() {
1850
1908
  );
1851
1909
  }
1852
1910
 
1911
+ assertNoCloudflareWorkerStubDynamicImports(code, jsFile);
1912
+
1853
1913
  fs.writeFileSync(jsFile, code);
1854
1914
  }
1855
1915
 
@@ -84,6 +84,7 @@ export {
84
84
  unregisterRemotePushRegistrationForOwner,
85
85
  upsertRemotePushRegistration,
86
86
  } from "./remote-push-store.js";
87
+ export { deliverPendingRemotePushNotifications } from "./remote-push-delivery.js";
87
88
  export type {
88
89
  ComputerApprovalScope,
89
90
  ComputerCommandAction,
@@ -109,6 +109,7 @@ import {
109
109
  unregisterRemoteDevice,
110
110
  updateRemoteDeviceDetails,
111
111
  } from "./remote-devices-store.js";
112
+ import { startRemotePushDeliveryJob } from "./remote-push-delivery-job.js";
112
113
  import {
113
114
  listRemotePushNotificationsForOwner,
114
115
  listRemotePushRegistrationsForOwner,
@@ -579,7 +580,6 @@ function mountedPathParts(event: any, mountSuffix: string): string[] {
579
580
  function remoteCommandPushPayload(
580
581
  command: RemoteCommand,
581
582
  ): Record<string, unknown> {
582
- const result = readObject(command.result);
583
583
  const status = command.status;
584
584
  const title =
585
585
  status === "completed"
@@ -587,14 +587,19 @@ function remoteCommandPushPayload(
587
587
  : status === "failed"
588
588
  ? "Remote run failed"
589
589
  : "Remote run updated";
590
+ const body =
591
+ status === "completed"
592
+ ? "Open Agent Native to review the result."
593
+ : status === "failed"
594
+ ? "Open Agent Native to review the failure."
595
+ : "Open Agent Native to review the latest status.";
590
596
  return {
591
597
  title,
592
- body: command.errorMessage ?? readString(result?.message),
598
+ body,
593
599
  commandId: command.id,
594
600
  hostId: command.deviceId,
595
601
  kind: command.kind,
596
602
  status,
597
- result: command.result,
598
603
  updatedAt: command.updatedAt,
599
604
  };
600
605
  }
@@ -2897,6 +2902,7 @@ export function createIntegrationsPlugin(
2897
2902
  });
2898
2903
  startA2AContinuationRetryJob(adapterMap);
2899
2904
  startRemoteCommandsRetryJob();
2905
+ startRemotePushDeliveryJob();
2900
2906
 
2901
2907
  // ─── Start Google Docs poller/push ────────────────────────────
2902
2908
  if (adapterMap.has("google-docs")) {
@@ -0,0 +1,48 @@
1
+ import { deliverPendingRemotePushNotifications } from "./remote-push-delivery.js";
2
+
3
+ const DELIVERY_INTERVAL_MS = 60_000;
4
+
5
+ let retryInterval: ReturnType<typeof setInterval> | null = null;
6
+ let initialTimer: ReturnType<typeof setTimeout> | null = null;
7
+ let running = false;
8
+
9
+ export async function runRemotePushDelivery(): Promise<void> {
10
+ if (running) return;
11
+ running = true;
12
+ try {
13
+ await deliverPendingRemotePushNotifications();
14
+ } catch (error) {
15
+ console.error("[integrations] Remote push delivery failed", {
16
+ error: error instanceof Error ? error.name : "UnknownError",
17
+ });
18
+ } finally {
19
+ running = false;
20
+ }
21
+ }
22
+
23
+ export function startRemotePushDeliveryJob(): void {
24
+ if (retryInterval) return;
25
+ initialTimer = setTimeout(() => void runRemotePushDelivery(), 10_000);
26
+ unrefTimer(initialTimer);
27
+ retryInterval = setInterval(
28
+ () => void runRemotePushDelivery(),
29
+ DELIVERY_INTERVAL_MS,
30
+ );
31
+ unrefTimer(retryInterval);
32
+ }
33
+
34
+ export function stopRemotePushDeliveryJob(): void {
35
+ if (initialTimer) {
36
+ clearTimeout(initialTimer);
37
+ initialTimer = null;
38
+ }
39
+ if (retryInterval) {
40
+ clearInterval(retryInterval);
41
+ retryInterval = null;
42
+ }
43
+ running = false;
44
+ }
45
+
46
+ function unrefTimer(timer: ReturnType<typeof setInterval>): void {
47
+ (timer as unknown as { unref?: () => void }).unref?.();
48
+ }