@secondlayer/shared 4.2.0 → 4.3.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,115 @@
1
+ import { type Kysely, sql } from "kysely";
2
+
3
+ async function tableExists(db: Kysely<unknown>, tableName: string) {
4
+ const { rows } = await sql<{ exists: boolean }>`
5
+ SELECT to_regclass(${`public.${tableName}`}) IS NOT NULL AS exists
6
+ `.execute(db);
7
+ return rows[0]?.exists === true;
8
+ }
9
+
10
+ export async function up(db: Kysely<unknown>): Promise<void> {
11
+ if (!(await tableExists(db, "subgraphs"))) {
12
+ console.log("Skipping subgraph_operations; subgraphs table is absent");
13
+ return;
14
+ }
15
+
16
+ await sql`
17
+ CREATE TABLE IF NOT EXISTS subgraph_operations (
18
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
19
+ subgraph_id uuid NOT NULL REFERENCES subgraphs(id) ON DELETE CASCADE,
20
+ subgraph_name text NOT NULL,
21
+ account_id text,
22
+ kind text NOT NULL CHECK (kind IN ('reindex', 'backfill')),
23
+ status text NOT NULL DEFAULT 'queued' CHECK (status IN ('queued', 'running', 'completed', 'failed', 'cancelled')),
24
+ from_block bigint,
25
+ to_block bigint,
26
+ cancel_requested boolean NOT NULL DEFAULT false,
27
+ locked_by text,
28
+ locked_until timestamptz,
29
+ started_at timestamptz,
30
+ finished_at timestamptz,
31
+ processed_blocks bigint,
32
+ error text,
33
+ created_at timestamptz NOT NULL DEFAULT now(),
34
+ updated_at timestamptz NOT NULL DEFAULT now()
35
+ )
36
+ `.execute(db);
37
+
38
+ await sql`
39
+ CREATE UNIQUE INDEX IF NOT EXISTS subgraph_operations_active_unique
40
+ ON subgraph_operations (subgraph_id)
41
+ WHERE status IN ('queued', 'running')
42
+ `.execute(db);
43
+
44
+ await sql`
45
+ CREATE INDEX IF NOT EXISTS subgraph_operations_claim_idx
46
+ ON subgraph_operations (created_at)
47
+ WHERE status = 'queued'
48
+ `.execute(db);
49
+
50
+ await sql`
51
+ CREATE INDEX IF NOT EXISTS subgraph_operations_stale_running_idx
52
+ ON subgraph_operations (locked_until)
53
+ WHERE status = 'running'
54
+ `.execute(db);
55
+
56
+ await sql`
57
+ CREATE OR REPLACE FUNCTION notify_subgraph_operation_new()
58
+ RETURNS trigger AS $$
59
+ BEGIN
60
+ PERFORM pg_notify('subgraph_operations:new', NEW.id::text);
61
+ RETURN NEW;
62
+ END;
63
+ $$ LANGUAGE plpgsql
64
+ `.execute(db);
65
+
66
+ await sql`
67
+ DROP TRIGGER IF EXISTS subgraph_operations_insert_notify ON subgraph_operations
68
+ `.execute(db);
69
+ await sql`
70
+ CREATE TRIGGER subgraph_operations_insert_notify
71
+ AFTER INSERT ON subgraph_operations
72
+ FOR EACH ROW
73
+ WHEN (NEW.status = 'queued')
74
+ EXECUTE FUNCTION notify_subgraph_operation_new()
75
+ `.execute(db);
76
+
77
+ await sql`
78
+ DROP TRIGGER IF EXISTS subgraph_operations_cancel_notify ON subgraph_operations
79
+ `.execute(db);
80
+ await sql`
81
+ CREATE TRIGGER subgraph_operations_cancel_notify
82
+ AFTER UPDATE OF cancel_requested ON subgraph_operations
83
+ FOR EACH ROW
84
+ WHEN (NEW.cancel_requested = true AND OLD.cancel_requested IS DISTINCT FROM NEW.cancel_requested)
85
+ EXECUTE FUNCTION notify_subgraph_operation_new()
86
+ `.execute(db);
87
+ }
88
+
89
+ export async function down(db: Kysely<unknown>): Promise<void> {
90
+ if (!(await tableExists(db, "subgraph_operations"))) {
91
+ return;
92
+ }
93
+
94
+ await sql`
95
+ DROP TRIGGER IF EXISTS subgraph_operations_cancel_notify ON subgraph_operations
96
+ `.execute(db);
97
+ await sql`
98
+ DROP TRIGGER IF EXISTS subgraph_operations_insert_notify ON subgraph_operations
99
+ `.execute(db);
100
+ await sql`
101
+ DROP FUNCTION IF EXISTS notify_subgraph_operation_new()
102
+ `.execute(db);
103
+ await sql`
104
+ DROP INDEX IF EXISTS subgraph_operations_stale_running_idx
105
+ `.execute(db);
106
+ await sql`
107
+ DROP INDEX IF EXISTS subgraph_operations_claim_idx
108
+ `.execute(db);
109
+ await sql`
110
+ DROP INDEX IF EXISTS subgraph_operations_active_unique
111
+ `.execute(db);
112
+ await sql`
113
+ DROP TABLE IF EXISTS subgraph_operations
114
+ `.execute(db);
115
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "4.2.0",
3
+ "version": "4.3.1",
4
4
  "type": "module",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
@@ -33,6 +33,10 @@
33
33
  "types": "./dist/src/db/queries/subgraph-gaps.d.ts",
34
34
  "import": "./dist/src/db/queries/subgraph-gaps.js"
35
35
  },
36
+ "./db/queries/subgraph-operations": {
37
+ "types": "./dist/src/db/queries/subgraph-operations.d.ts",
38
+ "import": "./dist/src/db/queries/subgraph-operations.js"
39
+ },
36
40
  "./db/jsonb": {
37
41
  "types": "./dist/src/db/jsonb.d.ts",
38
42
  "import": "./dist/src/db/jsonb.js"