@aouda/client 0.1.9 → 0.1.10
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/cli/index.cjs +203 -6
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +203 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/{client-CxP9Vnc8.d.cts → client-Dgenr-cE.d.cts} +92 -2
- package/dist/{client-CxP9Vnc8.d.ts → client-Dgenr-cE.d.ts} +92 -2
- package/dist/index.cjs +208 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +205 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.d.cts
CHANGED
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -392,7 +392,7 @@ import { fileURLToPath } from "url";
|
|
|
392
392
|
// package.json
|
|
393
393
|
var package_default = {
|
|
394
394
|
name: "@aouda/client",
|
|
395
|
-
version: "0.1.
|
|
395
|
+
version: "0.1.10",
|
|
396
396
|
description: "Official TypeScript/JavaScript client library for Aouda",
|
|
397
397
|
type: "module",
|
|
398
398
|
main: "./dist/index.cjs",
|
|
@@ -1483,7 +1483,15 @@ var ERROR_CODE_MAP = {
|
|
|
1483
1483
|
AUTH_TOKEN_INVALID: AoudaAuthenticationError,
|
|
1484
1484
|
AUTH_TOKEN_REVOKED: AoudaAuthenticationError,
|
|
1485
1485
|
AUTH_API_KEY_INVALID: AoudaAuthenticationError,
|
|
1486
|
-
AUTH_REQUIRED: AoudaAuthenticationError
|
|
1486
|
+
AUTH_REQUIRED: AoudaAuthenticationError,
|
|
1487
|
+
NAMED_QUERY_NOT_FOUND: AoudaNotFoundError,
|
|
1488
|
+
NAMED_MUTATION_NOT_FOUND: AoudaNotFoundError,
|
|
1489
|
+
NAMED_QUERY_BATCH_EMPTY: AoudaValidationError,
|
|
1490
|
+
NAMED_QUERY_BATCH_TOO_LARGE: AoudaValidationError,
|
|
1491
|
+
NAMED_QUERY_BATCH_MUTATION: AoudaValidationError,
|
|
1492
|
+
NAMED_QUERY_BIND_FAILED: AoudaValidationError,
|
|
1493
|
+
NAMED_QUERY_PARAM_REQUIRED: AoudaValidationError,
|
|
1494
|
+
NAMED_MUTATION_BIND_FAILED: AoudaValidationError
|
|
1487
1495
|
};
|
|
1488
1496
|
function createComposedAbortController(...signals) {
|
|
1489
1497
|
const controller = new AbortController();
|
|
@@ -2376,6 +2384,7 @@ var TableSubscription = class {
|
|
|
2376
2384
|
this._started = false;
|
|
2377
2385
|
this._startPromise = null;
|
|
2378
2386
|
this._lastVersion = 0;
|
|
2387
|
+
this._pendingSnapshotRows = [];
|
|
2379
2388
|
this.id = createStreamingId("sub");
|
|
2380
2389
|
this._transport = transport;
|
|
2381
2390
|
this._tableName = tableName;
|
|
@@ -2432,6 +2441,7 @@ var TableSubscription = class {
|
|
|
2432
2441
|
return;
|
|
2433
2442
|
}
|
|
2434
2443
|
try {
|
|
2444
|
+
this._pendingSnapshotRows = [];
|
|
2435
2445
|
const resumeFrom = this._lastVersion > 0 ? this._lastVersion : void 0;
|
|
2436
2446
|
await this._sendSubscribe(resumeFrom);
|
|
2437
2447
|
} catch (error) {
|
|
@@ -2460,7 +2470,13 @@ var TableSubscription = class {
|
|
|
2460
2470
|
}
|
|
2461
2471
|
switch (message.type) {
|
|
2462
2472
|
case "snapshot":
|
|
2463
|
-
this.
|
|
2473
|
+
this._handleSnapshotPage(message);
|
|
2474
|
+
return;
|
|
2475
|
+
case "snapshot_complete":
|
|
2476
|
+
this._handleSnapshotComplete(message);
|
|
2477
|
+
return;
|
|
2478
|
+
case "gap":
|
|
2479
|
+
void this._handleGap(message);
|
|
2464
2480
|
return;
|
|
2465
2481
|
case "change":
|
|
2466
2482
|
this._handleChange(message);
|
|
@@ -2472,9 +2488,13 @@ var TableSubscription = class {
|
|
|
2472
2488
|
return;
|
|
2473
2489
|
}
|
|
2474
2490
|
}
|
|
2475
|
-
|
|
2491
|
+
_handleSnapshotPage(message) {
|
|
2492
|
+
this._pendingSnapshotRows.push(...message.rows);
|
|
2493
|
+
}
|
|
2494
|
+
_handleSnapshotComplete(message) {
|
|
2476
2495
|
this._lastVersion = message.version;
|
|
2477
|
-
const rows =
|
|
2496
|
+
const rows = this._pendingSnapshotRows;
|
|
2497
|
+
this._pendingSnapshotRows = [];
|
|
2478
2498
|
this._onSnapshot?.(rows, message.version);
|
|
2479
2499
|
this._queue.push({
|
|
2480
2500
|
type: "snapshot",
|
|
@@ -2482,6 +2502,16 @@ var TableSubscription = class {
|
|
|
2482
2502
|
version: message.version
|
|
2483
2503
|
});
|
|
2484
2504
|
}
|
|
2505
|
+
async _handleGap(message) {
|
|
2506
|
+
this._pendingSnapshotRows = [];
|
|
2507
|
+
this._lastVersion = message.last_seq;
|
|
2508
|
+
try {
|
|
2509
|
+
await this._sendSubscribe(message.last_seq);
|
|
2510
|
+
} catch (error) {
|
|
2511
|
+
const wrapped = error instanceof Error ? error : new AoudaConnectionError("Subscription gap resume failed");
|
|
2512
|
+
this._notifyError(wrapped);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2485
2515
|
_handleChange(message) {
|
|
2486
2516
|
this._lastVersion = message.version;
|
|
2487
2517
|
const event = {
|
|
@@ -2496,6 +2526,7 @@ var TableSubscription = class {
|
|
|
2496
2526
|
this._queue.push(event);
|
|
2497
2527
|
}
|
|
2498
2528
|
_handleServerError(message) {
|
|
2529
|
+
this._pendingSnapshotRows = [];
|
|
2499
2530
|
const error = new AoudaConnectionError(
|
|
2500
2531
|
`Subscription error (${message.code}): ${message.message}`
|
|
2501
2532
|
);
|
|
@@ -4903,6 +4934,147 @@ var MaterializedQueriesApi = class {
|
|
|
4903
4934
|
}
|
|
4904
4935
|
};
|
|
4905
4936
|
|
|
4937
|
+
// src/named-queries.ts
|
|
4938
|
+
var MAX_NAMED_QUERY_BATCH_SIZE = 32;
|
|
4939
|
+
function raiseDeprecationWarnings(sink, warnings) {
|
|
4940
|
+
if (warnings == null) return;
|
|
4941
|
+
for (const warning of warnings) {
|
|
4942
|
+
if (warning.code !== "NAMED_QUERY_DEPRECATED" && warning.code !== "NAMED_MUTATION_DEPRECATED") {
|
|
4943
|
+
continue;
|
|
4944
|
+
}
|
|
4945
|
+
const sunset = warning.sunsetAt != null ? ` sunsetAt=${warning.sunsetAt}` : "";
|
|
4946
|
+
const hash = warning.hash != null && warning.hash.length > 0 ? ` hash=${warning.hash}` : "";
|
|
4947
|
+
sink({
|
|
4948
|
+
code: warning.code,
|
|
4949
|
+
hash: warning.hash,
|
|
4950
|
+
sunsetAt: warning.sunsetAt,
|
|
4951
|
+
message: `${warning.code}:${hash}${sunset}`.trim()
|
|
4952
|
+
});
|
|
4953
|
+
}
|
|
4954
|
+
}
|
|
4955
|
+
function emptyStats() {
|
|
4956
|
+
return {
|
|
4957
|
+
rowsScanned: 0,
|
|
4958
|
+
rowsReturned: 0,
|
|
4959
|
+
segmentsAccessed: 0,
|
|
4960
|
+
executionMs: 0
|
|
4961
|
+
};
|
|
4962
|
+
}
|
|
4963
|
+
var NamedQueriesApi = class {
|
|
4964
|
+
constructor(transport, database, onWarning) {
|
|
4965
|
+
this.transport = transport;
|
|
4966
|
+
this.database = database;
|
|
4967
|
+
this.onWarning = onWarning;
|
|
4968
|
+
}
|
|
4969
|
+
async execute(hash, args, options) {
|
|
4970
|
+
if (typeof hash !== "string" || hash.trim().length === 0) {
|
|
4971
|
+
throw new Error("Named query hash must be a non-empty string");
|
|
4972
|
+
}
|
|
4973
|
+
const prefix = databasePath2(this.database);
|
|
4974
|
+
const path4 = `${prefix}/named-queries/${encodeURIComponent(hash)}/query?format=columnar`;
|
|
4975
|
+
const response = await this.transport.post(
|
|
4976
|
+
path4,
|
|
4977
|
+
{ args: args ?? {} },
|
|
4978
|
+
{ signal: options?.signal }
|
|
4979
|
+
);
|
|
4980
|
+
const rows = columnarToRows(response);
|
|
4981
|
+
raiseDeprecationWarnings(this.onWarning, response.warnings);
|
|
4982
|
+
return {
|
|
4983
|
+
rows,
|
|
4984
|
+
stats: response.stats,
|
|
4985
|
+
warnings: response.warnings
|
|
4986
|
+
};
|
|
4987
|
+
}
|
|
4988
|
+
async batch(items, options) {
|
|
4989
|
+
if (items.length === 0) {
|
|
4990
|
+
throw new AoudaValidationError(
|
|
4991
|
+
"Named query batch requires a non-empty queries array.",
|
|
4992
|
+
"NAMED_QUERY_BATCH_EMPTY",
|
|
4993
|
+
400
|
|
4994
|
+
);
|
|
4995
|
+
}
|
|
4996
|
+
if (items.length > MAX_NAMED_QUERY_BATCH_SIZE) {
|
|
4997
|
+
throw new AoudaValidationError(
|
|
4998
|
+
`Named query batch exceeds ${MAX_NAMED_QUERY_BATCH_SIZE} elements.`,
|
|
4999
|
+
"NAMED_QUERY_BATCH_TOO_LARGE",
|
|
5000
|
+
400
|
|
5001
|
+
);
|
|
5002
|
+
}
|
|
5003
|
+
const prefix = databasePath2(this.database);
|
|
5004
|
+
const path4 = `${prefix}/named-queries/batch?format=columnar`;
|
|
5005
|
+
const envelope = await this.transport.post(
|
|
5006
|
+
path4,
|
|
5007
|
+
{ queries: items },
|
|
5008
|
+
{ signal: options?.signal }
|
|
5009
|
+
);
|
|
5010
|
+
return (envelope.results ?? []).map((slot) => {
|
|
5011
|
+
if (slot.code != null && slot.code.length > 0) {
|
|
5012
|
+
return {
|
|
5013
|
+
isError: true,
|
|
5014
|
+
code: slot.code,
|
|
5015
|
+
error: slot.error
|
|
5016
|
+
};
|
|
5017
|
+
}
|
|
5018
|
+
const columnar = {
|
|
5019
|
+
columns: slot.columns ?? [],
|
|
5020
|
+
types: slot.types ?? [],
|
|
5021
|
+
data: slot.data ?? [],
|
|
5022
|
+
rowCount: slot.rowCount ?? 0,
|
|
5023
|
+
stats: slot.stats ?? emptyStats(),
|
|
5024
|
+
warnings: slot.warnings
|
|
5025
|
+
};
|
|
5026
|
+
const result = {
|
|
5027
|
+
rows: columnarToRows(columnar),
|
|
5028
|
+
stats: columnar.stats,
|
|
5029
|
+
warnings: slot.warnings
|
|
5030
|
+
};
|
|
5031
|
+
raiseDeprecationWarnings(this.onWarning, slot.warnings);
|
|
5032
|
+
return { isError: false, result };
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
5035
|
+
};
|
|
5036
|
+
var NamedMutationsApi = class {
|
|
5037
|
+
constructor(transport, database, onWarning) {
|
|
5038
|
+
this.transport = transport;
|
|
5039
|
+
this.database = database;
|
|
5040
|
+
this.onWarning = onWarning;
|
|
5041
|
+
}
|
|
5042
|
+
async execute(hash, args) {
|
|
5043
|
+
if (typeof hash !== "string" || hash.trim().length === 0) {
|
|
5044
|
+
throw new Error("Named mutation hash must be a non-empty string");
|
|
5045
|
+
}
|
|
5046
|
+
const prefix = databasePath2(this.database);
|
|
5047
|
+
const path4 = `${prefix}/named-mutations/${encodeURIComponent(hash)}/execute`;
|
|
5048
|
+
const wire = await this.transport.post(path4, {
|
|
5049
|
+
args: args ?? {}
|
|
5050
|
+
});
|
|
5051
|
+
let op = "unknown";
|
|
5052
|
+
let rowsAffected = 0;
|
|
5053
|
+
if (wire.rowsInserted != null) {
|
|
5054
|
+
op = "insert";
|
|
5055
|
+
rowsAffected = wire.rowsInserted;
|
|
5056
|
+
} else if (wire.rowsUpdated != null) {
|
|
5057
|
+
op = "update";
|
|
5058
|
+
rowsAffected = wire.rowsUpdated;
|
|
5059
|
+
} else if (wire.rowsDeleted != null) {
|
|
5060
|
+
op = "delete";
|
|
5061
|
+
rowsAffected = wire.rowsDeleted;
|
|
5062
|
+
}
|
|
5063
|
+
raiseDeprecationWarnings(this.onWarning, wire.warnings);
|
|
5064
|
+
const returning = wire.rows == null ? void 0 : {
|
|
5065
|
+
rows: columnarToRows(wire.rows),
|
|
5066
|
+
stats: wire.rows.stats,
|
|
5067
|
+
warnings: wire.rows.warnings
|
|
5068
|
+
};
|
|
5069
|
+
return {
|
|
5070
|
+
op,
|
|
5071
|
+
rowsAffected,
|
|
5072
|
+
returning,
|
|
5073
|
+
warnings: wire.warnings
|
|
5074
|
+
};
|
|
5075
|
+
}
|
|
5076
|
+
};
|
|
5077
|
+
|
|
4906
5078
|
// src/streaming/websocket-transport.ts
|
|
4907
5079
|
import { decode as decodeMessagePack, encode as encodeMessagePack } from "@msgpack/msgpack";
|
|
4908
5080
|
var DEFAULT_PING_INTERVAL_MS = 2e4;
|
|
@@ -5665,6 +5837,19 @@ var AoudaClient = class {
|
|
|
5665
5837
|
this.transport,
|
|
5666
5838
|
this.database
|
|
5667
5839
|
);
|
|
5840
|
+
const onNamedArtifactWarning = options.onNamedArtifactWarning ?? ((warning) => {
|
|
5841
|
+
console.warn(warning.message);
|
|
5842
|
+
});
|
|
5843
|
+
this._namedQueries = new NamedQueriesApi(
|
|
5844
|
+
this.transport,
|
|
5845
|
+
this.database,
|
|
5846
|
+
onNamedArtifactWarning
|
|
5847
|
+
);
|
|
5848
|
+
this._namedMutations = new NamedMutationsApi(
|
|
5849
|
+
this.transport,
|
|
5850
|
+
this.database,
|
|
5851
|
+
onNamedArtifactWarning
|
|
5852
|
+
);
|
|
5668
5853
|
}
|
|
5669
5854
|
/**
|
|
5670
5855
|
* Connects to the Aouda server.
|
|
@@ -5807,6 +5992,18 @@ var AoudaClient = class {
|
|
|
5807
5992
|
get materializedQueries() {
|
|
5808
5993
|
return this._materializedQueries;
|
|
5809
5994
|
}
|
|
5995
|
+
/**
|
|
5996
|
+
* Hash-only named-query execute and batch. Names are codegen aliases (D-5).
|
|
5997
|
+
*/
|
|
5998
|
+
get namedQueries() {
|
|
5999
|
+
return this._namedQueries;
|
|
6000
|
+
}
|
|
6001
|
+
/**
|
|
6002
|
+
* Hash-only named-mutation execute. No batch.
|
|
6003
|
+
*/
|
|
6004
|
+
get namedMutations() {
|
|
6005
|
+
return this._namedMutations;
|
|
6006
|
+
}
|
|
5810
6007
|
/**
|
|
5811
6008
|
* Access auth operations (signUp, signIn, signOut, refresh, me, changePassword).
|
|
5812
6009
|
* @returns The auth API.
|
|
@@ -5954,7 +6151,7 @@ Usage:
|
|
|
5954
6151
|
npx @aouda/client schema <command> [options]
|
|
5955
6152
|
|
|
5956
6153
|
Commands:
|
|
5957
|
-
generate Fetch schema from Aouda server and output TypeScript types
|
|
6154
|
+
generate Fetch schema from Aouda server and output TypeScript types (tables + named query/mutation hashes)
|
|
5958
6155
|
schema Schema management (diff, apply, export, validate, history, seed)
|
|
5959
6156
|
diff Show migration plan (desired vs current)
|
|
5960
6157
|
apply Apply schema (use --allow-destructive for drops; --dry-run to preview)
|