@fadhilp/stateql 0.5.4 → 0.6.0
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 +64 -21
- package/dist/src/adapters.d.ts +1 -0
- package/dist/src/adapters.js +19 -6
- package/dist/src/cli.js +48 -2
- package/dist/src/connection.d.ts +1 -0
- package/dist/src/connection.js +29 -3
- package/dist/src/index.d.ts +1 -1
- package/dist/src/migrations.js +10 -0
- package/dist/src/mongodb.d.ts +48 -0
- package/dist/src/mongodb.js +868 -0
- package/dist/src/response-data.js +12 -0
- package/dist/src/sql.d.ts +3 -1
- package/dist/src/sql.js +3 -0
- package/dist/src/stateql.d.ts +8 -1
- package/dist/src/stateql.js +544 -22
- package/dist/src/store.d.ts +5 -2
- package/dist/src/store.js +13 -7
- package/dist/src/types.d.ts +90 -2
- package/package.json +3 -2
package/dist/src/store.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatabaseSync } from "node:sqlite";
|
|
2
|
-
import type { Column, Driver, Row, SqlParameters, StateConfidence } from "./types.js";
|
|
2
|
+
import type { Column, Driver, MongoWriteOutcome, Row, SqlParameters, StateConfidence } from "./types.js";
|
|
3
3
|
export interface SessionRecord {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
@@ -61,6 +61,7 @@ export interface OperationRecord {
|
|
|
61
61
|
idempotency_key: string | null;
|
|
62
62
|
state_version_before: string;
|
|
63
63
|
state_version_after: string | null;
|
|
64
|
+
outcome_json: string | null;
|
|
64
65
|
created_at: string;
|
|
65
66
|
}
|
|
66
67
|
export interface TransactionRecord {
|
|
@@ -211,7 +212,7 @@ export declare class StateStore {
|
|
|
211
212
|
previous?: OperationRecord;
|
|
212
213
|
denied?: "membership" | "transaction";
|
|
213
214
|
};
|
|
214
|
-
finishOperation(operationId: string, affectedRows: number, stateVersion: string): OperationRecord;
|
|
215
|
+
finishOperation(operationId: string, affectedRows: number, stateVersion: string, outcome?: MongoWriteOutcome): OperationRecord;
|
|
215
216
|
failOperation(operationId: string): void;
|
|
216
217
|
markOperationOutcomeUnknown(operationId: string): void;
|
|
217
218
|
createTransaction(input: {
|
|
@@ -235,6 +236,7 @@ export declare class StateStore {
|
|
|
235
236
|
operations: Array<{
|
|
236
237
|
id: string;
|
|
237
238
|
affectedRows: number;
|
|
239
|
+
outcome?: MongoWriteOutcome;
|
|
238
240
|
}>;
|
|
239
241
|
}): string;
|
|
240
242
|
savePlan(input: {
|
|
@@ -260,6 +262,7 @@ export declare class StateStore {
|
|
|
260
262
|
operationId: string;
|
|
261
263
|
connectionId: string;
|
|
262
264
|
affectedRows: number;
|
|
265
|
+
outcome?: MongoWriteOutcome;
|
|
263
266
|
}): {
|
|
264
267
|
operation: OperationRecord;
|
|
265
268
|
stateVersion: string;
|
package/dist/src/store.js
CHANGED
|
@@ -480,12 +480,13 @@ export class StateStore {
|
|
|
480
480
|
throw error;
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
|
-
finishOperation(operationId, affectedRows, stateVersion) {
|
|
483
|
+
finishOperation(operationId, affectedRows, stateVersion, outcome) {
|
|
484
484
|
this.db
|
|
485
485
|
.prepare(`UPDATE operations
|
|
486
|
-
SET status = 'committed', affected_rows = ?, state_version_after =
|
|
486
|
+
SET status = 'committed', affected_rows = ?, state_version_after = ?,
|
|
487
|
+
outcome_json = ?
|
|
487
488
|
WHERE id = ?`)
|
|
488
|
-
.run(affectedRows, stateVersion, operationId);
|
|
489
|
+
.run(affectedRows, stateVersion, outcomeJson(outcome), operationId);
|
|
489
490
|
return this.getOperation(operationId);
|
|
490
491
|
}
|
|
491
492
|
failOperation(operationId) {
|
|
@@ -695,9 +696,10 @@ export class StateStore {
|
|
|
695
696
|
stateVersion = `sv_${row.version}`;
|
|
696
697
|
this.db
|
|
697
698
|
.prepare(`UPDATE operations
|
|
698
|
-
SET status = 'committed', affected_rows = ?, state_version_after =
|
|
699
|
+
SET status = 'committed', affected_rows = ?, state_version_after = ?,
|
|
700
|
+
outcome_json = ?
|
|
699
701
|
WHERE id = ?`)
|
|
700
|
-
.run(operation.affectedRows, stateVersion, operation.id);
|
|
702
|
+
.run(operation.affectedRows, stateVersion, outcomeJson(operation.outcome), operation.id);
|
|
701
703
|
}
|
|
702
704
|
this.db
|
|
703
705
|
.prepare(`UPDATE transactions
|
|
@@ -772,9 +774,10 @@ export class StateStore {
|
|
|
772
774
|
const stateVersion = `sv_${row.version}`;
|
|
773
775
|
this.db
|
|
774
776
|
.prepare(`UPDATE operations
|
|
775
|
-
SET status = 'committed', affected_rows = ?, state_version_after =
|
|
777
|
+
SET status = 'committed', affected_rows = ?, state_version_after = ?,
|
|
778
|
+
outcome_json = ?
|
|
776
779
|
WHERE id = ?`)
|
|
777
|
-
.run(input.affectedRows, stateVersion, input.operationId);
|
|
780
|
+
.run(input.affectedRows, stateVersion, outcomeJson(input.outcome), input.operationId);
|
|
778
781
|
this.db
|
|
779
782
|
.prepare(`UPDATE plans SET applied_operation_id = ?, claim_token = NULL
|
|
780
783
|
WHERE id = ? AND claim_token = ?`)
|
|
@@ -1011,6 +1014,9 @@ export class StateStore {
|
|
|
1011
1014
|
}
|
|
1012
1015
|
}
|
|
1013
1016
|
}
|
|
1017
|
+
function outcomeJson(outcome) {
|
|
1018
|
+
return outcome === undefined ? null : JSON.stringify(toJsonSafe(outcome));
|
|
1019
|
+
}
|
|
1014
1020
|
function boundedHistorySql(sql) {
|
|
1015
1021
|
if (sql === undefined)
|
|
1016
1022
|
return null;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type SqlDriver = "sqlite" | "postgres" | "mysql";
|
|
2
|
+
export type Driver = SqlDriver | "mongodb";
|
|
2
3
|
export type CredentialAccess = "read" | "write";
|
|
3
4
|
export type CredentialOperation = "connect" | "query" | "inspect" | "plan" | "exec" | "apply" | "transaction.commit";
|
|
4
5
|
export interface CredentialRequest {
|
|
@@ -108,6 +109,77 @@ export interface StateQLSnapshot {
|
|
|
108
109
|
history: HistoryEntry[];
|
|
109
110
|
}
|
|
110
111
|
export type SqlParameters = unknown[] | Record<string, unknown>;
|
|
112
|
+
export type MongoDocument = Record<string, unknown>;
|
|
113
|
+
export interface MongoFindOptions {
|
|
114
|
+
projection?: MongoDocument;
|
|
115
|
+
sort?: MongoDocument | Array<[string, 1 | -1]>;
|
|
116
|
+
skip?: number;
|
|
117
|
+
limit?: number;
|
|
118
|
+
hint?: string | MongoDocument;
|
|
119
|
+
collation?: MongoDocument;
|
|
120
|
+
}
|
|
121
|
+
export interface MongoAggregateOptions {
|
|
122
|
+
allowDiskUse?: boolean;
|
|
123
|
+
hint?: string | MongoDocument;
|
|
124
|
+
collation?: MongoDocument;
|
|
125
|
+
}
|
|
126
|
+
export interface MongoMutationOptions {
|
|
127
|
+
upsert?: boolean;
|
|
128
|
+
collation?: MongoDocument;
|
|
129
|
+
hint?: string | MongoDocument;
|
|
130
|
+
}
|
|
131
|
+
export type MongoReadCommand = {
|
|
132
|
+
operation: "find";
|
|
133
|
+
collection: string;
|
|
134
|
+
filter?: MongoDocument;
|
|
135
|
+
options?: MongoFindOptions;
|
|
136
|
+
} | {
|
|
137
|
+
operation: "aggregate";
|
|
138
|
+
collection: string;
|
|
139
|
+
pipeline: MongoDocument[];
|
|
140
|
+
options?: MongoAggregateOptions;
|
|
141
|
+
};
|
|
142
|
+
export type MongoWriteCommand = {
|
|
143
|
+
operation: "insertOne";
|
|
144
|
+
collection: string;
|
|
145
|
+
document: MongoDocument;
|
|
146
|
+
options?: Record<string, never>;
|
|
147
|
+
} | {
|
|
148
|
+
operation: "insertMany";
|
|
149
|
+
collection: string;
|
|
150
|
+
documents: MongoDocument[];
|
|
151
|
+
options?: {
|
|
152
|
+
ordered?: boolean;
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
operation: "updateOne" | "updateMany";
|
|
156
|
+
collection: string;
|
|
157
|
+
filter: MongoDocument;
|
|
158
|
+
update: MongoDocument | MongoDocument[];
|
|
159
|
+
options?: MongoMutationOptions;
|
|
160
|
+
} | {
|
|
161
|
+
operation: "replaceOne";
|
|
162
|
+
collection: string;
|
|
163
|
+
filter: MongoDocument;
|
|
164
|
+
replacement: MongoDocument;
|
|
165
|
+
options?: MongoMutationOptions;
|
|
166
|
+
} | {
|
|
167
|
+
operation: "deleteOne" | "deleteMany";
|
|
168
|
+
collection: string;
|
|
169
|
+
filter: MongoDocument;
|
|
170
|
+
options?: Omit<MongoMutationOptions, "upsert">;
|
|
171
|
+
};
|
|
172
|
+
export interface MongoWriteOutcome {
|
|
173
|
+
acknowledged: boolean;
|
|
174
|
+
inserted_id?: unknown;
|
|
175
|
+
inserted_ids?: unknown[];
|
|
176
|
+
inserted_count?: number;
|
|
177
|
+
matched_count?: number;
|
|
178
|
+
modified_count?: number;
|
|
179
|
+
upserted_count?: number;
|
|
180
|
+
upserted_id?: unknown;
|
|
181
|
+
deleted_count?: number;
|
|
182
|
+
}
|
|
111
183
|
export interface ExecutionOptions {
|
|
112
184
|
timeoutMs?: number;
|
|
113
185
|
signal?: AbortSignal;
|
|
@@ -133,6 +205,9 @@ export interface QueryOptions extends ExecutionOptions {
|
|
|
133
205
|
params?: SqlParameters;
|
|
134
206
|
cache?: "auto" | "bypass" | "require";
|
|
135
207
|
}
|
|
208
|
+
export interface MongoQueryOptions extends ExecutionOptions {
|
|
209
|
+
cache?: "auto" | "bypass" | "require";
|
|
210
|
+
}
|
|
136
211
|
export interface FilterOptions {
|
|
137
212
|
params?: SqlParameters;
|
|
138
213
|
}
|
|
@@ -143,6 +218,12 @@ export interface ExecOptions extends ExecutionOptions {
|
|
|
143
218
|
allowUnbounded?: boolean;
|
|
144
219
|
allowDestructive?: boolean;
|
|
145
220
|
}
|
|
221
|
+
export interface MongoExecOptions extends ExecutionOptions {
|
|
222
|
+
replay?: boolean;
|
|
223
|
+
idempotencyKey?: string;
|
|
224
|
+
allowUnbounded?: boolean;
|
|
225
|
+
allowDestructive?: boolean;
|
|
226
|
+
}
|
|
146
227
|
export interface ConnectOptions extends ExecutionOptions {
|
|
147
228
|
name?: string;
|
|
148
229
|
readOnly?: boolean;
|
|
@@ -162,7 +243,11 @@ export interface PlanOptions extends ExecutionOptions {
|
|
|
162
243
|
allowUnbounded?: boolean;
|
|
163
244
|
allowDestructive?: boolean;
|
|
164
245
|
}
|
|
165
|
-
export
|
|
246
|
+
export interface MongoPlanOptions extends ExecutionOptions {
|
|
247
|
+
allowUnbounded?: boolean;
|
|
248
|
+
allowDestructive?: boolean;
|
|
249
|
+
}
|
|
250
|
+
export type BatchCommandName = "connect" | "disconnect" | "status" | "profile.add" | "profile.list" | "profile.show" | "profile.remove" | "session.start" | "session.list" | "session.show" | "session.summary" | "session.close" | "query" | "filter" | "exec" | "show" | "rows" | "count" | "columns" | "alias.set" | "inspect" | "transaction.begin" | "transaction.status" | "transaction.commit" | "transaction.rollback" | "plan" | "mongo.query" | "mongo.exec" | "mongo.plan" | "apply" | "history" | "receipt" | "doctor" | "purge" | "capabilities";
|
|
166
251
|
export interface BatchCommand {
|
|
167
252
|
command: BatchCommandName;
|
|
168
253
|
target?: string;
|
|
@@ -174,6 +259,7 @@ export interface BatchCommand {
|
|
|
174
259
|
kind?: string;
|
|
175
260
|
table?: string;
|
|
176
261
|
params?: SqlParameters;
|
|
262
|
+
mongo?: MongoReadCommand | MongoWriteCommand;
|
|
177
263
|
cache?: "auto" | "bypass" | "require";
|
|
178
264
|
read_only?: boolean;
|
|
179
265
|
secret_env?: string;
|
|
@@ -355,6 +441,7 @@ export interface OperationData {
|
|
|
355
441
|
state_version_before: string;
|
|
356
442
|
state_version_after: string | null;
|
|
357
443
|
replay_of?: string;
|
|
444
|
+
outcome?: MongoWriteOutcome;
|
|
358
445
|
}
|
|
359
446
|
export interface ExecData extends OperationData {
|
|
360
447
|
duplicate?: boolean;
|
|
@@ -421,6 +508,7 @@ export interface PurgeData {
|
|
|
421
508
|
export interface CapabilitiesData {
|
|
422
509
|
drivers: Driver[];
|
|
423
510
|
features: Record<string, boolean>;
|
|
511
|
+
driver_features?: Partial<Record<Driver, Record<string, boolean>>>;
|
|
424
512
|
}
|
|
425
513
|
export interface RemovedProfileData {
|
|
426
514
|
profile: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fadhilp/stateql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Stateful, agent-oriented database CLI for safe result reuse",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsc -p tsconfig.json",
|
|
28
|
-
"test": "npm run build && node --test dist/test/cli.test.js dist/test/credential.test.js dist/test/mysql.test.js dist/test/postgres.test.js dist/test/query.test.js dist/test/sqlite.test.js dist/test/store.test.js dist/test/terminal.test.js dist/test/transaction.test.js dist/test/write.test.js",
|
|
28
|
+
"test": "npm run build && node --test dist/test/cli.test.js dist/test/credential.test.js dist/test/mongodb.test.js dist/test/mysql.test.js dist/test/postgres.test.js dist/test/query.test.js dist/test/sqlite.test.js dist/test/store.test.js dist/test/terminal.test.js dist/test/transaction.test.js dist/test/write.test.js",
|
|
29
29
|
"release": "npm version",
|
|
30
30
|
"version": "npm install",
|
|
31
31
|
"prepack": "npm test"
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"node": ">=22.16"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
+
"mongodb": "^6.21.0",
|
|
47
48
|
"mysql2": "^3.23.1",
|
|
48
49
|
"node-sql-parser": "^5.4.0",
|
|
49
50
|
"pg": "^8.16.3"
|