@rebasepro/client 0.9.1-canary.d198c11 → 0.9.1-canary.e2fc7b6
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/index.es.js +35 -9
- package/dist/index.es.js.map +1 -1
- package/dist/transport.d.ts +21 -0
- package/dist/websocket.d.ts +13 -0
- package/package.json +4 -4
- package/src/realtime-row-identity.test.ts +254 -0
- package/src/transport.ts +21 -0
- package/src/websocket.ts +62 -11
- package/dist/collection.test.d.ts +0 -1
- package/dist/cron.test.d.ts +0 -1
- package/dist/data-proxy.test.d.ts +0 -1
- package/dist/realtime-optout.test.d.ts +0 -1
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, GeoPoint, PUBLIC_STORAGE_PREFIX, RebaseApiError, RebaseApiError as RebaseApiError$1, RebaseClientError, Vector, isPublicStoragePath } from "@rebasepro/types";
|
|
2
|
-
import { QueryBuilder, and, cond, or, serializeFilter, serializeLogicalCondition, serializeOrderBy } from "@rebasepro/common";
|
|
2
|
+
import { COMPOSITE_ID_SEPARATOR, QueryBuilder, and, buildCompositeId, cond, or, serializeFilter, serializeLogicalCondition, serializeOrderBy } from "@rebasepro/common";
|
|
3
3
|
import { toSnakeCase } from "@rebasepro/utils";
|
|
4
4
|
//#region src/reviver.ts
|
|
5
5
|
function rebaseReviver(_key, value) {
|
|
@@ -1696,7 +1696,9 @@ var RebaseWebSocketClient = class {
|
|
|
1696
1696
|
const collectionSub = this.collectionSubscriptions.get(subscriptionKey);
|
|
1697
1697
|
if (collectionSub) {
|
|
1698
1698
|
const incomingRows = message.rows || [];
|
|
1699
|
-
const
|
|
1699
|
+
const updatePks = message.pks;
|
|
1700
|
+
if (updatePks) collectionSub.pks = updatePks;
|
|
1701
|
+
const rows = this.mergeRows(collectionSub.latestData, incomingRows, collectionSub.pks);
|
|
1700
1702
|
collectionSub.latestData = rows;
|
|
1701
1703
|
collectionSub.lastUpdated = Date.now();
|
|
1702
1704
|
collectionSub.isInitialDataReceived = true;
|
|
@@ -1718,12 +1720,14 @@ var RebaseWebSocketClient = class {
|
|
|
1718
1720
|
const collectionSub = this.collectionSubscriptions.get(subscriptionKey);
|
|
1719
1721
|
if (collectionSub && collectionSub.isInitialDataReceived && collectionSub.latestData) {
|
|
1720
1722
|
const patchWireEntity = message.row ?? null;
|
|
1721
|
-
const
|
|
1723
|
+
const patchMessage = message;
|
|
1724
|
+
const patchEntityId = patchMessage.id;
|
|
1725
|
+
if (patchMessage.pks) collectionSub.pks = patchMessage.pks;
|
|
1722
1726
|
const patchRow = patchWireEntity ? patchWireEntity : null;
|
|
1723
1727
|
let updated;
|
|
1724
|
-
if (patchRow === null) updated = collectionSub.latestData.filter((e) =>
|
|
1728
|
+
if (patchRow === null) updated = collectionSub.latestData.filter((e) => this.rowAddress(e, collectionSub.pks) !== String(patchEntityId));
|
|
1725
1729
|
else {
|
|
1726
|
-
const idx = collectionSub.latestData.findIndex((e) =>
|
|
1730
|
+
const idx = collectionSub.latestData.findIndex((e) => this.rowAddress(e, collectionSub.pks) === String(patchEntityId));
|
|
1727
1731
|
if (idx >= 0) {
|
|
1728
1732
|
updated = [...collectionSub.latestData];
|
|
1729
1733
|
updated[idx] = patchRow;
|
|
@@ -2073,17 +2077,39 @@ var RebaseWebSocketClient = class {
|
|
|
2073
2077
|
return val;
|
|
2074
2078
|
}
|
|
2075
2079
|
/**
|
|
2080
|
+
* The address of a row, for matching it against another copy of itself.
|
|
2081
|
+
*
|
|
2082
|
+
* A row is exactly its columns and carries no address, so it is derived
|
|
2083
|
+
* from the key columns the server named — including the ordinary case where
|
|
2084
|
+
* that key is `id`, which the server reports like any other.
|
|
2085
|
+
*
|
|
2086
|
+
* Undefined when there are no keys, which means the server could not
|
|
2087
|
+
* resolve any: such rows genuinely cannot be recognised, and guessing at a
|
|
2088
|
+
* column called `id` would be inventing an identity for a table that has
|
|
2089
|
+
* none.
|
|
2090
|
+
*/
|
|
2091
|
+
rowAddress(row, pks) {
|
|
2092
|
+
if (!pks || pks.length === 0) return void 0;
|
|
2093
|
+
const address = buildCompositeId(row, pks);
|
|
2094
|
+
if (!address || address.split(COMPOSITE_ID_SEPARATOR).every((part) => part === "")) return void 0;
|
|
2095
|
+
return address;
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2076
2098
|
* Merge incoming rows with cached data, preserving cached references
|
|
2077
2099
|
* for rows whose values haven't changed. This avoids unnecessary
|
|
2078
2100
|
* React re-renders when the server refetches all rows but most
|
|
2079
2101
|
* haven't actually changed.
|
|
2080
2102
|
*/
|
|
2081
|
-
mergeRows(cached, incoming) {
|
|
2103
|
+
mergeRows(cached, incoming, pks) {
|
|
2082
2104
|
if (!cached || cached.length === 0) return incoming;
|
|
2083
2105
|
const cachedById = /* @__PURE__ */ new Map();
|
|
2084
|
-
for (const row of cached)
|
|
2106
|
+
for (const row of cached) {
|
|
2107
|
+
const address = this.rowAddress(row, pks);
|
|
2108
|
+
if (address !== void 0) cachedById.set(address, row);
|
|
2109
|
+
}
|
|
2085
2110
|
return incoming.map((incomingRow) => {
|
|
2086
|
-
const
|
|
2111
|
+
const address = this.rowAddress(incomingRow, pks);
|
|
2112
|
+
const cachedRow = address === void 0 ? void 0 : cachedById.get(address);
|
|
2087
2113
|
if (!cachedRow) return incomingRow;
|
|
2088
2114
|
const normCached = this.normalizeForComparison(cachedRow);
|
|
2089
2115
|
const normIncoming = this.normalizeForComparison(incomingRow);
|
|
@@ -2095,7 +2121,7 @@ var RebaseWebSocketClient = class {
|
|
|
2095
2121
|
cached: normCached[key],
|
|
2096
2122
|
incoming: normIncoming[key]
|
|
2097
2123
|
};
|
|
2098
|
-
console.debug(`[RebaseWS] Row ${
|
|
2124
|
+
console.debug(`[RebaseWS] Row ${address} refetch mismatch:\n`, JSON.stringify(mismatches, null, 2));
|
|
2099
2125
|
}
|
|
2100
2126
|
return incomingRow;
|
|
2101
2127
|
});
|