bullmq-dash 0.1.8 → 0.2.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/README.md CHANGED
@@ -76,6 +76,25 @@ bullmq-dash --queues email,notifications,payments
76
76
  bullmq-dash --poll-interval 5000
77
77
  ```
78
78
 
79
+ ## Browser Terminal Mode
80
+
81
+ `bullmq-dash` includes a built-in web terminal mode powered by a Fastify + PTY bridge.
82
+
83
+ ```bash
84
+ bullmq-dash --web --redis-host localhost --redis-port 6379
85
+ ```
86
+
87
+ Then open:
88
+
89
+ ```text
90
+ http://127.0.0.1:3001
91
+ ```
92
+
93
+ Optional web server flags:
94
+
95
+ - `--web-host <host>` (default: `127.0.0.1`)
96
+ - `--web-port <port>` (default: `3001`)
97
+
79
98
  ## Keyboard Shortcuts
80
99
 
81
100
  ### Navigation
package/dist/app.d.ts CHANGED
@@ -2,6 +2,7 @@ export declare class App {
2
2
  private renderer;
3
3
  private elements;
4
4
  private unsubscribeState;
5
+ private syncIntervalId;
5
6
  start(): Promise<void>;
6
7
  private createElements;
7
8
  private setupKeyboardHandling;
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AA4DA,qBAAa,GAAG;IACd,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,gBAAgB,CAA6B;IAE/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B5B,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,qBAAqB;YAYf,cAAc;YAwJd,aAAa;YAgBb,mBAAmB;YAgBnB,oBAAoB;YAmBpB,aAAa;YA4Bb,eAAe;IAoB7B,OAAO,CAAC,MAAM;YAqGA,OAAO;CAoBtB"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AA8DA,qBAAa,GAAG;IACd,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,cAAc,CAA+C;IAE/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC5B,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,qBAAqB;YAYf,cAAc;YAwJd,aAAa;YAgBb,mBAAmB;YAgBnB,oBAAoB;YAmBpB,aAAa;YA4Bb,eAAe;IAoB7B,OAAO,CAAC,MAAM;YAqGA,OAAO;CA2BtB"}
package/dist/config.d.ts CHANGED
@@ -72,6 +72,9 @@ export interface CliArgs {
72
72
  help?: boolean;
73
73
  version?: boolean;
74
74
  tui?: boolean;
75
+ web?: boolean;
76
+ webHost?: string;
77
+ webPort?: number;
75
78
  subcommand?: Subcommand;
76
79
  humanFriendly?: boolean;
77
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIlD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,WAAW,OAAO;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAiKD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAwB/F;AAiMD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,MAAM,GAAG,SAAS,CAoBpB;AAED,wBAAgB,YAAY,IAAI,OAAO,CAkHtC;AAED,wBAAgB,QAAQ,CAAC,QAAQ,GAAE,MAAU,GAAG,IAAI,CAGnD;AAED,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAoBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAM/E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAsBnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAChE,OAAO,EAAE,OAAO,GACf,MAAM,CAsBR;AAKD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,IAAI,MAAM,CAKlC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":""}
@@ -4,6 +4,12 @@ export interface JobSummary {
4
4
  name: string;
5
5
  state: string;
6
6
  timestamp: number;
7
+ /**
8
+ * Optional preview payload. Populated by the Redis fetch path so callers
9
+ * (sync, polling, JSON reporter) can write `data_preview` to SQLite without
10
+ * casting through `unknown`. Not loaded from SQLite reads.
11
+ */
12
+ data?: unknown;
7
13
  }
8
14
  export interface JobDetail extends JobSummary {
9
15
  data: unknown;
@@ -35,14 +41,27 @@ export type JsonJobStatus = (typeof VALID_JOB_STATUSES)[number];
35
41
  * Returns up to `maxResults` jobs (default 1000) to prevent OOM on huge queues.
36
42
  * Used by subcommand mode for bulk export.
37
43
  */
38
- export declare function getAllJobs(queueName: string, status?: JsonJobStatus, maxResults?: number): Promise<{
44
+ export declare function getAllJobs(queueName: string, status?: JsonJobStatus, maxResults?: number, includeData?: boolean): Promise<{
39
45
  jobs: JobSummary[];
40
46
  total: number;
41
47
  }>;
48
+ /**
49
+ * Paginate through all job IDs in a queue, yielding batches.
50
+ *
51
+ * Uses `queue.getRanges()` per state, paginating in chunks of SYNC_PAGE_SIZE.
52
+ * Each yielded batch contains `{ id, state }` pairs ready for staging insertion.
53
+ *
54
+ * This never holds more than one page of IDs in memory at a time, making it
55
+ * safe for queues with millions of jobs.
56
+ */
57
+ export declare function getAllJobIds(queueName: string): AsyncGenerator<Array<{
58
+ id: string;
59
+ state: string;
60
+ }>>;
42
61
  /**
43
62
  * Get jobs by status with pagination
44
63
  */
45
- export declare function getJobs(queueName: string, status: JobListView, page?: number, pageSize?: number): Promise<JobsResult>;
64
+ export declare function getJobs(queueName: string, status: JobListView, page?: number, pageSize?: number, includeData?: boolean): Promise<JobsResult>;
46
65
  /**
47
66
  * Get detailed information for a single job
48
67
  */
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../src/data/jobs.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,SAAS,GACT,YAAY,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD;;GAEG;AACH,eAAO,MAAM,kBAAkB,+DAAgE,CAAC;AAChG,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAQhE;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,aAAa,EACtB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAmFhD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAAkB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAgHrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2B9F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGrE"}
1
+ {"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../src/data/jobs.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,SAAS,GACT,YAAY,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD;;GAEG;AACH,eAAO,MAAM,kBAAkB,+DAAgE,CAAC;AAChG,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAQhE;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,aAAa,EACtB,UAAU,GAAE,MAA4B,EACxC,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAyFhD;AAED;;;;;;;;GAQG;AACH,wBAAuB,YAAY,CACjC,SAAS,EAAE,MAAM,GAChB,cAAc,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA2BtD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAAkB,EAC5B,WAAW,GAAE,OAAe,GAC3B,OAAO,CAAC,UAAU,CAAC,CAsHrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2B9F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGrE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jobs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.test.d.ts","sourceRoot":"","sources":["../../src/data/jobs.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"queues.d.ts","sourceRoot":"","sources":["../../src/data/queues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAgB/B,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAejD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAkD5D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA8B1E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAM9D;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpD"}
1
+ {"version":3,"file":"queues.d.ts","sourceRoot":"","sources":["../../src/data/queues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAgB/B,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAejD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAqD5D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA8B1E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAM9D;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpD"}
@@ -0,0 +1,118 @@
1
+ import { Database } from "bun:sqlite";
2
+ export declare function createSqliteDb(dbPath?: string): Database;
3
+ export declare function getSqliteDb(): Database;
4
+ export declare function closeSqliteDb(): void;
5
+ export interface JobRow {
6
+ id: string;
7
+ queue: string;
8
+ name: string | null;
9
+ state: string;
10
+ timestamp: number | null;
11
+ data_preview: string | null;
12
+ }
13
+ export interface JobQueryParams {
14
+ queue: string;
15
+ search?: string;
16
+ state?: string;
17
+ sort?: string;
18
+ order?: "asc" | "desc";
19
+ page?: number;
20
+ pageSize?: number;
21
+ }
22
+ export interface JobQueryResult {
23
+ jobs: JobRow[];
24
+ total: number;
25
+ }
26
+ export declare function queryJobs(params: JobQueryParams): JobQueryResult;
27
+ export declare function upsertJobs(queue: string, jobs: Array<{
28
+ id: string;
29
+ name: string;
30
+ state: string;
31
+ timestamp: number;
32
+ data?: unknown;
33
+ }>): void;
34
+ export declare function getJobFromDb(queue: string, jobId: string): JobRow | null;
35
+ export declare function getQueueJobCount(queue: string): number;
36
+ /**
37
+ * Rebuild the FTS5 index from the jobs table.
38
+ * Useful after bulk operations or if the index gets out of sync.
39
+ */
40
+ export declare function rebuildFtsIndex(): void;
41
+ /**
42
+ * Upsert job stubs — only id, queue, and state.
43
+ *
44
+ * Used by incremental sync to cheaply record job existence and state
45
+ * without fetching full job data from Redis. Preserves existing name,
46
+ * timestamp, and data_preview if the job already exists.
47
+ */
48
+ export declare function upsertJobStubs(queue: string, jobs: Array<{
49
+ id: string;
50
+ state: string;
51
+ }>): void;
52
+ export interface SyncState {
53
+ queue: string;
54
+ jobCount: number;
55
+ syncedAt: number;
56
+ }
57
+ export declare function getSyncState(queue: string): SyncState | null;
58
+ export declare function upsertSyncState(queue: string, input: {
59
+ jobCount: number;
60
+ syncedAt: number;
61
+ }): void;
62
+ /**
63
+ * Create the sync_staging temporary table.
64
+ * Called at the start of each sync cycle, dropped at the end.
65
+ *
66
+ * Uses a TEMP table so it never touches disk, is automatically scoped to the
67
+ * current connection (we use a single shared connection — see getSqliteDb),
68
+ * and is cleaned up if the process exits unexpectedly. We also drop any
69
+ * leftover `main.sync_staging` from a previous version that created it on
70
+ * disk, so upgrades don't trip over a stale table.
71
+ */
72
+ export declare function createSyncStaging(): void;
73
+ /**
74
+ * Insert a batch of job IDs + states into the staging table.
75
+ * Called repeatedly during paginated getRanges() fetching.
76
+ */
77
+ export declare function insertStagingBatch(queue: string, jobs: Array<{
78
+ id: string;
79
+ state: string;
80
+ }>): void;
81
+ /**
82
+ * Find job IDs that exist in staging but not in the jobs table.
83
+ * These are new jobs that need to be inserted. Returns id + state so the
84
+ * caller can build job stubs without a second round-trip to SQLite.
85
+ */
86
+ export declare function findNewIdsByStagingDiff(queue: string): Array<{
87
+ id: string;
88
+ state: string;
89
+ }>;
90
+ /**
91
+ * Find job IDs that exist in both staging and jobs table but have different states.
92
+ * Returns the staging (new) state for each changed job.
93
+ */
94
+ export declare function findChangedIdsByStagingDiff(queue: string): Array<{
95
+ id: string;
96
+ state: string;
97
+ }>;
98
+ /**
99
+ * Find job IDs that exist in the jobs table but NOT in staging.
100
+ * These are candidates for stale-row deletion. Callers may filter the list
101
+ * (e.g., to skip jobs polling just upserted) before calling deleteJobsByIds.
102
+ *
103
+ * Uses a LEFT JOIN anti-join (rather than `NOT IN (subquery)`) so SQLite can
104
+ * use the (queue, id) primary key on both sides and avoid materializing the
105
+ * staging subquery for every row in `jobs`. This matters at 5M+ scale.
106
+ */
107
+ export declare function findStaleIdsByStagingDiff(queue: string): string[];
108
+ /**
109
+ * Batch-delete jobs by (queue, id). Returns the number of IDs passed in —
110
+ * we don't use `result.changes` because FTS5 triggers inflate the count
111
+ * (shadow table writes from `jobs_ad` are included in the changes tally).
112
+ */
113
+ export declare function deleteJobsByIds(queue: string, ids: string[]): number;
114
+ /**
115
+ * Drop the staging table. Called at the end of each sync cycle.
116
+ */
117
+ export declare function dropSyncStaging(): void;
118
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/data/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sqlite.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.test.d.ts","sourceRoot":"","sources":["../../src/data/sqlite.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ export interface SyncResult {
2
+ inserted: number;
3
+ stateUpdated: number;
4
+ deleted: number;
5
+ total: number;
6
+ /** Set when the sync failed; callers can use this to surface the error. */
7
+ error?: string;
8
+ }
9
+ /** Test-only helper: reset the sync lock between tests. */
10
+ export declare function __resetSyncLockForTests(): void;
11
+ /**
12
+ * Test-only helper: force the sync lock into a "held since `acquiredAtMs`"
13
+ * state so the next caller can exercise the stale-lock stealing path.
14
+ */
15
+ export declare function __forceSyncLockForTests(acquiredAtMs: number): void;
16
+ /**
17
+ * Notify the sync layer that polling just wrote fresh state for these jobs.
18
+ * Sync's next diff will skip state overwrite and stale-delete for them until
19
+ * either RECENT_POLL_WINDOW_MS elapses or the next polling write replaces the
20
+ * timestamp.
21
+ */
22
+ export declare function markPolledWrites(queue: string, jobIds: readonly string[]): void;
23
+ /** Test-only helper: reset the recently-polled map between tests. */
24
+ export declare function __resetRecentlyPolledForTests(): void;
25
+ /**
26
+ * Sync a single queue from Redis to SQLite — incrementally at scale.
27
+ *
28
+ * Uses a staging table for SQL-side diffing:
29
+ * 1. Paginate all job IDs from Redis into staging (5000 at a time)
30
+ * 2. SQL JOIN to find new IDs → insert as stubs (id + state, no data)
31
+ * 3. SQL JOIN to find changed states → update state only
32
+ * (skip IDs polling refreshed after sync started — staging is stale for those)
33
+ * 4. SQL LEFT JOIN to find stale IDs → delete
34
+ * (same exclusion — polling may have just inserted a job sync's snapshot missed)
35
+ * 5. Update sync_state metadata
36
+ *
37
+ * Name, timestamp, and data_preview are populated lazily when jobs are
38
+ * viewed in TUI or fetched via CLI — not during background sync.
39
+ *
40
+ * **Concurrency:** NOT parallel-safe. The `sync_staging` TEMP table is
41
+ * shared across the single SQLite connection, so concurrent calls to
42
+ * `syncQueue` (or `fullSync`) would interleave staging rows and corrupt
43
+ * the diff. A module-level guard rejects overlapping calls.
44
+ *
45
+ * **Failure recovery:** there is no partial-progress checkpoint. If a sync
46
+ * fails mid-way (Redis disconnect, SQLite error, process killed), the
47
+ * staging table is dropped and the next run starts from scratch. Already-
48
+ * persisted jobs are preserved; the next successful sync will reconcile.
49
+ */
50
+ export declare function syncQueue(queueName: string): Promise<SyncResult>;
51
+ export interface FullSyncResult {
52
+ queues: number;
53
+ totalInserted: number;
54
+ totalDeleted: number;
55
+ /** Per-queue failures. Empty array means every queue succeeded. */
56
+ errors: Array<{
57
+ queue: string;
58
+ error: string;
59
+ }>;
60
+ }
61
+ /**
62
+ * Full sync: discover all queues and sync each one sequentially.
63
+ *
64
+ * Sequential because they share the same staging table. Each queue
65
+ * creates/drops the staging table in its own syncQueue() call.
66
+ *
67
+ * Per-queue failures are collected into `errors` rather than aborting the
68
+ * whole sync. A non-empty `errors` array with `queues > 0` means partial
69
+ * success; `queues: 0` with `errors: [{queue: "", ...}]` means discovery
70
+ * itself failed.
71
+ */
72
+ export declare function fullSync(): Promise<FullSyncResult>;
73
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/data/sync.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsCD,2DAA2D;AAC3D,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAGlE;AAsBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAQ/E;AAED,qEAAqE;AACrE,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD;AAOD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA6GtE;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CAiCxD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.test.d.ts","sourceRoot":"","sources":["../../src/data/sync.test.ts"],"names":[],"mappings":""}