@electric-sql/client 1.3.1 → 1.4.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/cjs/index.cjs +109 -6
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +65 -1
- package/dist/index.browser.mjs +3 -3
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.legacy-esm.js +107 -6
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +107 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +39 -2
- package/src/constants.ts +4 -0
- package/src/expression-compiler.ts +132 -0
- package/src/index.ts +1 -0
- package/src/types.ts +28 -0
package/dist/index.mjs
CHANGED
|
@@ -467,6 +467,8 @@ var SUBSET_PARAM_LIMIT = `subset__limit`;
|
|
|
467
467
|
var SUBSET_PARAM_OFFSET = `subset__offset`;
|
|
468
468
|
var SUBSET_PARAM_ORDER_BY = `subset__order_by`;
|
|
469
469
|
var SUBSET_PARAM_WHERE_PARAMS = `subset__params`;
|
|
470
|
+
var SUBSET_PARAM_WHERE_EXPR = `subset__where_expr`;
|
|
471
|
+
var SUBSET_PARAM_ORDER_BY_EXPR = `subset__order_by_expr`;
|
|
470
472
|
var ELECTRIC_PROTOCOL_QUERY_PARAMS = [
|
|
471
473
|
LIVE_QUERY_PARAM,
|
|
472
474
|
LIVE_SSE_QUERY_PARAM,
|
|
@@ -479,7 +481,9 @@ var ELECTRIC_PROTOCOL_QUERY_PARAMS = [
|
|
|
479
481
|
SUBSET_PARAM_LIMIT,
|
|
480
482
|
SUBSET_PARAM_OFFSET,
|
|
481
483
|
SUBSET_PARAM_ORDER_BY,
|
|
482
|
-
SUBSET_PARAM_WHERE_PARAMS
|
|
484
|
+
SUBSET_PARAM_WHERE_PARAMS,
|
|
485
|
+
SUBSET_PARAM_WHERE_EXPR,
|
|
486
|
+
SUBSET_PARAM_ORDER_BY_EXPR
|
|
483
487
|
];
|
|
484
488
|
|
|
485
489
|
// src/fetch.ts
|
|
@@ -766,6 +770,81 @@ function chainAborter(aborter, sourceSignal) {
|
|
|
766
770
|
function noop() {
|
|
767
771
|
}
|
|
768
772
|
|
|
773
|
+
// src/expression-compiler.ts
|
|
774
|
+
function compileExpression(expr, columnMapper) {
|
|
775
|
+
switch (expr.type) {
|
|
776
|
+
case `ref`: {
|
|
777
|
+
const mappedColumn = columnMapper ? columnMapper(expr.column) : expr.column;
|
|
778
|
+
return quoteIdentifier(mappedColumn);
|
|
779
|
+
}
|
|
780
|
+
case `val`:
|
|
781
|
+
return `$${expr.paramIndex}`;
|
|
782
|
+
case `func`:
|
|
783
|
+
return compileFunction(expr, columnMapper);
|
|
784
|
+
default: {
|
|
785
|
+
const _exhaustive = expr;
|
|
786
|
+
throw new Error(`Unknown expression type: ${JSON.stringify(_exhaustive)}`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function compileFunction(expr, columnMapper) {
|
|
791
|
+
const args = expr.args.map((arg) => compileExpression(arg, columnMapper));
|
|
792
|
+
switch (expr.name) {
|
|
793
|
+
// Binary comparison operators
|
|
794
|
+
case `eq`:
|
|
795
|
+
return `${args[0]} = ${args[1]}`;
|
|
796
|
+
case `gt`:
|
|
797
|
+
return `${args[0]} > ${args[1]}`;
|
|
798
|
+
case `gte`:
|
|
799
|
+
return `${args[0]} >= ${args[1]}`;
|
|
800
|
+
case `lt`:
|
|
801
|
+
return `${args[0]} < ${args[1]}`;
|
|
802
|
+
case `lte`:
|
|
803
|
+
return `${args[0]} <= ${args[1]}`;
|
|
804
|
+
// Logical operators
|
|
805
|
+
case `and`:
|
|
806
|
+
return args.map((a) => `(${a})`).join(` AND `);
|
|
807
|
+
case `or`:
|
|
808
|
+
return args.map((a) => `(${a})`).join(` OR `);
|
|
809
|
+
case `not`:
|
|
810
|
+
return `NOT (${args[0]})`;
|
|
811
|
+
// Special operators
|
|
812
|
+
case `in`:
|
|
813
|
+
return `${args[0]} = ANY(${args[1]})`;
|
|
814
|
+
case `like`:
|
|
815
|
+
return `${args[0]} LIKE ${args[1]}`;
|
|
816
|
+
case `ilike`:
|
|
817
|
+
return `${args[0]} ILIKE ${args[1]}`;
|
|
818
|
+
case `isNull`:
|
|
819
|
+
case `isUndefined`:
|
|
820
|
+
return `${args[0]} IS NULL`;
|
|
821
|
+
// String functions
|
|
822
|
+
case `upper`:
|
|
823
|
+
return `UPPER(${args[0]})`;
|
|
824
|
+
case `lower`:
|
|
825
|
+
return `LOWER(${args[0]})`;
|
|
826
|
+
case `length`:
|
|
827
|
+
return `LENGTH(${args[0]})`;
|
|
828
|
+
case `concat`:
|
|
829
|
+
return `CONCAT(${args.join(`, `)})`;
|
|
830
|
+
// Other functions
|
|
831
|
+
case `coalesce`:
|
|
832
|
+
return `COALESCE(${args.join(`, `)})`;
|
|
833
|
+
default:
|
|
834
|
+
throw new Error(`Unknown function: ${expr.name}`);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
function compileOrderBy(clauses, columnMapper) {
|
|
838
|
+
return clauses.map((clause) => {
|
|
839
|
+
const mappedColumn = columnMapper ? columnMapper(clause.column) : clause.column;
|
|
840
|
+
let sql = quoteIdentifier(mappedColumn);
|
|
841
|
+
if (clause.direction === `desc`) sql += ` DESC`;
|
|
842
|
+
if (clause.nulls === `first`) sql += ` NULLS FIRST`;
|
|
843
|
+
if (clause.nulls === `last`) sql += ` NULLS LAST`;
|
|
844
|
+
return sql;
|
|
845
|
+
}).join(`, `);
|
|
846
|
+
}
|
|
847
|
+
|
|
769
848
|
// src/client.ts
|
|
770
849
|
import {
|
|
771
850
|
fetchEventSource
|
|
@@ -1433,7 +1512,7 @@ requestShape_fn = async function() {
|
|
|
1433
1512
|
return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
|
|
1434
1513
|
};
|
|
1435
1514
|
constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
|
|
1436
|
-
var _a, _b, _c, _d;
|
|
1515
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1437
1516
|
const [requestHeaders, params] = await Promise.all([
|
|
1438
1517
|
resolveHeaders(this.options.headers),
|
|
1439
1518
|
this.options.params ? toInternalParams(convertWhereParamsToObj(this.options.params)) : void 0
|
|
@@ -1478,10 +1557,20 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
|
|
|
1478
1557
|
}
|
|
1479
1558
|
}
|
|
1480
1559
|
if (subsetParams) {
|
|
1481
|
-
if (subsetParams.
|
|
1560
|
+
if (subsetParams.whereExpr) {
|
|
1561
|
+
const compiledWhere = compileExpression(
|
|
1562
|
+
subsetParams.whereExpr,
|
|
1563
|
+
(_c = this.options.columnMapper) == null ? void 0 : _c.encode
|
|
1564
|
+
);
|
|
1565
|
+
setQueryParam(fetchUrl, SUBSET_PARAM_WHERE, compiledWhere);
|
|
1566
|
+
fetchUrl.searchParams.set(
|
|
1567
|
+
SUBSET_PARAM_WHERE_EXPR,
|
|
1568
|
+
JSON.stringify(subsetParams.whereExpr)
|
|
1569
|
+
);
|
|
1570
|
+
} else if (subsetParams.where && typeof subsetParams.where === `string`) {
|
|
1482
1571
|
const encodedWhere = encodeWhereClause(
|
|
1483
1572
|
subsetParams.where,
|
|
1484
|
-
(
|
|
1573
|
+
(_d = this.options.columnMapper) == null ? void 0 : _d.encode
|
|
1485
1574
|
);
|
|
1486
1575
|
setQueryParam(fetchUrl, SUBSET_PARAM_WHERE, encodedWhere);
|
|
1487
1576
|
}
|
|
@@ -1494,10 +1583,20 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
|
|
|
1494
1583
|
setQueryParam(fetchUrl, SUBSET_PARAM_LIMIT, subsetParams.limit);
|
|
1495
1584
|
if (subsetParams.offset)
|
|
1496
1585
|
setQueryParam(fetchUrl, SUBSET_PARAM_OFFSET, subsetParams.offset);
|
|
1497
|
-
if (subsetParams.
|
|
1586
|
+
if (subsetParams.orderByExpr) {
|
|
1587
|
+
const compiledOrderBy = compileOrderBy(
|
|
1588
|
+
subsetParams.orderByExpr,
|
|
1589
|
+
(_e = this.options.columnMapper) == null ? void 0 : _e.encode
|
|
1590
|
+
);
|
|
1591
|
+
setQueryParam(fetchUrl, SUBSET_PARAM_ORDER_BY, compiledOrderBy);
|
|
1592
|
+
fetchUrl.searchParams.set(
|
|
1593
|
+
SUBSET_PARAM_ORDER_BY_EXPR,
|
|
1594
|
+
JSON.stringify(subsetParams.orderByExpr)
|
|
1595
|
+
);
|
|
1596
|
+
} else if (subsetParams.orderBy && typeof subsetParams.orderBy === `string`) {
|
|
1498
1597
|
const encodedOrderBy = encodeWhereClause(
|
|
1499
1598
|
subsetParams.orderBy,
|
|
1500
|
-
(
|
|
1599
|
+
(_f = this.options.columnMapper) == null ? void 0 : _f.encode
|
|
1501
1600
|
);
|
|
1502
1601
|
setQueryParam(fetchUrl, SUBSET_PARAM_ORDER_BY, encodedOrderBy);
|
|
1503
1602
|
}
|
|
@@ -2078,6 +2177,8 @@ export {
|
|
|
2078
2177
|
Shape,
|
|
2079
2178
|
ShapeStream,
|
|
2080
2179
|
camelToSnake,
|
|
2180
|
+
compileExpression,
|
|
2181
|
+
compileOrderBy,
|
|
2081
2182
|
createColumnMapper,
|
|
2082
2183
|
isChangeMessage,
|
|
2083
2184
|
isControlMessage,
|