Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@electric-sql/client

Package Overview
Dependencies
Maintainers
3
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@electric-sql/client - npm Package Compare versions

Comparing version 0.8.0 to 0.9.0

77

dist/index.d.ts

@@ -120,3 +120,2 @@ /**

declare const DATABASE_ID_QUERY_PARAM = "database_id";
declare const COLUMNS_QUERY_PARAM = "columns";

@@ -132,36 +131,15 @@ declare const LIVE_CACHE_BUSTER_QUERY_PARAM = "cursor";

type Replica = `full` | `default`;
type ReservedParamKeys = typeof DATABASE_ID_QUERY_PARAM | typeof COLUMNS_QUERY_PARAM | typeof LIVE_CACHE_BUSTER_QUERY_PARAM | typeof SHAPE_HANDLE_QUERY_PARAM | typeof LIVE_QUERY_PARAM | typeof OFFSET_QUERY_PARAM | typeof TABLE_QUERY_PARAM | typeof WHERE_QUERY_PARAM | typeof REPLICA_PARAM;
type ParamsRecord = Omit<Record<string, string>, ReservedParamKeys>;
type RetryOpts = {
params?: ParamsRecord;
headers?: Record<string, string>;
};
type ShapeStreamErrorHandler = (error: Error) => void | RetryOpts | Promise<void | RetryOpts>;
/**
* Options for constructing a ShapeStream.
* PostgreSQL-specific shape parameters that can be provided externally
*/
interface ShapeStreamOptions<T = never> {
/**
* The full URL to where the Shape is served. This can either be the Electric server
* directly or a proxy. E.g. for a local Electric instance, you might set `http://localhost:3000/v1/shape`
*/
url: string;
/**
* Which database to use.
* This is optional unless Electric is used with multiple databases.
*/
databaseId?: string;
/**
* The root table for the shape. Passed as a query parameter. Not required if you set the table in your proxy.
*/
type PostgresParams = {
/** The root table for the shape. Not required if you set the table in your proxy. */
table?: string;
/**
* The where clauses for the shape.
*/
where?: string;
/**
* The columns to include in the shape.
* Must include primary keys, and can only inlude valid columns.
* Must include primary keys, and can only include valid columns.
*/
columns?: string[];
/** The where clauses for the shape */
where?: string;
/**

@@ -174,7 +152,30 @@ * If `replica` is `default` (the default) then Electric will only send the

*
* Setting `replica` to `full` will obviously result in higher bandwidth
* usage and so is not recommended.
* Setting `replica` to `full` will result in higher bandwidth
* usage and so is not generally recommended.
*/
replica?: Replica;
};
type ReservedParamKeys = typeof COLUMNS_QUERY_PARAM | typeof LIVE_CACHE_BUSTER_QUERY_PARAM | typeof SHAPE_HANDLE_QUERY_PARAM | typeof LIVE_QUERY_PARAM | typeof OFFSET_QUERY_PARAM | typeof TABLE_QUERY_PARAM | typeof WHERE_QUERY_PARAM | typeof REPLICA_PARAM;
/**
* External params type - what users provide.
* Includes documented PostgreSQL params and allows string or string[] values for any additional params.
*/
type ExternalParamsRecord = Partial<PostgresParams> & {
[K in string as K extends ReservedParamKeys ? never : K]: string | string[];
};
type RetryOpts = {
params?: ExternalParamsRecord;
headers?: Record<string, string>;
};
type ShapeStreamErrorHandler = (error: Error) => void | RetryOpts | Promise<void | RetryOpts>;
/**
* Options for constructing a ShapeStream.
*/
interface ShapeStreamOptions<T = never> {
/**
* The full URL to where the Shape is served. This can either be the Electric server
* directly or a proxy. E.g. for a local Electric instance, you might set `http://localhost:3000/v1/shape`
*/
url: string;
/**
* The "offset" on the shape log. This is typically not set as the ShapeStream

@@ -202,5 +203,8 @@ * will handle this automatically. A common scenario where you might pass an offset

* Note: You cannot use Electric's reserved parameter names
* (table, where, columns, offset, handle, live, cursor, database_id, replica).
* (offset, handle, live, cursor).
*
* PostgreSQL-specific options like table, where, columns, and replica
* should be specified here.
*/
params?: ParamsRecord;
params?: ExternalParamsRecord;
/**

@@ -218,3 +222,3 @@ * Automatically fetch updates to the Shape. If you just want to sync the current

* This is optional, when it is not provided any shapestream errors will be thrown.
* If the function is provided and returns an object containing parameters and/or headers
* If the function returns an object containing parameters and/or headers
* the shapestream will apply those changes and try syncing again.

@@ -308,3 +312,8 @@ * If the function returns void the shapestream is stopped.

* ```
* const shapeStream = new ShapeStream<{ foo: number }>(url: `http://localhost:3000/v1/shape`, table: `foo`})
* const shapeStream = new ShapeStream<{ foo: number }>({
* url: `http://localhost:3000/v1/shape`,
* params: {
* table: `foo`
* }
* })
* const shape = new Shape(shapeStream)

@@ -311,0 +320,0 @@ * ```

@@ -253,3 +253,2 @@ var __defProp = Object.defineProperty;

var CHUNK_UP_TO_DATE_HEADER = `electric-up-to-date`;
var DATABASE_ID_QUERY_PARAM = `database_id`;
var COLUMNS_QUERY_PARAM = `columns`;

@@ -440,2 +439,3 @@ var LIVE_CACHE_BUSTER_QUERY_PARAM = `cursor`;

nextUrl.searchParams.set(OFFSET_QUERY_PARAM, lastOffset);
nextUrl.searchParams.sort();
return nextUrl.toString();

@@ -455,14 +455,16 @@ }

var RESERVED_PARAMS = /* @__PURE__ */ new Set([
DATABASE_ID_QUERY_PARAM,
COLUMNS_QUERY_PARAM,
LIVE_CACHE_BUSTER_QUERY_PARAM,
SHAPE_HANDLE_QUERY_PARAM,
LIVE_QUERY_PARAM,
OFFSET_QUERY_PARAM,
TABLE_QUERY_PARAM,
WHERE_QUERY_PARAM,
REPLICA_PARAM
OFFSET_QUERY_PARAM
]);
var _error, _fetchClient2, _messageParser, _subscribers, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _connected, _shapeHandle, _databaseId, _schema, _onError, _replica, _ShapeStream_instances, start_fn, publish_fn, sendErrorToSubscribers_fn, reset_fn;
var _ShapeStream = class _ShapeStream {
function toInternalParams(params) {
const result = {};
for (const [key, value] of Object.entries(params)) {
result[key] = Array.isArray(value) ? value.join(`,`) : value;
}
return result;
}
var _error, _fetchClient2, _messageParser, _subscribers, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _connected, _shapeHandle, _schema, _onError, _ShapeStream_instances, start_fn, publish_fn, sendErrorToSubscribers_fn, reset_fn;
var ShapeStream = class {
constructor(options) {

@@ -482,6 +484,4 @@ __privateAdd(this, _ShapeStream_instances);

__privateAdd(this, _shapeHandle);
__privateAdd(this, _databaseId);
__privateAdd(this, _schema);
__privateAdd(this, _onError);
__privateAdd(this, _replica);
var _a, _b, _c;

@@ -493,5 +493,3 @@ this.options = __spreadValues({ subscribe: true }, options);

__privateSet(this, _shapeHandle, this.options.handle);
__privateSet(this, _databaseId, this.options.databaseId);
__privateSet(this, _messageParser, new MessageParser(options.parser));
__privateSet(this, _replica, this.options.replica);
__privateSet(this, _onError, this.options.onError);

@@ -562,12 +560,10 @@ const baseFetchClient = (_b = options.fetchClient) != null ? _b : (...args) => fetch(...args);

_shapeHandle = new WeakMap();
_databaseId = new WeakMap();
_schema = new WeakMap();
_onError = new WeakMap();
_replica = new WeakMap();
_ShapeStream_instances = new WeakSet();
start_fn = async function() {
var _a, _b, _c;
var _a, _b;
try {
while (!((_a = this.options.signal) == null ? void 0 : _a.aborted) && !__privateGet(this, _isUpToDate) || this.options.subscribe) {
const { url, table, where, columns, signal } = this.options;
const { url, signal } = this.options;
const fetchUrl = new URL(url);

@@ -583,10 +579,20 @@ if (this.options.params) {

}
for (const [key, value] of Object.entries(this.options.params)) {
const params = toInternalParams(this.options.params);
if (params.table)
fetchUrl.searchParams.set(TABLE_QUERY_PARAM, params.table);
if (params.where)
fetchUrl.searchParams.set(WHERE_QUERY_PARAM, params.where);
if (params.columns)
fetchUrl.searchParams.set(COLUMNS_QUERY_PARAM, params.columns);
if (params.replica)
fetchUrl.searchParams.set(REPLICA_PARAM, params.replica);
const customParams = __spreadValues({}, params);
delete customParams.table;
delete customParams.where;
delete customParams.columns;
delete customParams.replica;
for (const [key, value] of Object.entries(customParams)) {
fetchUrl.searchParams.set(key, value);
}
}
if (table) fetchUrl.searchParams.set(TABLE_QUERY_PARAM, table);
if (where) fetchUrl.searchParams.set(WHERE_QUERY_PARAM, where);
if (columns && columns.length > 0)
fetchUrl.searchParams.set(COLUMNS_QUERY_PARAM, columns.join(`,`));
fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, __privateGet(this, _lastOffset));

@@ -606,8 +612,3 @@ if (__privateGet(this, _isUpToDate)) {

}
if (__privateGet(this, _databaseId)) {
fetchUrl.searchParams.set(DATABASE_ID_QUERY_PARAM, __privateGet(this, _databaseId));
}
if (((_b = __privateGet(this, _replica)) != null ? _b : _ShapeStream.Replica.DEFAULT) != _ShapeStream.Replica.DEFAULT) {
fetchUrl.searchParams.set(REPLICA_PARAM, __privateGet(this, _replica));
}
fetchUrl.searchParams.sort();
let response;

@@ -650,3 +651,3 @@ try {

};
__privateSet(this, _schema, (_c = __privateGet(this, _schema)) != null ? _c : getSchema());
__privateSet(this, _schema, (_b = __privateGet(this, _schema)) != null ? _b : getSchema());
const messages = status === 204 ? `[]` : await response.text();

@@ -717,7 +718,6 @@ if (status === 204) {

};
_ShapeStream.Replica = {
ShapeStream.Replica = {
FULL: `full`,
DEFAULT: `default`
};
var ShapeStream = _ShapeStream;
function validateOptions(options) {

@@ -724,0 +724,0 @@ if (!options.url) {

{
"name": "@electric-sql/client",
"version": "0.8.0",
"version": "0.9.0",
"description": "Postgres everywhere - your data, in sync, wherever you need it.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -54,3 +54,5 @@ <p align="center">

url: `${BASE_URL}/v1/shape`,
table: `foo`,
params: {
table: `foo`
}
})

@@ -61,3 +63,2 @@

url: `${BASE_URL}/v1/shape`,
table: `foo`,
headers: {

@@ -67,2 +68,3 @@ 'Authorization': 'Bearer token'

params: {
table: `foo`,
'custom-param': 'value'

@@ -86,3 +88,5 @@ }

url: `${BASE_URL}/v1/shape`,
table: `foo`,
params: {
table: `foo`
}
})

@@ -108,3 +112,5 @@ const shape = new Shape(stream)

url: `${BASE_URL}/v1/shape`,
table: `foo`,
params: {
table: `foo`
},
onError: (error) => {

@@ -111,0 +117,0 @@ // Handle all stream errors here

@@ -37,3 +37,2 @@ import {

WHERE_QUERY_PARAM,
DATABASE_ID_QUERY_PARAM,
TABLE_QUERY_PARAM,

@@ -44,4 +43,2 @@ REPLICA_PARAM,

const RESERVED_PARAMS = new Set([
DATABASE_ID_QUERY_PARAM,
COLUMNS_QUERY_PARAM,
LIVE_CACHE_BUSTER_QUERY_PARAM,

@@ -51,5 +48,2 @@ SHAPE_HANDLE_QUERY_PARAM,

OFFSET_QUERY_PARAM,
TABLE_QUERY_PARAM,
WHERE_QUERY_PARAM,
REPLICA_PARAM,
])

@@ -59,4 +53,32 @@

/**
* PostgreSQL-specific shape parameters that can be provided externally
*/
type PostgresParams = {
/** The root table for the shape. Not required if you set the table in your proxy. */
table?: string
/**
* The columns to include in the shape.
* Must include primary keys, and can only include valid columns.
*/
columns?: string[]
/** The where clauses for the shape */
where?: string
/**
* If `replica` is `default` (the default) then Electric will only send the
* changed columns in an update.
*
* If it's `full` Electric will send the entire row with both changed and
* unchanged values.
*
* Setting `replica` to `full` will result in higher bandwidth
* usage and so is not generally recommended.
*/
replica?: Replica
}
type ReservedParamKeys =
| typeof DATABASE_ID_QUERY_PARAM
| typeof COLUMNS_QUERY_PARAM

@@ -71,8 +93,34 @@ | typeof LIVE_CACHE_BUSTER_QUERY_PARAM

type ParamsRecord = Omit<Record<string, string>, ReservedParamKeys>
/**
* External params type - what users provide.
* Includes documented PostgreSQL params and allows string or string[] values for any additional params.
*/
type ExternalParamsRecord = Partial<PostgresParams> & {
[K in string as K extends ReservedParamKeys ? never : K]: string | string[]
}
/**
* Internal params type - used within the library.
* All values are converted to strings.
*/
type InternalParamsRecord = {
[K in string as K extends ReservedParamKeys ? never : K]: string
}
/**
* Helper function to convert external params to internal format
*/
function toInternalParams(params: ExternalParamsRecord): InternalParamsRecord {
const result: InternalParamsRecord = {}
for (const [key, value] of Object.entries(params)) {
result[key] = Array.isArray(value) ? value.join(`,`) : value
}
return result
}
type RetryOpts = {
params?: ParamsRecord
params?: ExternalParamsRecord
headers?: Record<string, string>
}
type ShapeStreamErrorHandler = (

@@ -93,36 +141,2 @@ error: Error

/**
* Which database to use.
* This is optional unless Electric is used with multiple databases.
*/
databaseId?: string
/**
* The root table for the shape. Passed as a query parameter. Not required if you set the table in your proxy.
*/
table?: string
/**
* The where clauses for the shape.
*/
where?: string
/**
* The columns to include in the shape.
* Must include primary keys, and can only inlude valid columns.
*/
columns?: string[]
/**
* If `replica` is `default` (the default) then Electric will only send the
* changed columns in an update.
*
* If it's `full` Electric will send the entire row with both changed and
* unchanged values.
*
* Setting `replica` to `full` will obviously result in higher bandwidth
* usage and so is not recommended.
*/
replica?: Replica
/**
* The "offset" on the shape log. This is typically not set as the ShapeStream

@@ -153,5 +167,8 @@ * will handle this automatically. A common scenario where you might pass an offset

* Note: You cannot use Electric's reserved parameter names
* (table, where, columns, offset, handle, live, cursor, database_id, replica).
* (offset, handle, live, cursor).
*
* PostgreSQL-specific options like table, where, columns, and replica
* should be specified here.
*/
params?: ParamsRecord
params?: ExternalParamsRecord

@@ -172,3 +189,3 @@ /**

* This is optional, when it is not provided any shapestream errors will be thrown.
* If the function is provided and returns an object containing parameters and/or headers
* If the function returns an object containing parameters and/or headers
* the shapestream will apply those changes and try syncing again.

@@ -257,6 +274,4 @@ * If the function returns void the shapestream is stopped.

#shapeHandle?: string
#databaseId?: string
#schema?: Schema
#onError?: ShapeStreamErrorHandler
#replica?: Replica

@@ -269,5 +284,3 @@ constructor(options: ShapeStreamOptions<GetExtensions<T>>) {

this.#shapeHandle = this.options.handle
this.#databaseId = this.options.databaseId
this.#messageParser = new MessageParser<T>(options.parser)
this.#replica = this.options.replica
this.#onError = this.options.onError

@@ -316,3 +329,3 @@

) {
const { url, table, where, columns, signal } = this.options
const { url, signal } = this.options

@@ -333,4 +346,22 @@ const fetchUrl = new URL(url)

for (const [key, value] of Object.entries(this.options.params)) {
fetchUrl.searchParams.set(key, value)
// Add PostgreSQL-specific parameters from params
const params = toInternalParams(this.options.params)
if (params.table)
fetchUrl.searchParams.set(TABLE_QUERY_PARAM, params.table)
if (params.where)
fetchUrl.searchParams.set(WHERE_QUERY_PARAM, params.where)
if (params.columns)
fetchUrl.searchParams.set(COLUMNS_QUERY_PARAM, params.columns)
if (params.replica)
fetchUrl.searchParams.set(REPLICA_PARAM, params.replica)
// Add any remaining custom parameters
const customParams = { ...params }
delete customParams.table
delete customParams.where
delete customParams.columns
delete customParams.replica
for (const [key, value] of Object.entries(customParams)) {
fetchUrl.searchParams.set(key, value as string)
}

@@ -340,6 +371,2 @@ }

// Add Electric's internal parameters
if (table) fetchUrl.searchParams.set(TABLE_QUERY_PARAM, table)
if (where) fetchUrl.searchParams.set(WHERE_QUERY_PARAM, where)
if (columns && columns.length > 0)
fetchUrl.searchParams.set(COLUMNS_QUERY_PARAM, columns.join(`,`))
fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, this.#lastOffset)

@@ -363,13 +390,5 @@

if (this.#databaseId) {
fetchUrl.searchParams.set(DATABASE_ID_QUERY_PARAM, this.#databaseId!)
}
// sort query params in-place for stable URLs and improved cache hits
fetchUrl.searchParams.sort()
if (
(this.#replica ?? ShapeStream.Replica.DEFAULT) !=
ShapeStream.Replica.DEFAULT
) {
fetchUrl.searchParams.set(REPLICA_PARAM, this.#replica as string)
}
let response!: Response

@@ -376,0 +395,0 @@ try {

@@ -6,3 +6,2 @@ export const LIVE_CACHE_BUSTER_HEADER = `electric-cursor`

export const CHUNK_UP_TO_DATE_HEADER = `electric-up-to-date`
export const DATABASE_ID_QUERY_PARAM = `database_id`
export const COLUMNS_QUERY_PARAM = `columns`

@@ -9,0 +8,0 @@ export const LIVE_CACHE_BUSTER_QUERY_PARAM = `cursor`

@@ -315,2 +315,3 @@ import {

nextUrl.searchParams.set(OFFSET_QUERY_PARAM, lastOffset)
nextUrl.searchParams.sort()
return nextUrl.toString()

@@ -317,0 +318,0 @@ }

@@ -24,3 +24,8 @@ import { Message, Offset, Row } from './types'

* ```
* const shapeStream = new ShapeStream<{ foo: number }>(url: `http://localhost:3000/v1/shape`, table: `foo`})
* const shapeStream = new ShapeStream<{ foo: number }>({
* url: `http://localhost:3000/v1/shape`,
* params: {
* table: `foo`
* }
* })
* const shape = new Shape(shapeStream)

@@ -27,0 +32,0 @@ * ```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc