@fadhilp/stateql 0.4.4 → 0.5.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.
@@ -121,6 +121,7 @@ export interface StateQLOptions extends ExecutionOptions {
121
121
  maxCellCharacters?: number;
122
122
  maxResultRows?: number;
123
123
  maxResultBytes?: number;
124
+ maxStateBytes?: number;
124
125
  credentialResolver?: CredentialResolver;
125
126
  now?: () => Date;
126
127
  }
@@ -160,7 +161,7 @@ export interface PlanOptions extends ExecutionOptions {
160
161
  allowUnbounded?: boolean;
161
162
  allowDestructive?: boolean;
162
163
  }
163
- 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" | "capabilities";
164
+ 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";
164
165
  export interface BatchCommand {
165
166
  command: BatchCommandName;
166
167
  target?: string;
@@ -184,6 +185,7 @@ export interface BatchCommand {
184
185
  limit?: number;
185
186
  isolation?: string;
186
187
  timeout_ms?: number;
188
+ scope?: "expired" | "results" | "history" | "all";
187
189
  }
188
190
  export interface BatchOptions {
189
191
  continueOnError?: boolean;
@@ -194,3 +196,239 @@ export interface Column {
194
196
  type: string;
195
197
  }
196
198
  export type Row = Record<string, unknown>;
199
+ /** Data returned by the stable, non-dynamic StateQL public methods. */
200
+ export interface ConnectionData {
201
+ connection_id: string;
202
+ driver: Driver;
203
+ database: string;
204
+ name: string;
205
+ profile: string | null;
206
+ read_only: boolean;
207
+ state_version: string;
208
+ state_confidence: StateConfidence;
209
+ }
210
+ export interface ProfileData {
211
+ profile: string;
212
+ target: string | null;
213
+ secret_env: string | null;
214
+ read_only: boolean;
215
+ }
216
+ export interface ProfilesData {
217
+ profiles: ProfileData[];
218
+ }
219
+ export interface StatusConnectionData {
220
+ connection_id: string;
221
+ name: string;
222
+ driver: Driver;
223
+ database: string;
224
+ read_only: boolean;
225
+ }
226
+ export interface TransactionReferenceData {
227
+ transaction_id: string;
228
+ owner_actor_id: string;
229
+ state: string;
230
+ }
231
+ export interface StatusData {
232
+ session_id: string;
233
+ session_name: string;
234
+ actor_id: string;
235
+ connection: StatusConnectionData | null;
236
+ transaction: TransactionReferenceData | null;
237
+ state_version: string | null;
238
+ }
239
+ export interface ActorLinkData {
240
+ session_id: string;
241
+ actor_id: string;
242
+ linked: boolean;
243
+ }
244
+ export interface ActorUnlinkData {
245
+ session_id: string;
246
+ actor_id: string;
247
+ unlinked: boolean;
248
+ }
249
+ export interface ActorData {
250
+ actor_id: string;
251
+ attached_at: string;
252
+ }
253
+ export interface ActorsData {
254
+ session_id: string;
255
+ actors: ActorData[];
256
+ }
257
+ export interface ActorResolutionData {
258
+ actor_id: string;
259
+ session: {
260
+ session_id: string;
261
+ name: string;
262
+ status: string;
263
+ } | null;
264
+ }
265
+ export interface SessionData {
266
+ session_id: string;
267
+ name: string;
268
+ state: string;
269
+ active_connection: string | null;
270
+ active_transaction: string | null;
271
+ }
272
+ export interface SessionListItem {
273
+ session_id: string;
274
+ name: string;
275
+ status: string;
276
+ active_connection: string | null;
277
+ active_transaction: string | null;
278
+ }
279
+ export interface SessionsData {
280
+ sessions: SessionListItem[];
281
+ }
282
+ export interface RecentResultData {
283
+ alias: string | null;
284
+ handle: string;
285
+ rows: number;
286
+ }
287
+ export interface RecentOperationData {
288
+ handle: string;
289
+ actor_id: string;
290
+ type: string;
291
+ affected_rows: number | null;
292
+ status: string;
293
+ }
294
+ export interface SessionSummaryData {
295
+ session_id: string;
296
+ name: string;
297
+ connection: string | null;
298
+ state_version: string | null;
299
+ transaction: string | null;
300
+ known_results: RecentResultData[];
301
+ recent_operations: RecentOperationData[];
302
+ }
303
+ export interface ResultData {
304
+ result_id: string;
305
+ rows: number;
306
+ columns: Column[];
307
+ preview: Row[];
308
+ preview_count: number;
309
+ truncated: boolean;
310
+ cached: boolean;
311
+ duplicate_of?: string;
312
+ state_version: string;
313
+ storage: {
314
+ mode: string;
315
+ expires_at: string;
316
+ };
317
+ }
318
+ export interface RowsData {
319
+ result_id: string;
320
+ offset: number;
321
+ limit: number;
322
+ rows: Row[];
323
+ returned: number;
324
+ total: number;
325
+ truncated: boolean;
326
+ next_offset: number | null;
327
+ }
328
+ export interface CountData {
329
+ result_id: string;
330
+ rows: number;
331
+ }
332
+ export interface ColumnsData {
333
+ result_id: string;
334
+ columns: Column[];
335
+ }
336
+ export interface AliasData {
337
+ alias: string;
338
+ result_id: string;
339
+ }
340
+ export interface ExportData {
341
+ result_id: string;
342
+ output: string;
343
+ format: "json" | "jsonl" | "csv";
344
+ rows: number;
345
+ }
346
+ export interface OperationData {
347
+ operation_id: string;
348
+ actor_id: string;
349
+ statement_type: string;
350
+ affected_rows: number | null;
351
+ status: string;
352
+ committed: boolean;
353
+ transaction_id: string | null;
354
+ state_version_before: string;
355
+ state_version_after: string | null;
356
+ replay_of?: string;
357
+ }
358
+ export interface ExecData extends OperationData {
359
+ duplicate?: boolean;
360
+ duplicate_of?: string;
361
+ duplicate_override?: boolean;
362
+ idempotency_key?: string;
363
+ }
364
+ export interface TransactionData {
365
+ transaction_id: string;
366
+ state: string;
367
+ owner_actor_id: string;
368
+ connection_id: string;
369
+ statements: number;
370
+ pending_writes: number;
371
+ start_state_version: string;
372
+ isolation_level: string;
373
+ age_ms: number;
374
+ }
375
+ export interface CommitTransactionData {
376
+ transaction_id: string;
377
+ state: string;
378
+ statements_executed: number;
379
+ affected_rows: number;
380
+ state_version: string;
381
+ }
382
+ export interface RollbackTransactionData {
383
+ transaction_id: string;
384
+ state: string;
385
+ discarded_statements: number;
386
+ }
387
+ export interface PlanData {
388
+ plan_id: string;
389
+ statement_type: string;
390
+ destructive: boolean;
391
+ requires_confirmation: boolean;
392
+ required_overrides: string[];
393
+ state_version: string;
394
+ owner_actor_id: string;
395
+ expires_at: string;
396
+ }
397
+ export interface ApplyData extends ExecData {
398
+ plan_id: string;
399
+ }
400
+ export interface HistoryData {
401
+ history: HistoryEntry[];
402
+ }
403
+ export interface DoctorData {
404
+ integrity: "ok" | "issues";
405
+ issues: Array<{
406
+ code: string;
407
+ record?: string;
408
+ }>;
409
+ migrations: string[];
410
+ storage: {
411
+ result_bytes: number;
412
+ results: number;
413
+ history: number;
414
+ };
415
+ }
416
+ export interface PurgeData {
417
+ scope: "expired" | "results" | "history" | "all";
418
+ deleted: number;
419
+ }
420
+ export interface CapabilitiesData {
421
+ drivers: Driver[];
422
+ features: Record<string, boolean>;
423
+ }
424
+ export interface RemovedProfileData {
425
+ profile: string;
426
+ removed: boolean;
427
+ }
428
+ export interface DisconnectData {
429
+ disconnected: boolean;
430
+ }
431
+ export interface CloseSessionData {
432
+ session_id: string;
433
+ state: string;
434
+ }
@@ -1,8 +1,11 @@
1
- import type { Row } from "./types.js";
1
+ import type { Column, Row, SqlParameters } from "./types.js";
2
2
  export declare function defaultHome(): string;
3
3
  export declare function hash(value: unknown): string;
4
4
  export declare function stableStringify(value: unknown): string;
5
- export declare function parseJson<T>(value: string, fallback: T): T;
5
+ export declare function parseJson<T>(value: string, context: string, validate?: (parsed: unknown) => parsed is T): T;
6
+ export declare function isSqlParameters(value: unknown): value is SqlParameters;
7
+ export declare function isRows(value: unknown): value is Row[];
8
+ export declare function isColumns(value: unknown): value is Column[];
6
9
  export declare function redact(value: string): string;
7
10
  export declare function compactRows(rows: Row[], maxCellCharacters: number): Row[];
8
11
  export declare function toJsonSafe<T>(value: T): T;
package/dist/src/util.js CHANGED
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { homedir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { env, platform } from "node:process";
5
+ import { StateQLError } from "./errors.js";
5
6
  export function defaultHome() {
6
7
  if (env.STQL_HOME)
7
8
  return resolve(env.STQL_HOME);
@@ -25,13 +26,34 @@ function sortValue(value) {
25
26
  .sort(([left], [right]) => left.localeCompare(right))
26
27
  .map(([key, item]) => [key, sortValue(item)]));
27
28
  }
28
- export function parseJson(value, fallback) {
29
+ export function parseJson(value, context, validate) {
30
+ let parsed;
29
31
  try {
30
- return JSON.parse(value);
32
+ parsed = JSON.parse(value);
31
33
  }
32
34
  catch {
33
- return fallback;
35
+ throw corruptedState(context);
34
36
  }
37
+ if (validate && !validate(parsed))
38
+ throw corruptedState(context);
39
+ return parsed;
40
+ }
41
+ export function isSqlParameters(value) {
42
+ return Array.isArray(value) || isRecord(value);
43
+ }
44
+ export function isRows(value) {
45
+ return Array.isArray(value) && value.every(isRecord);
46
+ }
47
+ export function isColumns(value) {
48
+ return Array.isArray(value) && value.every((column) => isRecord(column) &&
49
+ typeof column.name === "string" &&
50
+ typeof column.type === "string");
51
+ }
52
+ function isRecord(value) {
53
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
54
+ }
55
+ function corruptedState(context) {
56
+ return new StateQLError("STATE_CORRUPTED", `Stored ${context} is corrupted.`, { suggestedAction: "Run stql doctor, then purge the affected data." });
35
57
  }
36
58
  export function redact(value) {
37
59
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fadhilp/stateql",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "Stateful, agent-oriented database CLI for safe result reuse",
5
5
  "repository": {
6
6
  "type": "git",