@electric-sql/client 0.8.0 → 0.9.1
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/README.md +10 -4
- package/dist/cjs/index.cjs +45 -46
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +394 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +49 -38
- package/dist/index.legacy-esm.js +44 -46
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +44 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +33 -28
- package/src/client.ts +87 -68
- package/src/constants.ts +0 -1
- package/src/fetch.ts +3 -2
- package/src/shape.ts +17 -12
- package/src/types.ts +3 -1
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default types for SQL but can be extended with additional types when using a custom parser.
|
|
3
|
+
* @typeParam Extensions - Additional value types.
|
|
4
|
+
*/
|
|
5
|
+
type Value<Extensions = never> = string | number | boolean | bigint | null | Extensions | Value<Extensions>[] | {
|
|
6
|
+
[key: string]: Value<Extensions>;
|
|
7
|
+
};
|
|
8
|
+
type Row<Extensions = never> = Record<string, Value<Extensions>>;
|
|
9
|
+
type GetExtensions<T extends Row<unknown>> = T extends Row<infer Extensions> ? Extensions : never;
|
|
10
|
+
type Offset = `-1` | `${number}_${number}`;
|
|
11
|
+
interface Header {
|
|
12
|
+
[key: Exclude<string, `operation` | `control`>]: Value;
|
|
13
|
+
}
|
|
14
|
+
type Operation = `insert` | `update` | `delete`;
|
|
15
|
+
type ControlMessage = {
|
|
16
|
+
headers: Header & {
|
|
17
|
+
control: `up-to-date` | `must-refetch`;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type ChangeMessage<T extends Row<unknown> = Row> = {
|
|
21
|
+
key: string;
|
|
22
|
+
value: T;
|
|
23
|
+
headers: Header & {
|
|
24
|
+
operation: Operation;
|
|
25
|
+
};
|
|
26
|
+
offset: Offset;
|
|
27
|
+
};
|
|
28
|
+
type Message<T extends Row<unknown> = Row> = ControlMessage | ChangeMessage<T>;
|
|
29
|
+
/**
|
|
30
|
+
* Common properties for all columns.
|
|
31
|
+
* `dims` is the number of dimensions of the column. Only provided if the column is an array.
|
|
32
|
+
* `not_null` is true if the column has a `NOT NULL` constraint and is omitted otherwise.
|
|
33
|
+
*/
|
|
34
|
+
type CommonColumnProps = {
|
|
35
|
+
dims?: number;
|
|
36
|
+
not_null?: boolean;
|
|
37
|
+
};
|
|
38
|
+
type RegularColumn = {
|
|
39
|
+
type: string;
|
|
40
|
+
} & CommonColumnProps;
|
|
41
|
+
type VarcharColumn = {
|
|
42
|
+
type: `varchar`;
|
|
43
|
+
max_length?: number;
|
|
44
|
+
} & CommonColumnProps;
|
|
45
|
+
type BpcharColumn = {
|
|
46
|
+
type: `bpchar`;
|
|
47
|
+
length?: number;
|
|
48
|
+
} & CommonColumnProps;
|
|
49
|
+
type TimeColumn = {
|
|
50
|
+
type: `time` | `timetz` | `timestamp` | `timestamptz`;
|
|
51
|
+
precision?: number;
|
|
52
|
+
} & CommonColumnProps;
|
|
53
|
+
type IntervalColumn = {
|
|
54
|
+
type: `interval`;
|
|
55
|
+
fields?: `YEAR` | `MONTH` | `DAY` | `HOUR` | `MINUTE` | `YEAR TO MONTH` | `DAY TO HOUR` | `DAY TO MINUTE` | `DAY TO SECOND` | `HOUR TO MINUTE` | `HOUR TO SECOND` | `MINUTE TO SECOND`;
|
|
56
|
+
} & CommonColumnProps;
|
|
57
|
+
type IntervalColumnWithPrecision = {
|
|
58
|
+
type: `interval`;
|
|
59
|
+
precision?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
60
|
+
fields?: `SECOND`;
|
|
61
|
+
} & CommonColumnProps;
|
|
62
|
+
type BitColumn = {
|
|
63
|
+
type: `bit`;
|
|
64
|
+
length: number;
|
|
65
|
+
} & CommonColumnProps;
|
|
66
|
+
type NumericColumn = {
|
|
67
|
+
type: `numeric`;
|
|
68
|
+
precision?: number;
|
|
69
|
+
scale?: number;
|
|
70
|
+
} & CommonColumnProps;
|
|
71
|
+
type ColumnInfo = RegularColumn | VarcharColumn | BpcharColumn | TimeColumn | IntervalColumn | IntervalColumnWithPrecision | BitColumn | NumericColumn;
|
|
72
|
+
type Schema = {
|
|
73
|
+
[key: string]: ColumnInfo;
|
|
74
|
+
};
|
|
75
|
+
type TypedMessages<T extends Row<unknown> = Row> = {
|
|
76
|
+
messages: Array<Message<T>>;
|
|
77
|
+
schema: ColumnInfo;
|
|
78
|
+
};
|
|
79
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
80
|
+
|
|
81
|
+
type NullToken = null | `NULL`;
|
|
82
|
+
type Token = Exclude<string, NullToken>;
|
|
83
|
+
type ParseFunction<Extensions = never> = (value: Token, additionalInfo?: Omit<ColumnInfo, `type` | `dims`>) => Value<Extensions>;
|
|
84
|
+
/**
|
|
85
|
+
* @typeParam Extensions - Additional types that can be parsed by this parser beyond the standard SQL types.
|
|
86
|
+
* Defaults to no additional types.
|
|
87
|
+
*/
|
|
88
|
+
type Parser<Extensions = never> = {
|
|
89
|
+
[key: string]: ParseFunction<Extensions>;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
declare class FetchError extends Error {
|
|
93
|
+
url: string;
|
|
94
|
+
status: number;
|
|
95
|
+
text?: string;
|
|
96
|
+
json?: object;
|
|
97
|
+
headers: Record<string, string>;
|
|
98
|
+
constructor(status: number, text: string | undefined, json: object | undefined, headers: Record<string, string>, url: string, message?: string);
|
|
99
|
+
static fromResponse(response: Response, url: string): Promise<FetchError>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface BackoffOptions {
|
|
103
|
+
/**
|
|
104
|
+
* Initial delay before retrying in milliseconds
|
|
105
|
+
*/
|
|
106
|
+
initialDelay: number;
|
|
107
|
+
/**
|
|
108
|
+
* Maximum retry delay in milliseconds
|
|
109
|
+
*/
|
|
110
|
+
maxDelay: number;
|
|
111
|
+
multiplier: number;
|
|
112
|
+
onFailedAttempt?: () => void;
|
|
113
|
+
debug?: boolean;
|
|
114
|
+
}
|
|
115
|
+
declare const BackoffDefaults: {
|
|
116
|
+
initialDelay: number;
|
|
117
|
+
maxDelay: number;
|
|
118
|
+
multiplier: number;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
declare const COLUMNS_QUERY_PARAM = "columns";
|
|
122
|
+
declare const LIVE_CACHE_BUSTER_QUERY_PARAM = "cursor";
|
|
123
|
+
declare const SHAPE_HANDLE_QUERY_PARAM = "handle";
|
|
124
|
+
declare const LIVE_QUERY_PARAM = "live";
|
|
125
|
+
declare const OFFSET_QUERY_PARAM = "offset";
|
|
126
|
+
declare const TABLE_QUERY_PARAM = "table";
|
|
127
|
+
declare const WHERE_QUERY_PARAM = "where";
|
|
128
|
+
declare const REPLICA_PARAM = "replica";
|
|
129
|
+
|
|
130
|
+
type Replica = `full` | `default`;
|
|
131
|
+
/**
|
|
132
|
+
* PostgreSQL-specific shape parameters that can be provided externally
|
|
133
|
+
*/
|
|
134
|
+
type PostgresParams = {
|
|
135
|
+
/** The root table for the shape. Not required if you set the table in your proxy. */
|
|
136
|
+
table?: string;
|
|
137
|
+
/**
|
|
138
|
+
* The columns to include in the shape.
|
|
139
|
+
* Must include primary keys, and can only include valid columns.
|
|
140
|
+
*/
|
|
141
|
+
columns?: string[];
|
|
142
|
+
/** The where clauses for the shape */
|
|
143
|
+
where?: string;
|
|
144
|
+
/**
|
|
145
|
+
* If `replica` is `default` (the default) then Electric will only send the
|
|
146
|
+
* changed columns in an update.
|
|
147
|
+
*
|
|
148
|
+
* If it's `full` Electric will send the entire row with both changed and
|
|
149
|
+
* unchanged values.
|
|
150
|
+
*
|
|
151
|
+
* Setting `replica` to `full` will result in higher bandwidth
|
|
152
|
+
* usage and so is not generally recommended.
|
|
153
|
+
*/
|
|
154
|
+
replica?: Replica;
|
|
155
|
+
};
|
|
156
|
+
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;
|
|
157
|
+
/**
|
|
158
|
+
* External params type - what users provide.
|
|
159
|
+
* Includes documented PostgreSQL params and allows string or string[] values for any additional params.
|
|
160
|
+
*/
|
|
161
|
+
type ExternalParamsRecord = Partial<PostgresParams> & {
|
|
162
|
+
[K in string as K extends ReservedParamKeys ? never : K]: string | string[];
|
|
163
|
+
};
|
|
164
|
+
type RetryOpts = {
|
|
165
|
+
params?: ExternalParamsRecord;
|
|
166
|
+
headers?: Record<string, string>;
|
|
167
|
+
};
|
|
168
|
+
type ShapeStreamErrorHandler = (error: Error) => void | RetryOpts | Promise<void | RetryOpts>;
|
|
169
|
+
/**
|
|
170
|
+
* Options for constructing a ShapeStream.
|
|
171
|
+
*/
|
|
172
|
+
interface ShapeStreamOptions<T = never> {
|
|
173
|
+
/**
|
|
174
|
+
* The full URL to where the Shape is served. This can either be the Electric server
|
|
175
|
+
* directly or a proxy. E.g. for a local Electric instance, you might set `http://localhost:3000/v1/shape`
|
|
176
|
+
*/
|
|
177
|
+
url: string;
|
|
178
|
+
/**
|
|
179
|
+
* The "offset" on the shape log. This is typically not set as the ShapeStream
|
|
180
|
+
* will handle this automatically. A common scenario where you might pass an offset
|
|
181
|
+
* is if you're maintaining a local cache of the log. If you've gone offline
|
|
182
|
+
* and are re-starting a ShapeStream to catch-up to the latest state of the Shape,
|
|
183
|
+
* you'd pass in the last offset and shapeHandle you'd seen from the Electric server
|
|
184
|
+
* so it knows at what point in the shape to catch you up from.
|
|
185
|
+
*/
|
|
186
|
+
offset?: Offset;
|
|
187
|
+
/**
|
|
188
|
+
* Similar to `offset`, this isn't typically used unless you're maintaining
|
|
189
|
+
* a cache of the shape log.
|
|
190
|
+
*/
|
|
191
|
+
handle?: string;
|
|
192
|
+
/**
|
|
193
|
+
* HTTP headers to attach to requests made by the client.
|
|
194
|
+
* Can be used for adding authentication headers.
|
|
195
|
+
*/
|
|
196
|
+
headers?: Record<string, string>;
|
|
197
|
+
/**
|
|
198
|
+
* Additional request parameters to attach to the URL.
|
|
199
|
+
* These will be merged with Electric's standard parameters.
|
|
200
|
+
* Note: You cannot use Electric's reserved parameter names
|
|
201
|
+
* (offset, handle, live, cursor).
|
|
202
|
+
*
|
|
203
|
+
* PostgreSQL-specific options like table, where, columns, and replica
|
|
204
|
+
* should be specified here.
|
|
205
|
+
*/
|
|
206
|
+
params?: ExternalParamsRecord;
|
|
207
|
+
/**
|
|
208
|
+
* Automatically fetch updates to the Shape. If you just want to sync the current
|
|
209
|
+
* shape and stop, pass false.
|
|
210
|
+
*/
|
|
211
|
+
subscribe?: boolean;
|
|
212
|
+
signal?: AbortSignal;
|
|
213
|
+
fetchClient?: typeof fetch;
|
|
214
|
+
backoffOptions?: BackoffOptions;
|
|
215
|
+
parser?: Parser<T>;
|
|
216
|
+
/**
|
|
217
|
+
* A function for handling shapestream errors.
|
|
218
|
+
* This is optional, when it is not provided any shapestream errors will be thrown.
|
|
219
|
+
* If the function returns an object containing parameters and/or headers
|
|
220
|
+
* the shapestream will apply those changes and try syncing again.
|
|
221
|
+
* If the function returns void the shapestream is stopped.
|
|
222
|
+
*/
|
|
223
|
+
onError?: ShapeStreamErrorHandler;
|
|
224
|
+
}
|
|
225
|
+
interface ShapeStreamInterface<T extends Row<unknown> = Row> {
|
|
226
|
+
subscribe(callback: (messages: Message<T>[]) => MaybePromise<void>, onError?: (error: FetchError | Error) => void): () => void;
|
|
227
|
+
unsubscribeAll(): void;
|
|
228
|
+
isLoading(): boolean;
|
|
229
|
+
lastSyncedAt(): number | undefined;
|
|
230
|
+
lastSynced(): number;
|
|
231
|
+
isConnected(): boolean;
|
|
232
|
+
isUpToDate: boolean;
|
|
233
|
+
lastOffset: Offset;
|
|
234
|
+
shapeHandle?: string;
|
|
235
|
+
error?: unknown;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Reads updates to a shape from Electric using HTTP requests and long polling. Notifies subscribers
|
|
239
|
+
* when new messages come in. Doesn't maintain any history of the
|
|
240
|
+
* log but does keep track of the offset position and is the best way
|
|
241
|
+
* to consume the HTTP `GET /v1/shape` api.
|
|
242
|
+
*
|
|
243
|
+
* @constructor
|
|
244
|
+
* @param {ShapeStreamOptions} options - configure the shape stream
|
|
245
|
+
* @example
|
|
246
|
+
* Register a callback function to subscribe to the messages.
|
|
247
|
+
* ```
|
|
248
|
+
* const stream = new ShapeStream(options)
|
|
249
|
+
* stream.subscribe(messages => {
|
|
250
|
+
* // messages is 1 or more row updates
|
|
251
|
+
* })
|
|
252
|
+
* ```
|
|
253
|
+
*
|
|
254
|
+
* To abort the stream, abort the `signal`
|
|
255
|
+
* passed in via the `ShapeStreamOptions`.
|
|
256
|
+
* ```
|
|
257
|
+
* const aborter = new AbortController()
|
|
258
|
+
* const issueStream = new ShapeStream({
|
|
259
|
+
* url: `${BASE_URL}/${table}`
|
|
260
|
+
* subscribe: true,
|
|
261
|
+
* signal: aborter.signal,
|
|
262
|
+
* })
|
|
263
|
+
* // Later...
|
|
264
|
+
* aborter.abort()
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
declare class ShapeStream<T extends Row<unknown> = Row> implements ShapeStreamInterface<T> {
|
|
268
|
+
#private;
|
|
269
|
+
static readonly Replica: {
|
|
270
|
+
FULL: Replica;
|
|
271
|
+
DEFAULT: Replica;
|
|
272
|
+
};
|
|
273
|
+
readonly options: ShapeStreamOptions<GetExtensions<T>>;
|
|
274
|
+
constructor(options: ShapeStreamOptions<GetExtensions<T>>);
|
|
275
|
+
get shapeHandle(): string | undefined;
|
|
276
|
+
get error(): unknown;
|
|
277
|
+
get isUpToDate(): boolean;
|
|
278
|
+
get lastOffset(): Offset;
|
|
279
|
+
subscribe(callback: (messages: Message<T>[]) => MaybePromise<void>, onError?: (error: Error) => void): () => void;
|
|
280
|
+
unsubscribeAll(): void;
|
|
281
|
+
/** Unix time at which we last synced. Undefined when `isLoading` is true. */
|
|
282
|
+
lastSyncedAt(): number | undefined;
|
|
283
|
+
/** Time elapsed since last sync (in ms). Infinity if we did not yet sync. */
|
|
284
|
+
lastSynced(): number;
|
|
285
|
+
/** Indicates if we are connected to the Electric sync service. */
|
|
286
|
+
isConnected(): boolean;
|
|
287
|
+
/** True during initial fetch. False afterwise. */
|
|
288
|
+
isLoading(): boolean;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
type ShapeData<T extends Row<unknown> = Row> = Map<string, T>;
|
|
292
|
+
type ShapeChangedCallback<T extends Row<unknown> = Row> = (data: {
|
|
293
|
+
value: ShapeData<T>;
|
|
294
|
+
rows: T[];
|
|
295
|
+
}) => void;
|
|
296
|
+
/**
|
|
297
|
+
* A Shape is an object that subscribes to a shape log,
|
|
298
|
+
* keeps a materialised shape `.rows` in memory and
|
|
299
|
+
* notifies subscribers when the value has changed.
|
|
300
|
+
*
|
|
301
|
+
* It can be used without a framework and as a primitive
|
|
302
|
+
* to simplify developing framework hooks.
|
|
303
|
+
*
|
|
304
|
+
* @constructor
|
|
305
|
+
* @param {ShapeStream<T extends Row>} - the underlying shape stream
|
|
306
|
+
* @example
|
|
307
|
+
* ```
|
|
308
|
+
* const shapeStream = new ShapeStream<{ foo: number }>({
|
|
309
|
+
* url: `http://localhost:3000/v1/shape`,
|
|
310
|
+
* params: {
|
|
311
|
+
* table: `foo`
|
|
312
|
+
* }
|
|
313
|
+
* })
|
|
314
|
+
* const shape = new Shape(shapeStream)
|
|
315
|
+
* ```
|
|
316
|
+
*
|
|
317
|
+
* `rows` returns a promise that resolves the Shape data once the Shape has been
|
|
318
|
+
* fully loaded (and when resuming from being offline):
|
|
319
|
+
*
|
|
320
|
+
* const rows = await shape.rows
|
|
321
|
+
*
|
|
322
|
+
* `currentRows` returns the current data synchronously:
|
|
323
|
+
*
|
|
324
|
+
* const rows = shape.currentRows
|
|
325
|
+
*
|
|
326
|
+
* Subscribe to updates. Called whenever the shape updates in Postgres.
|
|
327
|
+
*
|
|
328
|
+
* shape.subscribe(({ rows }) => {
|
|
329
|
+
* console.log(rows)
|
|
330
|
+
* })
|
|
331
|
+
*/
|
|
332
|
+
declare class Shape<T extends Row<unknown> = Row> {
|
|
333
|
+
#private;
|
|
334
|
+
readonly stream: ShapeStreamInterface<T>;
|
|
335
|
+
constructor(stream: ShapeStreamInterface<T>);
|
|
336
|
+
get isUpToDate(): boolean;
|
|
337
|
+
get lastOffset(): Offset;
|
|
338
|
+
get handle(): string | undefined;
|
|
339
|
+
get rows(): Promise<T[]>;
|
|
340
|
+
get currentRows(): T[];
|
|
341
|
+
get value(): Promise<ShapeData<T>>;
|
|
342
|
+
get currentValue(): ShapeData<T>;
|
|
343
|
+
get error(): false | FetchError;
|
|
344
|
+
/** Unix time at which we last synced. Undefined when `isLoading` is true. */
|
|
345
|
+
lastSyncedAt(): number | undefined;
|
|
346
|
+
/** Time elapsed since last sync (in ms). Infinity if we did not yet sync. */
|
|
347
|
+
lastSynced(): number;
|
|
348
|
+
/** True during initial fetch. False afterwise. */
|
|
349
|
+
isLoading(): boolean;
|
|
350
|
+
/** Indicates if we are connected to the Electric sync service. */
|
|
351
|
+
isConnected(): boolean;
|
|
352
|
+
subscribe(callback: ShapeChangedCallback<T>): () => void;
|
|
353
|
+
unsubscribeAll(): void;
|
|
354
|
+
get numSubscribers(): number;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Type guard for checking {@link Message} is {@link ChangeMessage}.
|
|
359
|
+
*
|
|
360
|
+
* See [TS docs](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards)
|
|
361
|
+
* for information on how to use type guards.
|
|
362
|
+
*
|
|
363
|
+
* @param message - the message to check
|
|
364
|
+
* @returns true if the message is a {@link ChangeMessage}
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* if (isChangeMessage(message)) {
|
|
369
|
+
* const msgChng: ChangeMessage = message // Ok
|
|
370
|
+
* const msgCtrl: ControlMessage = message // Err, type mismatch
|
|
371
|
+
* }
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
declare function isChangeMessage<T extends Row<unknown> = Row>(message: Message<T>): message is ChangeMessage<T>;
|
|
375
|
+
/**
|
|
376
|
+
* Type guard for checking {@link Message} is {@link ControlMessage}.
|
|
377
|
+
*
|
|
378
|
+
* See [TS docs](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards)
|
|
379
|
+
* for information on how to use type guards.
|
|
380
|
+
*
|
|
381
|
+
* @param message - the message to check
|
|
382
|
+
* @returns true if the message is a {@link ControlMessage}
|
|
383
|
+
*
|
|
384
|
+
* * @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* if (isControlMessage(message)) {
|
|
387
|
+
* const msgChng: ChangeMessage = message // Err, type mismatch
|
|
388
|
+
* const msgCtrl: ControlMessage = message // Ok
|
|
389
|
+
* }
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
declare function isControlMessage<T extends Row<unknown> = Row>(message: Message<T>): message is ControlMessage;
|
|
393
|
+
|
|
394
|
+
export { BackoffDefaults, type BackoffOptions, type BitColumn, type BpcharColumn, type ChangeMessage, type ColumnInfo, type CommonColumnProps, type ControlMessage, FetchError, type GetExtensions, type IntervalColumn, type IntervalColumnWithPrecision, type MaybePromise, type Message, type NumericColumn, type Offset, type Operation, type RegularColumn, type Row, type Schema, Shape, type ShapeChangedCallback, type ShapeData, ShapeStream, type ShapeStreamInterface, type ShapeStreamOptions, type TimeColumn, type TypedMessages, type Value, type VarcharColumn, isChangeMessage, isControlMessage };
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Ge=Object.defineProperty,Je=Object.defineProperties;var ze=Object.getOwnPropertyDescriptors;var ee=Object.getOwnPropertySymbols;var xe=Object.prototype.hasOwnProperty,Se=Object.prototype.propertyIsEnumerable;var Ce=s=>{throw TypeError(s)};var _e=(s,e,t)=>e in s?Ge(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,R=(s,e)=>{for(var t in e||(e={}))xe.call(e,t)&&_e(s,t,e[t]);if(ee)for(var t of ee(e))Se.call(e,t)&&_e(s,t,e[t]);return s},te=(s,e)=>Je(s,ze(e));var Me=(s,e)=>{var t={};for(var r in s)xe.call(s,r)&&e.indexOf(r)<0&&(t[r]=s[r]);if(s!=null&&ee)for(var r of ee(s))e.indexOf(r)<0&&Se.call(s,r)&&(t[r]=s[r]);return t};var Ee=(s,e,t)=>e.has(s)||Ce("Cannot "+t);var o=(s,e,t)=>(Ee(s,e,"read from private field"),t?t.call(s):e.get(s)),u=(s,e,t)=>e.has(s)?Ce("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(s):e.set(s,t),l=(s,e,t,r)=>(Ee(s,e,"write to private field"),r?r.call(s,t):e.set(s,t),t),m=(s,e,t)=>(Ee(s,e,"access private method"),t);var P=(s,e,t)=>new Promise((r,a)=>{var n=h=>{try{c(t.next(h))}catch(f){a(f)}},i=h=>{try{c(t.throw(h))}catch(f){a(f)}},c=h=>h.done?r(h.value):Promise.resolve(h.value).then(n,i);c((t=t.apply(s,e)).next())});var A=class s extends Error{constructor(t,r,a,n,i,c){super(c||`HTTP Error ${t} at ${i}: ${r!=null?r:JSON.stringify(a)}`);this.url=i;this.name="FetchError",this.status=t,this.text=r,this.json=a,this.headers=n}static fromResponse(t,r){return P(this,null,function*(){let a=t.status,n=Object.fromEntries([...t.headers.entries()]),i,c,h=t.headers.get("content-type");return h&&h.includes("application/json")?c=yield t.json():i=yield t.text(),new s(a,i,c,n,r)})}},B=class extends Error{constructor(){super("Fetch with backoff aborted"),this.name="FetchBackoffAbortError"}};var se=class extends Error{constructor(){super("Invalid shape options: missing required url parameter"),this.name="MissingShapeUrlError"}},re=class extends Error{constructor(){super("Invalid signal option. It must be an instance of AbortSignal."),this.name="InvalidSignalError"}},ne=class extends Error{constructor(){super("shapeHandle is required if this isn't an initial fetch (i.e. offset > -1)"),this.name="MissingShapeHandleError"}},ae=class extends Error{constructor(e){super(`Cannot use reserved Electric parameter names in custom params: ${e.join(", ")}`),this.name="ReservedParamError"}},oe=class extends Error{constructor(e){super(`Column "${e!=null?e:"unknown"}" does not allow NULL values`),this.name="ParserNullValueError"}};var ie=class extends Error{constructor(e,t){let r=`The response for the shape request to ${e} didn't include the following required headers:
|
|
2
2
|
`;t.forEach(a=>{r+=`- ${a}
|
|
3
3
|
`}),r+=`
|
|
4
4
|
This is often due to a proxy not setting CORS correctly so that all Electric headers can be read by the client.`,r+=`
|
|
5
|
-
For more information visit the troubleshooting guide: /docs/guides/troubleshooting/missing-headers`,super(r)}};var ue=s=>Number(s),ot=s=>s==="true"||s==="t",at=s=>BigInt(s),Fe=s=>JSON.parse(s),it=s=>s,ct={int2:ue,int4:ue,int8:at,bool:ot,float4:ue,float8:ue,json:Fe,jsonb:Fe};function lt(s,e){let t=0,r=null,a="",o=!1,i=0,h;function f(l){let p=[];for(;t<l.length;t++){if(r=l[t],o)r==="\\"?a+=l[++t]:r==='"'?(p.push(e?e(a):a),a="",o=l[t+1]==='"',i=t+2):a+=r;else if(r==='"')o=!0;else if(r==="{")i=++t,p.push(f(l));else if(r==="}"){o=!1,i<t&&p.push(e?e(l.slice(i,t)):l.slice(i,t)),i=t+1;break}else r===","&&h!=="}"&&h!=='"'&&(p.push(e?e(l.slice(i,t)):l.slice(i,t)),i=t+1);h=r}return i<t&&p.push(e?e(l.slice(i,t+1)):l.slice(i,t+1)),p}return f(s)[0]}var pe=class{constructor(e){this.parser=A(A({},ct),e)}parse(e,t){return JSON.parse(e,(r,a)=>{if(r==="value"&&typeof a=="object"&&a!==null){let o=a;Object.keys(o).forEach(i=>{o[i]=this.parseRow(i,o[i],t)})}return a})}parseRow(e,t,r){var b;let a=r[e];if(!a)return t;let p=a,{type:o,dims:i}=p,h=Ie(p,["type","dims"]),f=(b=this.parser[o])!=null?b:it,l=Ne(f,a,e);return i&&i>0?Ne((m,W)=>lt(m,l),a,e)(t):l(t,h)}};function Ne(s,e,t){var a;let r=!((a=e.not_null)!=null&&a);return o=>{if(ht(o)){if(!r)throw new he(t!=null?t:"unknown");return null}return s(o,e)}}function ht(s){return s===null||s==="NULL"}function de(s){return"key"in s}function Ee(s){return!de(s)}function Be(s){return Ee(s)&&s.headers.control==="up-to-date"}var Ye="electric-cursor",G="electric-handle",me="electric-offset",Qe="electric-schema",Ve="electric-up-to-date",be="database_id",Pe="columns",ye="cursor",K="handle",C="live",J="offset",Te="table",_e="where",we="replica";var ft=[429],Re={initialDelay:100,maxDelay:1e4,multiplier:1.3};function je(s,e=Re){let{initialDelay:t,maxDelay:r,multiplier:a,debug:o=!1,onFailedAttempt:i}=e;return(...h)=>P(this,null,function*(){var N;let f=h[0],l=h[1],p=t,b=0;for(;;)try{let m=yield s(...h);if(m.ok)return m;throw yield y.fromResponse(m,f.toString())}catch(m){if(i==null||i(),(N=l==null?void 0:l.signal)!=null&&N.aborted)throw new B;if(m instanceof y&&!ft.includes(m.status)&&m.status>=400&&m.status<500)throw m;yield new Promise(W=>setTimeout(W,p)),p=Math.min(p*a,r),o&&(b++,console.log(`Retry attempt #${b} after ${p}ms`))}})}var ut={maxChunksToPrefetch:2};function qe(s,e=ut){let{maxChunksToPrefetch:t}=e,r;return(...o)=>P(this,null,function*(){let i=o[0].toString(),h=r==null?void 0:r.consume(...o);if(h)return h;r==null||r.abort();let f=yield s(...o),l=xe(i,f);return l&&(r=new Se({fetchClient:s,maxPrefetchedRequests:t,url:l,requestInit:o[1]})),f})}var pt=["electric-offset","electric-handle"],dt=["electric-cursor"],Et=["electric-schema"];function We(s){return(...e)=>P(this,null,function*(){let t=yield s(...e);if(t.ok){let r=t.headers,a=[],o=l=>a.push(...l.filter(p=>!r.has(p)));o(pt);let h=e[0].toString(),f=new URL(h);if(f.searchParams.has(C,"true")&&o(dt),(!f.searchParams.has(C)||f.searchParams.has(C,"false"))&&o(Et),a.length>0)throw new fe(h,a)}return t})}var z,X,T,L,_,Y,ge,Se=class{constructor(e){u(this,Y);u(this,z);u(this,X);u(this,T,new Map);u(this,L);u(this,_);var t;c(this,z,(t=e.fetchClient)!=null?t:(...r)=>fetch(...r)),c(this,X,e.maxPrefetchedRequests),c(this,L,e.url.toString()),c(this,_,n(this,L)),E(this,Y,ge).call(this,e.url,e.requestInit)}abort(){n(this,T).forEach(([e,t])=>t.abort())}consume(...e){var a;let t=e[0].toString(),r=(a=n(this,T).get(t))==null?void 0:a[0];if(!(!r||t!==n(this,L)))return n(this,T).delete(t),r.then(o=>{let i=xe(t,o);c(this,L,i),n(this,_)&&!n(this,T).has(n(this,_))&&E(this,Y,ge).call(this,n(this,_),e[1])}).catch(()=>{}),r}};z=new WeakMap,X=new WeakMap,T=new WeakMap,L=new WeakMap,_=new WeakMap,Y=new WeakSet,ge=function(...e){var a,o;let t=e[0].toString();if(n(this,T).size>=n(this,X))return;let r=new AbortController;try{let i=n(this,z).call(this,t,oe(A({},(a=e[1])!=null?a:{}),{signal:mt(r,(o=e[1])==null?void 0:o.signal)}));n(this,T).set(t,[i,r]),i.then(h=>{if(!h.ok||r.signal.aborted)return;let f=xe(t,h);if(!f||f===t){c(this,_,void 0);return}return c(this,_,f),E(this,Y,ge).call(this,f,e[1])}).catch(()=>{})}catch(i){}};function xe(s,e){let t=e.headers.get(G),r=e.headers.get(me),a=e.headers.has(Ve);if(!t||!r||a)return;let o=new URL(s);if(!o.searchParams.has(C))return o.searchParams.set(K,t),o.searchParams.set(J,r),o.toString()}function mt(s,e){return e&&(e.aborted?s.abort():e.addEventListener("abort",()=>s.abort(),{once:!0})),s.signal}var Ge=new Set([be,Pe,ye,K,C,J,Te,_e,we]),ee,te,se,k,U,I,H,w,D,S,Q,F,V,j,g,Me,Ce,Ke,ke,Z=class Z{constructor(e){u(this,g);u(this,ee,null);u(this,te);u(this,se);u(this,k,new Map);u(this,U);u(this,I);u(this,H);u(this,w,!1);u(this,D,!1);u(this,S);u(this,Q);u(this,F);u(this,V);u(this,j);var a,o,i;this.options=A({subscribe:!0},e),gt(this.options),c(this,U,(a=this.options.offset)!=null?a:"-1"),c(this,I,""),c(this,S,this.options.handle),c(this,Q,this.options.databaseId),c(this,se,new pe(e.parser)),c(this,j,this.options.replica),c(this,V,this.options.onError);let t=(o=e.fetchClient)!=null?o:(...h)=>fetch(...h),r=je(t,oe(A({},(i=e.backoffOptions)!=null?i:Re),{onFailedAttempt:()=>{var h,f;c(this,D,!1),(f=(h=e.backoffOptions)==null?void 0:h.onFailedAttempt)==null||f.call(h)}}));c(this,te,We(qe(r))),E(this,g,Me).call(this)}get shapeHandle(){return n(this,S)}get error(){return n(this,ee)}get isUpToDate(){return n(this,w)}get lastOffset(){return n(this,U)}subscribe(e,t=()=>{}){let r=Math.random();return n(this,k).set(r,[e,t]),()=>{n(this,k).delete(r)}}unsubscribeAll(){n(this,k).clear()}lastSyncedAt(){return n(this,H)}lastSynced(){return n(this,H)===void 0?1/0:Date.now()-n(this,H)}isConnected(){return n(this,D)}isLoading(){return!n(this,w)}};ee=new WeakMap,te=new WeakMap,se=new WeakMap,k=new WeakMap,U=new WeakMap,I=new WeakMap,H=new WeakMap,w=new WeakMap,D=new WeakMap,S=new WeakMap,Q=new WeakMap,F=new WeakMap,V=new WeakMap,j=new WeakMap,g=new WeakSet,Me=function(){return P(this,null,function*(){var e,t,r;try{for(;!((e=this.options.signal)!=null&&e.aborted)&&!n(this,w)||this.options.subscribe;){let{url:a,table:o,where:i,columns:h,signal:f}=this.options,l=new URL(a);if(this.options.params){let d=Object.keys(this.options.params).filter($=>Ge.has($));if(d.length>0)throw new Error(`Cannot use reserved Electric parameter names in custom params: ${d.join(", ")}`);for(let[$,tt]of Object.entries(this.options.params))l.searchParams.set($,tt)}o&&l.searchParams.set(Te,o),i&&l.searchParams.set(_e,i),h&&h.length>0&&l.searchParams.set(Pe,h.join(",")),l.searchParams.set(J,n(this,U)),n(this,w)&&(l.searchParams.set(C,"true"),l.searchParams.set(ye,n(this,I))),n(this,S)&&l.searchParams.set(K,n(this,S)),n(this,Q)&&l.searchParams.set(be,n(this,Q)),((t=n(this,j))!=null?t:Z.Replica.DEFAULT)!=Z.Replica.DEFAULT&&l.searchParams.set(we,n(this,j));let p;try{p=yield n(this,te).call(this,l.toString(),{signal:f,headers:this.options.headers}),c(this,D,!0)}catch(d){if(d instanceof B)break;if(!(d instanceof y))throw d;if(d.status==409){let $=d.headers[G];E(this,g,ke).call(this,$),yield E(this,g,Ce).call(this,d.json);continue}else if(d.status>=400&&d.status<500)throw E(this,g,Ke).call(this,d),d}let{headers:b,status:N}=p,m=b.get(G);m&&c(this,S,m);let W=b.get(me);W&&c(this,U,W);let He=b.get(Ye);He&&c(this,I,He);let Ze=()=>{let d=b.get(Qe);return d?JSON.parse(d):{}};c(this,F,(r=n(this,F))!=null?r:Ze());let et=N===204?"[]":yield p.text();N===204&&c(this,H,Date.now());let re=n(this,se).parse(et,n(this,F));if(re.length>0){let d=re[re.length-1];Be(d)&&(c(this,H,Date.now()),c(this,w,!0)),yield E(this,g,Ce).call(this,re)}}}catch(a){if(c(this,ee,a),n(this,V)){let o=yield n(this,V).call(this,a);typeof o=="object"&&(E(this,g,ke).call(this),"params"in o&&(this.options.params=o.params),"headers"in o&&(this.options.headers=o.headers),E(this,g,Me).call(this));return}throw a}finally{c(this,D,!1)}})},Ce=function(e){return P(this,null,function*(){yield Promise.all(Array.from(n(this,k).values()).map(a=>P(this,[a],function*([t,r]){try{yield t(e)}catch(o){queueMicrotask(()=>{throw o})}})))})},Ke=function(e){n(this,k).forEach(([t,r])=>{r==null||r(e)})},ke=function(e){c(this,U,"-1"),c(this,I,""),c(this,S,e),c(this,w,!1),c(this,D,!1),c(this,F,void 0)},Z.Replica={FULL:"full",DEFAULT:"default"};var $e=Z;function gt(s){if(!s.url)throw new ae;if(s.signal&&!(s.signal instanceof AbortSignal))throw new ie;if(s.offset!==void 0&&s.offset!=="-1"&&!s.handle)throw new ce;if(s.params){let e=Object.keys(s.params).filter(t=>Ge.has(t));if(e.length>0)throw new le(e)}}var R,x,O,q,v,M,ze,Xe,Ue,Je=class{constructor(e){u(this,M);u(this,R);u(this,x,new Map);u(this,O,new Map);u(this,q,!1);u(this,v,!1);c(this,R,e),n(this,R).subscribe(E(this,M,ze).bind(this),E(this,M,Xe).bind(this))}get isUpToDate(){return n(this,R).isUpToDate}get lastOffset(){return n(this,R).lastOffset}get handle(){return n(this,R).shapeHandle}get rows(){return this.value.then(e=>Array.from(e.values()))}get currentRows(){return Array.from(this.currentValue.values())}get value(){return new Promise((e,t)=>{if(n(this,R).isUpToDate)e(this.currentValue);else{let r=this.subscribe(({value:a})=>{r(),n(this,v)&&t(n(this,v)),e(a)})}})}get currentValue(){return n(this,x)}get error(){return n(this,v)}lastSyncedAt(){return n(this,R).lastSyncedAt()}lastSynced(){return n(this,R).lastSynced()}isLoading(){return n(this,R).isLoading()}isConnected(){return n(this,R).isConnected()}subscribe(e){let t=Math.random();return n(this,O).set(t,e),()=>{n(this,O).delete(t)}}unsubscribeAll(){n(this,O).clear()}get numSubscribers(){return n(this,O).size}};R=new WeakMap,x=new WeakMap,O=new WeakMap,q=new WeakMap,v=new WeakMap,M=new WeakSet,ze=function(e){let t=!1,r=!1,a=!1;e.forEach(o=>{if(de(o))switch(t=["insert","update","delete"].includes(o.headers.operation),o.headers.operation){case"insert":n(this,x).set(o.key,o.value);break;case"update":n(this,x).set(o.key,A(A({},n(this,x).get(o.key)),o.value));break;case"delete":n(this,x).delete(o.key);break}if(Ee(o))switch(o.headers.control){case"up-to-date":r=!0,n(this,q)||(a=!0);break;case"must-refetch":n(this,x).clear(),c(this,v,!1),c(this,q,!1),r=!1,a=!1;break}}),(a||r&&t)&&(c(this,q,!0),E(this,M,Ue).call(this))},Xe=function(e){e instanceof y&&(c(this,v,e),E(this,M,Ue).call(this))},Ue=function(){n(this,O).forEach(e=>{e({value:this.currentValue,rows:this.currentRows})})};export{Re as BackoffDefaults,y as FetchError,Je as Shape,$e as ShapeStream,de as isChangeMessage,Ee as isControlMessage};
|
|
5
|
+
For more information visit the troubleshooting guide: /docs/guides/troubleshooting/missing-headers`,super(r)}};var ce=s=>Number(s),Xe=s=>s==="true"||s==="t",Ze=s=>BigInt(s),ke=s=>JSON.parse(s),et=s=>s,tt={int2:ce,int4:ce,int8:Ze,bool:Xe,float4:ce,float8:ce,json:ke,jsonb:ke};function st(s,e){let t=0,r=null,a="",n=!1,i=0,c;function h(f){let p=[];for(;t<f.length;t++){if(r=f[t],n)r==="\\"?a+=f[++t]:r==='"'?(p.push(e?e(a):a),a="",n=f[t+1]==='"',i=t+2):a+=r;else if(r==='"')n=!0;else if(r==="{")i=++t,p.push(h(f));else if(r==="}"){n=!1,i<t&&p.push(e?e(f.slice(i,t)):f.slice(i,t)),i=t+1;break}else r===","&&c!=="}"&&c!=='"'&&(p.push(e?e(f.slice(i,t)):f.slice(i,t)),i=t+1);c=r}return i<t&&p.push(e?e(f.slice(i,t+1)):f.slice(i,t+1)),p}return h(s)[0]}var le=class{constructor(e){this.parser=R(R({},tt),e)}parse(e,t){return JSON.parse(e,(r,a)=>{if(r==="value"&&typeof a=="object"&&a!==null){let n=a;Object.keys(n).forEach(i=>{n[i]=this.parseRow(i,n[i],t)})}return a})}parseRow(e,t,r){var C;let a=r[e];if(!a)return t;let p=a,{type:n,dims:i}=p,c=Me(p,["type","dims"]),h=(C=this.parser[n])!=null?C:et,f=Ue(h,a,e);return i&&i>0?Ue((E,L)=>st(E,f),a,e)(t):f(t,c)}};function Ue(s,e,t){var a;let r=!((a=e.not_null)!=null&&a);return n=>{if(rt(n)){if(!r)throw new oe(t!=null?t:"unknown");return null}return s(n,e)}}function rt(s){return s===null||s==="NULL"}function he(s){return"key"in s}function fe(s){return!he(s)}function He(s){return fe(s)&&s.headers.control==="up-to-date"}var ve="electric-cursor",K="electric-handle",ue="electric-offset",Oe="electric-schema",De="electric-up-to-date",Le="columns",ge="cursor",W="handle",M="live",$="offset",Ie="table",Fe="where",Ne="replica";var nt=[429],de={initialDelay:100,maxDelay:1e4,multiplier:1.3};function Be(s,e=de){let{initialDelay:t,maxDelay:r,multiplier:a,debug:n=!1,onFailedAttempt:i}=e;return(...c)=>P(this,null,function*(){var V;let h=c[0],f=c[1],p=t,C=0;for(;;)try{let E=yield s(...c);if(E.ok)return E;throw yield A.fromResponse(E,h.toString())}catch(E){if(i==null||i(),(V=f==null?void 0:f.signal)!=null&&V.aborted)throw new B;if(E instanceof A&&!nt.includes(E.status)&&E.status>=400&&E.status<500)throw E;yield new Promise(L=>setTimeout(L,p)),p=Math.min(p*a,r),n&&(C++,console.log(`Retry attempt #${C} after ${p}ms`))}})}var at={maxChunksToPrefetch:2};function Ye(s,e=at){let{maxChunksToPrefetch:t}=e,r;return(...n)=>P(this,null,function*(){let i=n[0].toString(),c=r==null?void 0:r.consume(...n);if(c)return c;r==null||r.abort();let h=yield s(...n),f=be(i,h);return f&&(r=new Re({fetchClient:s,maxPrefetchedRequests:t,url:f,requestInit:n[1]})),h})}var ot=["electric-offset","electric-handle"],it=["electric-cursor"],ct=["electric-schema"];function je(s){return(...e)=>P(this,null,function*(){let t=yield s(...e);if(t.ok){let r=t.headers,a=[],n=f=>a.push(...f.filter(p=>!r.has(p)));n(ot);let c=e[0].toString(),h=new URL(c);if(h.searchParams.get(M)==="true"&&n(it),(!h.searchParams.has(M)||h.searchParams.get(M)==="false")&&n(ct),a.length>0)throw new ie(c,a)}return t})}var G,J,y,I,T,Y,pe,Re=class{constructor(e){u(this,Y);u(this,G);u(this,J);u(this,y,new Map);u(this,I);u(this,T);var t;l(this,G,(t=e.fetchClient)!=null?t:(...r)=>fetch(...r)),l(this,J,e.maxPrefetchedRequests),l(this,I,e.url.toString()),l(this,T,o(this,I)),m(this,Y,pe).call(this,e.url,e.requestInit)}abort(){o(this,y).forEach(([e,t])=>t.abort())}consume(...e){var a;let t=e[0].toString(),r=(a=o(this,y).get(t))==null?void 0:a[0];if(!(!r||t!==o(this,I)))return o(this,y).delete(t),r.then(n=>{let i=be(t,n);l(this,I,i),o(this,T)&&!o(this,y).has(o(this,T))&&m(this,Y,pe).call(this,o(this,T),e[1])}).catch(()=>{}),r}};G=new WeakMap,J=new WeakMap,y=new WeakMap,I=new WeakMap,T=new WeakMap,Y=new WeakSet,pe=function(...e){var a,n;let t=e[0].toString();if(o(this,y).size>=o(this,J))return;let r=new AbortController;try{let i=o(this,G).call(this,t,te(R({},(a=e[1])!=null?a:{}),{signal:lt(r,(n=e[1])==null?void 0:n.signal)}));o(this,y).set(t,[i,r]),i.then(c=>{if(!c.ok||r.signal.aborted)return;let h=be(t,c);if(!h||h===t){l(this,T,void 0);return}return l(this,T,h),m(this,Y,pe).call(this,h,e[1])}).catch(()=>{})}catch(i){}};function be(s,e){let t=e.headers.get(K),r=e.headers.get(ue),a=e.headers.has(De);if(!t||!r||a)return;let n=new URL(s);if(!n.searchParams.has(M))return n.searchParams.set(W,t),n.searchParams.set($,r),n.searchParams.sort(),n.toString()}function lt(s,e){return e&&(e.aborted?s.abort():e.addEventListener("abort",()=>s.abort(),{once:!0})),s.signal}var Qe=new Set([ge,W,M,$]);function ht(s){let e={};for(let[t,r]of Object.entries(s))e[t]=Array.isArray(r)?r.join(","):r;return e}var z,X,Z,k,U,F,H,w,v,_,N,j,g,Ae,ye,Ve,Te,Pe=class{constructor(e){u(this,g);u(this,z,null);u(this,X);u(this,Z);u(this,k,new Map);u(this,U);u(this,F);u(this,H);u(this,w,!1);u(this,v,!1);u(this,_);u(this,N);u(this,j);var a,n,i;this.options=R({subscribe:!0},e),ft(this.options),l(this,U,(a=this.options.offset)!=null?a:"-1"),l(this,F,""),l(this,_,this.options.handle),l(this,Z,new le(e.parser)),l(this,j,this.options.onError);let t=(n=e.fetchClient)!=null?n:(...c)=>fetch(...c),r=Be(t,te(R({},(i=e.backoffOptions)!=null?i:de),{onFailedAttempt:()=>{var c,h;l(this,v,!1),(h=(c=e.backoffOptions)==null?void 0:c.onFailedAttempt)==null||h.call(c)}}));l(this,X,je(Ye(r))),m(this,g,Ae).call(this)}get shapeHandle(){return o(this,_)}get error(){return o(this,z)}get isUpToDate(){return o(this,w)}get lastOffset(){return o(this,U)}subscribe(e,t=()=>{}){let r=Math.random();return o(this,k).set(r,[e,t]),()=>{o(this,k).delete(r)}}unsubscribeAll(){o(this,k).clear()}lastSyncedAt(){return o(this,H)}lastSynced(){return o(this,H)===void 0?1/0:Date.now()-o(this,H)}isConnected(){return o(this,v)}isLoading(){return!o(this,w)}};z=new WeakMap,X=new WeakMap,Z=new WeakMap,k=new WeakMap,U=new WeakMap,F=new WeakMap,H=new WeakMap,w=new WeakMap,v=new WeakMap,_=new WeakMap,N=new WeakMap,j=new WeakMap,g=new WeakSet,Ae=function(){return P(this,null,function*(){var e,t;try{for(;!((e=this.options.signal)!=null&&e.aborted)&&!o(this,w)||this.options.subscribe;){let{url:r,signal:a}=this.options,n=new URL(r);if(this.options.params){let d=Object.keys(this.options.params).filter(me=>Qe.has(me));if(d.length>0)throw new Error(`Cannot use reserved Electric parameter names in custom params: ${d.join(", ")}`);let b=ht(this.options.params);b.table&&n.searchParams.set(Ie,b.table),b.where&&n.searchParams.set(Fe,b.where),b.columns&&n.searchParams.set(Le,b.columns),b.replica&&n.searchParams.set(Ne,b.replica);let q=R({},b);delete q.table,delete q.where,delete q.columns,delete q.replica;for(let[me,$e]of Object.entries(q))n.searchParams.set(me,$e)}n.searchParams.set($,o(this,U)),o(this,w)&&(n.searchParams.set(M,"true"),n.searchParams.set(ge,o(this,F))),o(this,_)&&n.searchParams.set(W,o(this,_)),n.searchParams.sort();let i;try{i=yield o(this,X).call(this,n.toString(),{signal:a,headers:this.options.headers}),l(this,v,!0)}catch(d){if(d instanceof B)break;if(!(d instanceof A))throw d;if(d.status==409){let b=d.headers[K];m(this,g,Te).call(this,b),yield m(this,g,ye).call(this,d.json);continue}else if(d.status>=400&&d.status<500)throw m(this,g,Ve).call(this,d),d}let{headers:c,status:h}=i,f=c.get(K);f&&l(this,_,f);let p=c.get(ue);p&&l(this,U,p);let C=c.get(ve);C&&l(this,F,C);let V=()=>{let d=c.get(Oe);return d?JSON.parse(d):{}};l(this,N,(t=o(this,N))!=null?t:V());let E=h===204?"[]":yield i.text();h===204&&l(this,H,Date.now());let L=o(this,Z).parse(E,o(this,N));if(L.length>0){let d=L[L.length-1];He(d)&&(l(this,H,Date.now()),l(this,w,!0)),yield m(this,g,ye).call(this,L)}}}catch(r){if(l(this,z,r),o(this,j)){let a=yield o(this,j).call(this,r);typeof a=="object"&&(m(this,g,Te).call(this),"params"in a&&(this.options.params=a.params),"headers"in a&&(this.options.headers=a.headers),m(this,g,Ae).call(this));return}throw r}finally{l(this,v,!1)}})},ye=function(e){return P(this,null,function*(){yield Promise.all(Array.from(o(this,k).values()).map(a=>P(this,[a],function*([t,r]){try{yield t(e)}catch(n){queueMicrotask(()=>{throw n})}})))})},Ve=function(e){o(this,k).forEach(([t,r])=>{r==null||r(e)})},Te=function(e){l(this,U,"-1"),l(this,F,""),l(this,_,e),l(this,w,!1),l(this,v,!1),l(this,N,void 0)},Pe.Replica={FULL:"full",DEFAULT:"default"};function ft(s){if(!s.url)throw new se;if(s.signal&&!(s.signal instanceof AbortSignal))throw new re;if(s.offset!==void 0&&s.offset!=="-1"&&!s.handle)throw new ne;if(s.params){let e=Object.keys(s.params).filter(t=>Qe.has(t));if(e.length>0)throw new ae(e)}}var x,O,Q,D,S,Ke,We,we,qe=class{constructor(e){u(this,S);u(this,x,new Map);u(this,O,new Map);u(this,Q,!1);u(this,D,!1);this.stream=e,this.stream.subscribe(m(this,S,Ke).bind(this),m(this,S,We).bind(this))}get isUpToDate(){return this.stream.isUpToDate}get lastOffset(){return this.stream.lastOffset}get handle(){return this.stream.shapeHandle}get rows(){return this.value.then(e=>Array.from(e.values()))}get currentRows(){return Array.from(this.currentValue.values())}get value(){return new Promise((e,t)=>{if(this.stream.isUpToDate)e(this.currentValue);else{let r=this.subscribe(({value:a})=>{r(),o(this,D)&&t(o(this,D)),e(a)})}})}get currentValue(){return o(this,x)}get error(){return o(this,D)}lastSyncedAt(){return this.stream.lastSyncedAt()}lastSynced(){return this.stream.lastSynced()}isLoading(){return this.stream.isLoading()}isConnected(){return this.stream.isConnected()}subscribe(e){let t=Math.random();return o(this,O).set(t,e),()=>{o(this,O).delete(t)}}unsubscribeAll(){o(this,O).clear()}get numSubscribers(){return o(this,O).size}};x=new WeakMap,O=new WeakMap,Q=new WeakMap,D=new WeakMap,S=new WeakSet,Ke=function(e){let t=!1,r=!1,a=!1;e.forEach(n=>{if(he(n))switch(t=["insert","update","delete"].includes(n.headers.operation),n.headers.operation){case"insert":o(this,x).set(n.key,n.value);break;case"update":o(this,x).set(n.key,R(R({},o(this,x).get(n.key)),n.value));break;case"delete":o(this,x).delete(n.key);break}if(fe(n))switch(n.headers.control){case"up-to-date":r=!0,o(this,Q)||(a=!0);break;case"must-refetch":o(this,x).clear(),l(this,D,!1),l(this,Q,!1),r=!1,a=!1;break}}),(a||r&&t)&&(l(this,Q,!0),m(this,S,we).call(this))},We=function(e){e instanceof A&&(l(this,D,e),m(this,S,we).call(this))},we=function(){o(this,O).forEach(e=>{e({value:this.currentValue,rows:this.currentRows})})};export{de as BackoffDefaults,A as FetchError,qe as Shape,Pe as ShapeStream,he as isChangeMessage,fe as isControlMessage};
|
|
6
6
|
//# sourceMappingURL=index.browser.mjs.map
|