@dittolive/ditto 4.7.0 → 4.7.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 +2 -2
- package/node/ditto.cjs.js +70 -56
- package/node/ditto.darwin-arm64.node +0 -0
- package/node/ditto.darwin-x64.node +0 -0
- package/node/ditto.linux-arm.node +0 -0
- package/node/ditto.linux-arm64.node +0 -0
- package/node/ditto.linux-x64.node +0 -0
- package/node/ditto.win32-x64.node +0 -0
- package/node/transports.darwin-arm64.node +0 -0
- package/node/transports.darwin-x64.node +0 -0
- package/package.json +1 -1
- package/react-native/android/build.gradle +1 -1
- package/react-native/src/sources/@ditto.core.ts +1 -1
- package/react-native/src/sources/@environment.ts +1 -1
- package/react-native/src/sources/attachment-fetcher-manager.ts +1 -1
- package/react-native/src/sources/attachment-fetcher.ts +2 -2
- package/react-native/src/sources/bridge.ts +1 -1
- package/react-native/src/sources/ditto.ts +7 -3
- package/react-native/src/sources/ffi.ts +16 -11
- package/react-native/src/sources/live-query-manager.ts +3 -4
- package/react-native/src/sources/live-query.ts +2 -1
- package/react-native/src/sources/pending-collections-operation.ts +15 -6
- package/react-native/src/sources/pending-cursor-operation.ts +2 -2
- package/react-native/src/sources/pending-id-specific-operation.ts +3 -3
- package/react-native/src/sources/presence-manager.ts +8 -9
- package/react-native/src/sources/presence.ts +6 -6
- package/react-native/src/sources/small-peer-info.ts +2 -2
- package/react-native/src/sources/store-observer.ts +1 -1
- package/react-native/src/sources/store.ts +5 -2
- package/react-native/src/sources/subscription-manager.ts +12 -12
- package/react-native/src/sources/subscription.ts +2 -2
- package/types/ditto.d.ts +8 -4
- package/web/ditto.es6.js +1 -1
- package/web/ditto.umd.js +1 -1
- package/web/ditto.wasm +0 -0
- package/react-native/android/.project +0 -34
- package/react-native/android/bin/.project +0 -34
- package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.class +0 -0
- package/react-native/android/bin/src/main/java/com/dittolive/rnsdk/DittoRNSDKPackage.class +0 -0
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.json +0 -14
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a.log +0 -1
- package/react-native/android/build/intermediates/cxx/abi_configuration_4i3a4k2a_key.json +0 -23
- package/react-native/android/build/intermediates/cxx/create_cxx_tasks_371_timing.txt +0 -5
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.json +0 -11
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f.log +0 -72
- package/react-native/android/build/intermediates/cxx/ndk_locator_record_4q2c3f1f_key.json +0 -10
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
_Ditto is a cross-platform SDK that allows mobile, web, and IoT apps to sync
|
|
4
4
|
with and even without connectivity._
|
|
5
5
|
|
|
6
|
-
Version: **4.7.
|
|
6
|
+
Version: **4.7.1**
|
|
7
7
|
|
|
8
8
|
For more information please visit [ditto.live](https://ditto.live), as well as the
|
|
9
|
-
[API Reference](https://software.ditto.live/js/Ditto/4.7.
|
|
9
|
+
[API Reference](https://software.ditto.live/js/Ditto/4.7.1/api-reference/) for this particular version.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
package/node/ditto.cjs.js
CHANGED
|
@@ -802,14 +802,18 @@ function addSubscription(ditto, collectionName, query, queryArgsCBOR, orderBy, l
|
|
|
802
802
|
ensureInitialized();
|
|
803
803
|
const collectionNameX = bytesFromString(collectionName);
|
|
804
804
|
const queryX = bytesFromString(query);
|
|
805
|
-
|
|
805
|
+
const statusCode = ditto_add_subscription(ditto, collectionNameX, queryX, queryArgsCBOR, orderBy, limit, offset);
|
|
806
|
+
if (statusCode !== 0)
|
|
807
|
+
throw new Error(errorMessage() || `ditto_add_subscription() failed with error code: ${statusCode}`);
|
|
806
808
|
}
|
|
807
809
|
/** @internal */
|
|
808
810
|
function removeSubscription(ditto, collectionName, query, queryArgsCBOR, orderBy, limit, offset) {
|
|
809
811
|
ensureInitialized();
|
|
810
812
|
const collectionNameX = bytesFromString(collectionName);
|
|
811
813
|
const queryX = bytesFromString(query);
|
|
812
|
-
|
|
814
|
+
const statusCode = ditto_remove_subscription(ditto, collectionNameX, queryX, queryArgsCBOR, orderBy, limit, offset);
|
|
815
|
+
if (statusCode !== 0)
|
|
816
|
+
throw new Error(errorMessage() || `ditto_remove_subscription() failed with error code: ${statusCode}`);
|
|
813
817
|
}
|
|
814
818
|
/** @internal */
|
|
815
819
|
function tryAddSyncSubscription(dittoPointer, query, queryArgsCBOR) {
|
|
@@ -1232,7 +1236,7 @@ function setDeadlockTimeout(duration) {
|
|
|
1232
1236
|
setDeadlockTimeout$1(duration);
|
|
1233
1237
|
}
|
|
1234
1238
|
/** @internal */
|
|
1235
|
-
|
|
1239
|
+
function dittoRegisterPresenceV1Callback(self, cb) {
|
|
1236
1240
|
ensureInitialized();
|
|
1237
1241
|
ditto_register_presence_v1_callback(self, wrapBackgroundCbForFFI((err) => log('Error', `The registered presence callback v1 errored with ${err}`), (cJsonStr) => {
|
|
1238
1242
|
const jsonStr = refCStringToString(cJsonStr);
|
|
@@ -1242,10 +1246,10 @@ async function dittoRegisterPresenceV1Callback(self, cb) {
|
|
|
1242
1246
|
/** @internal */
|
|
1243
1247
|
async function dittoClearPresenceCallback(self) {
|
|
1244
1248
|
ensureInitialized();
|
|
1245
|
-
|
|
1249
|
+
return ditto_clear_presence_callback(self);
|
|
1246
1250
|
}
|
|
1247
1251
|
/** @internal */
|
|
1248
|
-
|
|
1252
|
+
function dittoRegisterPresenceV3Callback(self, cb) {
|
|
1249
1253
|
ensureInitialized();
|
|
1250
1254
|
ditto_register_presence_v3_callback(self, wrapBackgroundCbForFFI((err) => log('Error', `The registered presence callback v3 errored with ${err}`), (cJsonStr) => {
|
|
1251
1255
|
const jsonStr = refCStringToString(cJsonStr);
|
|
@@ -1255,7 +1259,7 @@ async function dittoRegisterPresenceV3Callback(self, cb) {
|
|
|
1255
1259
|
/** @internal */
|
|
1256
1260
|
async function dittoClearPresenceV3Callback(self) {
|
|
1257
1261
|
ensureInitialized();
|
|
1258
|
-
ditto_clear_presence_v3_callback(self);
|
|
1262
|
+
return ditto_clear_presence_v3_callback(self);
|
|
1259
1263
|
}
|
|
1260
1264
|
/** @internal */
|
|
1261
1265
|
function presencePeerMetadataJSON(self) {
|
|
@@ -1367,7 +1371,7 @@ function dittoSmallPeerInfoSetMetadata(dittoPointer, metadata) {
|
|
|
1367
1371
|
}
|
|
1368
1372
|
}
|
|
1369
1373
|
/** @internal */
|
|
1370
|
-
|
|
1374
|
+
function dittoSmallPeerInfoCollectionSetTransportConfigData(self, transportConfigData) {
|
|
1371
1375
|
ensureInitialized();
|
|
1372
1376
|
ditto_small_peer_info_set_transport_config_data(self, transportConfigData);
|
|
1373
1377
|
}
|
|
@@ -2218,7 +2222,7 @@ class AttachmentToken {
|
|
|
2218
2222
|
|
|
2219
2223
|
// NOTE: this is patched up with the actual build version by Jake task
|
|
2220
2224
|
// build:package and has to be a valid semantic version as defined here: https://semver.org.
|
|
2221
|
-
const fullBuildVersionString = '4.7.
|
|
2225
|
+
const fullBuildVersionString = '4.7.1';
|
|
2222
2226
|
|
|
2223
2227
|
//
|
|
2224
2228
|
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
@@ -4017,7 +4021,7 @@ Bridge.ditto = new _a(async (dittoPointer) => {
|
|
|
4017
4021
|
// HACK: quick and dirty, clear all presence callbacks. This covers presence
|
|
4018
4022
|
// v1 and v2 callbacks. v3 should be cleared properly by the `Presence`
|
|
4019
4023
|
// class itself.
|
|
4020
|
-
dittoClearPresenceCallback(dittoPointer);
|
|
4024
|
+
await dittoClearPresenceCallback(dittoPointer);
|
|
4021
4025
|
await dittoShutdown(dittoPointer);
|
|
4022
4026
|
dittoFree(dittoPointer);
|
|
4023
4027
|
});
|
|
@@ -6002,7 +6006,7 @@ class AttachmentFetcher {
|
|
|
6002
6006
|
}
|
|
6003
6007
|
this.ditto.store.removeAttachmentFetcher(this);
|
|
6004
6008
|
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
6005
|
-
this.ditto.deferCloseAsync(async () => {
|
|
6009
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
6006
6010
|
// Cancel the fetcher if it is still running.
|
|
6007
6011
|
const cancelToken = await this.cancelTokenPromise;
|
|
6008
6012
|
if (cancelToken) {
|
|
@@ -6012,7 +6016,7 @@ class AttachmentFetcher {
|
|
|
6012
6016
|
}
|
|
6013
6017
|
else {
|
|
6014
6018
|
// Legacy case where the fetcher was started from `Collection.fetchAttachment()`.
|
|
6015
|
-
step(async () => {
|
|
6019
|
+
void step(async () => {
|
|
6016
6020
|
await this.manager.stopAttachmentFetcher(this);
|
|
6017
6021
|
if (this.rejectPendingFetch != null) {
|
|
6018
6022
|
this.rejectPendingFetch();
|
|
@@ -6414,7 +6418,8 @@ class LiveQuery {
|
|
|
6414
6418
|
moves: cCBParams.moves.map((move) => ({ from: move[0], to: move[1] })),
|
|
6415
6419
|
});
|
|
6416
6420
|
}
|
|
6417
|
-
|
|
6421
|
+
// We discard the return promise because error-handling is not supported.
|
|
6422
|
+
void handler(documents, event, signalNext);
|
|
6418
6423
|
});
|
|
6419
6424
|
});
|
|
6420
6425
|
if (!liveQueryID) {
|
|
@@ -6602,9 +6607,9 @@ class PendingCursorOperation extends BasePendingCursorOperation {
|
|
|
6602
6607
|
}
|
|
6603
6608
|
/** @internal */
|
|
6604
6609
|
_observe(handler, waitForNextSignal) {
|
|
6605
|
-
function wrappedHandler(documents, event, nextSignal) {
|
|
6610
|
+
async function wrappedHandler(documents, event, nextSignal) {
|
|
6606
6611
|
try {
|
|
6607
|
-
return handler.call(this, documents, event);
|
|
6612
|
+
return await handler.call(this, documents, event);
|
|
6608
6613
|
}
|
|
6609
6614
|
finally {
|
|
6610
6615
|
nextSignal();
|
|
@@ -6762,7 +6767,7 @@ class PendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
|
6762
6767
|
}
|
|
6763
6768
|
/** @internal */
|
|
6764
6769
|
_observe(handler, waitForNextSignal) {
|
|
6765
|
-
const liveQuery = new LiveQuery(this.query, null, null, [], -1, 0, this.collection, (documents, event, signalNext) => {
|
|
6770
|
+
const liveQuery = new LiveQuery(this.query, null, null, [], -1, 0, this.collection, async (documents, event, signalNext) => {
|
|
6766
6771
|
if (documents.length > 1) {
|
|
6767
6772
|
throw new Error(`Internal inconsistency, single document live query returned more than one document. Query: ${this.query}}.`);
|
|
6768
6773
|
}
|
|
@@ -6785,11 +6790,11 @@ class PendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
|
6785
6790
|
const oldDocument = event.isInitial === true ? undefined : event.oldDocuments[0];
|
|
6786
6791
|
const singleDocumentEvent = new SingleDocumentLiveQueryEvent(event.isInitial, oldDocument);
|
|
6787
6792
|
if (waitForNextSignal) {
|
|
6788
|
-
handler(document, singleDocumentEvent, signalNext);
|
|
6793
|
+
void handler(document, singleDocumentEvent, signalNext);
|
|
6789
6794
|
}
|
|
6790
6795
|
else {
|
|
6791
6796
|
try {
|
|
6792
|
-
handler(document, singleDocumentEvent);
|
|
6797
|
+
await handler(document, singleDocumentEvent);
|
|
6793
6798
|
}
|
|
6794
6799
|
finally {
|
|
6795
6800
|
signalNext();
|
|
@@ -7080,7 +7085,7 @@ class StoreObserver {
|
|
|
7080
7085
|
const result = Bridge.queryResult.bridge(cCBParams.query_result, () => new QueryResult(cCBParams.query_result));
|
|
7081
7086
|
Logger.debug(`Invoking user event handler with new event for store observer ${storeObserverID}`);
|
|
7082
7087
|
observationHandler(result, () => {
|
|
7083
|
-
strongThis.signalNext();
|
|
7088
|
+
return strongThis.signalNext();
|
|
7084
7089
|
});
|
|
7085
7090
|
}
|
|
7086
7091
|
mapFFIErrors(() => {
|
|
@@ -7187,7 +7192,9 @@ class PendingCollectionsOperation {
|
|
|
7187
7192
|
* function calls to.
|
|
7188
7193
|
*/
|
|
7189
7194
|
sort(propertyPath, direction = 'ascending') {
|
|
7190
|
-
|
|
7195
|
+
// The return value is ignored here because we don't want to await the
|
|
7196
|
+
// completion of the operation at this point.
|
|
7197
|
+
void this.pendingCursorOperation.sort(propertyPath, direction);
|
|
7191
7198
|
return this;
|
|
7192
7199
|
}
|
|
7193
7200
|
/**
|
|
@@ -7205,7 +7212,9 @@ class PendingCollectionsOperation {
|
|
|
7205
7212
|
* function calls to.
|
|
7206
7213
|
*/
|
|
7207
7214
|
offset(offset) {
|
|
7208
|
-
|
|
7215
|
+
// The return value is ignored here because we don't want to await the
|
|
7216
|
+
// completion of the operation at this point.
|
|
7217
|
+
void this.pendingCursorOperation.offset(offset);
|
|
7209
7218
|
return this;
|
|
7210
7219
|
}
|
|
7211
7220
|
/**
|
|
@@ -7217,7 +7226,9 @@ class PendingCollectionsOperation {
|
|
|
7217
7226
|
* function calls to.
|
|
7218
7227
|
*/
|
|
7219
7228
|
limit(limit) {
|
|
7220
|
-
|
|
7229
|
+
// The return value is ignored here because we don't want to await the
|
|
7230
|
+
// completion of the operation at this point.
|
|
7231
|
+
void this.pendingCursorOperation.limit(limit);
|
|
7221
7232
|
return this;
|
|
7222
7233
|
}
|
|
7223
7234
|
/**
|
|
@@ -7322,11 +7333,13 @@ class PendingCollectionsOperation {
|
|
|
7322
7333
|
moves: event.moves,
|
|
7323
7334
|
});
|
|
7324
7335
|
}
|
|
7336
|
+
// The handler return promises are ignored here because we are not
|
|
7337
|
+
// handling errors during handler execution.
|
|
7325
7338
|
if (waitForNextSignal) {
|
|
7326
|
-
handler(collEvent, nextSignal);
|
|
7339
|
+
void handler(collEvent, nextSignal);
|
|
7327
7340
|
}
|
|
7328
7341
|
else {
|
|
7329
|
-
handler(collEvent);
|
|
7342
|
+
void handler(collEvent);
|
|
7330
7343
|
}
|
|
7331
7344
|
};
|
|
7332
7345
|
return this.pendingCursorOperation._observe(collectionsObservationHandler, waitForNextSignal);
|
|
@@ -7724,9 +7737,9 @@ class Store {
|
|
|
7724
7737
|
// the first callback to the event handler is emitted before we return from
|
|
7725
7738
|
// the method call that started the observer.
|
|
7726
7739
|
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
7727
|
-
this.ditto.deferCloseAsync(async () => {
|
|
7740
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
7728
7741
|
return new Promise((resolve) => {
|
|
7729
|
-
step(async () => {
|
|
7742
|
+
void step(async () => {
|
|
7730
7743
|
try {
|
|
7731
7744
|
// prettier-ignore
|
|
7732
7745
|
await mapFFIErrorsAsync(async () => await liveQueryStart(dittoHandle.deref(), storeObserver.liveQueryID));
|
|
@@ -8006,6 +8019,7 @@ class Store {
|
|
|
8006
8019
|
return ditto.deferClose(() => {
|
|
8007
8020
|
const attachmentFetcher = new AttachmentFetcher(ditto, attachmentToken, null, eventHandler);
|
|
8008
8021
|
// @ts-expect-error modifying readonly property
|
|
8022
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
8009
8023
|
this.attachmentFetchers = Object.freeze([...this.attachmentFetchers, attachmentFetcher]);
|
|
8010
8024
|
return attachmentFetcher;
|
|
8011
8025
|
});
|
|
@@ -8132,8 +8146,10 @@ class Store {
|
|
|
8132
8146
|
return false;
|
|
8133
8147
|
}
|
|
8134
8148
|
const newAttachmentFetchers = [...this.attachmentFetchers];
|
|
8149
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
8135
8150
|
newAttachmentFetchers.splice(indexToDelete, 1);
|
|
8136
8151
|
// @ts-expect-error modifying readonly property
|
|
8152
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
8137
8153
|
this.attachmentFetchers = Object.freeze(newAttachmentFetchers);
|
|
8138
8154
|
return true;
|
|
8139
8155
|
}
|
|
@@ -8293,9 +8309,9 @@ class Presence {
|
|
|
8293
8309
|
*/
|
|
8294
8310
|
async setPeerMetadataJSONString(jsonString) {
|
|
8295
8311
|
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
8296
|
-
await this.ditto.
|
|
8312
|
+
await this.ditto.deferCloseAsync(async () => {
|
|
8297
8313
|
return mapFFIErrorsAsync(async () => {
|
|
8298
|
-
|
|
8314
|
+
return presenceTrySetPeerMetadataJSON(dittoHandle.deref(), jsonString);
|
|
8299
8315
|
});
|
|
8300
8316
|
});
|
|
8301
8317
|
}
|
|
@@ -8370,8 +8386,8 @@ class Presence {
|
|
|
8370
8386
|
unregister: () => {
|
|
8371
8387
|
const ditto = this.ditto;
|
|
8372
8388
|
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8373
|
-
ditto.
|
|
8374
|
-
dittoClearPresenceV3Callback(dittoHandle.deref());
|
|
8389
|
+
void ditto.deferCloseAsync(async () => {
|
|
8390
|
+
return dittoClearPresenceV3Callback(dittoHandle.deref());
|
|
8375
8391
|
});
|
|
8376
8392
|
},
|
|
8377
8393
|
process: (presenceGraphJSONString) => {
|
|
@@ -8410,7 +8426,7 @@ class LiveQueryManager {
|
|
|
8410
8426
|
// (by definition). This is a classic zalgo case. Fix by making
|
|
8411
8427
|
// `ditto_live_query_start()` trigger the first live query callback `async`,
|
|
8412
8428
|
// just like the subsequent ones.
|
|
8413
|
-
ditto.deferCloseAsync(async () => {
|
|
8429
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
8414
8430
|
const liveQueryID = liveQuery.liveQueryID;
|
|
8415
8431
|
if (!liveQueryID) {
|
|
8416
8432
|
throw new Error("Internal inconsistency, tried to add a live query that doesn't have a live query ID (probably stopped).");
|
|
@@ -8428,9 +8444,8 @@ class LiveQueryManager {
|
|
|
8428
8444
|
// not awaited on purpose; let the invocation of the initial observation
|
|
8429
8445
|
// happen in a "fire-and-forget" / detached / escaping fashion, to be
|
|
8430
8446
|
// consistent with the subsequent invocations.
|
|
8431
|
-
step(async () => {
|
|
8447
|
+
void step(async () => {
|
|
8432
8448
|
await liveQueryStart(dittoHandle.deref(), liveQueryID);
|
|
8433
|
-
// @ts-ignore
|
|
8434
8449
|
resolve();
|
|
8435
8450
|
});
|
|
8436
8451
|
});
|
|
@@ -8505,7 +8520,7 @@ class PresenceManager {
|
|
|
8505
8520
|
return token;
|
|
8506
8521
|
}
|
|
8507
8522
|
/** @internal */
|
|
8508
|
-
removeObserver(token) {
|
|
8523
|
+
async removeObserver(token) {
|
|
8509
8524
|
const callback = this.callbacksByPresenceToken[token];
|
|
8510
8525
|
if (typeof callback === 'undefined') {
|
|
8511
8526
|
throw new Error(`Can't remove presence observer, token '${token}' has never been registered before.`);
|
|
@@ -8521,7 +8536,7 @@ class PresenceManager {
|
|
|
8521
8536
|
// the observer objects themselves and remove it from the table
|
|
8522
8537
|
// as soon as the observer object is garbage collected.
|
|
8523
8538
|
this.callbacksByPresenceToken[token] = null;
|
|
8524
|
-
this.unregisterIfNeeded();
|
|
8539
|
+
return this.unregisterIfNeeded();
|
|
8525
8540
|
}
|
|
8526
8541
|
}
|
|
8527
8542
|
/** @internal */
|
|
@@ -8529,11 +8544,10 @@ class PresenceManager {
|
|
|
8529
8544
|
return typeof this.callbacksByPresenceToken[token] != 'undefined';
|
|
8530
8545
|
}
|
|
8531
8546
|
/** @internal */
|
|
8532
|
-
close() {
|
|
8547
|
+
async close() {
|
|
8533
8548
|
this.isClosed = true;
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
}
|
|
8549
|
+
const tokens = Object.keys(this.callbacksByPresenceToken);
|
|
8550
|
+
return Promise.all(tokens.map((token) => this.removeObserver(token)));
|
|
8537
8551
|
}
|
|
8538
8552
|
hasObservers() {
|
|
8539
8553
|
return Object.keys(this.callbacksByPresenceToken).length > 0;
|
|
@@ -8554,11 +8568,11 @@ class PresenceManager {
|
|
|
8554
8568
|
unregisterIfNeeded() {
|
|
8555
8569
|
const ditto = this.ditto;
|
|
8556
8570
|
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8557
|
-
ditto.
|
|
8571
|
+
return this.ditto.deferCloseAsync(async () => {
|
|
8558
8572
|
const needsToUnregister = !this.hasObservers() && this.isRegistered;
|
|
8559
8573
|
if (needsToUnregister) {
|
|
8560
8574
|
this.isRegistered = false;
|
|
8561
|
-
dittoClearPresenceCallback(dittoHandle.deref());
|
|
8575
|
+
await dittoClearPresenceCallback(dittoHandle.deref());
|
|
8562
8576
|
this.currentRemotePeers = [];
|
|
8563
8577
|
}
|
|
8564
8578
|
});
|
|
@@ -9213,12 +9227,13 @@ class SubscriptionManager {
|
|
|
9213
9227
|
/**
|
|
9214
9228
|
* Begin tracking a subscription instance and start it.
|
|
9215
9229
|
*
|
|
9216
|
-
* @internal
|
|
9230
|
+
* @internal
|
|
9231
|
+
*/
|
|
9217
9232
|
add(subscription) {
|
|
9218
9233
|
const ditto = this.ditto;
|
|
9219
9234
|
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9220
9235
|
const contextInfo = subscription.contextInfo;
|
|
9221
|
-
ditto.deferClose(
|
|
9236
|
+
ditto.deferClose(() => {
|
|
9222
9237
|
this.subscriptions[contextInfo.id] = new WeakRef(subscription);
|
|
9223
9238
|
this.finalizationRegistry.register(subscription, subscription.contextInfo, subscription);
|
|
9224
9239
|
addSubscription(dittoHandle.deref(), contextInfo.collectionName, contextInfo.query, contextInfo.queryArgsCBOR, contextInfo.orderBys, contextInfo.limit, contextInfo.offset);
|
|
@@ -9227,7 +9242,8 @@ class SubscriptionManager {
|
|
|
9227
9242
|
/**
|
|
9228
9243
|
* Stop tracking a subscription instance and cancel it.
|
|
9229
9244
|
*
|
|
9230
|
-
* @internal
|
|
9245
|
+
* @internal
|
|
9246
|
+
*/
|
|
9231
9247
|
remove(subscription) {
|
|
9232
9248
|
if (this.subscriptions[subscription.contextInfo.id] == null) {
|
|
9233
9249
|
throw new Error(`Internal inconsistency, tried to remove a subscription that is not tracked: ${subscription.contextInfo.id}`);
|
|
@@ -9238,16 +9254,13 @@ class SubscriptionManager {
|
|
|
9238
9254
|
/**
|
|
9239
9255
|
* Stop tracking all subscriptions and cancel them.
|
|
9240
9256
|
*
|
|
9241
|
-
* @internal
|
|
9257
|
+
* @internal
|
|
9258
|
+
*/
|
|
9242
9259
|
close() {
|
|
9243
|
-
this.ditto.deferClose(
|
|
9260
|
+
this.ditto.deferClose(() => {
|
|
9244
9261
|
for (const subscriptionID in this.subscriptions) {
|
|
9245
9262
|
const subscription = this.subscriptions[subscriptionID].deref();
|
|
9246
|
-
|
|
9247
|
-
// This doesn't call `Subscription.cancel()` because that is not
|
|
9248
|
-
// async and we want to wait for all subscriptions to be removed.
|
|
9249
|
-
this.remove(subscription);
|
|
9250
|
-
}
|
|
9263
|
+
subscription === null || subscription === void 0 ? void 0 : subscription.cancel();
|
|
9251
9264
|
}
|
|
9252
9265
|
});
|
|
9253
9266
|
}
|
|
@@ -9255,7 +9268,8 @@ class SubscriptionManager {
|
|
|
9255
9268
|
* Remove tracked subscription without unregistering from finalization
|
|
9256
9269
|
* registry.
|
|
9257
9270
|
*
|
|
9258
|
-
* @internal
|
|
9271
|
+
* @internal
|
|
9272
|
+
*/
|
|
9259
9273
|
removeWithContextInfo(contextInfo) {
|
|
9260
9274
|
const ditto = this.ditto;
|
|
9261
9275
|
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
@@ -9343,7 +9357,7 @@ class AttachmentFetcherManager {
|
|
|
9343
9357
|
// for this is that the FFI function `ditto_resolve_attachment()` is
|
|
9344
9358
|
// async but should be non-async. Refactor and make that non-async, then
|
|
9345
9359
|
// de-async-ify the closing mechanism.
|
|
9346
|
-
this.ditto.deferCloseAsync(async () => {
|
|
9360
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
9347
9361
|
const contextInfos = Object.values(this.contextInfoByID);
|
|
9348
9362
|
const stopped = contextInfos.map(async (contextInfo) => {
|
|
9349
9363
|
const attachmentFetcher = contextInfo.attachmentFetcher.deref();
|
|
@@ -9417,8 +9431,8 @@ class SmallPeerInfo {
|
|
|
9417
9431
|
throw new TypeError(`Expected boolean, got ${typeof newValue}`);
|
|
9418
9432
|
}
|
|
9419
9433
|
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
9420
|
-
this.ditto.
|
|
9421
|
-
dittoSmallPeerInfoSetEnabled(dittoHandle.deref(), newValue);
|
|
9434
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
9435
|
+
return dittoSmallPeerInfoSetEnabled(dittoHandle.deref(), newValue);
|
|
9422
9436
|
});
|
|
9423
9437
|
}
|
|
9424
9438
|
/**
|
|
@@ -9712,7 +9726,7 @@ class Ditto {
|
|
|
9712
9726
|
// auth all happens in the background and so there are no guarantees we
|
|
9713
9727
|
// need to uphold by making sure things are in a certain state before the
|
|
9714
9728
|
// constructor finishes
|
|
9715
|
-
dittoAuthSetLoginProvider(dittoPointer, loginProviderX);
|
|
9729
|
+
void dittoAuthSetLoginProvider(dittoPointer, loginProviderX);
|
|
9716
9730
|
}
|
|
9717
9731
|
else if (validIdentity.type === 'onlinePlayground') {
|
|
9718
9732
|
this.auth = new OnlineAuthenticator(this.keepAlive, this, {
|
|
@@ -10080,7 +10094,7 @@ class Ditto {
|
|
|
10080
10094
|
this.presence.close();
|
|
10081
10095
|
this.auth.close();
|
|
10082
10096
|
this.sync.close();
|
|
10083
|
-
this.presenceManager.close();
|
|
10097
|
+
await this.presenceManager.close();
|
|
10084
10098
|
this.liveQueryManager.close();
|
|
10085
10099
|
this.attachmentFetcherManager.close();
|
|
10086
10100
|
this.transportConditionsManager.close();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dittolive/ditto",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.1",
|
|
4
4
|
"description": "Ditto is a cross-platform embeddable NoSQL database that can sync with or without an internet connection.",
|
|
5
5
|
"homepage": "https://ditto.live",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -150,7 +150,7 @@ repositories {
|
|
|
150
150
|
|
|
151
151
|
// This can be moved to gradle.properties (minus the quotes) with no code changes
|
|
152
152
|
// here since `version` is a default project property.
|
|
153
|
-
version = "4.7.
|
|
153
|
+
version = "4.7.1"
|
|
154
154
|
|
|
155
155
|
dependencies {
|
|
156
156
|
// For < 0.71, this will be from the local maven repo
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from '
|
|
1
|
+
export * from '@dittolive/ditto/react-native/src/ditto.rn';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from '
|
|
1
|
+
export * from '@dittolive/ditto/react-native/src/environment/environment.fallback';
|
|
@@ -101,7 +101,7 @@ export class AttachmentFetcherManager {
|
|
|
101
101
|
* @internal
|
|
102
102
|
*/
|
|
103
103
|
close() {
|
|
104
|
-
this.ditto.deferCloseAsync(async () => {
|
|
104
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
105
105
|
const contextInfos = Object.values(this.contextInfoByID)
|
|
106
106
|
const stopped = contextInfos.map(async (contextInfo) => {
|
|
107
107
|
const attachmentFetcher = contextInfo.attachmentFetcher.deref()
|
|
@@ -60,7 +60,7 @@ export class AttachmentFetcher implements PromiseLike<Attachment | null> {
|
|
|
60
60
|
this.ditto.store.removeAttachmentFetcher(this)
|
|
61
61
|
|
|
62
62
|
const dittoHandle = Bridge.ditto.handleFor(this.ditto)
|
|
63
|
-
this.ditto.deferCloseAsync(async () => {
|
|
63
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
64
64
|
// Cancel the fetcher if it is still running.
|
|
65
65
|
const cancelToken = await this.cancelTokenPromise
|
|
66
66
|
if (cancelToken) {
|
|
@@ -70,7 +70,7 @@ export class AttachmentFetcher implements PromiseLike<Attachment | null> {
|
|
|
70
70
|
} else {
|
|
71
71
|
// Legacy case where the fetcher was started from `Collection.fetchAttachment()`.
|
|
72
72
|
|
|
73
|
-
step(async () => {
|
|
73
|
+
void step(async () => {
|
|
74
74
|
await this.manager.stopAttachmentFetcher(this)
|
|
75
75
|
if (this.rejectPendingFetch != null) {
|
|
76
76
|
this.rejectPendingFetch()
|
|
@@ -510,7 +510,7 @@ export class Bridge<T extends object, FFIType> {
|
|
|
510
510
|
|
|
511
511
|
/** @internal */
|
|
512
512
|
static readonly ditto = new Bridge<Ditto, FFI.FFIDitto>(async (dittoPointer) => {
|
|
513
|
-
FFI.dittoClearPresenceCallback(dittoPointer)
|
|
513
|
+
await FFI.dittoClearPresenceCallback(dittoPointer)
|
|
514
514
|
await FFI.dittoShutdown(dittoPointer)
|
|
515
515
|
FFI.dittoFree(dittoPointer)
|
|
516
516
|
})
|
|
@@ -301,7 +301,11 @@ export class Ditto {
|
|
|
301
301
|
Bridge.ditto.bridge(dittoPointer, this)
|
|
302
302
|
|
|
303
303
|
if (Environment.isReactNativeBuild) {
|
|
304
|
-
|
|
304
|
+
// FIXME: disabling sync needs to be awaited but that is not possible in
|
|
305
|
+
// the constructor
|
|
306
|
+
this.disableSyncWithV3().catch((error: any) => {
|
|
307
|
+
Logger.error(`Failed to disable sync with V3: ${error?.message}`)
|
|
308
|
+
})
|
|
305
309
|
}
|
|
306
310
|
|
|
307
311
|
// IMPORTANT: Keeping the auth client around accumulates run-times and
|
|
@@ -331,7 +335,7 @@ export class Ditto {
|
|
|
331
335
|
// auth all happens in the background and so there are no guarantees we
|
|
332
336
|
// need to uphold by making sure things are in a certain state before the
|
|
333
337
|
// constructor finishes
|
|
334
|
-
FFI.dittoAuthSetLoginProvider(dittoPointer, loginProviderX)
|
|
338
|
+
void FFI.dittoAuthSetLoginProvider(dittoPointer, loginProviderX)
|
|
335
339
|
} else if (validIdentity.type === 'onlinePlayground') {
|
|
336
340
|
this.auth = new OnlineAuthenticator(this.keepAlive, this, {
|
|
337
341
|
authenticationRequired: function (authenticator: Authenticator) {
|
|
@@ -699,7 +703,7 @@ export class Ditto {
|
|
|
699
703
|
this.presence.close()
|
|
700
704
|
this.auth.close()
|
|
701
705
|
this.sync.close()
|
|
702
|
-
this.presenceManager.close()
|
|
706
|
+
await this.presenceManager.close()
|
|
703
707
|
this.liveQueryManager.close()
|
|
704
708
|
this.attachmentFetcherManager.close()
|
|
705
709
|
this.transportConditionsManager.close()
|
|
@@ -539,23 +539,25 @@ export async function tryExecStatement(ditto: Pointer<FFIDitto>, writeTransactio
|
|
|
539
539
|
}
|
|
540
540
|
|
|
541
541
|
/** @internal */
|
|
542
|
-
export function addSubscription(ditto: Pointer<FFIDitto>, collectionName: string, query: string, queryArgsCBOR: Uint8Array | null, orderBy: OrderBy[], limit: number, offset: number) {
|
|
542
|
+
export function addSubscription(ditto: Pointer<FFIDitto>, collectionName: string, query: string, queryArgsCBOR: Uint8Array | null, orderBy: OrderBy[], limit: number, offset: number): void {
|
|
543
543
|
trace()
|
|
544
544
|
ensureInitialized()
|
|
545
545
|
|
|
546
546
|
const collectionNameX = bytesFromString(collectionName)
|
|
547
547
|
const queryX = bytesFromString(query)
|
|
548
|
-
|
|
548
|
+
const statusCode = dittoCore.ditto_add_subscription(ditto, collectionNameX, queryX, queryArgsCBOR, orderBy, limit, offset)
|
|
549
|
+
if (statusCode !== 0) throw new Error(errorMessage() || `ditto_add_subscription() failed with error code: ${statusCode}`)
|
|
549
550
|
}
|
|
550
551
|
|
|
551
552
|
/** @internal */
|
|
552
|
-
export function removeSubscription(ditto: Pointer<FFIDitto>, collectionName: string, query: string, queryArgsCBOR: Uint8Array | null, orderBy: OrderBy[], limit: number, offset: number) {
|
|
553
|
+
export function removeSubscription(ditto: Pointer<FFIDitto>, collectionName: string, query: string, queryArgsCBOR: Uint8Array | null, orderBy: OrderBy[], limit: number, offset: number): void {
|
|
553
554
|
trace()
|
|
554
555
|
ensureInitialized()
|
|
555
556
|
|
|
556
557
|
const collectionNameX = bytesFromString(collectionName)
|
|
557
558
|
const queryX = bytesFromString(query)
|
|
558
|
-
|
|
559
|
+
const statusCode = dittoCore.ditto_remove_subscription(ditto, collectionNameX, queryX, queryArgsCBOR, orderBy, limit, offset)
|
|
560
|
+
if (statusCode !== 0) throw new Error(errorMessage() || `ditto_remove_subscription() failed with error code: ${statusCode}`)
|
|
559
561
|
}
|
|
560
562
|
|
|
561
563
|
/** @internal */
|
|
@@ -1142,7 +1144,7 @@ export function setDeadlockTimeout(duration: number): void {
|
|
|
1142
1144
|
}
|
|
1143
1145
|
|
|
1144
1146
|
/** @internal */
|
|
1145
|
-
export
|
|
1147
|
+
export function dittoRegisterPresenceV1Callback(self: Pointer<FFIDitto>, cb: (json: string) => void): void {
|
|
1146
1148
|
trace()
|
|
1147
1149
|
ensureInitialized()
|
|
1148
1150
|
|
|
@@ -1162,11 +1164,12 @@ export async function dittoRegisterPresenceV1Callback(self: Pointer<FFIDitto>, c
|
|
|
1162
1164
|
export async function dittoClearPresenceCallback(self: Pointer<FFIDitto>): Promise<void> {
|
|
1163
1165
|
trace()
|
|
1164
1166
|
ensureInitialized()
|
|
1165
|
-
|
|
1167
|
+
|
|
1168
|
+
return dittoCore.ditto_clear_presence_callback(self)
|
|
1166
1169
|
}
|
|
1167
1170
|
|
|
1168
1171
|
/** @internal */
|
|
1169
|
-
export
|
|
1172
|
+
export function dittoRegisterPresenceV3Callback(self: Pointer<FFIDitto>, cb: (json: string) => void): void {
|
|
1170
1173
|
trace()
|
|
1171
1174
|
ensureInitialized()
|
|
1172
1175
|
|
|
@@ -1183,10 +1186,11 @@ export async function dittoRegisterPresenceV3Callback(self: Pointer<FFIDitto>, c
|
|
|
1183
1186
|
}
|
|
1184
1187
|
|
|
1185
1188
|
/** @internal */
|
|
1186
|
-
export async function dittoClearPresenceV3Callback(self: Pointer<FFIDitto>) {
|
|
1189
|
+
export async function dittoClearPresenceV3Callback(self: Pointer<FFIDitto>): Promise<void> {
|
|
1187
1190
|
trace()
|
|
1188
1191
|
ensureInitialized()
|
|
1189
|
-
|
|
1192
|
+
|
|
1193
|
+
return dittoCore.ditto_clear_presence_v3_callback(self)
|
|
1190
1194
|
}
|
|
1191
1195
|
|
|
1192
1196
|
/** @internal */
|
|
@@ -1343,9 +1347,10 @@ export function dittoSmallPeerInfoSetMetadata(dittoPointer: Pointer<FFIDitto>, m
|
|
|
1343
1347
|
}
|
|
1344
1348
|
|
|
1345
1349
|
/** @internal */
|
|
1346
|
-
export
|
|
1350
|
+
export function dittoSmallPeerInfoCollectionSetTransportConfigData(self: Pointer<FFIDitto>, transportConfigData: Uint8Array): void {
|
|
1347
1351
|
trace()
|
|
1348
1352
|
ensureInitialized()
|
|
1353
|
+
|
|
1349
1354
|
dittoCore.ditto_small_peer_info_set_transport_config_data(self, transportConfigData)
|
|
1350
1355
|
}
|
|
1351
1356
|
|
|
@@ -2105,7 +2110,7 @@ function wrapBackgroundCbForFFI<
|
|
|
2105
2110
|
/** @internal */
|
|
2106
2111
|
// prettier-ignore
|
|
2107
2112
|
function wrapAsyncBackgroundCbForFFI<
|
|
2108
|
-
F extends (...args: any[]) => (Promise<any> | any),
|
|
2113
|
+
F extends (...args: any[]) => (Promise<any> | any),
|
|
2109
2114
|
E extends (err: any) => void | null
|
|
2110
2115
|
>(onError: E, cb: F): (
|
|
2111
2116
|
ret_sender: (result: ReturnType<F>) => unknown, ...args: Parameters<F>
|
|
@@ -36,7 +36,7 @@ export class LiveQueryManager {
|
|
|
36
36
|
// `ditto_live_query_start()` trigger the first live query callback `async`,
|
|
37
37
|
// just like the subsequent ones.
|
|
38
38
|
|
|
39
|
-
ditto.deferCloseAsync(async () => {
|
|
39
|
+
void this.ditto.deferCloseAsync(async () => {
|
|
40
40
|
const liveQueryID = liveQuery.liveQueryID
|
|
41
41
|
if (!liveQueryID) {
|
|
42
42
|
throw new Error("Internal inconsistency, tried to add a live query that doesn't have a live query ID (probably stopped).")
|
|
@@ -54,13 +54,12 @@ export class LiveQueryManager {
|
|
|
54
54
|
|
|
55
55
|
ditto.keepAlive.retain(`LiveQuery.${liveQueryID}`)
|
|
56
56
|
|
|
57
|
-
return new Promise((resolve, reject) => {
|
|
57
|
+
return new Promise<void>((resolve, reject) => {
|
|
58
58
|
// not awaited on purpose; let the invocation of the initial observation
|
|
59
59
|
// happen in a "fire-and-forget" / detached / escaping fashion, to be
|
|
60
60
|
// consistent with the subsequent invocations.
|
|
61
|
-
step(async () => {
|
|
61
|
+
void step(async () => {
|
|
62
62
|
await FFI.liveQueryStart(dittoHandle.deref(), liveQueryID)
|
|
63
|
-
// @ts-ignore
|
|
64
63
|
resolve()
|
|
65
64
|
})
|
|
66
65
|
})
|