@taskcast/sqlite 0.1.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.
@@ -0,0 +1,14 @@
1
+ export { SqliteShortTermStore } from './short-term.js';
2
+ export { SqliteLongTermStore } from './long-term.js';
3
+ import { type Database as DatabaseType } from 'better-sqlite3';
4
+ import { SqliteShortTermStore } from './short-term.js';
5
+ import { SqliteLongTermStore } from './long-term.js';
6
+ export interface SqliteAdapterOptions {
7
+ path?: string;
8
+ }
9
+ export declare function createSqliteAdapters(options?: SqliteAdapterOptions): {
10
+ shortTermStore: SqliteShortTermStore;
11
+ longTermStore: SqliteLongTermStore;
12
+ db: DatabaseType;
13
+ };
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAiB,EAAE,KAAK,QAAQ,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,oBAAyB,GAAG;IACxE,cAAc,EAAE,oBAAoB,CAAA;IACpC,aAAa,EAAE,mBAAmB,CAAA;IAClC,EAAE,EAAE,YAAY,CAAA;CACjB,CAeA"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ export { SqliteShortTermStore } from './short-term.js';
2
+ export { SqliteLongTermStore } from './long-term.js';
3
+ import Database from 'better-sqlite3';
4
+ import { readFileSync } from 'node:fs';
5
+ import { join, dirname } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { SqliteShortTermStore } from './short-term.js';
8
+ import { SqliteLongTermStore } from './long-term.js';
9
+ export function createSqliteAdapters(options = {}) {
10
+ const dbPath = options.path ?? process.env['TASKCAST_SQLITE_PATH'] ?? './taskcast.db';
11
+ const db = new Database(dbPath);
12
+ db.pragma('journal_mode = WAL');
13
+ db.pragma('foreign_keys = ON');
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const migration = readFileSync(join(__dirname, '../migrations/001_initial.sql'), 'utf8');
16
+ db.exec(migration);
17
+ return {
18
+ shortTermStore: new SqliteShortTermStore(db),
19
+ longTermStore: new SqliteLongTermStore(db),
20
+ db,
21
+ };
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,QAA2C,MAAM,gBAAgB,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAMpD,MAAM,UAAU,oBAAoB,CAAC,UAAgC,EAAE;IAKrE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,eAAe,CAAA;IACrF,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC/B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC/B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAE9B,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACzD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,+BAA+B,CAAC,EAAE,MAAM,CAAC,CAAA;IACxF,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAElB,OAAO;QACL,cAAc,EAAE,IAAI,oBAAoB,CAAC,EAAE,CAAC;QAC5C,aAAa,EAAE,IAAI,mBAAmB,CAAC,EAAE,CAAC;QAC1C,EAAE;KACH,CAAA;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Task, TaskEvent, LongTermStore, EventQueryOptions, WorkerAuditEvent } from '@taskcast/core';
3
+ export declare class SqliteLongTermStore implements LongTermStore {
4
+ private db;
5
+ constructor(db: Database.Database);
6
+ saveTask(task: Task): Promise<void>;
7
+ getTask(taskId: string): Promise<Task | null>;
8
+ saveEvent(event: TaskEvent): Promise<void>;
9
+ getEvents(taskId: string, opts?: EventQueryOptions): Promise<TaskEvent[]>;
10
+ saveWorkerEvent(event: WorkerAuditEvent): Promise<void>;
11
+ getWorkerEvents(workerId: string, opts?: EventQueryOptions): Promise<WorkerAuditEvent[]>;
12
+ }
13
+ //# sourceMappingURL=long-term.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"long-term.d.ts","sourceRoot":"","sources":["../src/long-term.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAKzG,qBAAa,mBAAoB,YAAW,aAAa;IAC3C,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEnC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CnC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAQ7C,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB1C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmDzE,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAyC/F"}
@@ -0,0 +1,175 @@
1
+ import { rowToTask, rowToEvent, rowToWorkerEvent } from './row-mappers.js';
2
+ // ─── SqliteLongTermStore ──────────────────────────────────────────────────
3
+ export class SqliteLongTermStore {
4
+ db;
5
+ constructor(db) {
6
+ this.db = db;
7
+ }
8
+ async saveTask(task) {
9
+ const stmt = this.db.prepare(`
10
+ INSERT INTO taskcast_tasks (id, type, status, params, result, error, metadata, auth_config, webhooks, cleanup, created_at, updated_at, completed_at, ttl, tags, assign_mode, cost, assigned_worker, disconnect_policy)
11
+ VALUES (@id, @type, @status, @params, @result, @error, @metadata, @auth_config, @webhooks, @cleanup, @created_at, @updated_at, @completed_at, @ttl, @tags, @assign_mode, @cost, @assigned_worker, @disconnect_policy)
12
+ ON CONFLICT (id) DO UPDATE SET
13
+ type = excluded.type,
14
+ status = excluded.status,
15
+ params = excluded.params,
16
+ result = excluded.result,
17
+ error = excluded.error,
18
+ metadata = excluded.metadata,
19
+ auth_config = excluded.auth_config,
20
+ webhooks = excluded.webhooks,
21
+ cleanup = excluded.cleanup,
22
+ updated_at = excluded.updated_at,
23
+ completed_at = excluded.completed_at,
24
+ ttl = excluded.ttl,
25
+ tags = excluded.tags,
26
+ assign_mode = excluded.assign_mode,
27
+ cost = excluded.cost,
28
+ assigned_worker = excluded.assigned_worker,
29
+ disconnect_policy = excluded.disconnect_policy
30
+ `);
31
+ stmt.run({
32
+ id: task.id,
33
+ type: task.type ?? null,
34
+ status: task.status,
35
+ params: task.params ? JSON.stringify(task.params) : null,
36
+ result: task.result ? JSON.stringify(task.result) : null,
37
+ error: task.error ? JSON.stringify(task.error) : null,
38
+ metadata: task.metadata ? JSON.stringify(task.metadata) : null,
39
+ auth_config: task.authConfig ? JSON.stringify(task.authConfig) : null,
40
+ webhooks: task.webhooks ? JSON.stringify(task.webhooks) : null,
41
+ cleanup: task.cleanup ? JSON.stringify(task.cleanup) : null,
42
+ created_at: task.createdAt,
43
+ updated_at: task.updatedAt,
44
+ completed_at: task.completedAt ?? null,
45
+ ttl: task.ttl ?? null,
46
+ tags: task.tags ? JSON.stringify(task.tags) : null,
47
+ assign_mode: task.assignMode ?? null,
48
+ cost: task.cost ?? null,
49
+ assigned_worker: task.assignedWorker ?? null,
50
+ disconnect_policy: task.disconnectPolicy ?? null,
51
+ });
52
+ }
53
+ async getTask(taskId) {
54
+ const row = this.db.prepare('SELECT * FROM taskcast_tasks WHERE id = ?').get(taskId);
55
+ return row ? rowToTask(row) : null;
56
+ }
57
+ async saveEvent(event) {
58
+ this.db
59
+ .prepare(`INSERT INTO taskcast_events (id, task_id, idx, timestamp, type, level, data, series_id, series_mode)
60
+ VALUES (@id, @task_id, @idx, @timestamp, @type, @level, @data, @series_id, @series_mode)
61
+ ON CONFLICT (id) DO NOTHING`)
62
+ .run({
63
+ id: event.id,
64
+ task_id: event.taskId,
65
+ idx: event.index,
66
+ timestamp: event.timestamp,
67
+ type: event.type,
68
+ level: event.level,
69
+ data: event.data != null ? JSON.stringify(event.data) : null,
70
+ series_id: event.seriesId ?? null,
71
+ series_mode: event.seriesMode ?? null,
72
+ });
73
+ }
74
+ async getEvents(taskId, opts) {
75
+ const since = opts?.since;
76
+ const limit = opts?.limit;
77
+ let sql;
78
+ const params = [taskId];
79
+ if (since?.id) {
80
+ sql = `
81
+ SELECT * FROM taskcast_events
82
+ WHERE task_id = ?
83
+ AND idx > COALESCE(
84
+ (SELECT idx FROM taskcast_events WHERE task_id = ? AND id = ?),
85
+ -1
86
+ )
87
+ ORDER BY idx ASC
88
+ `;
89
+ params.push(taskId, since.id);
90
+ }
91
+ else if (since?.index !== undefined) {
92
+ sql = `
93
+ SELECT * FROM taskcast_events
94
+ WHERE task_id = ? AND idx > ?
95
+ ORDER BY idx ASC
96
+ `;
97
+ params.push(since.index);
98
+ }
99
+ else if (since?.timestamp !== undefined) {
100
+ sql = `
101
+ SELECT * FROM taskcast_events
102
+ WHERE task_id = ? AND timestamp > ?
103
+ ORDER BY idx ASC
104
+ `;
105
+ params.push(since.timestamp);
106
+ }
107
+ else {
108
+ sql = `
109
+ SELECT * FROM taskcast_events
110
+ WHERE task_id = ?
111
+ ORDER BY idx ASC
112
+ `;
113
+ }
114
+ if (limit) {
115
+ sql += ' LIMIT ?';
116
+ params.push(limit);
117
+ }
118
+ const rows = this.db.prepare(sql).all(...params);
119
+ return rows.map(rowToEvent);
120
+ }
121
+ // ─── Worker audit events ─────────────────────────────────────────────────
122
+ async saveWorkerEvent(event) {
123
+ this.db
124
+ .prepare(`INSERT INTO taskcast_worker_events (id, worker_id, timestamp, action, data)
125
+ VALUES (@id, @worker_id, @timestamp, @action, @data)
126
+ ON CONFLICT (id) DO NOTHING`)
127
+ .run({
128
+ id: event.id,
129
+ worker_id: event.workerId,
130
+ timestamp: event.timestamp,
131
+ action: event.action,
132
+ data: event.data ? JSON.stringify(event.data) : null,
133
+ });
134
+ }
135
+ async getWorkerEvents(workerId, opts) {
136
+ const since = opts?.since;
137
+ const limit = opts?.limit;
138
+ let sql;
139
+ const params = [workerId];
140
+ if (since?.timestamp !== undefined) {
141
+ sql = `
142
+ SELECT * FROM taskcast_worker_events
143
+ WHERE worker_id = ? AND timestamp > ?
144
+ ORDER BY timestamp ASC
145
+ `;
146
+ params.push(since.timestamp);
147
+ }
148
+ else if (since?.id) {
149
+ sql = `
150
+ SELECT * FROM taskcast_worker_events
151
+ WHERE worker_id = ?
152
+ AND timestamp > COALESCE(
153
+ (SELECT timestamp FROM taskcast_worker_events WHERE id = ?),
154
+ 0
155
+ )
156
+ ORDER BY timestamp ASC
157
+ `;
158
+ params.push(since.id);
159
+ }
160
+ else {
161
+ sql = `
162
+ SELECT * FROM taskcast_worker_events
163
+ WHERE worker_id = ?
164
+ ORDER BY timestamp ASC
165
+ `;
166
+ }
167
+ if (limit) {
168
+ sql += ' LIMIT ?';
169
+ params.push(limit);
170
+ }
171
+ const rows = this.db.prepare(sql).all(...params);
172
+ return rows.map(rowToWorkerEvent);
173
+ }
174
+ }
175
+ //# sourceMappingURL=long-term.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"long-term.js","sourceRoot":"","sources":["../src/long-term.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Task, TaskEvent, Worker, WorkerAssignment, WorkerAuditEvent } from '@taskcast/core';
2
+ export declare function rowToTask(row: Record<string, unknown>): Task;
3
+ export declare function rowToWorker(row: Record<string, unknown>): Worker;
4
+ export declare function rowToWorkerAssignment(row: Record<string, unknown>): WorkerAssignment;
5
+ export declare function rowToWorkerEvent(row: Record<string, unknown>): WorkerAuditEvent;
6
+ export declare function rowToEvent(row: Record<string, unknown>): TaskEvent;
7
+ //# sourceMappingURL=row-mappers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-mappers.d.ts","sourceRoot":"","sources":["../src/row-mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,SAAS,EAET,MAAM,EACN,gBAAgB,EAChB,gBAAgB,EAGjB,MAAM,gBAAgB,CAAA;AAEvB,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyB5D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAchE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAQpF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAS/E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAelE"}
@@ -0,0 +1,92 @@
1
+ export function rowToTask(row) {
2
+ const task = {
3
+ id: row['id'],
4
+ status: row['status'],
5
+ createdAt: row['created_at'],
6
+ updatedAt: row['updated_at'],
7
+ };
8
+ if (row['type'] != null)
9
+ task.type = row['type'];
10
+ if (row['params'] != null)
11
+ task.params = JSON.parse(row['params']);
12
+ if (row['result'] != null)
13
+ task.result = JSON.parse(row['result']);
14
+ if (row['error'] != null)
15
+ task.error = JSON.parse(row['error']);
16
+ if (row['metadata'] != null)
17
+ task.metadata = JSON.parse(row['metadata']);
18
+ if (row['auth_config'] != null)
19
+ task.authConfig = JSON.parse(row['auth_config']);
20
+ if (row['webhooks'] != null)
21
+ task.webhooks = JSON.parse(row['webhooks']);
22
+ if (row['cleanup'] != null)
23
+ task.cleanup = JSON.parse(row['cleanup']);
24
+ if (row['completed_at'] != null)
25
+ task.completedAt = row['completed_at'];
26
+ if (row['ttl'] != null)
27
+ task.ttl = row['ttl'];
28
+ if (row['tags'] != null)
29
+ task.tags = JSON.parse(row['tags']);
30
+ if (row['assign_mode'] != null)
31
+ task.assignMode = row['assign_mode'];
32
+ if (row['cost'] != null)
33
+ task.cost = row['cost'];
34
+ if (row['assigned_worker'] != null)
35
+ task.assignedWorker = row['assigned_worker'];
36
+ if (row['disconnect_policy'] != null)
37
+ task.disconnectPolicy = row['disconnect_policy'];
38
+ return task;
39
+ }
40
+ export function rowToWorker(row) {
41
+ const worker = {
42
+ id: row['id'],
43
+ status: row['status'],
44
+ matchRule: JSON.parse(row['match_rule']),
45
+ capacity: row['capacity'],
46
+ usedSlots: row['used_slots'],
47
+ weight: row['weight'],
48
+ connectionMode: row['connection_mode'],
49
+ connectedAt: row['connected_at'],
50
+ lastHeartbeatAt: row['last_heartbeat_at'],
51
+ };
52
+ if (row['metadata'] != null)
53
+ worker.metadata = JSON.parse(row['metadata']);
54
+ return worker;
55
+ }
56
+ export function rowToWorkerAssignment(row) {
57
+ return {
58
+ taskId: row['task_id'],
59
+ workerId: row['worker_id'],
60
+ cost: row['cost'],
61
+ assignedAt: row['assigned_at'],
62
+ status: row['status'],
63
+ };
64
+ }
65
+ export function rowToWorkerEvent(row) {
66
+ const event = {
67
+ id: row['id'],
68
+ workerId: row['worker_id'],
69
+ timestamp: row['timestamp'],
70
+ action: row['action'],
71
+ };
72
+ if (row['data'] != null)
73
+ event.data = JSON.parse(row['data']);
74
+ return event;
75
+ }
76
+ export function rowToEvent(row) {
77
+ const event = {
78
+ id: row['id'],
79
+ taskId: row['task_id'],
80
+ index: row['idx'],
81
+ timestamp: row['timestamp'],
82
+ type: row['type'],
83
+ level: row['level'],
84
+ data: row['data'] != null ? JSON.parse(row['data']) : null,
85
+ };
86
+ if (row['series_id'] != null)
87
+ event.seriesId = row['series_id'];
88
+ if (row['series_mode'] != null)
89
+ event.seriesMode = row['series_mode'];
90
+ return event;
91
+ }
92
+ //# sourceMappingURL=row-mappers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-mappers.js","sourceRoot":"","sources":["../src/row-mappers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Task, TaskEvent, ShortTermStore, EventQueryOptions, TaskFilter, Worker, WorkerFilter, WorkerAssignment } from '@taskcast/core';
3
+ export declare class SqliteShortTermStore implements ShortTermStore {
4
+ private db;
5
+ constructor(db: Database.Database);
6
+ saveTask(task: Task): Promise<void>;
7
+ getTask(taskId: string): Promise<Task | null>;
8
+ nextIndex(taskId: string): Promise<number>;
9
+ appendEvent(taskId: string, event: TaskEvent): Promise<void>;
10
+ getEvents(taskId: string, opts?: EventQueryOptions): Promise<TaskEvent[]>;
11
+ setTTL(_taskId: string, _ttlSeconds: number): Promise<void>;
12
+ getSeriesLatest(taskId: string, seriesId: string): Promise<TaskEvent | null>;
13
+ setSeriesLatest(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
14
+ replaceLastSeriesEvent(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
15
+ listTasks(filter: TaskFilter): Promise<Task[]>;
16
+ saveWorker(worker: Worker): Promise<void>;
17
+ getWorker(workerId: string): Promise<Worker | null>;
18
+ listWorkers(filter?: WorkerFilter): Promise<Worker[]>;
19
+ deleteWorker(workerId: string): Promise<void>;
20
+ claimTask(taskId: string, workerId: string, cost: number): Promise<boolean>;
21
+ addAssignment(assignment: WorkerAssignment): Promise<void>;
22
+ removeAssignment(taskId: string): Promise<void>;
23
+ getWorkerAssignments(workerId: string): Promise<WorkerAssignment[]>;
24
+ getTaskAssignment(taskId: string): Promise<WorkerAssignment | null>;
25
+ }
26
+ //# sourceMappingURL=short-term.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"short-term.d.ts","sourceRoot":"","sources":["../src/short-term.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EACV,IAAI,EACJ,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,YAAY,EACZ,gBAAgB,EACjB,MAAM,gBAAgB,CAAA;AAKvB,qBAAa,oBAAqB,YAAW,cAAc;IAC7C,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEnC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CnC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAQ7C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1C,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5D,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAqDzE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAQ5E,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF,sBAAsB,CAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,IAAI,CAAC;IA+BV,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IA6C9C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BzC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQnD,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBrD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyC3E,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB1D,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAQnE,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAO1E"}
@@ -0,0 +1,335 @@
1
+ import { rowToTask, rowToEvent, rowToWorker, rowToWorkerAssignment } from './row-mappers.js';
2
+ // ─── SqliteShortTermStore ─────────────────────────────────────────────────
3
+ export class SqliteShortTermStore {
4
+ db;
5
+ constructor(db) {
6
+ this.db = db;
7
+ }
8
+ async saveTask(task) {
9
+ const stmt = this.db.prepare(`
10
+ INSERT INTO taskcast_tasks (id, type, status, params, result, error, metadata, auth_config, webhooks, cleanup, created_at, updated_at, completed_at, ttl, tags, assign_mode, cost, assigned_worker, disconnect_policy)
11
+ VALUES (@id, @type, @status, @params, @result, @error, @metadata, @auth_config, @webhooks, @cleanup, @created_at, @updated_at, @completed_at, @ttl, @tags, @assign_mode, @cost, @assigned_worker, @disconnect_policy)
12
+ ON CONFLICT (id) DO UPDATE SET
13
+ type = excluded.type,
14
+ status = excluded.status,
15
+ params = excluded.params,
16
+ result = excluded.result,
17
+ error = excluded.error,
18
+ metadata = excluded.metadata,
19
+ auth_config = excluded.auth_config,
20
+ webhooks = excluded.webhooks,
21
+ cleanup = excluded.cleanup,
22
+ updated_at = excluded.updated_at,
23
+ completed_at = excluded.completed_at,
24
+ ttl = excluded.ttl,
25
+ tags = excluded.tags,
26
+ assign_mode = excluded.assign_mode,
27
+ cost = excluded.cost,
28
+ assigned_worker = excluded.assigned_worker,
29
+ disconnect_policy = excluded.disconnect_policy
30
+ `);
31
+ stmt.run({
32
+ id: task.id,
33
+ type: task.type ?? null,
34
+ status: task.status,
35
+ params: task.params ? JSON.stringify(task.params) : null,
36
+ result: task.result ? JSON.stringify(task.result) : null,
37
+ error: task.error ? JSON.stringify(task.error) : null,
38
+ metadata: task.metadata ? JSON.stringify(task.metadata) : null,
39
+ auth_config: task.authConfig ? JSON.stringify(task.authConfig) : null,
40
+ webhooks: task.webhooks ? JSON.stringify(task.webhooks) : null,
41
+ cleanup: task.cleanup ? JSON.stringify(task.cleanup) : null,
42
+ created_at: task.createdAt,
43
+ updated_at: task.updatedAt,
44
+ completed_at: task.completedAt ?? null,
45
+ ttl: task.ttl ?? null,
46
+ tags: task.tags ? JSON.stringify(task.tags) : null,
47
+ assign_mode: task.assignMode ?? null,
48
+ cost: task.cost ?? null,
49
+ assigned_worker: task.assignedWorker ?? null,
50
+ disconnect_policy: task.disconnectPolicy ?? null,
51
+ });
52
+ }
53
+ async getTask(taskId) {
54
+ const row = this.db.prepare('SELECT * FROM taskcast_tasks WHERE id = ?').get(taskId);
55
+ return row ? rowToTask(row) : null;
56
+ }
57
+ async nextIndex(taskId) {
58
+ const row = this.db
59
+ .prepare(`INSERT INTO taskcast_index_counters (task_id, counter)
60
+ VALUES (?, 0)
61
+ ON CONFLICT (task_id) DO UPDATE SET counter = counter + 1
62
+ RETURNING counter`)
63
+ .get(taskId);
64
+ return row.counter;
65
+ }
66
+ async appendEvent(taskId, event) {
67
+ this.db
68
+ .prepare(`INSERT INTO taskcast_events (id, task_id, idx, timestamp, type, level, data, series_id, series_mode)
69
+ VALUES (@id, @task_id, @idx, @timestamp, @type, @level, @data, @series_id, @series_mode)`)
70
+ .run({
71
+ id: event.id,
72
+ task_id: event.taskId,
73
+ idx: event.index,
74
+ timestamp: event.timestamp,
75
+ type: event.type,
76
+ level: event.level,
77
+ data: event.data != null ? JSON.stringify(event.data) : null,
78
+ series_id: event.seriesId ?? null,
79
+ series_mode: event.seriesMode ?? null,
80
+ });
81
+ }
82
+ async getEvents(taskId, opts) {
83
+ const since = opts?.since;
84
+ const limit = opts?.limit;
85
+ let sql;
86
+ const params = [taskId];
87
+ if (since?.id) {
88
+ // Find the idx of the since event, then return everything after it.
89
+ // If the id is not found, the subquery returns NULL and the WHERE
90
+ // condition `idx > NULL` is never true — we need to fall back to
91
+ // returning all events.
92
+ sql = `
93
+ SELECT * FROM taskcast_events
94
+ WHERE task_id = ?
95
+ AND idx > COALESCE(
96
+ (SELECT idx FROM taskcast_events WHERE task_id = ? AND id = ?),
97
+ -1
98
+ )
99
+ ORDER BY idx ASC
100
+ `;
101
+ params.push(taskId, since.id);
102
+ }
103
+ else if (since?.index !== undefined) {
104
+ sql = `
105
+ SELECT * FROM taskcast_events
106
+ WHERE task_id = ? AND idx > ?
107
+ ORDER BY idx ASC
108
+ `;
109
+ params.push(since.index);
110
+ }
111
+ else if (since?.timestamp !== undefined) {
112
+ sql = `
113
+ SELECT * FROM taskcast_events
114
+ WHERE task_id = ? AND timestamp > ?
115
+ ORDER BY idx ASC
116
+ `;
117
+ params.push(since.timestamp);
118
+ }
119
+ else {
120
+ sql = `
121
+ SELECT * FROM taskcast_events
122
+ WHERE task_id = ?
123
+ ORDER BY idx ASC
124
+ `;
125
+ }
126
+ if (limit) {
127
+ sql += ' LIMIT ?';
128
+ params.push(limit);
129
+ }
130
+ const rows = this.db.prepare(sql).all(...params);
131
+ return rows.map(rowToEvent);
132
+ }
133
+ async setTTL(_taskId, _ttlSeconds) {
134
+ // No-op: SQLite does not support key-level TTL.
135
+ }
136
+ async getSeriesLatest(taskId, seriesId) {
137
+ const row = this.db
138
+ .prepare('SELECT event_json FROM taskcast_series_latest WHERE task_id = ? AND series_id = ?')
139
+ .get(taskId, seriesId);
140
+ return row ? JSON.parse(row.event_json) : null;
141
+ }
142
+ async setSeriesLatest(taskId, seriesId, event) {
143
+ this.db
144
+ .prepare(`INSERT INTO taskcast_series_latest (task_id, series_id, event_json)
145
+ VALUES (?, ?, ?)
146
+ ON CONFLICT (task_id, series_id) DO UPDATE SET event_json = excluded.event_json`)
147
+ .run(taskId, seriesId, JSON.stringify(event));
148
+ }
149
+ async replaceLastSeriesEvent(taskId, seriesId, event) {
150
+ const prev = await this.getSeriesLatest(taskId, seriesId);
151
+ if (prev) {
152
+ // Replace content fields only, preserving the original id and idx so
153
+ // the event stays at its original position in idx-based ordering.
154
+ // This mirrors Redis lset behaviour where the list position is preserved.
155
+ this.db
156
+ .prepare(`UPDATE taskcast_events
157
+ SET data = @data, type = @type, level = @level,
158
+ series_id = @series_id, series_mode = @series_mode
159
+ WHERE id = @prev_id`)
160
+ .run({
161
+ prev_id: prev.id,
162
+ type: event.type,
163
+ level: event.level,
164
+ data: event.data != null ? JSON.stringify(event.data) : null,
165
+ series_id: event.seriesId ?? null,
166
+ series_mode: event.seriesMode ?? null,
167
+ });
168
+ }
169
+ else {
170
+ await this.appendEvent(taskId, event);
171
+ }
172
+ await this.setSeriesLatest(taskId, seriesId, event);
173
+ }
174
+ // ─── Task query ──────────────────────────────────────────────────────────
175
+ async listTasks(filter) {
176
+ let sql = 'SELECT * FROM taskcast_tasks WHERE 1=1';
177
+ const params = [];
178
+ if (filter.status?.length) {
179
+ sql += ` AND status IN (${filter.status.map(() => '?').join(', ')})`;
180
+ params.push(...filter.status);
181
+ }
182
+ if (filter.types?.length) {
183
+ sql += ` AND type IN (${filter.types.map(() => '?').join(', ')})`;
184
+ params.push(...filter.types);
185
+ }
186
+ if (filter.assignMode?.length) {
187
+ sql += ` AND assign_mode IN (${filter.assignMode.map(() => '?').join(', ')})`;
188
+ params.push(...filter.assignMode);
189
+ }
190
+ if (filter.excludeTaskIds?.length) {
191
+ sql += ` AND id NOT IN (${filter.excludeTaskIds.map(() => '?').join(', ')})`;
192
+ params.push(...filter.excludeTaskIds);
193
+ }
194
+ if (filter.limit !== undefined) {
195
+ sql += ' LIMIT ?';
196
+ params.push(filter.limit);
197
+ }
198
+ const rows = this.db.prepare(sql).all(...params);
199
+ let tasks = rows.map(rowToTask);
200
+ // Tag filtering is done in-memory because tags are stored as JSON text
201
+ if (filter.tags) {
202
+ const { all, any, none } = filter.tags;
203
+ tasks = tasks.filter((t) => {
204
+ const taskTags = t.tags ?? [];
205
+ if (all && !all.every((tag) => taskTags.includes(tag)))
206
+ return false;
207
+ if (any && !any.some((tag) => taskTags.includes(tag)))
208
+ return false;
209
+ if (none && none.some((tag) => taskTags.includes(tag)))
210
+ return false;
211
+ return true;
212
+ });
213
+ }
214
+ return tasks;
215
+ }
216
+ // ─── Worker state ────────────────────────────────────────────────────────
217
+ async saveWorker(worker) {
218
+ this.db
219
+ .prepare(`INSERT INTO taskcast_workers (id, status, match_rule, capacity, used_slots, weight, connection_mode, connected_at, last_heartbeat_at, metadata)
220
+ VALUES (@id, @status, @match_rule, @capacity, @used_slots, @weight, @connection_mode, @connected_at, @last_heartbeat_at, @metadata)
221
+ ON CONFLICT (id) DO UPDATE SET
222
+ status = excluded.status,
223
+ match_rule = excluded.match_rule,
224
+ capacity = excluded.capacity,
225
+ used_slots = excluded.used_slots,
226
+ weight = excluded.weight,
227
+ connection_mode = excluded.connection_mode,
228
+ connected_at = excluded.connected_at,
229
+ last_heartbeat_at = excluded.last_heartbeat_at,
230
+ metadata = excluded.metadata`)
231
+ .run({
232
+ id: worker.id,
233
+ status: worker.status,
234
+ match_rule: JSON.stringify(worker.matchRule),
235
+ capacity: worker.capacity,
236
+ used_slots: worker.usedSlots,
237
+ weight: worker.weight,
238
+ connection_mode: worker.connectionMode,
239
+ connected_at: worker.connectedAt,
240
+ last_heartbeat_at: worker.lastHeartbeatAt,
241
+ metadata: worker.metadata ? JSON.stringify(worker.metadata) : null,
242
+ });
243
+ }
244
+ async getWorker(workerId) {
245
+ const row = this.db
246
+ .prepare('SELECT * FROM taskcast_workers WHERE id = ?')
247
+ .get(workerId);
248
+ return row ? rowToWorker(row) : null;
249
+ }
250
+ async listWorkers(filter) {
251
+ let sql = 'SELECT * FROM taskcast_workers WHERE 1=1';
252
+ const params = [];
253
+ if (filter?.status?.length) {
254
+ sql += ` AND status IN (${filter.status.map(() => '?').join(', ')})`;
255
+ params.push(...filter.status);
256
+ }
257
+ if (filter?.connectionMode?.length) {
258
+ sql += ` AND connection_mode IN (${filter.connectionMode.map(() => '?').join(', ')})`;
259
+ params.push(...filter.connectionMode);
260
+ }
261
+ const rows = this.db.prepare(sql).all(...params);
262
+ return rows.map(rowToWorker);
263
+ }
264
+ async deleteWorker(workerId) {
265
+ this.db.prepare('DELETE FROM taskcast_workers WHERE id = ?').run(workerId);
266
+ }
267
+ // ─── Atomic claim ────────────────────────────────────────────────────────
268
+ async claimTask(taskId, workerId, cost) {
269
+ // SQLite is single-writer, so a transaction provides atomicity.
270
+ const claim = this.db.transaction(() => {
271
+ const workerRow = this.db
272
+ .prepare('SELECT * FROM taskcast_workers WHERE id = ?')
273
+ .get(workerId);
274
+ if (!workerRow)
275
+ return false;
276
+ const worker = rowToWorker(workerRow);
277
+ if (worker.usedSlots + cost > worker.capacity)
278
+ return false;
279
+ const taskRow = this.db
280
+ .prepare('SELECT * FROM taskcast_tasks WHERE id = ?')
281
+ .get(taskId);
282
+ if (!taskRow)
283
+ return false;
284
+ const task = rowToTask(taskRow);
285
+ if (task.status !== 'pending' && task.status !== 'assigned')
286
+ return false;
287
+ // Update task
288
+ this.db
289
+ .prepare(`UPDATE taskcast_tasks
290
+ SET status = 'assigned', assigned_worker = ?, cost = ?, updated_at = ?
291
+ WHERE id = ?`)
292
+ .run(workerId, cost, Date.now(), taskId);
293
+ // Update worker used slots
294
+ this.db
295
+ .prepare('UPDATE taskcast_workers SET used_slots = ? WHERE id = ?')
296
+ .run(worker.usedSlots + cost, workerId);
297
+ return true;
298
+ });
299
+ return claim();
300
+ }
301
+ // ─── Worker assignments ──────────────────────────────────────────────────
302
+ async addAssignment(assignment) {
303
+ this.db
304
+ .prepare(`INSERT INTO taskcast_worker_assignments (task_id, worker_id, cost, assigned_at, status)
305
+ VALUES (@task_id, @worker_id, @cost, @assigned_at, @status)
306
+ ON CONFLICT (task_id) DO UPDATE SET
307
+ worker_id = excluded.worker_id,
308
+ cost = excluded.cost,
309
+ assigned_at = excluded.assigned_at,
310
+ status = excluded.status`)
311
+ .run({
312
+ task_id: assignment.taskId,
313
+ worker_id: assignment.workerId,
314
+ cost: assignment.cost,
315
+ assigned_at: assignment.assignedAt,
316
+ status: assignment.status,
317
+ });
318
+ }
319
+ async removeAssignment(taskId) {
320
+ this.db.prepare('DELETE FROM taskcast_worker_assignments WHERE task_id = ?').run(taskId);
321
+ }
322
+ async getWorkerAssignments(workerId) {
323
+ const rows = this.db
324
+ .prepare('SELECT * FROM taskcast_worker_assignments WHERE worker_id = ?')
325
+ .all(workerId);
326
+ return rows.map(rowToWorkerAssignment);
327
+ }
328
+ async getTaskAssignment(taskId) {
329
+ const row = this.db
330
+ .prepare('SELECT * FROM taskcast_worker_assignments WHERE task_id = ?')
331
+ .get(taskId);
332
+ return row ? rowToWorkerAssignment(row) : null;
333
+ }
334
+ }
335
+ //# sourceMappingURL=short-term.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"short-term.js","sourceRoot":"","sources":["../src/short-term.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ CREATE TABLE IF NOT EXISTS taskcast_tasks (
2
+ id TEXT PRIMARY KEY,
3
+ type TEXT,
4
+ status TEXT NOT NULL,
5
+ params TEXT,
6
+ result TEXT,
7
+ error TEXT,
8
+ metadata TEXT,
9
+ auth_config TEXT,
10
+ webhooks TEXT,
11
+ cleanup TEXT,
12
+ created_at INTEGER NOT NULL,
13
+ updated_at INTEGER NOT NULL,
14
+ completed_at INTEGER,
15
+ ttl INTEGER,
16
+ tags TEXT,
17
+ assign_mode TEXT,
18
+ cost INTEGER,
19
+ assigned_worker TEXT,
20
+ disconnect_policy TEXT
21
+ );
22
+
23
+ CREATE TABLE IF NOT EXISTS taskcast_events (
24
+ id TEXT PRIMARY KEY,
25
+ task_id TEXT NOT NULL REFERENCES taskcast_tasks(id) ON DELETE CASCADE,
26
+ idx INTEGER NOT NULL,
27
+ timestamp INTEGER NOT NULL,
28
+ type TEXT NOT NULL,
29
+ level TEXT NOT NULL,
30
+ data TEXT,
31
+ series_id TEXT,
32
+ series_mode TEXT,
33
+ UNIQUE(task_id, idx)
34
+ );
35
+
36
+ CREATE TABLE IF NOT EXISTS taskcast_series_latest (
37
+ task_id TEXT NOT NULL,
38
+ series_id TEXT NOT NULL,
39
+ event_json TEXT NOT NULL,
40
+ PRIMARY KEY (task_id, series_id)
41
+ );
42
+
43
+ CREATE TABLE IF NOT EXISTS taskcast_index_counters (
44
+ task_id TEXT PRIMARY KEY,
45
+ counter INTEGER NOT NULL DEFAULT -1
46
+ );
47
+
48
+ CREATE INDEX IF NOT EXISTS idx_events_task_idx ON taskcast_events(task_id, idx);
49
+ CREATE INDEX IF NOT EXISTS idx_events_task_ts ON taskcast_events(task_id, timestamp);
50
+
51
+ -- Worker assignment columns on tasks
52
+ -- SQLite does not support ADD COLUMN IF NOT EXISTS, so we use CREATE TABLE IF NOT EXISTS
53
+ -- and these columns are added to the initial schema for new databases.
54
+ -- For existing databases, a separate migration would be needed.
55
+
56
+ -- Workers table
57
+ CREATE TABLE IF NOT EXISTS taskcast_workers (
58
+ id TEXT PRIMARY KEY,
59
+ status TEXT NOT NULL,
60
+ match_rule TEXT NOT NULL,
61
+ capacity INTEGER NOT NULL,
62
+ used_slots INTEGER NOT NULL,
63
+ weight INTEGER NOT NULL,
64
+ connection_mode TEXT NOT NULL,
65
+ connected_at INTEGER NOT NULL,
66
+ last_heartbeat_at INTEGER NOT NULL,
67
+ metadata TEXT
68
+ );
69
+
70
+ -- Worker assignments table
71
+ CREATE TABLE IF NOT EXISTS taskcast_worker_assignments (
72
+ task_id TEXT PRIMARY KEY,
73
+ worker_id TEXT NOT NULL,
74
+ cost INTEGER NOT NULL,
75
+ assigned_at INTEGER NOT NULL,
76
+ status TEXT NOT NULL
77
+ );
78
+
79
+ CREATE INDEX IF NOT EXISTS idx_worker_assignments_worker_id ON taskcast_worker_assignments(worker_id);
80
+
81
+ -- Worker audit events table
82
+ CREATE TABLE IF NOT EXISTS taskcast_worker_events (
83
+ id TEXT PRIMARY KEY,
84
+ worker_id TEXT NOT NULL,
85
+ timestamp INTEGER NOT NULL,
86
+ action TEXT NOT NULL,
87
+ data TEXT
88
+ );
89
+
90
+ CREATE INDEX IF NOT EXISTS idx_worker_events_worker_id ON taskcast_worker_events(worker_id, timestamp);
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@taskcast/sqlite",
3
+ "version": "0.1.1",
4
+ "description": "SQLite local storage adapter for Taskcast.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/weightwave/taskcast.git",
8
+ "directory": "packages/sqlite"
9
+ },
10
+ "homepage": "https://github.com/weightwave/taskcast/tree/main/packages/sqlite#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/weightwave/taskcast/issues"
13
+ },
14
+ "license": "MIT",
15
+ "files": [
16
+ "dist",
17
+ "migrations",
18
+ "LICENSE",
19
+ "README.md"
20
+ ],
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "provenance": true
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "test": "vitest run",
35
+ "test:watch": "vitest"
36
+ },
37
+ "dependencies": {
38
+ "@taskcast/core": "workspace:*",
39
+ "better-sqlite3": "^11.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/better-sqlite3": "^7.6.0",
43
+ "typescript": "^5.7.0",
44
+ "vitest": "^2.1.0",
45
+ "@vitest/coverage-v8": "^2.1.0"
46
+ }
47
+ }