@aouda/client 0.1.10 → 0.1.12
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 +162 -23
- 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 +162 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/{client-Dgenr-cE.d.cts → client-Q83x0Mz9.d.cts} +53 -7
- package/dist/{client-Dgenr-cE.d.ts → client-Q83x0Mz9.d.ts} +53 -7
- package/dist/index.cjs +162 -23
- 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 +162 -23
- 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.12",
|
|
396
396
|
description: "Official TypeScript/JavaScript client library for Aouda",
|
|
397
397
|
type: "module",
|
|
398
398
|
main: "./dist/index.cjs",
|
|
@@ -630,6 +630,7 @@ var AuthHandler = class {
|
|
|
630
630
|
this._tokenExpiry = null;
|
|
631
631
|
this._authenticated = false;
|
|
632
632
|
this._refreshPromise = null;
|
|
633
|
+
this._onAccessTokenRefreshed = null;
|
|
633
634
|
this._serverUrl = serverUrl.replace(/\/+$/, "");
|
|
634
635
|
this._timeout = timeout;
|
|
635
636
|
this._authBasePath = config.basePath;
|
|
@@ -879,10 +880,16 @@ var AuthHandler = class {
|
|
|
879
880
|
const thresholdSeconds = this._refreshThresholdMs / 1e3;
|
|
880
881
|
return this._tokenExpiry <= nowSeconds + thresholdSeconds;
|
|
881
882
|
}
|
|
883
|
+
setOnAccessTokenRefreshed(handler) {
|
|
884
|
+
this._onAccessTokenRefreshed = handler;
|
|
885
|
+
}
|
|
882
886
|
async _doRefresh() {
|
|
883
887
|
try {
|
|
884
888
|
const result = await this.callRefreshEndpoint();
|
|
885
889
|
this.handleSignInResult(result);
|
|
890
|
+
if (result.accessToken) {
|
|
891
|
+
this._onAccessTokenRefreshed?.(result.accessToken);
|
|
892
|
+
}
|
|
886
893
|
return true;
|
|
887
894
|
} catch {
|
|
888
895
|
return false;
|
|
@@ -2378,20 +2385,22 @@ var AsyncEventQueue = class {
|
|
|
2378
2385
|
}
|
|
2379
2386
|
};
|
|
2380
2387
|
var TableSubscription = class {
|
|
2381
|
-
constructor(transport,
|
|
2388
|
+
constructor(transport, identity, options = {}, onWarnings) {
|
|
2382
2389
|
this._queue = new AsyncEventQueue();
|
|
2383
2390
|
this._active = true;
|
|
2384
2391
|
this._started = false;
|
|
2385
2392
|
this._startPromise = null;
|
|
2386
2393
|
this._lastVersion = 0;
|
|
2387
2394
|
this._pendingSnapshotRows = [];
|
|
2395
|
+
this._forceFreshSubscribe = false;
|
|
2388
2396
|
this.id = createStreamingId("sub");
|
|
2389
2397
|
this._transport = transport;
|
|
2390
|
-
this.
|
|
2391
|
-
this._baseFilter = baseFilter;
|
|
2398
|
+
this._identity = identity;
|
|
2392
2399
|
this._onSnapshot = options.onSnapshot;
|
|
2393
2400
|
this._onChange = options.onChange;
|
|
2394
2401
|
this._onError = options.onError;
|
|
2402
|
+
this._onWarnings = onWarnings;
|
|
2403
|
+
this._conflate = options.conflate;
|
|
2395
2404
|
this._reconnectHandlerKey = `${this.id}::reconnect`;
|
|
2396
2405
|
}
|
|
2397
2406
|
get lastVersion() {
|
|
@@ -2442,7 +2451,8 @@ var TableSubscription = class {
|
|
|
2442
2451
|
}
|
|
2443
2452
|
try {
|
|
2444
2453
|
this._pendingSnapshotRows = [];
|
|
2445
|
-
const resumeFrom = this._lastVersion
|
|
2454
|
+
const resumeFrom = this._forceFreshSubscribe || this._lastVersion <= 0 ? void 0 : this._lastVersion;
|
|
2455
|
+
this._forceFreshSubscribe = false;
|
|
2446
2456
|
await this._sendSubscribe(resumeFrom);
|
|
2447
2457
|
} catch (error) {
|
|
2448
2458
|
const wrapped = error instanceof Error ? error : new AoudaConnectionError("Subscription reconnect failed");
|
|
@@ -2452,16 +2462,25 @@ var TableSubscription = class {
|
|
|
2452
2462
|
async _sendSubscribe(resumeFrom) {
|
|
2453
2463
|
const message = {
|
|
2454
2464
|
type: "subscribe",
|
|
2455
|
-
id: this.id
|
|
2456
|
-
target: this._tableName
|
|
2465
|
+
id: this.id
|
|
2457
2466
|
};
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2467
|
+
if (this._identity.kind === "named") {
|
|
2468
|
+
message.hash = this._identity.hash;
|
|
2469
|
+
if (this._identity.args !== void 0) {
|
|
2470
|
+
message.args = this._identity.args;
|
|
2471
|
+
}
|
|
2472
|
+
} else {
|
|
2473
|
+
message.target = this._identity.target;
|
|
2474
|
+
if (this._identity.filter !== void 0) {
|
|
2475
|
+
message.filter = this._identity.filter;
|
|
2476
|
+
}
|
|
2461
2477
|
}
|
|
2462
2478
|
if (resumeFrom !== void 0) {
|
|
2463
2479
|
message.resume_from = resumeFrom;
|
|
2464
2480
|
}
|
|
2481
|
+
if (this._conflate !== void 0) {
|
|
2482
|
+
message.conflate = this._conflate;
|
|
2483
|
+
}
|
|
2465
2484
|
await this._transport.send(message);
|
|
2466
2485
|
}
|
|
2467
2486
|
_handleMessage(message) {
|
|
@@ -2493,6 +2512,9 @@ var TableSubscription = class {
|
|
|
2493
2512
|
}
|
|
2494
2513
|
_handleSnapshotComplete(message) {
|
|
2495
2514
|
this._lastVersion = message.version;
|
|
2515
|
+
if (message.warnings != null && message.warnings.length > 0) {
|
|
2516
|
+
this._onWarnings?.(message.warnings);
|
|
2517
|
+
}
|
|
2496
2518
|
const rows = this._pendingSnapshotRows;
|
|
2497
2519
|
this._pendingSnapshotRows = [];
|
|
2498
2520
|
this._onSnapshot?.(rows, message.version);
|
|
@@ -2522,10 +2544,19 @@ var TableSubscription = class {
|
|
|
2522
2544
|
key: message.key,
|
|
2523
2545
|
version: message.version
|
|
2524
2546
|
};
|
|
2547
|
+
if (message.values_skipped !== void 0) {
|
|
2548
|
+
event.values_skipped = message.values_skipped;
|
|
2549
|
+
}
|
|
2525
2550
|
this._onChange?.(event);
|
|
2526
2551
|
this._queue.push(event);
|
|
2527
2552
|
}
|
|
2528
2553
|
_handleServerError(message) {
|
|
2554
|
+
if (message.code === "SLOW_CONSUMER") {
|
|
2555
|
+
this._pendingSnapshotRows = [];
|
|
2556
|
+
this._lastVersion = 0;
|
|
2557
|
+
this._forceFreshSubscribe = true;
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2529
2560
|
this._pendingSnapshotRows = [];
|
|
2530
2561
|
const error = new AoudaConnectionError(
|
|
2531
2562
|
`Subscription error (${message.code}): ${message.message}`
|
|
@@ -3233,16 +3264,16 @@ var TableQuery = class _TableQuery {
|
|
|
3233
3264
|
const whereClause = this.buildWhereClause();
|
|
3234
3265
|
const queryFilter = buildSubscriptionFilter(whereClause);
|
|
3235
3266
|
const mergedFilter = mergeFilterObjects(queryFilter, options.filter);
|
|
3236
|
-
const subscription = new TableSubscription(
|
|
3237
|
-
|
|
3238
|
-
this.tableName,
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
);
|
|
3267
|
+
const subscription = new TableSubscription(wsTransport, {
|
|
3268
|
+
kind: "table",
|
|
3269
|
+
target: this.tableName,
|
|
3270
|
+
filter: mergedFilter
|
|
3271
|
+
}, {
|
|
3272
|
+
onSnapshot: options.onSnapshot,
|
|
3273
|
+
onChange: options.onChange,
|
|
3274
|
+
onError: options.onError,
|
|
3275
|
+
conflate: options.conflate
|
|
3276
|
+
});
|
|
3246
3277
|
subscription.start();
|
|
3247
3278
|
return subscription;
|
|
3248
3279
|
}
|
|
@@ -3828,10 +3859,84 @@ function serializeUpdateValue(col, val) {
|
|
|
3828
3859
|
else: toNode(cond.else)
|
|
3829
3860
|
};
|
|
3830
3861
|
}
|
|
3862
|
+
if ("$upper" in val) {
|
|
3863
|
+
return { type: "call", fn: "upper", args: [unaryCallArg(col, val.$upper)] };
|
|
3864
|
+
}
|
|
3865
|
+
if ("$lower" in val) {
|
|
3866
|
+
return { type: "call", fn: "lower", args: [unaryCallArg(col, val.$lower)] };
|
|
3867
|
+
}
|
|
3868
|
+
if ("$trim" in val) {
|
|
3869
|
+
return { type: "call", fn: "trim", args: [unaryCallArg(col, val.$trim)] };
|
|
3870
|
+
}
|
|
3871
|
+
if ("$concat" in val) {
|
|
3872
|
+
const parts = val.$concat;
|
|
3873
|
+
return {
|
|
3874
|
+
type: "call",
|
|
3875
|
+
fn: "concat",
|
|
3876
|
+
args: parts.map((p) => valueToExprNode(p))
|
|
3877
|
+
};
|
|
3878
|
+
}
|
|
3879
|
+
if ("$substring" in val) {
|
|
3880
|
+
const spec = val.$substring;
|
|
3881
|
+
if (Array.isArray(spec)) {
|
|
3882
|
+
return {
|
|
3883
|
+
type: "call",
|
|
3884
|
+
fn: "substring",
|
|
3885
|
+
args: [{ type: "colRef", col }, ...spec.map((p) => valueToExprNode(p))]
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
return {
|
|
3889
|
+
type: "call",
|
|
3890
|
+
fn: "substring",
|
|
3891
|
+
args: [{ type: "colRef", col }, { type: "literal", value: spec }]
|
|
3892
|
+
};
|
|
3893
|
+
}
|
|
3894
|
+
if ("$round" in val) {
|
|
3895
|
+
return {
|
|
3896
|
+
type: "call",
|
|
3897
|
+
fn: "round",
|
|
3898
|
+
args: [
|
|
3899
|
+
{ type: "colRef", col },
|
|
3900
|
+
{ type: "literal", value: val.$round }
|
|
3901
|
+
]
|
|
3902
|
+
};
|
|
3903
|
+
}
|
|
3904
|
+
if ("$roundTo" in val) {
|
|
3905
|
+
return {
|
|
3906
|
+
type: "call",
|
|
3907
|
+
fn: "roundTo",
|
|
3908
|
+
args: [
|
|
3909
|
+
{ type: "colRef", col },
|
|
3910
|
+
{ type: "literal", value: val.$roundTo }
|
|
3911
|
+
]
|
|
3912
|
+
};
|
|
3913
|
+
}
|
|
3914
|
+
if ("$cast" in val) {
|
|
3915
|
+
return {
|
|
3916
|
+
type: "call",
|
|
3917
|
+
fn: "cast",
|
|
3918
|
+
args: [
|
|
3919
|
+
{ type: "colRef", col },
|
|
3920
|
+
{ type: "literal", value: val.$cast }
|
|
3921
|
+
]
|
|
3922
|
+
};
|
|
3923
|
+
}
|
|
3831
3924
|
throw new Error(
|
|
3832
3925
|
`Unknown expression operator in update() for column '${col}': ${JSON.stringify(val)}`
|
|
3833
3926
|
);
|
|
3834
3927
|
}
|
|
3928
|
+
function unaryCallArg(col, operand) {
|
|
3929
|
+
if (operand === true || operand === 1) {
|
|
3930
|
+
return { type: "colRef", col };
|
|
3931
|
+
}
|
|
3932
|
+
return valueToExprNode(operand);
|
|
3933
|
+
}
|
|
3934
|
+
function valueToExprNode(v) {
|
|
3935
|
+
if (typeof v === "string" && v.startsWith("$")) {
|
|
3936
|
+
return { type: "colRef", col: v.slice(1) };
|
|
3937
|
+
}
|
|
3938
|
+
return { type: "literal", value: v };
|
|
3939
|
+
}
|
|
3835
3940
|
|
|
3836
3941
|
// src/tables.ts
|
|
3837
3942
|
function validateNonEmptyString(value, name) {
|
|
@@ -4961,10 +5066,11 @@ function emptyStats() {
|
|
|
4961
5066
|
};
|
|
4962
5067
|
}
|
|
4963
5068
|
var NamedQueriesApi = class {
|
|
4964
|
-
constructor(transport, database, onWarning) {
|
|
5069
|
+
constructor(transport, database, onWarning, getStreamingTransport) {
|
|
4965
5070
|
this.transport = transport;
|
|
4966
5071
|
this.database = database;
|
|
4967
5072
|
this.onWarning = onWarning;
|
|
5073
|
+
this.getStreamingTransport = getStreamingTransport;
|
|
4968
5074
|
}
|
|
4969
5075
|
async execute(hash, args, options) {
|
|
4970
5076
|
if (typeof hash !== "string" || hash.trim().length === 0) {
|
|
@@ -5032,6 +5138,26 @@ var NamedQueriesApi = class {
|
|
|
5032
5138
|
return { isError: false, result };
|
|
5033
5139
|
});
|
|
5034
5140
|
}
|
|
5141
|
+
subscribe(hash, args, options = {}) {
|
|
5142
|
+
if (typeof hash !== "string" || hash.trim().length === 0) {
|
|
5143
|
+
throw new Error("Named query hash must be a non-empty string");
|
|
5144
|
+
}
|
|
5145
|
+
const subscription = new TableSubscription(
|
|
5146
|
+
this.getStreamingTransport(),
|
|
5147
|
+
{ kind: "named", hash, args },
|
|
5148
|
+
{
|
|
5149
|
+
onSnapshot: options.onSnapshot,
|
|
5150
|
+
onChange: options.onChange,
|
|
5151
|
+
onError: options.onError,
|
|
5152
|
+
conflate: options.conflate
|
|
5153
|
+
},
|
|
5154
|
+
(warnings) => {
|
|
5155
|
+
raiseDeprecationWarnings(this.onWarning, warnings);
|
|
5156
|
+
}
|
|
5157
|
+
);
|
|
5158
|
+
subscription.start();
|
|
5159
|
+
return subscription;
|
|
5160
|
+
}
|
|
5035
5161
|
};
|
|
5036
5162
|
var NamedMutationsApi = class {
|
|
5037
5163
|
constructor(transport, database, onWarning) {
|
|
@@ -5099,6 +5225,7 @@ var WebSocketTransport = class {
|
|
|
5099
5225
|
// Resolved/rejected when the auth handshake completes.
|
|
5100
5226
|
this._authResolve = null;
|
|
5101
5227
|
this._authReject = null;
|
|
5228
|
+
this._handshakeComplete = false;
|
|
5102
5229
|
this._serverUrl = serverUrl;
|
|
5103
5230
|
this._database = database;
|
|
5104
5231
|
this._authHandler = options.authHandler;
|
|
@@ -5108,6 +5235,11 @@ var WebSocketTransport = class {
|
|
|
5108
5235
|
this._maxMissedHeartbeats = options.maxMissedHeartbeats ?? DEFAULT_MAX_MISSED_HEARTBEATS;
|
|
5109
5236
|
this._enableCompression = options.enableCompression ?? true;
|
|
5110
5237
|
this._wireMode = options.wireMode ?? "json";
|
|
5238
|
+
this._authHandler?.setOnAccessTokenRefreshed((token) => {
|
|
5239
|
+
if (this._handshakeComplete && this._ws?.readyState === WS_READY_STATE_OPEN) {
|
|
5240
|
+
void this.send({ type: "re_auth", token });
|
|
5241
|
+
}
|
|
5242
|
+
});
|
|
5111
5243
|
}
|
|
5112
5244
|
// ─── Public API ────────────────────────────────────────────────────────────
|
|
5113
5245
|
/** Latest version number from the most recent server `heartbeat` message. */
|
|
@@ -5280,6 +5412,7 @@ var WebSocketTransport = class {
|
|
|
5280
5412
|
const resolve4 = this._authResolve;
|
|
5281
5413
|
this._authResolve = null;
|
|
5282
5414
|
this._authReject = null;
|
|
5415
|
+
this._handshakeComplete = true;
|
|
5283
5416
|
if (resolve4) resolve4();
|
|
5284
5417
|
break;
|
|
5285
5418
|
}
|
|
@@ -5306,10 +5439,15 @@ var WebSocketTransport = class {
|
|
|
5306
5439
|
break;
|
|
5307
5440
|
}
|
|
5308
5441
|
const id = "id" in msg ? msg.id : void 0;
|
|
5309
|
-
if (id !== void 0 && id !== null) {
|
|
5442
|
+
if (id !== void 0 && id !== null && id !== "") {
|
|
5310
5443
|
this._handlers.get(id)?.(msg);
|
|
5311
5444
|
} else {
|
|
5312
5445
|
this._handlers.get("__global__")?.(msg);
|
|
5446
|
+
for (const [key, handler] of this._handlers) {
|
|
5447
|
+
if (key !== "__global__") {
|
|
5448
|
+
handler(msg);
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5313
5451
|
}
|
|
5314
5452
|
}
|
|
5315
5453
|
// ─── Internal: reconnect ──────────────────────────────────────────────────
|
|
@@ -5843,7 +5981,8 @@ var AoudaClient = class {
|
|
|
5843
5981
|
this._namedQueries = new NamedQueriesApi(
|
|
5844
5982
|
this.transport,
|
|
5845
5983
|
this.database,
|
|
5846
|
-
onNamedArtifactWarning
|
|
5984
|
+
onNamedArtifactWarning,
|
|
5985
|
+
() => this._getOrCreateWebSocketTransport()
|
|
5847
5986
|
);
|
|
5848
5987
|
this._namedMutations = new NamedMutationsApi(
|
|
5849
5988
|
this.transport,
|