@dudousxd/nestjs-durable-store-drizzle 0.17.0 → 0.18.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/dist/index.cjs +180 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +398 -3
- package/dist/index.d.ts +398 -3
- package/dist/index.js +181 -4
- package/dist/index.js.map +1 -1
- package/dist/pg/index.cjs +158 -5
- package/dist/pg/index.cjs.map +1 -1
- package/dist/pg/index.d.cts +378 -3
- package/dist/pg/index.d.ts +378 -3
- package/dist/pg/index.js +159 -7
- package/dist/pg/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StateStore, WorkflowRun, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, SignalWaiter } from '@dudousxd/nestjs-durable-core';
|
|
1
|
+
import { StateStore, WorkflowRun, RetentionPolicy, StepCheckpoint, RunQuery, RunFacetQuery, RunFacetRow, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleRecord, ScheduleQuery, SignalWaiter } from '@dudousxd/nestjs-durable-core';
|
|
2
2
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
3
3
|
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
4
4
|
|
|
@@ -11,13 +11,16 @@ type DrizzleSqlite = BaseSQLiteDatabase<'sync' | 'async', unknown>;
|
|
|
11
11
|
declare class DrizzleStateStore implements StateStore {
|
|
12
12
|
private readonly db;
|
|
13
13
|
constructor(db: DrizzleSqlite);
|
|
14
|
+
tryAdmitSingleton(runId: string, tag: string, workflow: string, limit: number, retryWakeAt?: number): Promise<boolean>;
|
|
14
15
|
createRun(run: WorkflowRun): Promise<void>;
|
|
15
|
-
updateRun(runId: string,
|
|
16
|
+
updateRun(runId: string, inputPatch: Partial<WorkflowRun>): Promise<void>;
|
|
16
17
|
/** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
|
|
17
18
|
* the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
|
|
18
19
|
private reindexAttributes;
|
|
19
20
|
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
20
21
|
deleteRun(runId: string): Promise<void>;
|
|
22
|
+
deleteRuns(runIds: string[]): Promise<void>;
|
|
23
|
+
pruneTerminalRuns(policy: RetentionPolicy, nowMs: number, limit: number): Promise<number>;
|
|
21
24
|
getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
|
|
22
25
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
23
26
|
transaction<T>(work: (tx: {
|
|
@@ -39,6 +42,7 @@ declare class DrizzleStateStore implements StateStore {
|
|
|
39
42
|
* them, so a facet count and the page it labels are always taken over the same set. */
|
|
40
43
|
private runFilters;
|
|
41
44
|
listRuns(query: RunQuery): Promise<WorkflowRun[]>;
|
|
45
|
+
countRuns(query: Omit<RunQuery, 'limit' | 'offset'>): Promise<number>;
|
|
42
46
|
/** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a
|
|
43
47
|
* console can show whole-set counts next to a bounded page instead of downloading every run to
|
|
44
48
|
* count them in the browser. */
|
|
@@ -53,6 +57,11 @@ declare class DrizzleStateStore implements StateStore {
|
|
|
53
57
|
* contract): EXISTS already requires the key row to be present, so EXISTS(... <> ...) is exactly
|
|
54
58
|
* ne-with-present. Numeric operands compare `num_value`, everything else `str_value`. */
|
|
55
59
|
private attributeExists;
|
|
60
|
+
saveSchedule(record: ScheduleRecord): Promise<void>;
|
|
61
|
+
getSchedule(id: string): Promise<ScheduleRecord | null>;
|
|
62
|
+
updateSchedule(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
|
|
63
|
+
deleteSchedule(id: string): Promise<boolean>;
|
|
64
|
+
listSchedules(query: ScheduleQuery): Promise<ScheduleRecord[]>;
|
|
56
65
|
listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
|
|
57
66
|
getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
|
|
58
67
|
listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
|
|
@@ -1042,6 +1051,203 @@ declare const bufferedEvents: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
1042
1051
|
};
|
|
1043
1052
|
dialect: "sqlite";
|
|
1044
1053
|
}>;
|
|
1054
|
+
/**
|
|
1055
|
+
* Persisted schedules (`engine.schedules`). `spec`/`state` are JSON documents the engine owns; the
|
|
1056
|
+
* store only filters on the columns. `next_fire_at` is epoch ms, NULL when it never fires again.
|
|
1057
|
+
*
|
|
1058
|
+
* MIGRATION (you own this adapter's migrations): `drizzle-kit generate` picks the table up from
|
|
1059
|
+
* `durableSchema`; by hand it is the `durable_schedules` CREATE TABLE + index in the package docs.
|
|
1060
|
+
* Only needed if you use persisted schedules.
|
|
1061
|
+
*/
|
|
1062
|
+
declare const durableSchedules: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
1063
|
+
name: "durable_schedules";
|
|
1064
|
+
schema: undefined;
|
|
1065
|
+
columns: {
|
|
1066
|
+
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1067
|
+
name: "id";
|
|
1068
|
+
tableName: "durable_schedules";
|
|
1069
|
+
dataType: "string";
|
|
1070
|
+
columnType: "SQLiteText";
|
|
1071
|
+
data: string;
|
|
1072
|
+
driverParam: string;
|
|
1073
|
+
notNull: true;
|
|
1074
|
+
hasDefault: false;
|
|
1075
|
+
isPrimaryKey: true;
|
|
1076
|
+
isAutoincrement: false;
|
|
1077
|
+
hasRuntimeDefault: false;
|
|
1078
|
+
enumValues: [string, ...string[]];
|
|
1079
|
+
baseColumn: never;
|
|
1080
|
+
identity: undefined;
|
|
1081
|
+
generated: undefined;
|
|
1082
|
+
}, {}, {
|
|
1083
|
+
length: number | undefined;
|
|
1084
|
+
}>;
|
|
1085
|
+
namespace: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1086
|
+
name: "namespace";
|
|
1087
|
+
tableName: "durable_schedules";
|
|
1088
|
+
dataType: "string";
|
|
1089
|
+
columnType: "SQLiteText";
|
|
1090
|
+
data: string;
|
|
1091
|
+
driverParam: string;
|
|
1092
|
+
notNull: true;
|
|
1093
|
+
hasDefault: true;
|
|
1094
|
+
isPrimaryKey: false;
|
|
1095
|
+
isAutoincrement: false;
|
|
1096
|
+
hasRuntimeDefault: false;
|
|
1097
|
+
enumValues: [string, ...string[]];
|
|
1098
|
+
baseColumn: never;
|
|
1099
|
+
identity: undefined;
|
|
1100
|
+
generated: undefined;
|
|
1101
|
+
}, {}, {
|
|
1102
|
+
length: number | undefined;
|
|
1103
|
+
}>;
|
|
1104
|
+
workflow: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1105
|
+
name: "workflow";
|
|
1106
|
+
tableName: "durable_schedules";
|
|
1107
|
+
dataType: "string";
|
|
1108
|
+
columnType: "SQLiteText";
|
|
1109
|
+
data: string;
|
|
1110
|
+
driverParam: string;
|
|
1111
|
+
notNull: true;
|
|
1112
|
+
hasDefault: false;
|
|
1113
|
+
isPrimaryKey: false;
|
|
1114
|
+
isAutoincrement: false;
|
|
1115
|
+
hasRuntimeDefault: false;
|
|
1116
|
+
enumValues: [string, ...string[]];
|
|
1117
|
+
baseColumn: never;
|
|
1118
|
+
identity: undefined;
|
|
1119
|
+
generated: undefined;
|
|
1120
|
+
}, {}, {
|
|
1121
|
+
length: number | undefined;
|
|
1122
|
+
}>;
|
|
1123
|
+
paused: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1124
|
+
name: "paused";
|
|
1125
|
+
tableName: "durable_schedules";
|
|
1126
|
+
dataType: "boolean";
|
|
1127
|
+
columnType: "SQLiteBoolean";
|
|
1128
|
+
data: boolean;
|
|
1129
|
+
driverParam: number;
|
|
1130
|
+
notNull: true;
|
|
1131
|
+
hasDefault: true;
|
|
1132
|
+
isPrimaryKey: false;
|
|
1133
|
+
isAutoincrement: false;
|
|
1134
|
+
hasRuntimeDefault: false;
|
|
1135
|
+
enumValues: undefined;
|
|
1136
|
+
baseColumn: never;
|
|
1137
|
+
identity: undefined;
|
|
1138
|
+
generated: undefined;
|
|
1139
|
+
}, {}, {}>;
|
|
1140
|
+
nextFireAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1141
|
+
name: "next_fire_at";
|
|
1142
|
+
tableName: "durable_schedules";
|
|
1143
|
+
dataType: "number";
|
|
1144
|
+
columnType: "SQLiteInteger";
|
|
1145
|
+
data: number;
|
|
1146
|
+
driverParam: number;
|
|
1147
|
+
notNull: false;
|
|
1148
|
+
hasDefault: false;
|
|
1149
|
+
isPrimaryKey: false;
|
|
1150
|
+
isAutoincrement: false;
|
|
1151
|
+
hasRuntimeDefault: false;
|
|
1152
|
+
enumValues: undefined;
|
|
1153
|
+
baseColumn: never;
|
|
1154
|
+
identity: undefined;
|
|
1155
|
+
generated: undefined;
|
|
1156
|
+
}, {}, {}>;
|
|
1157
|
+
tags: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1158
|
+
name: "tags";
|
|
1159
|
+
tableName: "durable_schedules";
|
|
1160
|
+
dataType: "json";
|
|
1161
|
+
columnType: "SQLiteTextJson";
|
|
1162
|
+
data: string[];
|
|
1163
|
+
driverParam: string;
|
|
1164
|
+
notNull: false;
|
|
1165
|
+
hasDefault: false;
|
|
1166
|
+
isPrimaryKey: false;
|
|
1167
|
+
isAutoincrement: false;
|
|
1168
|
+
hasRuntimeDefault: false;
|
|
1169
|
+
enumValues: undefined;
|
|
1170
|
+
baseColumn: never;
|
|
1171
|
+
identity: undefined;
|
|
1172
|
+
generated: undefined;
|
|
1173
|
+
}, {}, {
|
|
1174
|
+
$type: string[];
|
|
1175
|
+
}>;
|
|
1176
|
+
spec: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1177
|
+
name: "spec";
|
|
1178
|
+
tableName: "durable_schedules";
|
|
1179
|
+
dataType: "json";
|
|
1180
|
+
columnType: "SQLiteTextJson";
|
|
1181
|
+
data: Record<string, unknown>;
|
|
1182
|
+
driverParam: string;
|
|
1183
|
+
notNull: true;
|
|
1184
|
+
hasDefault: false;
|
|
1185
|
+
isPrimaryKey: false;
|
|
1186
|
+
isAutoincrement: false;
|
|
1187
|
+
hasRuntimeDefault: false;
|
|
1188
|
+
enumValues: undefined;
|
|
1189
|
+
baseColumn: never;
|
|
1190
|
+
identity: undefined;
|
|
1191
|
+
generated: undefined;
|
|
1192
|
+
}, {}, {
|
|
1193
|
+
$type: Record<string, unknown>;
|
|
1194
|
+
}>;
|
|
1195
|
+
state: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1196
|
+
name: "state";
|
|
1197
|
+
tableName: "durable_schedules";
|
|
1198
|
+
dataType: "json";
|
|
1199
|
+
columnType: "SQLiteTextJson";
|
|
1200
|
+
data: Record<string, unknown>;
|
|
1201
|
+
driverParam: string;
|
|
1202
|
+
notNull: true;
|
|
1203
|
+
hasDefault: false;
|
|
1204
|
+
isPrimaryKey: false;
|
|
1205
|
+
isAutoincrement: false;
|
|
1206
|
+
hasRuntimeDefault: false;
|
|
1207
|
+
enumValues: undefined;
|
|
1208
|
+
baseColumn: never;
|
|
1209
|
+
identity: undefined;
|
|
1210
|
+
generated: undefined;
|
|
1211
|
+
}, {}, {
|
|
1212
|
+
$type: Record<string, unknown>;
|
|
1213
|
+
}>;
|
|
1214
|
+
createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1215
|
+
name: "created_at";
|
|
1216
|
+
tableName: "durable_schedules";
|
|
1217
|
+
dataType: "number";
|
|
1218
|
+
columnType: "SQLiteInteger";
|
|
1219
|
+
data: number;
|
|
1220
|
+
driverParam: number;
|
|
1221
|
+
notNull: true;
|
|
1222
|
+
hasDefault: false;
|
|
1223
|
+
isPrimaryKey: false;
|
|
1224
|
+
isAutoincrement: false;
|
|
1225
|
+
hasRuntimeDefault: false;
|
|
1226
|
+
enumValues: undefined;
|
|
1227
|
+
baseColumn: never;
|
|
1228
|
+
identity: undefined;
|
|
1229
|
+
generated: undefined;
|
|
1230
|
+
}, {}, {}>;
|
|
1231
|
+
updatedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1232
|
+
name: "updated_at";
|
|
1233
|
+
tableName: "durable_schedules";
|
|
1234
|
+
dataType: "number";
|
|
1235
|
+
columnType: "SQLiteInteger";
|
|
1236
|
+
data: number;
|
|
1237
|
+
driverParam: number;
|
|
1238
|
+
notNull: true;
|
|
1239
|
+
hasDefault: false;
|
|
1240
|
+
isPrimaryKey: false;
|
|
1241
|
+
isAutoincrement: false;
|
|
1242
|
+
hasRuntimeDefault: false;
|
|
1243
|
+
enumValues: undefined;
|
|
1244
|
+
baseColumn: never;
|
|
1245
|
+
identity: undefined;
|
|
1246
|
+
generated: undefined;
|
|
1247
|
+
}, {}, {}>;
|
|
1248
|
+
};
|
|
1249
|
+
dialect: "sqlite";
|
|
1250
|
+
}>;
|
|
1045
1251
|
declare const durableSchema: {
|
|
1046
1252
|
workflowRuns: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
1047
1253
|
name: "durable_workflow_runs";
|
|
@@ -2004,6 +2210,195 @@ declare const durableSchema: {
|
|
|
2004
2210
|
};
|
|
2005
2211
|
dialect: "sqlite";
|
|
2006
2212
|
}>;
|
|
2213
|
+
durableSchedules: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
2214
|
+
name: "durable_schedules";
|
|
2215
|
+
schema: undefined;
|
|
2216
|
+
columns: {
|
|
2217
|
+
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2218
|
+
name: "id";
|
|
2219
|
+
tableName: "durable_schedules";
|
|
2220
|
+
dataType: "string";
|
|
2221
|
+
columnType: "SQLiteText";
|
|
2222
|
+
data: string;
|
|
2223
|
+
driverParam: string;
|
|
2224
|
+
notNull: true;
|
|
2225
|
+
hasDefault: false;
|
|
2226
|
+
isPrimaryKey: true;
|
|
2227
|
+
isAutoincrement: false;
|
|
2228
|
+
hasRuntimeDefault: false;
|
|
2229
|
+
enumValues: [string, ...string[]];
|
|
2230
|
+
baseColumn: never;
|
|
2231
|
+
identity: undefined;
|
|
2232
|
+
generated: undefined;
|
|
2233
|
+
}, {}, {
|
|
2234
|
+
length: number | undefined;
|
|
2235
|
+
}>;
|
|
2236
|
+
namespace: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2237
|
+
name: "namespace";
|
|
2238
|
+
tableName: "durable_schedules";
|
|
2239
|
+
dataType: "string";
|
|
2240
|
+
columnType: "SQLiteText";
|
|
2241
|
+
data: string;
|
|
2242
|
+
driverParam: string;
|
|
2243
|
+
notNull: true;
|
|
2244
|
+
hasDefault: true;
|
|
2245
|
+
isPrimaryKey: false;
|
|
2246
|
+
isAutoincrement: false;
|
|
2247
|
+
hasRuntimeDefault: false;
|
|
2248
|
+
enumValues: [string, ...string[]];
|
|
2249
|
+
baseColumn: never;
|
|
2250
|
+
identity: undefined;
|
|
2251
|
+
generated: undefined;
|
|
2252
|
+
}, {}, {
|
|
2253
|
+
length: number | undefined;
|
|
2254
|
+
}>;
|
|
2255
|
+
workflow: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2256
|
+
name: "workflow";
|
|
2257
|
+
tableName: "durable_schedules";
|
|
2258
|
+
dataType: "string";
|
|
2259
|
+
columnType: "SQLiteText";
|
|
2260
|
+
data: string;
|
|
2261
|
+
driverParam: string;
|
|
2262
|
+
notNull: true;
|
|
2263
|
+
hasDefault: false;
|
|
2264
|
+
isPrimaryKey: false;
|
|
2265
|
+
isAutoincrement: false;
|
|
2266
|
+
hasRuntimeDefault: false;
|
|
2267
|
+
enumValues: [string, ...string[]];
|
|
2268
|
+
baseColumn: never;
|
|
2269
|
+
identity: undefined;
|
|
2270
|
+
generated: undefined;
|
|
2271
|
+
}, {}, {
|
|
2272
|
+
length: number | undefined;
|
|
2273
|
+
}>;
|
|
2274
|
+
paused: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2275
|
+
name: "paused";
|
|
2276
|
+
tableName: "durable_schedules";
|
|
2277
|
+
dataType: "boolean";
|
|
2278
|
+
columnType: "SQLiteBoolean";
|
|
2279
|
+
data: boolean;
|
|
2280
|
+
driverParam: number;
|
|
2281
|
+
notNull: true;
|
|
2282
|
+
hasDefault: true;
|
|
2283
|
+
isPrimaryKey: false;
|
|
2284
|
+
isAutoincrement: false;
|
|
2285
|
+
hasRuntimeDefault: false;
|
|
2286
|
+
enumValues: undefined;
|
|
2287
|
+
baseColumn: never;
|
|
2288
|
+
identity: undefined;
|
|
2289
|
+
generated: undefined;
|
|
2290
|
+
}, {}, {}>;
|
|
2291
|
+
nextFireAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2292
|
+
name: "next_fire_at";
|
|
2293
|
+
tableName: "durable_schedules";
|
|
2294
|
+
dataType: "number";
|
|
2295
|
+
columnType: "SQLiteInteger";
|
|
2296
|
+
data: number;
|
|
2297
|
+
driverParam: number;
|
|
2298
|
+
notNull: false;
|
|
2299
|
+
hasDefault: false;
|
|
2300
|
+
isPrimaryKey: false;
|
|
2301
|
+
isAutoincrement: false;
|
|
2302
|
+
hasRuntimeDefault: false;
|
|
2303
|
+
enumValues: undefined;
|
|
2304
|
+
baseColumn: never;
|
|
2305
|
+
identity: undefined;
|
|
2306
|
+
generated: undefined;
|
|
2307
|
+
}, {}, {}>;
|
|
2308
|
+
tags: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2309
|
+
name: "tags";
|
|
2310
|
+
tableName: "durable_schedules";
|
|
2311
|
+
dataType: "json";
|
|
2312
|
+
columnType: "SQLiteTextJson";
|
|
2313
|
+
data: string[];
|
|
2314
|
+
driverParam: string;
|
|
2315
|
+
notNull: false;
|
|
2316
|
+
hasDefault: false;
|
|
2317
|
+
isPrimaryKey: false;
|
|
2318
|
+
isAutoincrement: false;
|
|
2319
|
+
hasRuntimeDefault: false;
|
|
2320
|
+
enumValues: undefined;
|
|
2321
|
+
baseColumn: never;
|
|
2322
|
+
identity: undefined;
|
|
2323
|
+
generated: undefined;
|
|
2324
|
+
}, {}, {
|
|
2325
|
+
$type: string[];
|
|
2326
|
+
}>;
|
|
2327
|
+
spec: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2328
|
+
name: "spec";
|
|
2329
|
+
tableName: "durable_schedules";
|
|
2330
|
+
dataType: "json";
|
|
2331
|
+
columnType: "SQLiteTextJson";
|
|
2332
|
+
data: Record<string, unknown>;
|
|
2333
|
+
driverParam: string;
|
|
2334
|
+
notNull: true;
|
|
2335
|
+
hasDefault: false;
|
|
2336
|
+
isPrimaryKey: false;
|
|
2337
|
+
isAutoincrement: false;
|
|
2338
|
+
hasRuntimeDefault: false;
|
|
2339
|
+
enumValues: undefined;
|
|
2340
|
+
baseColumn: never;
|
|
2341
|
+
identity: undefined;
|
|
2342
|
+
generated: undefined;
|
|
2343
|
+
}, {}, {
|
|
2344
|
+
$type: Record<string, unknown>;
|
|
2345
|
+
}>;
|
|
2346
|
+
state: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2347
|
+
name: "state";
|
|
2348
|
+
tableName: "durable_schedules";
|
|
2349
|
+
dataType: "json";
|
|
2350
|
+
columnType: "SQLiteTextJson";
|
|
2351
|
+
data: Record<string, unknown>;
|
|
2352
|
+
driverParam: string;
|
|
2353
|
+
notNull: true;
|
|
2354
|
+
hasDefault: false;
|
|
2355
|
+
isPrimaryKey: false;
|
|
2356
|
+
isAutoincrement: false;
|
|
2357
|
+
hasRuntimeDefault: false;
|
|
2358
|
+
enumValues: undefined;
|
|
2359
|
+
baseColumn: never;
|
|
2360
|
+
identity: undefined;
|
|
2361
|
+
generated: undefined;
|
|
2362
|
+
}, {}, {
|
|
2363
|
+
$type: Record<string, unknown>;
|
|
2364
|
+
}>;
|
|
2365
|
+
createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2366
|
+
name: "created_at";
|
|
2367
|
+
tableName: "durable_schedules";
|
|
2368
|
+
dataType: "number";
|
|
2369
|
+
columnType: "SQLiteInteger";
|
|
2370
|
+
data: number;
|
|
2371
|
+
driverParam: number;
|
|
2372
|
+
notNull: true;
|
|
2373
|
+
hasDefault: false;
|
|
2374
|
+
isPrimaryKey: false;
|
|
2375
|
+
isAutoincrement: false;
|
|
2376
|
+
hasRuntimeDefault: false;
|
|
2377
|
+
enumValues: undefined;
|
|
2378
|
+
baseColumn: never;
|
|
2379
|
+
identity: undefined;
|
|
2380
|
+
generated: undefined;
|
|
2381
|
+
}, {}, {}>;
|
|
2382
|
+
updatedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2383
|
+
name: "updated_at";
|
|
2384
|
+
tableName: "durable_schedules";
|
|
2385
|
+
dataType: "number";
|
|
2386
|
+
columnType: "SQLiteInteger";
|
|
2387
|
+
data: number;
|
|
2388
|
+
driverParam: number;
|
|
2389
|
+
notNull: true;
|
|
2390
|
+
hasDefault: false;
|
|
2391
|
+
isPrimaryKey: false;
|
|
2392
|
+
isAutoincrement: false;
|
|
2393
|
+
hasRuntimeDefault: false;
|
|
2394
|
+
enumValues: undefined;
|
|
2395
|
+
baseColumn: never;
|
|
2396
|
+
identity: undefined;
|
|
2397
|
+
generated: undefined;
|
|
2398
|
+
}, {}, {}>;
|
|
2399
|
+
};
|
|
2400
|
+
dialect: "sqlite";
|
|
2401
|
+
}>;
|
|
2007
2402
|
};
|
|
2008
2403
|
/**
|
|
2009
2404
|
* Tables this store creates and manages (you run the migrations — see the package README — but
|
|
@@ -2021,4 +2416,4 @@ declare const durableSchema: {
|
|
|
2021
2416
|
*/
|
|
2022
2417
|
declare function durableManagedTables(): string[];
|
|
2023
2418
|
|
|
2024
|
-
export { DEFAULT_NAMESPACE, DrizzleStateStore, bufferedEvents, bufferedSignals, durableManagedTables, durableSchema, runAttributes, signalWaiters, stepCheckpoints, workflowRuns };
|
|
2419
|
+
export { DEFAULT_NAMESPACE, DrizzleStateStore, bufferedEvents, bufferedSignals, durableManagedTables, durableSchedules, durableSchema, runAttributes, signalWaiters, stepCheckpoints, workflowRuns };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/drizzle-state-store.ts
|
|
5
|
-
import { RUN_VALUE_FACET_SCAN, attributePredicateOperands, axisIsRunColumn, mergeRunFacetRows, mergeRunValueFacetRows, normalizeAttributeRows, runValueFacetsFromRuns } from "@dudousxd/nestjs-durable-core";
|
|
6
|
-
import { and, asc, desc, eq, exists, inArray, isNotNull, isNull, like, lte, or, sql } from "drizzle-orm";
|
|
5
|
+
import { RUN_VALUE_FACET_SCAN, SINGLETON_ACTIVE_STATUSES, TERMINAL_RUN_STATUSES, attributePredicateOperands, axisIsRunColumn, clearTerminalSingletonAdmission, mergeRunFacetRows, mergeRunValueFacetRows, normalizeAttributeRows, parseDuration, runValueFacetsFromRuns, singletonAdmissionDenialPatch, singletonAdmissionTags } from "@dudousxd/nestjs-durable-core";
|
|
6
|
+
import { and, asc, desc, eq, exists, inArray, isNotNull, isNull, like, lt, lte, or, sql } from "drizzle-orm";
|
|
7
7
|
|
|
8
8
|
// src/schema.ts
|
|
9
9
|
import { getTableName } from "drizzle-orm";
|
|
@@ -160,13 +160,41 @@ var bufferedEvents = sqliteTable("durable_buffered_events", {
|
|
|
160
160
|
}),
|
|
161
161
|
publishedAt: integer("published_at").notNull()
|
|
162
162
|
});
|
|
163
|
+
var durableSchedules = sqliteTable(
|
|
164
|
+
"durable_schedules",
|
|
165
|
+
{
|
|
166
|
+
id: text("id").primaryKey(),
|
|
167
|
+
namespace: text("namespace").notNull().default(DEFAULT_NAMESPACE),
|
|
168
|
+
workflow: text("workflow").notNull(),
|
|
169
|
+
paused: integer("paused", {
|
|
170
|
+
mode: "boolean"
|
|
171
|
+
}).notNull().default(false),
|
|
172
|
+
nextFireAt: integer("next_fire_at"),
|
|
173
|
+
tags: text("tags", {
|
|
174
|
+
mode: "json"
|
|
175
|
+
}).$type(),
|
|
176
|
+
spec: text("spec", {
|
|
177
|
+
mode: "json"
|
|
178
|
+
}).$type().notNull(),
|
|
179
|
+
state: text("state", {
|
|
180
|
+
mode: "json"
|
|
181
|
+
}).$type().notNull(),
|
|
182
|
+
createdAt: integer("created_at").notNull(),
|
|
183
|
+
updatedAt: integer("updated_at").notNull()
|
|
184
|
+
},
|
|
185
|
+
// The poll's "due by T" scan: `paused = 0 AND next_fire_at <= T ORDER BY next_fire_at`.
|
|
186
|
+
(t) => [
|
|
187
|
+
index("durable_schedules_due_idx").on(t.paused, t.nextFireAt)
|
|
188
|
+
]
|
|
189
|
+
);
|
|
163
190
|
var durableSchema = {
|
|
164
191
|
workflowRuns,
|
|
165
192
|
stepCheckpoints,
|
|
166
193
|
runAttributes,
|
|
167
194
|
signalWaiters,
|
|
168
195
|
bufferedSignals,
|
|
169
|
-
bufferedEvents
|
|
196
|
+
bufferedEvents,
|
|
197
|
+
durableSchedules
|
|
170
198
|
};
|
|
171
199
|
function durableManagedTables() {
|
|
172
200
|
return Object.values(durableSchema).map((table) => getTableName(table));
|
|
@@ -193,11 +221,39 @@ var DrizzleStateStore = class {
|
|
|
193
221
|
constructor(db) {
|
|
194
222
|
this.db = db;
|
|
195
223
|
}
|
|
224
|
+
async tryAdmitSingleton(runId, tag, workflow, limit, retryWakeAt) {
|
|
225
|
+
return this.db.transaction((tx) => {
|
|
226
|
+
const where = and(eq(workflowRuns.workflow, workflow), inArray(workflowRuns.status, SINGLETON_ACTIVE_STATUSES));
|
|
227
|
+
const claim = /* @__PURE__ */ __name((rows) => {
|
|
228
|
+
const runs = rows.map(fromRunRow);
|
|
229
|
+
const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);
|
|
230
|
+
if (!tags) {
|
|
231
|
+
const patch = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);
|
|
232
|
+
if (!patch) return false;
|
|
233
|
+
const parked = tx.update(workflowRuns).set(toRunPatch(patch)).where(eq(workflowRuns.id, runId)).run();
|
|
234
|
+
return parked instanceof Promise ? parked.then(() => false) : false;
|
|
235
|
+
}
|
|
236
|
+
const written = tx.update(workflowRuns).set({
|
|
237
|
+
tags
|
|
238
|
+
}).where(eq(workflowRuns.id, runId)).run();
|
|
239
|
+
return written instanceof Promise ? written.then(() => true) : true;
|
|
240
|
+
}, "claim");
|
|
241
|
+
const read = /* @__PURE__ */ __name(() => {
|
|
242
|
+
const rows = tx.select().from(workflowRuns).where(where).all();
|
|
243
|
+
return rows instanceof Promise ? rows.then(claim) : claim(rows);
|
|
244
|
+
}, "read");
|
|
245
|
+
const locked = tx.update(workflowRuns).set({
|
|
246
|
+
workflow
|
|
247
|
+
}).where(where).run();
|
|
248
|
+
return locked instanceof Promise ? locked.then(read) : read();
|
|
249
|
+
});
|
|
250
|
+
}
|
|
196
251
|
async createRun(run) {
|
|
197
252
|
await this.db.insert(workflowRuns).values(toRunRow(run));
|
|
198
253
|
await this.reindexAttributes(run.id, run.searchAttributes);
|
|
199
254
|
}
|
|
200
|
-
async updateRun(runId,
|
|
255
|
+
async updateRun(runId, inputPatch) {
|
|
256
|
+
const patch = inputPatch.status && TERMINAL_RUN_STATUSES.includes(inputPatch.status) ? await clearTerminalSingletonAdmission(runId, inputPatch, (id) => this.getRun(id)) : inputPatch;
|
|
201
257
|
const row = toRunPatch(patch);
|
|
202
258
|
if (Object.keys(row).length) await this.db.update(workflowRuns).set(row).where(eq(workflowRuns.id, runId));
|
|
203
259
|
if ("searchAttributes" in patch) await this.reindexAttributes(runId, patch.searchAttributes);
|
|
@@ -219,6 +275,44 @@ var DrizzleStateStore = class {
|
|
|
219
275
|
await this.db.delete(runAttributes).where(eq(runAttributes.runId, runId));
|
|
220
276
|
await this.db.delete(workflowRuns).where(eq(workflowRuns.id, runId));
|
|
221
277
|
}
|
|
278
|
+
async deleteRuns(runIds) {
|
|
279
|
+
if (runIds.length === 0) return;
|
|
280
|
+
await this.db.delete(stepCheckpoints).where(inArray(stepCheckpoints.runId, runIds));
|
|
281
|
+
await this.db.delete(signalWaiters).where(inArray(signalWaiters.runId, runIds));
|
|
282
|
+
await this.db.delete(runAttributes).where(inArray(runAttributes.runId, runIds));
|
|
283
|
+
await this.db.delete(workflowRuns).where(inArray(workflowRuns.id, runIds));
|
|
284
|
+
}
|
|
285
|
+
async pruneTerminalRuns(policy, nowMs, limit) {
|
|
286
|
+
const statuses = policy.statuses.filter((s) => TERMINAL_RUN_STATUSES.includes(s));
|
|
287
|
+
if (statuses.length === 0 || limit <= 0) return 0;
|
|
288
|
+
if (policy.maxAge == null && policy.maxCount == null) return 0;
|
|
289
|
+
const scoped = this.runFilters({
|
|
290
|
+
...policy.scope ?? {},
|
|
291
|
+
statuses
|
|
292
|
+
});
|
|
293
|
+
const ids = /* @__PURE__ */ new Set();
|
|
294
|
+
if (policy.maxAge != null) {
|
|
295
|
+
const cutoff = nowMs - parseDuration(policy.maxAge);
|
|
296
|
+
const rows = await this.db.select({
|
|
297
|
+
id: workflowRuns.id
|
|
298
|
+
}).from(workflowRuns).where(and(...scoped, lt(workflowRuns.updatedAt, cutoff))).orderBy(asc(workflowRuns.updatedAt)).limit(limit);
|
|
299
|
+
for (const r of rows) ids.add(r.id);
|
|
300
|
+
}
|
|
301
|
+
if (policy.maxCount != null && ids.size < limit) {
|
|
302
|
+
const rows = await this.db.select({
|
|
303
|
+
id: workflowRuns.id
|
|
304
|
+
}).from(workflowRuns).where(and(...scoped)).orderBy(desc(workflowRuns.updatedAt), desc(workflowRuns.id)).limit(limit).offset(policy.maxCount);
|
|
305
|
+
for (const r of rows) {
|
|
306
|
+
if (ids.size >= limit) break;
|
|
307
|
+
ids.add(r.id);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const doomed = [
|
|
311
|
+
...ids
|
|
312
|
+
].slice(0, limit);
|
|
313
|
+
await this.deleteRuns(doomed);
|
|
314
|
+
return doomed.length;
|
|
315
|
+
}
|
|
222
316
|
async getCheckpoint(runId, seq) {
|
|
223
317
|
const rows = await this.db.select().from(stepCheckpoints).where(and(eq(stepCheckpoints.runId, runId), eq(stepCheckpoints.seq, seq))).limit(1);
|
|
224
318
|
return rows[0] ? fromCheckpointRow(rows[0]) : null;
|
|
@@ -330,6 +424,13 @@ var DrizzleStateStore = class {
|
|
|
330
424
|
const rows = await this.db.select().from(workflowRuns).where(filters.length ? and(...filters) : void 0).orderBy(desc(workflowRuns.createdAt)).limit(query.limit ?? -1).offset(query.offset ?? 0);
|
|
331
425
|
return rows.map(fromRunRow);
|
|
332
426
|
}
|
|
427
|
+
async countRuns(query) {
|
|
428
|
+
const filters = this.runFilters(query);
|
|
429
|
+
const rows = await this.db.select({
|
|
430
|
+
count: sql`count(*)`
|
|
431
|
+
}).from(workflowRuns).where(filters.length ? and(...filters) : void 0);
|
|
432
|
+
return Number(rows[0]?.count ?? 0);
|
|
433
|
+
}
|
|
333
434
|
/** `GROUP BY status, origin` over the same predicates {@link listRuns} pages — one aggregate, so a
|
|
334
435
|
* console can show whole-set counts next to a bounded page instead of downloading every run to
|
|
335
436
|
* count them in the browser. */
|
|
@@ -379,6 +480,36 @@ var DrizzleStateStore = class {
|
|
|
379
480
|
one: sql`1`
|
|
380
481
|
}).from(runAttributes).where(and(eq(runAttributes.runId, workflowRuns.id), eq(runAttributes.key, f.key), anyOf(comparisons))));
|
|
381
482
|
}
|
|
483
|
+
// ---- persisted schedules ----------------------------------------------------------------------
|
|
484
|
+
async saveSchedule(record) {
|
|
485
|
+
const row = toScheduleRow(record);
|
|
486
|
+
await this.db.insert(durableSchedules).values(row).onConflictDoUpdate({
|
|
487
|
+
target: durableSchedules.id,
|
|
488
|
+
set: row
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
async getSchedule(id) {
|
|
492
|
+
const rows = await this.db.select().from(durableSchedules).where(eq(durableSchedules.id, id)).limit(1);
|
|
493
|
+
return rows[0] ? fromScheduleRow(rows[0]) : null;
|
|
494
|
+
}
|
|
495
|
+
async updateSchedule(id, patch, expectedNextFireAt) {
|
|
496
|
+
const set = toSchedulePatch(patch);
|
|
497
|
+
if (!Object.keys(set).length) return await this.getSchedule(id) !== null;
|
|
498
|
+
const rows = await this.db.update(durableSchedules).set(set).where(and(eq(durableSchedules.id, id), expectedNextFireAt === void 0 ? void 0 : expectedNextFireAt === null ? isNull(durableSchedules.nextFireAt) : eq(durableSchedules.nextFireAt, expectedNextFireAt))).returning({
|
|
499
|
+
id: durableSchedules.id
|
|
500
|
+
});
|
|
501
|
+
return rows.length > 0;
|
|
502
|
+
}
|
|
503
|
+
async deleteSchedule(id) {
|
|
504
|
+
const rows = await this.db.delete(durableSchedules).where(eq(durableSchedules.id, id)).returning({
|
|
505
|
+
id: durableSchedules.id
|
|
506
|
+
});
|
|
507
|
+
return rows.length > 0;
|
|
508
|
+
}
|
|
509
|
+
async listSchedules(query) {
|
|
510
|
+
const rows = await this.db.select().from(durableSchedules).where(and(query.namespace !== void 0 ? eq(durableSchedules.namespace, query.namespace) : void 0, query.workflow !== void 0 ? eq(durableSchedules.workflow, query.workflow) : void 0, query.paused !== void 0 ? eq(durableSchedules.paused, query.paused) : void 0, query.tag !== void 0 ? like(durableSchedules.tags, `%"${query.tag}"%`) : void 0, query.dueBy !== void 0 ? and(eq(durableSchedules.paused, false), lte(durableSchedules.nextFireAt, query.dueBy)) : void 0)).orderBy(sql`${durableSchedules.nextFireAt} IS NULL`, asc(durableSchedules.nextFireAt), asc(durableSchedules.id)).limit(query.limit ?? -1).offset(query.offset ?? 0);
|
|
511
|
+
return rows.map(fromScheduleRow);
|
|
512
|
+
}
|
|
382
513
|
async listCheckpoints(runId) {
|
|
383
514
|
const rows = await this.db.select().from(stepCheckpoints).where(eq(stepCheckpoints.runId, runId)).orderBy(asc(stepCheckpoints.seq));
|
|
384
515
|
return rows.map(fromCheckpointRow);
|
|
@@ -591,12 +722,58 @@ function fromCheckpointRow(row) {
|
|
|
591
722
|
};
|
|
592
723
|
}
|
|
593
724
|
__name(fromCheckpointRow, "fromCheckpointRow");
|
|
725
|
+
function toScheduleRow(r) {
|
|
726
|
+
return {
|
|
727
|
+
id: r.id,
|
|
728
|
+
namespace: r.namespace,
|
|
729
|
+
workflow: r.workflow,
|
|
730
|
+
paused: r.paused,
|
|
731
|
+
nextFireAt: r.nextFireAt,
|
|
732
|
+
tags: r.tags ?? null,
|
|
733
|
+
spec: r.spec,
|
|
734
|
+
state: r.state,
|
|
735
|
+
createdAt: r.createdAt.getTime(),
|
|
736
|
+
updatedAt: r.updatedAt.getTime()
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
__name(toScheduleRow, "toScheduleRow");
|
|
740
|
+
function toSchedulePatch(patch) {
|
|
741
|
+
const set = {};
|
|
742
|
+
if ("namespace" in patch && patch.namespace !== void 0) set.namespace = patch.namespace;
|
|
743
|
+
if ("workflow" in patch && patch.workflow !== void 0) set.workflow = patch.workflow;
|
|
744
|
+
if ("paused" in patch && patch.paused !== void 0) set.paused = patch.paused;
|
|
745
|
+
if ("nextFireAt" in patch) set.nextFireAt = patch.nextFireAt ?? null;
|
|
746
|
+
if ("tags" in patch) set.tags = patch.tags ?? null;
|
|
747
|
+
if ("spec" in patch && patch.spec !== void 0) set.spec = patch.spec;
|
|
748
|
+
if ("state" in patch && patch.state !== void 0) set.state = patch.state;
|
|
749
|
+
if ("updatedAt" in patch && patch.updatedAt !== void 0) set.updatedAt = patch.updatedAt.getTime();
|
|
750
|
+
return set;
|
|
751
|
+
}
|
|
752
|
+
__name(toSchedulePatch, "toSchedulePatch");
|
|
753
|
+
function fromScheduleRow(row) {
|
|
754
|
+
return {
|
|
755
|
+
id: row.id,
|
|
756
|
+
namespace: row.namespace,
|
|
757
|
+
workflow: row.workflow,
|
|
758
|
+
paused: row.paused,
|
|
759
|
+
nextFireAt: row.nextFireAt ?? null,
|
|
760
|
+
...row.tags ? {
|
|
761
|
+
tags: row.tags
|
|
762
|
+
} : {},
|
|
763
|
+
spec: row.spec ?? {},
|
|
764
|
+
state: row.state ?? {},
|
|
765
|
+
createdAt: new Date(row.createdAt),
|
|
766
|
+
updatedAt: new Date(row.updatedAt)
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
__name(fromScheduleRow, "fromScheduleRow");
|
|
594
770
|
export {
|
|
595
771
|
DEFAULT_NAMESPACE,
|
|
596
772
|
DrizzleStateStore,
|
|
597
773
|
bufferedEvents,
|
|
598
774
|
bufferedSignals,
|
|
599
775
|
durableManagedTables,
|
|
776
|
+
durableSchedules,
|
|
600
777
|
durableSchema,
|
|
601
778
|
runAttributes,
|
|
602
779
|
signalWaiters,
|