@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.
@@ -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;
@@ -1,4 +1,5 @@
1
- export type Driver = "sqlite" | "postgres" | "mysql";
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 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" | "apply" | "history" | "receipt" | "doctor" | "purge" | "capabilities";
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.5.4",
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"