@persql/sdk 1.0.0 → 1.2.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/dist/index.d.cts CHANGED
@@ -91,6 +91,30 @@ interface QueryResult<T = Record<string, unknown>> {
91
91
  data: T[];
92
92
  rowsRead: number;
93
93
  rowsWritten: number;
94
+ /**
95
+ * Per-call usage and cost the server echoes on `query()`. Undefined in
96
+ * local mode (no server) and on the per-statement results of `batch()`
97
+ * (a batch reports one aggregate meta, not one per statement).
98
+ */
99
+ meta?: QueryMeta;
100
+ }
101
+ /**
102
+ * Usage and cost the server attaches to a query response. `costUsd` is
103
+ * computed from the public rate card — the same numbers the spend report
104
+ * uses. `snapshot` is set when the auto-snapshot pipeline took a labeled
105
+ * bookmark before a destructive call.
106
+ */
107
+ interface QueryMeta {
108
+ rowsRead: number;
109
+ rowsWritten: number;
110
+ durationMs: number;
111
+ statementCount: number;
112
+ costUsd: number;
113
+ snapshot: {
114
+ id: string;
115
+ label: string;
116
+ } | null;
117
+ queryLogId: string;
94
118
  }
95
119
  interface BatchOptions {
96
120
  /** Wrap all statements in BEGIN/COMMIT. Rolls back on first error. */
@@ -344,8 +368,22 @@ declare class PerSQL {
344
368
  */
345
369
  database(path: string): PerSQLDatabase;
346
370
  database(namespace: string, slug: string): PerSQLDatabase;
371
+ /**
372
+ * Provision and list databases in the token's namespace. `create`
373
+ * needs an unscoped admin token; `database()` then gives you a handle
374
+ * to query the result.
375
+ */
376
+ get databases(): PerSQLDatabases;
347
377
  /** @internal */
348
378
  request<T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
379
+ /**
380
+ * @internal — like `request`, but also surfaces the response `meta`
381
+ * envelope (usage + `costUsd`) that the data-only `request` drops.
382
+ */
383
+ requestWithMeta<T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, body?: unknown, headers?: Record<string, string>): Promise<{
384
+ data: T;
385
+ meta?: QueryMeta;
386
+ }>;
349
387
  /** @internal — raw fetch returning the underlying Response. */
350
388
  fetchRaw(method: "GET", path: string): Promise<Response>;
351
389
  /**
@@ -383,6 +421,51 @@ declare class SupportClient {
383
421
  id: string;
384
422
  }>;
385
423
  }
424
+ interface DatabaseInfo {
425
+ id: string;
426
+ namespaceId: string;
427
+ slug: string;
428
+ name: string;
429
+ status: string;
430
+ region: string;
431
+ forkedFromId: string | null;
432
+ forkedAt: string | null;
433
+ expiresAt: string | null;
434
+ branchRef: string | null;
435
+ createdAt: string;
436
+ updatedAt: string;
437
+ }
438
+ interface CreateDatabaseOptions {
439
+ /** Display name, 1-50 chars. */
440
+ name: string;
441
+ /** URL slug; derived from `name` when omitted. */
442
+ slug?: string;
443
+ /** Region hint: auto, wnam, enam, weur, eeur, apac. Default: auto. */
444
+ region?: string;
445
+ /** Auto-delete after N days (1..30). Null/undefined = keep until deleted. */
446
+ ttlDays?: number | null;
447
+ }
448
+ /**
449
+ * Namespace-level database management. Reached via `persql.databases`.
450
+ * Both calls require a server-mode (non-local) client.
451
+ */
452
+ declare class PerSQLDatabases {
453
+ private readonly client;
454
+ constructor(client: PerSQL);
455
+ /**
456
+ * Provision a new isolated database and return its metadata. Requires
457
+ * an unscoped admin token (scoped tokens can't create databases).
458
+ */
459
+ create(opts: CreateDatabaseOptions): Promise<DatabaseInfo>;
460
+ /** List databases in the token's namespace, newest first (paginated). */
461
+ list(opts?: {
462
+ cursor?: string;
463
+ pageSize?: number;
464
+ }): Promise<{
465
+ data: DatabaseInfo[];
466
+ nextCursor: string | null;
467
+ }>;
468
+ }
386
469
  declare class PerSQLDatabase {
387
470
  private readonly client;
388
471
  readonly namespace: string;
@@ -564,6 +647,56 @@ declare class PerSQLDatabase {
564
647
  * server.
565
648
  */
566
649
  subscribe(options: SubscribeOptions): () => void;
650
+ /**
651
+ * Long-poll for row-changes on this database. Returns immediately
652
+ * if changes newer than `since` are already buffered; otherwise
653
+ * blocks server-side for up to `waitMs` (default 25s, max 25s).
654
+ *
655
+ * Most callers want `changes()` instead — an async iterator that
656
+ * loops `waitForChanges` forever, surfacing each batch as it
657
+ * arrives.
658
+ */
659
+ waitForChanges(opts?: {
660
+ since?: number;
661
+ waitMs?: number;
662
+ tables?: string[];
663
+ }): Promise<{
664
+ changes: Array<{
665
+ seq: number;
666
+ ts: number;
667
+ table: string;
668
+ kind: SubscribeChangeKind;
669
+ }>;
670
+ cursor: number;
671
+ restarted: boolean;
672
+ }>;
673
+ /**
674
+ * Async-iterator change feed. Loops `waitForChanges` forever and
675
+ * yields one batch per server response. Pass an `AbortSignal` to
676
+ * stop the loop cleanly.
677
+ *
678
+ * ```ts
679
+ * const ctl = new AbortController();
680
+ * for await (const batch of db.changes({ signal: ctl.signal })) {
681
+ * for (const c of batch.changes) console.log(c.kind, c.table);
682
+ * }
683
+ * ```
684
+ */
685
+ changes(opts?: {
686
+ since?: number;
687
+ tables?: string[];
688
+ waitMs?: number;
689
+ signal?: AbortSignal;
690
+ }): AsyncGenerator<{
691
+ changes: Array<{
692
+ seq: number;
693
+ ts: number;
694
+ table: string;
695
+ kind: SubscribeChangeKind;
696
+ }>;
697
+ cursor: number;
698
+ restarted: boolean;
699
+ }>;
567
700
  /**
568
701
  * Returns the callback shape `drizzle-orm/sqlite-proxy` expects.
569
702
  * Pair with `drizzle()` from that module to get a typed,
@@ -927,6 +1060,11 @@ declare class PerSQLProposals {
927
1060
  * rows, and returns a single-use `executionToken` valid for 10 min
928
1061
  * (override with `ttlSec`, max 1 hour). Nothing is mutated until
929
1062
  * `apply()` is called.
1063
+ *
1064
+ * Local mode keeps the token in-process: single-use still holds, but
1065
+ * `estimatedAffectedRows` is always `null` (no server estimator) and a
1066
+ * stale/unknown token throws a plain `Error` rather than the HTTP
1067
+ * 404/403 of the server path.
930
1068
  */
931
1069
  propose(sql: string, opts?: ProposeOptions): Promise<ProposalPlan>;
932
1070
  /**
@@ -1058,4 +1196,4 @@ type SqliteProxyDriver = (sql: string, params: unknown[], method: "all" | "run"
1058
1196
  rows: unknown;
1059
1197
  }>;
1060
1198
 
1061
- export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateSupportTicketOptions, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
1199
+ export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
package/dist/index.d.ts CHANGED
@@ -91,6 +91,30 @@ interface QueryResult<T = Record<string, unknown>> {
91
91
  data: T[];
92
92
  rowsRead: number;
93
93
  rowsWritten: number;
94
+ /**
95
+ * Per-call usage and cost the server echoes on `query()`. Undefined in
96
+ * local mode (no server) and on the per-statement results of `batch()`
97
+ * (a batch reports one aggregate meta, not one per statement).
98
+ */
99
+ meta?: QueryMeta;
100
+ }
101
+ /**
102
+ * Usage and cost the server attaches to a query response. `costUsd` is
103
+ * computed from the public rate card — the same numbers the spend report
104
+ * uses. `snapshot` is set when the auto-snapshot pipeline took a labeled
105
+ * bookmark before a destructive call.
106
+ */
107
+ interface QueryMeta {
108
+ rowsRead: number;
109
+ rowsWritten: number;
110
+ durationMs: number;
111
+ statementCount: number;
112
+ costUsd: number;
113
+ snapshot: {
114
+ id: string;
115
+ label: string;
116
+ } | null;
117
+ queryLogId: string;
94
118
  }
95
119
  interface BatchOptions {
96
120
  /** Wrap all statements in BEGIN/COMMIT. Rolls back on first error. */
@@ -344,8 +368,22 @@ declare class PerSQL {
344
368
  */
345
369
  database(path: string): PerSQLDatabase;
346
370
  database(namespace: string, slug: string): PerSQLDatabase;
371
+ /**
372
+ * Provision and list databases in the token's namespace. `create`
373
+ * needs an unscoped admin token; `database()` then gives you a handle
374
+ * to query the result.
375
+ */
376
+ get databases(): PerSQLDatabases;
347
377
  /** @internal */
348
378
  request<T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
379
+ /**
380
+ * @internal — like `request`, but also surfaces the response `meta`
381
+ * envelope (usage + `costUsd`) that the data-only `request` drops.
382
+ */
383
+ requestWithMeta<T>(method: "GET" | "POST" | "PUT" | "DELETE", path: string, body?: unknown, headers?: Record<string, string>): Promise<{
384
+ data: T;
385
+ meta?: QueryMeta;
386
+ }>;
349
387
  /** @internal — raw fetch returning the underlying Response. */
350
388
  fetchRaw(method: "GET", path: string): Promise<Response>;
351
389
  /**
@@ -383,6 +421,51 @@ declare class SupportClient {
383
421
  id: string;
384
422
  }>;
385
423
  }
424
+ interface DatabaseInfo {
425
+ id: string;
426
+ namespaceId: string;
427
+ slug: string;
428
+ name: string;
429
+ status: string;
430
+ region: string;
431
+ forkedFromId: string | null;
432
+ forkedAt: string | null;
433
+ expiresAt: string | null;
434
+ branchRef: string | null;
435
+ createdAt: string;
436
+ updatedAt: string;
437
+ }
438
+ interface CreateDatabaseOptions {
439
+ /** Display name, 1-50 chars. */
440
+ name: string;
441
+ /** URL slug; derived from `name` when omitted. */
442
+ slug?: string;
443
+ /** Region hint: auto, wnam, enam, weur, eeur, apac. Default: auto. */
444
+ region?: string;
445
+ /** Auto-delete after N days (1..30). Null/undefined = keep until deleted. */
446
+ ttlDays?: number | null;
447
+ }
448
+ /**
449
+ * Namespace-level database management. Reached via `persql.databases`.
450
+ * Both calls require a server-mode (non-local) client.
451
+ */
452
+ declare class PerSQLDatabases {
453
+ private readonly client;
454
+ constructor(client: PerSQL);
455
+ /**
456
+ * Provision a new isolated database and return its metadata. Requires
457
+ * an unscoped admin token (scoped tokens can't create databases).
458
+ */
459
+ create(opts: CreateDatabaseOptions): Promise<DatabaseInfo>;
460
+ /** List databases in the token's namespace, newest first (paginated). */
461
+ list(opts?: {
462
+ cursor?: string;
463
+ pageSize?: number;
464
+ }): Promise<{
465
+ data: DatabaseInfo[];
466
+ nextCursor: string | null;
467
+ }>;
468
+ }
386
469
  declare class PerSQLDatabase {
387
470
  private readonly client;
388
471
  readonly namespace: string;
@@ -564,6 +647,56 @@ declare class PerSQLDatabase {
564
647
  * server.
565
648
  */
566
649
  subscribe(options: SubscribeOptions): () => void;
650
+ /**
651
+ * Long-poll for row-changes on this database. Returns immediately
652
+ * if changes newer than `since` are already buffered; otherwise
653
+ * blocks server-side for up to `waitMs` (default 25s, max 25s).
654
+ *
655
+ * Most callers want `changes()` instead — an async iterator that
656
+ * loops `waitForChanges` forever, surfacing each batch as it
657
+ * arrives.
658
+ */
659
+ waitForChanges(opts?: {
660
+ since?: number;
661
+ waitMs?: number;
662
+ tables?: string[];
663
+ }): Promise<{
664
+ changes: Array<{
665
+ seq: number;
666
+ ts: number;
667
+ table: string;
668
+ kind: SubscribeChangeKind;
669
+ }>;
670
+ cursor: number;
671
+ restarted: boolean;
672
+ }>;
673
+ /**
674
+ * Async-iterator change feed. Loops `waitForChanges` forever and
675
+ * yields one batch per server response. Pass an `AbortSignal` to
676
+ * stop the loop cleanly.
677
+ *
678
+ * ```ts
679
+ * const ctl = new AbortController();
680
+ * for await (const batch of db.changes({ signal: ctl.signal })) {
681
+ * for (const c of batch.changes) console.log(c.kind, c.table);
682
+ * }
683
+ * ```
684
+ */
685
+ changes(opts?: {
686
+ since?: number;
687
+ tables?: string[];
688
+ waitMs?: number;
689
+ signal?: AbortSignal;
690
+ }): AsyncGenerator<{
691
+ changes: Array<{
692
+ seq: number;
693
+ ts: number;
694
+ table: string;
695
+ kind: SubscribeChangeKind;
696
+ }>;
697
+ cursor: number;
698
+ restarted: boolean;
699
+ }>;
567
700
  /**
568
701
  * Returns the callback shape `drizzle-orm/sqlite-proxy` expects.
569
702
  * Pair with `drizzle()` from that module to get a typed,
@@ -927,6 +1060,11 @@ declare class PerSQLProposals {
927
1060
  * rows, and returns a single-use `executionToken` valid for 10 min
928
1061
  * (override with `ttlSec`, max 1 hour). Nothing is mutated until
929
1062
  * `apply()` is called.
1063
+ *
1064
+ * Local mode keeps the token in-process: single-use still holds, but
1065
+ * `estimatedAffectedRows` is always `null` (no server estimator) and a
1066
+ * stale/unknown token throws a plain `Error` rather than the HTTP
1067
+ * 404/403 of the server path.
930
1068
  */
931
1069
  propose(sql: string, opts?: ProposeOptions): Promise<ProposalPlan>;
932
1070
  /**
@@ -1058,4 +1196,4 @@ type SqliteProxyDriver = (sql: string, params: unknown[], method: "all" | "run"
1058
1196
  rows: unknown;
1059
1197
  }>;
1060
1198
 
1061
- export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateSupportTicketOptions, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
1199
+ export { type AiSdkTool, type AnthropicTool, type ApprovalEvent, ApprovalRequiredError, type ApprovalRule, type ApprovalRuleHit, type ApprovalStatus, type BatchExpect, type BatchOptions, type BranchInfo, type BranchMergeMode, type BranchMergeOptions, type BranchMergePlanStep, type BranchMergeResult, type BranchUpsertOptions, type ClaimBranchOptions, type ClaimedBranch, type CreateApprovalRuleInput, type CreateDatabaseOptions, type CreateSupportTicketOptions, type DatabaseInfo, type DatabaseSchema, type DatabaseToolBundle, type DescribeBundle, type HandoffClaim, type LangChainTool, type MastraTool, type OpenAiAgentsTool, type OpenAiTool, PerSQL, PerSQLApprovalRules, PerSQLApprovals, PerSQLBranches, PerSQLDatabase, PerSQLDatabases, PerSQLError, type PerSQLOptions, PerSQLProposals, type PollApprovalOptions, type ProposalPlan, type ProposeOptions, type QueryLogEntry, type QueryMeta, type QueryOptions, type QueryResult, RateLimitError, type RawQueryResult, type SchemaDoctorReport, type SchemaSearchResponse, type SingleToolBundle, type SqlErrorDetail, type SqlErrorKind, type SqliteProxyDriver, type Statement, type SubscribeApprovalOptions, type SubscribeChange, type SubscribeChangeKind, type SubscribeOptions, SupportClient, type TableInfo, type TableSample, type ValidateResult, type WhoamiInfo };
package/dist/index.js CHANGED
@@ -5,11 +5,12 @@ import {
5
5
  PerSQLApprovals,
6
6
  PerSQLBranches,
7
7
  PerSQLDatabase,
8
+ PerSQLDatabases,
8
9
  PerSQLError,
9
10
  PerSQLProposals,
10
11
  RateLimitError,
11
12
  SupportClient
12
- } from "./chunk-ZRZANHPI.js";
13
+ } from "./chunk-GH75ERQ6.js";
13
14
  export {
14
15
  ApprovalRequiredError,
15
16
  PerSQL,
@@ -17,6 +18,7 @@ export {
17
18
  PerSQLApprovals,
18
19
  PerSQLBranches,
19
20
  PerSQLDatabase,
21
+ PerSQLDatabases,
20
22
  PerSQLError,
21
23
  PerSQLProposals,
22
24
  RateLimitError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@persql/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript SDK for PerSQL — SQLite databases on the edge for AI agents",
5
5
  "license": "MIT",
6
6
  "type": "module",