@electric-sql/client 1.5.3 → 1.5.5
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 +218 -6
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +4 -3
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.legacy-esm.js +217 -7
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +217 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +29 -5
- package/src/helpers.ts +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -463,10 +463,10 @@ function snakeCamelMapper(schema) {
|
|
|
463
463
|
|
|
464
464
|
// src/helpers.ts
|
|
465
465
|
function isChangeMessage(message) {
|
|
466
|
-
return `key` in message;
|
|
466
|
+
return message != null && `key` in message;
|
|
467
467
|
}
|
|
468
468
|
function isControlMessage(message) {
|
|
469
|
-
return !isChangeMessage(message);
|
|
469
|
+
return message != null && !isChangeMessage(message);
|
|
470
470
|
}
|
|
471
471
|
function isUpToDateMessage(message) {
|
|
472
472
|
return isControlMessage(message) && message.headers.control === `up-to-date`;
|
|
@@ -891,8 +891,202 @@ function compileOrderBy(clauses, columnMapper) {
|
|
|
891
891
|
}).join(`, `);
|
|
892
892
|
}
|
|
893
893
|
|
|
894
|
-
//
|
|
895
|
-
|
|
894
|
+
// ../../node_modules/.pnpm/@microsoft+fetch-event-source@2.0.1_patch_hash=46f4e76dd960e002a542732bb4323817a24fce1673cb71e2f458fe09776fa188/node_modules/@microsoft/fetch-event-source/lib/esm/parse.js
|
|
895
|
+
async function getBytes(stream, onChunk) {
|
|
896
|
+
const reader = stream.getReader();
|
|
897
|
+
let result;
|
|
898
|
+
while (!(result = await reader.read()).done) {
|
|
899
|
+
onChunk(result.value);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
function getLines(onLine) {
|
|
903
|
+
let buffer;
|
|
904
|
+
let position;
|
|
905
|
+
let fieldLength;
|
|
906
|
+
let discardTrailingNewline = false;
|
|
907
|
+
return function onChunk(arr) {
|
|
908
|
+
if (buffer === void 0) {
|
|
909
|
+
buffer = arr;
|
|
910
|
+
position = 0;
|
|
911
|
+
fieldLength = -1;
|
|
912
|
+
} else {
|
|
913
|
+
buffer = concat(buffer, arr);
|
|
914
|
+
}
|
|
915
|
+
const bufLength = buffer.length;
|
|
916
|
+
let lineStart = 0;
|
|
917
|
+
while (position < bufLength) {
|
|
918
|
+
if (discardTrailingNewline) {
|
|
919
|
+
if (buffer[position] === 10) {
|
|
920
|
+
lineStart = ++position;
|
|
921
|
+
}
|
|
922
|
+
discardTrailingNewline = false;
|
|
923
|
+
}
|
|
924
|
+
let lineEnd = -1;
|
|
925
|
+
for (; position < bufLength && lineEnd === -1; ++position) {
|
|
926
|
+
switch (buffer[position]) {
|
|
927
|
+
case 58:
|
|
928
|
+
if (fieldLength === -1) {
|
|
929
|
+
fieldLength = position - lineStart;
|
|
930
|
+
}
|
|
931
|
+
break;
|
|
932
|
+
case 13:
|
|
933
|
+
discardTrailingNewline = true;
|
|
934
|
+
case 10:
|
|
935
|
+
lineEnd = position;
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
if (lineEnd === -1) {
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
|
|
943
|
+
lineStart = position;
|
|
944
|
+
fieldLength = -1;
|
|
945
|
+
}
|
|
946
|
+
if (lineStart === bufLength) {
|
|
947
|
+
buffer = void 0;
|
|
948
|
+
} else if (lineStart !== 0) {
|
|
949
|
+
buffer = buffer.subarray(lineStart);
|
|
950
|
+
position -= lineStart;
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
function getMessages(onId, onRetry, onMessage) {
|
|
955
|
+
let message = newMessage();
|
|
956
|
+
const decoder = new TextDecoder();
|
|
957
|
+
return function onLine(line, fieldLength) {
|
|
958
|
+
if (line.length === 0) {
|
|
959
|
+
onMessage === null || onMessage === void 0 ? void 0 : onMessage(message);
|
|
960
|
+
message = newMessage();
|
|
961
|
+
} else if (fieldLength > 0) {
|
|
962
|
+
const field = decoder.decode(line.subarray(0, fieldLength));
|
|
963
|
+
const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1);
|
|
964
|
+
const value = decoder.decode(line.subarray(valueOffset));
|
|
965
|
+
switch (field) {
|
|
966
|
+
case "data":
|
|
967
|
+
message.data = message.data ? message.data + "\n" + value : value;
|
|
968
|
+
break;
|
|
969
|
+
case "event":
|
|
970
|
+
message.event = value;
|
|
971
|
+
break;
|
|
972
|
+
case "id":
|
|
973
|
+
onId(message.id = value);
|
|
974
|
+
break;
|
|
975
|
+
case "retry":
|
|
976
|
+
const retry = parseInt(value, 10);
|
|
977
|
+
if (!isNaN(retry)) {
|
|
978
|
+
onRetry(message.retry = retry);
|
|
979
|
+
}
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
function concat(a, b) {
|
|
986
|
+
const res = new Uint8Array(a.length + b.length);
|
|
987
|
+
res.set(a);
|
|
988
|
+
res.set(b, a.length);
|
|
989
|
+
return res;
|
|
990
|
+
}
|
|
991
|
+
function newMessage() {
|
|
992
|
+
return {
|
|
993
|
+
data: "",
|
|
994
|
+
event: "",
|
|
995
|
+
id: "",
|
|
996
|
+
retry: void 0
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// ../../node_modules/.pnpm/@microsoft+fetch-event-source@2.0.1_patch_hash=46f4e76dd960e002a542732bb4323817a24fce1673cb71e2f458fe09776fa188/node_modules/@microsoft/fetch-event-source/lib/esm/fetch.js
|
|
1001
|
+
var __rest = function(s, e) {
|
|
1002
|
+
var t = {};
|
|
1003
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
1004
|
+
t[p] = s[p];
|
|
1005
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
1006
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
1007
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
1008
|
+
t[p[i]] = s[p[i]];
|
|
1009
|
+
}
|
|
1010
|
+
return t;
|
|
1011
|
+
};
|
|
1012
|
+
var EventStreamContentType = "text/event-stream";
|
|
1013
|
+
var DefaultRetryInterval = 1e3;
|
|
1014
|
+
var LastEventId = "last-event-id";
|
|
1015
|
+
function fetchEventSource(input, _a) {
|
|
1016
|
+
var { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, fetch: inputFetch } = _a, rest = __rest(_a, ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden", "fetch"]);
|
|
1017
|
+
return new Promise((resolve, reject) => {
|
|
1018
|
+
const headers = Object.assign({}, inputHeaders);
|
|
1019
|
+
if (!headers.accept) {
|
|
1020
|
+
headers.accept = EventStreamContentType;
|
|
1021
|
+
}
|
|
1022
|
+
let curRequestController;
|
|
1023
|
+
function onVisibilityChange() {
|
|
1024
|
+
curRequestController.abort();
|
|
1025
|
+
if (typeof document !== "undefined" && !document.hidden) {
|
|
1026
|
+
create();
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
if (typeof document !== "undefined" && !openWhenHidden) {
|
|
1030
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1031
|
+
}
|
|
1032
|
+
let retryInterval = DefaultRetryInterval;
|
|
1033
|
+
let retryTimer = 0;
|
|
1034
|
+
function dispose() {
|
|
1035
|
+
if (typeof document !== "undefined") {
|
|
1036
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1037
|
+
}
|
|
1038
|
+
clearTimeout(retryTimer);
|
|
1039
|
+
curRequestController.abort();
|
|
1040
|
+
}
|
|
1041
|
+
inputSignal === null || inputSignal === void 0 ? void 0 : inputSignal.addEventListener("abort", () => {
|
|
1042
|
+
dispose();
|
|
1043
|
+
});
|
|
1044
|
+
const fetch2 = inputFetch !== null && inputFetch !== void 0 ? inputFetch : window.fetch;
|
|
1045
|
+
const onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
|
|
1046
|
+
async function create() {
|
|
1047
|
+
var _a2;
|
|
1048
|
+
curRequestController = new AbortController();
|
|
1049
|
+
const sig = inputSignal.aborted ? inputSignal : curRequestController.signal;
|
|
1050
|
+
try {
|
|
1051
|
+
const response = await fetch2(input, Object.assign(Object.assign({}, rest), { headers, signal: sig }));
|
|
1052
|
+
await onopen(response);
|
|
1053
|
+
await getBytes(response.body, getLines(getMessages((id) => {
|
|
1054
|
+
if (id) {
|
|
1055
|
+
headers[LastEventId] = id;
|
|
1056
|
+
} else {
|
|
1057
|
+
delete headers[LastEventId];
|
|
1058
|
+
}
|
|
1059
|
+
}, (retry) => {
|
|
1060
|
+
retryInterval = retry;
|
|
1061
|
+
}, onmessage)));
|
|
1062
|
+
onclose === null || onclose === void 0 ? void 0 : onclose();
|
|
1063
|
+
dispose();
|
|
1064
|
+
resolve();
|
|
1065
|
+
} catch (err) {
|
|
1066
|
+
if (sig.aborted) {
|
|
1067
|
+
dispose();
|
|
1068
|
+
reject(err);
|
|
1069
|
+
} else if (!curRequestController.signal.aborted) {
|
|
1070
|
+
try {
|
|
1071
|
+
const interval = (_a2 = onerror === null || onerror === void 0 ? void 0 : onerror(err)) !== null && _a2 !== void 0 ? _a2 : retryInterval;
|
|
1072
|
+
clearTimeout(retryTimer);
|
|
1073
|
+
retryTimer = setTimeout(create, interval);
|
|
1074
|
+
} catch (innerErr) {
|
|
1075
|
+
dispose();
|
|
1076
|
+
reject(innerErr);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
create();
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
function defaultOnOpen(response) {
|
|
1085
|
+
const contentType = response.headers.get("content-type");
|
|
1086
|
+
if (!(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(EventStreamContentType))) {
|
|
1087
|
+
throw new Error(`Expected content-type to be ${EventStreamContentType}, Actual: ${contentType}`);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
896
1090
|
|
|
897
1091
|
// src/expired-shapes-cache.ts
|
|
898
1092
|
var ExpiredShapesCache = class {
|
|
@@ -2127,7 +2321,8 @@ requestShape_fn = async function() {
|
|
|
2127
2321
|
}
|
|
2128
2322
|
const newShapeHandle = e.headers[SHAPE_HANDLE_HEADER] || `${__privateGet(this, _syncState).handle}-next`;
|
|
2129
2323
|
__privateMethod(this, _ShapeStream_instances, reset_fn).call(this, newShapeHandle);
|
|
2130
|
-
|
|
2324
|
+
const messages409 = Array.isArray(e.json) ? e.json : e.json != null ? [e.json] : [];
|
|
2325
|
+
await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, messages409);
|
|
2131
2326
|
return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
|
|
2132
2327
|
} else {
|
|
2133
2328
|
throw e;
|
|
@@ -2310,6 +2505,12 @@ onInitialResponse_fn = async function(response) {
|
|
|
2310
2505
|
return true;
|
|
2311
2506
|
};
|
|
2312
2507
|
onMessages_fn = async function(batch, isSseMessage = false) {
|
|
2508
|
+
if (!Array.isArray(batch)) {
|
|
2509
|
+
console.warn(
|
|
2510
|
+
`[Electric] #onMessages called with non-array argument (${typeof batch}). This is a client bug \u2014 please report it.`
|
|
2511
|
+
);
|
|
2512
|
+
return;
|
|
2513
|
+
}
|
|
2313
2514
|
if (batch.length === 0) return;
|
|
2314
2515
|
const lastMessage = batch[batch.length - 1];
|
|
2315
2516
|
const hasUpToDateMessage = isUpToDateMessage(lastMessage);
|
|
@@ -2366,6 +2567,7 @@ fetchShape_fn = async function(opts) {
|
|
|
2366
2567
|
return __privateMethod(this, _ShapeStream_instances, requestShapeLongPoll_fn).call(this, opts);
|
|
2367
2568
|
};
|
|
2368
2569
|
requestShapeLongPoll_fn = async function(opts) {
|
|
2570
|
+
var _a;
|
|
2369
2571
|
const { fetchUrl, requestAbortController, headers } = opts;
|
|
2370
2572
|
const response = await __privateGet(this, _fetchClient2).call(this, fetchUrl.toString(), {
|
|
2371
2573
|
signal: requestAbortController.signal,
|
|
@@ -2378,6 +2580,16 @@ requestShapeLongPoll_fn = async function(opts) {
|
|
|
2378
2580
|
const res = await response.text();
|
|
2379
2581
|
const messages = res || `[]`;
|
|
2380
2582
|
const batch = __privateGet(this, _messageParser).parse(messages, schema);
|
|
2583
|
+
if (!Array.isArray(batch)) {
|
|
2584
|
+
const preview = (_a = JSON.stringify(batch)) == null ? void 0 : _a.slice(0, 200);
|
|
2585
|
+
throw new FetchError(
|
|
2586
|
+
response.status,
|
|
2587
|
+
`Received non-array response body from shape endpoint. This may indicate a proxy or CDN is returning an unexpected response. Expected a JSON array, got ${typeof batch}: ${preview}`,
|
|
2588
|
+
void 0,
|
|
2589
|
+
Object.fromEntries(response.headers.entries()),
|
|
2590
|
+
fetchUrl.toString()
|
|
2591
|
+
);
|
|
2592
|
+
}
|
|
2381
2593
|
await __privateMethod(this, _ShapeStream_instances, onMessages_fn).call(this, batch);
|
|
2382
2594
|
};
|
|
2383
2595
|
requestShapeSSE_fn = async function(opts) {
|
|
@@ -2390,7 +2602,7 @@ requestShapeSSE_fn = async function(opts) {
|
|
|
2390
2602
|
let ignoredStaleResponse = false;
|
|
2391
2603
|
try {
|
|
2392
2604
|
let buffer = [];
|
|
2393
|
-
await
|
|
2605
|
+
await fetchEventSource(fetchUrl.toString(), {
|
|
2394
2606
|
headers: sseHeaders,
|
|
2395
2607
|
fetch: fetch2,
|
|
2396
2608
|
onopen: async (response) => {
|