@remit/imap-worker 0.0.31 → 0.0.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/imap-worker",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -106,6 +106,10 @@ const deps = (): MailboxManagementDeps =>
106
106
  h.calls.push({ method: "mailbox.update", args });
107
107
  if (h.mailboxUpdateError) throw h.mailboxUpdateError;
108
108
  },
109
+ findByPathPrefix: async (...args: unknown[]) => {
110
+ h.calls.push({ method: "mailbox.findByPathPrefix", args });
111
+ return [];
112
+ },
109
113
  delete: record("mailbox.delete"),
110
114
  },
111
115
  secrets: {},
@@ -70,15 +70,18 @@ const isMailboxPresentUpstream = (error: unknown): boolean => {
70
70
  * Pinned invariant for the whole-chain terminal guards below.
71
71
  *
72
72
  * Each handler wraps its `MailboxManagementService.sync*` chain in a try/catch
73
- * that treats a NotFoundError as terminal (ack with a WARN, issue #289). That
74
- * is only sound because `syncCreate` / `syncRename` / `syncDelete` and their
75
- * error-recovery branches here touch nothing but the single target mailbox
76
- * row via `mailboxService.get/update/delete(accountId, mailboxId)`. So the only
77
- * row a NotFoundError can refer to is that target, and its absence can only mean
78
- * the user deleted the folder mid-sync never an unrelated missing entity that
79
- * should have been retried. If a sync method ever reads or writes a second
80
- * entity, narrow these catches (match the mailboxId / re-check existence) before
81
- * a NotFoundError from elsewhere is silently acked.
73
+ * that treats a NotFoundError as terminal (ack with a WARN, issue #289). That is
74
+ * only sound while the sole row a NotFoundError can refer to is the target
75
+ * mailbox, so its absence can only mean the user deleted the folder mid-sync —
76
+ * never an unrelated missing entity that should have been retried.
77
+ *
78
+ * `syncCreate` and `syncDelete` hold to that by touching nothing but the target
79
+ * row. `syncRename` also writes the renamed subtree's descendant rows, and keeps
80
+ * the invariant by absorbing their NotFoundErrors itself: a descendant deleted
81
+ * mid-settle never reaches these catches. Any sync method that reads or writes a
82
+ * second entity owes the same, or these catches must be narrowed (match the
83
+ * mailboxId / re-check existence) before a NotFoundError from elsewhere is
84
+ * silently acked.
82
85
  */
83
86
 
84
87
  /**
@@ -6,15 +6,20 @@
6
6
  * in remit-account-worker/src/config.ts).
7
7
  *
8
8
  * `tickIntervalSeconds` drives how often the tick itself runs — the
9
- * EventBridge schedule rate in prod, the local-runner loop delay in dev — and
10
- * must stay well below `offlineIntervalSeconds` so a tick reliably observes
11
- * every account crossing the threshold. CDK and this runtime default must
12
- * agree — see infra/lib/config.ts's `mailboxSync` stage config.
9
+ * EventBridge schedule rate on a managed deployment, the runner's loop delay
10
+ * everywhere else — and must stay well below `offlineIntervalSeconds` so a tick
11
+ * reliably observes every account crossing the threshold. CDK and this runtime
12
+ * default must agree — see infra/lib/config.ts's `mailboxSync` stage config.
13
13
  *
14
14
  * `offlineIntervalSeconds` is the only due-ness threshold: an account is due
15
15
  * once its last successful sync is older than this interval. There is no
16
16
  * "online" tier — client-side polling (useStaleAccountSync) covers an
17
17
  * account while its mail is actively open in the web client.
18
+ *
19
+ * The defaults below are a floor for a deployment that sets neither. The
20
+ * standalone stack sets both, at a cadence sized for one box and a handful of
21
+ * accounts, and the checker's stall threshold is derived from those values —
22
+ * see deploy/vps/docker-compose.sqlite.yml's `scheduler` service.
18
23
  */
19
24
 
20
25
  const DEFAULT_TICK_INTERVAL_SECONDS = 60 * 60; // 1 hour
@@ -16,8 +16,8 @@ const sqsClient = createQueueProducer({ queueUrl: mailboxesQueueUrl });
16
16
  * (#1247, restructured #1251). Ticks at `MAILBOX_SYNC_TICK_INTERVAL_SECONDS`
17
17
  * (rate schedule, wired in infra/stacks/dev/stacks/remit-worker-stack.ts) and
18
18
  * delegates the actual decision + enqueue to `runSchedulerTick` — the same
19
- * function the local dev-stack timer loop calls (see `local-runner.ts`), so
20
- * production and local dev run one code path.
19
+ * function the timer loop calls on a deployment with no EventBridge (see
20
+ * `runner.ts`), so every deployment runs one code path.
21
21
  *
22
22
  * Uses the EventBridge event's own `time` (the scheduled fire time) as the
23
23
  * tick's `now`, rather than `Date.now()` at processing time. This is what
@@ -8,18 +8,15 @@ import { getOfflineIntervalMs, getTickIntervalMs } from "./config.js";
8
8
  import { runSchedulerTick } from "./run-tick.js";
9
9
 
10
10
  /**
11
- * Standalone scheduled-sync runner for the local pg-dev docker-compose stack
12
- * (#1247, restructured #1251). Production ticks `runSchedulerTick` off an
13
- * EventBridge schedule (see handler.ts); ElasticMQ/the pg-dev stack has no
14
- * EventBridge, so this process ticks on a plain loop at the same
15
- * `MAILBOX_SYNC_TICK_INTERVAL_SECONDS` cadence instead same function, same
16
- * config knobs, so local dev behaves like production rather than needing its
17
- * own scheduling logic.
11
+ * The scheduled-sync runner for every deployment that has no EventBridge: the
12
+ * self-host stack's `scheduler` service and the local dev compose stack. A
13
+ * managed deployment fires `runSchedulerTick` off an EventBridge schedule (see
14
+ * handler.ts); this process ticks the same function on a plain loop at the same
15
+ * `MAILBOX_SYNC_TICK_INTERVAL_SECONDS` cadence, so there is one scheduling
16
+ * implementation and one set of knobs.
18
17
  *
19
- * This is a dev-only harness, not production code: like
20
- * `e2e-processor-shim.ts`, a tick failure crashes the process loudly rather
21
- * than swallowing it — docker-compose's `restart: unless-stopped` brings it
22
- * back for the next tick.
18
+ * A tick failure crashes the process loudly rather than being swallowed —
19
+ * compose's `restart: unless-stopped` brings it back for the next tick.
23
20
  */
24
21
 
25
22
  const log = createLogger();
@@ -40,7 +37,7 @@ const CRASH_BACKOFF_MS = 5_000;
40
37
 
41
38
  log.info(
42
39
  { tickIntervalMs, offlineIntervalMs },
43
- "Local scheduled-sync runner started",
40
+ "Scheduled-sync runner started",
44
41
  );
45
42
 
46
43
  const runLoop = async (): Promise<void> => {