@dittolive/ditto 4.7.4 → 4.8.0-rc.2
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/DittoReactNative.podspec +33 -2
- package/README.md +2 -2
- package/node/ditto.cjs.js +341 -376
- 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/package.json +2 -2
- package/react-native/android/build.gradle +24 -64
- package/react-native/android/cpp-adapter.cpp +37 -104
- package/react-native/android/src/main/AndroidManifestNew.xml +2 -0
- package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.java +5 -70
- package/react-native/cpp/include/ConnectionRequest.h +1 -1
- package/react-native/cpp/include/IO.h +2 -0
- package/react-native/cpp/include/Logger.h +2 -1
- package/react-native/cpp/include/Misc.h +1 -0
- package/react-native/cpp/include/main.h +4 -2
- package/react-native/cpp/src/Attachment.cpp +1 -3
- package/react-native/cpp/src/ConnectionRequest.cpp +1 -1
- package/react-native/cpp/src/IO.cpp +79 -0
- package/react-native/cpp/src/Logger.cpp +63 -0
- package/react-native/cpp/src/Misc.cpp +21 -0
- package/react-native/cpp/src/main.cpp +10 -4
- package/react-native/ditto.es6.js +2 -0
- package/react-native/dittoffi/dittoffi.h +137 -40
- package/react-native/ios/DittoRNSDK.mm +19 -124
- package/react-native.config.js +2 -1
- package/types/ditto.d.ts +2412 -2032
- package/web/ditto.es6.js +1 -1
- package/web/ditto.umd.js +1 -1
- package/web/ditto.wasm +0 -0
- package/node/transports.darwin-arm64.node +0 -0
- package/node/transports.darwin-x64.node +0 -0
- package/react-native/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/react-native/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/react-native/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/react-native/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/react-native/android/.gradle/8.9/gc.properties +0 -0
- package/react-native/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/react-native/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/react-native/android/.gradle/vcs-1/gc.properties +0 -0
- package/react-native/lib/commonjs/ditto.rn.js +0 -93
- package/react-native/lib/commonjs/ditto.rn.js.map +0 -1
- package/react-native/lib/commonjs/index.js +0 -61
- package/react-native/lib/commonjs/index.js.map +0 -1
- package/react-native/lib/module/ditto.rn.js +0 -89
- package/react-native/lib/module/ditto.rn.js.map +0 -1
- package/react-native/lib/module/index.js +0 -27
- package/react-native/lib/module/index.js.map +0 -1
- package/react-native/lib/typescript/ditto.rn.d.ts +0 -15
- package/react-native/lib/typescript/ditto.rn.d.ts.map +0 -1
- package/react-native/lib/typescript/index.d.ts +0 -1
- package/react-native/lib/typescript/index.d.ts.map +0 -1
- package/react-native/src/ditto.rn.ts +0 -123
- package/react-native/src/environment/environment.fallback.ts +0 -4
- package/react-native/src/index.ts +0 -29
- package/react-native/src/sources/@cbor-redux.ts +0 -2
- package/react-native/src/sources/@ditto.core.ts +0 -1
- package/react-native/src/sources/@environment.ts +0 -1
- package/react-native/src/sources/attachment-fetch-event.ts +0 -54
- package/react-native/src/sources/attachment-fetcher-manager.ts +0 -145
- package/react-native/src/sources/attachment-fetcher.ts +0 -265
- package/react-native/src/sources/attachment-token.ts +0 -129
- package/react-native/src/sources/attachment.ts +0 -121
- package/react-native/src/sources/augment.ts +0 -108
- package/react-native/src/sources/authenticator.ts +0 -314
- package/react-native/src/sources/base-pending-cursor-operation.ts +0 -255
- package/react-native/src/sources/base-pending-id-specific-operation.ts +0 -112
- package/react-native/src/sources/bridge.ts +0 -557
- package/react-native/src/sources/build-time-constants.ts +0 -8
- package/react-native/src/sources/cbor.ts +0 -20
- package/react-native/src/sources/collection-interface.ts +0 -73
- package/react-native/src/sources/collection.ts +0 -219
- package/react-native/src/sources/collections-event.ts +0 -99
- package/react-native/src/sources/connection-request.ts +0 -142
- package/react-native/src/sources/counter.ts +0 -82
- package/react-native/src/sources/ditto.ts +0 -991
- package/react-native/src/sources/document-id.ts +0 -163
- package/react-native/src/sources/document-path.ts +0 -308
- package/react-native/src/sources/document.ts +0 -237
- package/react-native/src/sources/epilogue.ts +0 -32
- package/react-native/src/sources/error-codes.ts +0 -114
- package/react-native/src/sources/error.ts +0 -256
- package/react-native/src/sources/essentials.ts +0 -81
- package/react-native/src/sources/ffi-error.ts +0 -134
- package/react-native/src/sources/ffi.ts +0 -2190
- package/react-native/src/sources/identity.ts +0 -163
- package/react-native/src/sources/init.ts +0 -71
- package/react-native/src/sources/internal.ts +0 -143
- package/react-native/src/sources/keep-alive.ts +0 -73
- package/react-native/src/sources/key-path.ts +0 -198
- package/react-native/src/sources/live-query-event.ts +0 -208
- package/react-native/src/sources/live-query-manager.ts +0 -110
- package/react-native/src/sources/live-query.ts +0 -167
- package/react-native/src/sources/logger.ts +0 -196
- package/react-native/src/sources/main.ts +0 -61
- package/react-native/src/sources/observer-manager.ts +0 -185
- package/react-native/src/sources/observer.ts +0 -79
- package/react-native/src/sources/pending-collections-operation.ts +0 -241
- package/react-native/src/sources/pending-cursor-operation.ts +0 -218
- package/react-native/src/sources/pending-id-specific-operation.ts +0 -218
- package/react-native/src/sources/presence-manager.ts +0 -170
- package/react-native/src/sources/presence.ts +0 -427
- package/react-native/src/sources/query-result-item.ts +0 -131
- package/react-native/src/sources/query-result.ts +0 -55
- package/react-native/src/sources/register.ts +0 -95
- package/react-native/src/sources/small-peer-info.ts +0 -166
- package/react-native/src/sources/static-tcp-client.ts +0 -8
- package/react-native/src/sources/store-observer.ts +0 -170
- package/react-native/src/sources/store.ts +0 -630
- package/react-native/src/sources/subscription-manager.ts +0 -99
- package/react-native/src/sources/subscription.ts +0 -89
- package/react-native/src/sources/sync-subscription.ts +0 -90
- package/react-native/src/sources/sync.ts +0 -561
- package/react-native/src/sources/test-helpers.ts +0 -24
- package/react-native/src/sources/transport-conditions-manager.ts +0 -104
- package/react-native/src/sources/transport-config.ts +0 -430
- package/react-native/src/sources/update-result.ts +0 -66
- package/react-native/src/sources/update-results-map.ts +0 -65
- package/react-native/src/sources/websocket-client.ts +0 -7
- package/react-native/src/sources/write-transaction-collection.ts +0 -122
- package/react-native/src/sources/write-transaction-pending-cursor-operation.ts +0 -101
- package/react-native/src/sources/write-transaction-pending-id-specific-operation.ts +0 -74
- package/react-native/src/sources/write-transaction.ts +0 -121
package/node/ditto.cjs.js
CHANGED
|
@@ -278,18 +278,6 @@ const ditto = (function () {
|
|
|
278
278
|
|
|
279
279
|
throw new Error("No native module 'ditto." + target + ".node' found. Please check the Ditto documentation for supported platforms.")
|
|
280
280
|
})();
|
|
281
|
-
|
|
282
|
-
// Kept in a block scope to avoid leaking the target variable. The native
|
|
283
|
-
// module registers its functions in global scope.
|
|
284
|
-
{
|
|
285
|
-
const target = process.platform + '-' + process.arch;
|
|
286
|
-
try {
|
|
287
|
-
if (target === 'darwin-x64') require('./transports.darwin-x64.node');
|
|
288
|
-
if (target === 'darwin-arm64') require('./transports.darwin-arm64.node');
|
|
289
|
-
} catch (error) {
|
|
290
|
-
console.warn("Couldn't load native module 'transports." + target + ".node' due to error:" + error.toString());
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
281
|
function ble_client_free_handle(...args) { return ditto.ble_client_free_handle(...args) }
|
|
294
282
|
function ble_server_free_handle(...args) { return ditto.ble_server_free_handle(...args) }
|
|
295
283
|
function boxCBytesIntoBuffer(...args) { return ditto.boxCBytesIntoBuffer(...args) }
|
|
@@ -417,10 +405,12 @@ function dittoffi_connection_request_free(...args) { return ditto.dittoffi_conne
|
|
|
417
405
|
function dittoffi_connection_request_identity_service_metadata_json(...args) { return ditto.dittoffi_connection_request_identity_service_metadata_json(...args) }
|
|
418
406
|
function dittoffi_connection_request_peer_key_string(...args) { return ditto.dittoffi_connection_request_peer_key_string(...args) }
|
|
419
407
|
function dittoffi_connection_request_peer_metadata_json(...args) { return ditto.dittoffi_connection_request_peer_metadata_json(...args) }
|
|
408
|
+
function dittoffi_crypto_generate_secure_random_token(...args) { return ditto.dittoffi_crypto_generate_secure_random_token(...args) }
|
|
420
409
|
function dittoffi_error_code(...args) { return ditto.dittoffi_error_code(...args) }
|
|
421
410
|
function dittoffi_error_description(...args) { return ditto.dittoffi_error_description(...args) }
|
|
422
411
|
function dittoffi_error_free(...args) { return ditto.dittoffi_error_free(...args) }
|
|
423
412
|
function dittoffi_get_sdk_semver(...args) { return ditto.dittoffi_get_sdk_semver(...args) }
|
|
413
|
+
function dittoffi_logger_try_export_to_file_async(...args) { return ditto.dittoffi_logger_try_export_to_file_async(...args) }
|
|
424
414
|
function dittoffi_presence_peer_metadata_json(...args) { return ditto.dittoffi_presence_peer_metadata_json(...args) }
|
|
425
415
|
function dittoffi_presence_set_connection_request_handler(...args) { return ditto.dittoffi_presence_set_connection_request_handler(...args) }
|
|
426
416
|
function dittoffi_presence_try_set_peer_metadata_json(...args) { return ditto.dittoffi_presence_try_set_peer_metadata_json(...args) }
|
|
@@ -446,8 +436,6 @@ function mdns_server_free_handle(...args) { return ditto.mdns_server_free_handle
|
|
|
446
436
|
function refCBytesIntoBuffer(...args) { return ditto.refCBytesIntoBuffer(...args) }
|
|
447
437
|
function refCStringToString(...args) { return ditto.refCStringToString(...args) }
|
|
448
438
|
function setDeadlockTimeout$1(...args) { return ditto.setDeadlockTimeout(...args) }
|
|
449
|
-
function static_tcp_client_free_handle(...args) { return ditto.static_tcp_client_free_handle(...args) }
|
|
450
|
-
function websocket_client_free_handle(...args) { return ditto.websocket_client_free_handle(...args) }
|
|
451
439
|
function withOutBoxCBytes(...args) { return ditto.withOutBoxCBytes(...args) }
|
|
452
440
|
|
|
453
441
|
const isWebBuild = false;
|
|
@@ -821,7 +809,6 @@ function tryAddSyncSubscription(dittoPointer, query, queryArgsCBOR) {
|
|
|
821
809
|
const queryBuffer = bytesFromString(query);
|
|
822
810
|
const result = dittoffi_try_add_sync_subscription(dittoPointer, queryBuffer, queryArgsCBOR);
|
|
823
811
|
throwOnErrorResult(result.error, 'dittoffi_try_add_sync_subscription');
|
|
824
|
-
return;
|
|
825
812
|
}
|
|
826
813
|
/** @internal */
|
|
827
814
|
function tryRemoveSyncSubscription(dittoPointer, query, queryArgsCBOR) {
|
|
@@ -829,7 +816,6 @@ function tryRemoveSyncSubscription(dittoPointer, query, queryArgsCBOR) {
|
|
|
829
816
|
const queryBuffer = bytesFromString(query);
|
|
830
817
|
const result = dittoffi_try_remove_sync_subscription(dittoPointer, queryBuffer, queryArgsCBOR);
|
|
831
818
|
throwOnErrorResult(result.error, 'dittoffi_try_remove_sync_subscription');
|
|
832
|
-
return;
|
|
833
819
|
}
|
|
834
820
|
// ----------------------------------------------------------- QueryResult ------
|
|
835
821
|
/**
|
|
@@ -1017,15 +1003,6 @@ async function writeTransactionRollback(ditto, transaction) {
|
|
|
1017
1003
|
if (errorCode !== 0)
|
|
1018
1004
|
throw new Error(errorMessage() || `ditto_write_transaction_rollback() failed with error code: ${errorCode}`);
|
|
1019
1005
|
}
|
|
1020
|
-
/** @internal */
|
|
1021
|
-
function staticTCPClientFreeHandle(self) {
|
|
1022
|
-
static_tcp_client_free_handle(self);
|
|
1023
|
-
}
|
|
1024
|
-
/** @internal */
|
|
1025
|
-
function websocketClientFreeHandle(self) {
|
|
1026
|
-
ensureInitialized();
|
|
1027
|
-
websocket_client_free_handle(self);
|
|
1028
|
-
}
|
|
1029
1006
|
// --------------------------------------------------------------- Logger ------
|
|
1030
1007
|
/** @internal */
|
|
1031
1008
|
function loggerInit() {
|
|
@@ -1088,11 +1065,22 @@ function loggerSetLogFile(path) {
|
|
|
1088
1065
|
const pathBytesOrNull = path ? bytesFromString(path) : null;
|
|
1089
1066
|
const errorCode = ditto_logger_set_log_file(pathBytesOrNull);
|
|
1090
1067
|
if (errorCode !== 0) {
|
|
1091
|
-
errorMessage();
|
|
1092
|
-
throw new Error(`Can't set log file, due to error: ${
|
|
1068
|
+
const message = errorMessage();
|
|
1069
|
+
throw new Error(`Can't set log file, due to error: ${message}`);
|
|
1093
1070
|
}
|
|
1094
1071
|
}
|
|
1095
1072
|
/** @internal */
|
|
1073
|
+
async function loggerTryExportToFileAsync(path) {
|
|
1074
|
+
ensureInitialized();
|
|
1075
|
+
const pathBytes = bytesFromString(path);
|
|
1076
|
+
const result = await new Promise((resolve, reject) => {
|
|
1077
|
+
const wrappedCallback = wrapBackgroundCbForFFI(reject, resolve);
|
|
1078
|
+
dittoffi_logger_try_export_to_file_async(pathBytes, wrappedCallback);
|
|
1079
|
+
});
|
|
1080
|
+
throwOnErrorResult(result.error, 'dittoffi_logger_try_export_to_file_async');
|
|
1081
|
+
return result.success;
|
|
1082
|
+
}
|
|
1083
|
+
/** @internal */
|
|
1096
1084
|
function log(level, message) {
|
|
1097
1085
|
ensureInitialized();
|
|
1098
1086
|
const messageBuffer = bytesFromString(message);
|
|
@@ -1236,6 +1224,12 @@ function setDeadlockTimeout(duration) {
|
|
|
1236
1224
|
setDeadlockTimeout$1(duration);
|
|
1237
1225
|
}
|
|
1238
1226
|
/** @internal */
|
|
1227
|
+
function cryptoGenerateSecureRandomToken() {
|
|
1228
|
+
ensureInitialized();
|
|
1229
|
+
const docIDString = dittoffi_crypto_generate_secure_random_token();
|
|
1230
|
+
return boxCStringIntoString(docIDString);
|
|
1231
|
+
}
|
|
1232
|
+
/** @internal */
|
|
1239
1233
|
function dittoRegisterPresenceV1Callback(self, cb) {
|
|
1240
1234
|
ensureInitialized();
|
|
1241
1235
|
ditto_register_presence_v1_callback(self, wrapBackgroundCbForFFI((err) => log('Error', `The registered presence callback v1 errored with ${err}`), (cJsonStr) => {
|
|
@@ -1531,9 +1525,11 @@ function dittoStopHTTPServer(dittoPointer) {
|
|
|
1531
1525
|
return ditto_stop_http_server(dittoPointer);
|
|
1532
1526
|
}
|
|
1533
1527
|
/** @internal */
|
|
1534
|
-
function dittoRunGarbageCollection(dittoPointer) {
|
|
1528
|
+
async function dittoRunGarbageCollection(dittoPointer) {
|
|
1535
1529
|
ensureInitialized();
|
|
1536
|
-
|
|
1530
|
+
const statusCode = await ditto_run_garbage_collection(dittoPointer);
|
|
1531
|
+
if (statusCode !== 0)
|
|
1532
|
+
throw new Error(errorMessage() || `ditto_run_garbage_collection() failed with error code: ${statusCode}`);
|
|
1537
1533
|
}
|
|
1538
1534
|
/** @internal */
|
|
1539
1535
|
async function dittoDisableSyncWithV3(dittoPointer) {
|
|
@@ -1613,14 +1609,7 @@ onError) {
|
|
|
1613
1609
|
return ditto_auth_client_set_validity_listener(ditto, validityUpdateRawCb);
|
|
1614
1610
|
}
|
|
1615
1611
|
// ----------------------------------------------------------- Transports ------
|
|
1616
|
-
/**
|
|
1617
|
-
* We currently don't initialize transports through this function but rather in
|
|
1618
|
-
* the NAPI module registration in `transports.c` due to an issue with importing
|
|
1619
|
-
* the functions required by this function.
|
|
1620
|
-
* See https://github.com/getditto/ditto/issues/10723
|
|
1621
|
-
*
|
|
1622
|
-
* @internal
|
|
1623
|
-
*/
|
|
1612
|
+
/** @internal */
|
|
1624
1613
|
function transportsInit() {
|
|
1625
1614
|
ensureInitialized();
|
|
1626
1615
|
const { output: wasInitialized, errorType } = withTransportsError(ditto_sdk_transports_init);
|
|
@@ -1871,13 +1860,26 @@ const ERROR_CODES = {
|
|
|
1871
1860
|
/** Internal error for unexpected system states */
|
|
1872
1861
|
internal: 'An unexpected internal error occurred. Please get in touch with Ditto customer service to report this incident.',
|
|
1873
1862
|
/** Internal error with an unknown error cause */
|
|
1863
|
+
// REFACTOR: May be replaced by `unknown` in v5. Tracked in #12755.
|
|
1874
1864
|
'internal/unknown-error': 'An unexpected internal error occurred. Please get in touch with Ditto customer service to report this incident.',
|
|
1875
1865
|
//
|
|
1876
1866
|
// Errors originating in the SDK
|
|
1877
1867
|
//
|
|
1878
1868
|
/** Error when using a feature not supported by the current environment */
|
|
1869
|
+
// REFACTOR: May be replaced by `unsupported` in v5. Tracked in #12755.
|
|
1879
1870
|
'sdk/unsupported': 'The feature is not supported by the current environment.',
|
|
1880
1871
|
//
|
|
1872
|
+
// IO errors
|
|
1873
|
+
//
|
|
1874
|
+
/** Error when a file or directory already exists */
|
|
1875
|
+
'io/already-exists': 'A file or directory already exists.',
|
|
1876
|
+
/** Error when a file or directory could not be found */
|
|
1877
|
+
'io/not-found': 'A file or directory could not be found.',
|
|
1878
|
+
/** Error when permission is denied for a file operation */
|
|
1879
|
+
'io/permission-denied': 'The operation failed due to insufficient permissions.',
|
|
1880
|
+
/** Error when an IO operation failed for an unspecified reason. See error message for details. */
|
|
1881
|
+
'io/operation-failed': 'The operation failed.',
|
|
1882
|
+
//
|
|
1881
1883
|
// Query errors
|
|
1882
1884
|
//
|
|
1883
1885
|
/** Error for invalid DQL query arguments. */
|
|
@@ -1949,6 +1951,13 @@ const DEFAULT_STATUS_CODE_MAPPING = {
|
|
|
1949
1951
|
ActivationLicenseUnsupportedFutureVersion: ['activation/license-token-unsupported-future-version'],
|
|
1950
1952
|
ActivationNotActivated: ['activation/not-activated'],
|
|
1951
1953
|
//
|
|
1954
|
+
// Input/output errors
|
|
1955
|
+
//
|
|
1956
|
+
IoAlreadyExists: ['io/already-exists'],
|
|
1957
|
+
IoNotFound: ['io/not-found'],
|
|
1958
|
+
IoPermissionDenied: ['io/permission-denied'],
|
|
1959
|
+
IoOperationFailed: ['io/operation-failed'],
|
|
1960
|
+
//
|
|
1952
1961
|
// SDK-specific errors
|
|
1953
1962
|
//
|
|
1954
1963
|
JsFloatingStoreOperation: ['internal', 'Internal inconsistency, an outstanding store operation was not awaited.'],
|
|
@@ -1977,6 +1986,8 @@ const DEFAULT_STATUS_CODE_MAPPING = {
|
|
|
1977
1986
|
ValidationInvalidJson: ['validation/invalid-json'],
|
|
1978
1987
|
ValidationNotAMap: ['validation/not-an-object'],
|
|
1979
1988
|
ValidationSizeLimitExceeded: ['validation/size-limit-exceeded'],
|
|
1989
|
+
Unsupported: ['sdk/unsupported'],
|
|
1990
|
+
Unknown: ['internal/unknown-error'], // May be updated in v5, c.f. #12755
|
|
1980
1991
|
default: ['internal/unknown-error'],
|
|
1981
1992
|
};
|
|
1982
1993
|
/**
|
|
@@ -2222,7 +2233,7 @@ class AttachmentToken {
|
|
|
2222
2233
|
|
|
2223
2234
|
// NOTE: this is patched up with the actual build version by Jake task
|
|
2224
2235
|
// build:package and has to be a valid semantic version as defined here: https://semver.org.
|
|
2225
|
-
const fullBuildVersionString = '4.
|
|
2236
|
+
const fullBuildVersionString = '4.8.0-rc.2';
|
|
2226
2237
|
|
|
2227
2238
|
//
|
|
2228
2239
|
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
@@ -2253,7 +2264,6 @@ async function init(options = {}) {
|
|
|
2253
2264
|
initSDKVersion('Unknown', 'JavaScript', fullBuildVersionString);
|
|
2254
2265
|
break;
|
|
2255
2266
|
}
|
|
2256
|
-
loggerInit();
|
|
2257
2267
|
}
|
|
2258
2268
|
|
|
2259
2269
|
//
|
|
@@ -2262,6 +2272,16 @@ async function init(options = {}) {
|
|
|
2262
2272
|
/**
|
|
2263
2273
|
* Class with static methods to customize the logging behavior from Ditto and
|
|
2264
2274
|
* log messages with the Ditto logging infrastructure.
|
|
2275
|
+
*
|
|
2276
|
+
* Currently, Ditto uses the persistence directory of the Ditto instance that
|
|
2277
|
+
* was most recently created to store a limited amount of logs. Ditto may
|
|
2278
|
+
* continue writing logs to a persistence directory even after the associated
|
|
2279
|
+
* Ditto instance is {@link Ditto.close | closed}. If this is a concern,
|
|
2280
|
+
* consider either disabling logging by setting {@link Logger.enabled} to
|
|
2281
|
+
* `false`, or instantiating a new Ditto instance. After either of these
|
|
2282
|
+
* actions, it is safe to remove the persistence directory. Please refer to
|
|
2283
|
+
* {@link Logger.exportToFile | `exportToFile()`} for further details on locally
|
|
2284
|
+
* collected logs.
|
|
2265
2285
|
*/
|
|
2266
2286
|
class Logger {
|
|
2267
2287
|
/**
|
|
@@ -2298,7 +2318,13 @@ class Logger {
|
|
|
2298
2318
|
var _a;
|
|
2299
2319
|
this.setLogFile((_a = url === null || url === void 0 ? void 0 : url.pathname) !== null && _a !== void 0 ? _a : null);
|
|
2300
2320
|
}
|
|
2301
|
-
/**
|
|
2321
|
+
/**
|
|
2322
|
+
* Whether the logger is currently enabled.
|
|
2323
|
+
*
|
|
2324
|
+
* Logs exported through {@link exportToFile | exportToFile()} are not
|
|
2325
|
+
* affected by this setting and will also include logs emitted while
|
|
2326
|
+
* {@link enabled} is `false`.
|
|
2327
|
+
*/
|
|
2302
2328
|
static get enabled() {
|
|
2303
2329
|
return loggerEnabledGet();
|
|
2304
2330
|
}
|
|
@@ -2325,6 +2351,9 @@ class Logger {
|
|
|
2325
2351
|
*
|
|
2326
2352
|
* For example if this is set to `Warning`, then only logs that are logged
|
|
2327
2353
|
* with the `Warning` or `Error` log levels will be shown.
|
|
2354
|
+
*
|
|
2355
|
+
* Logs exported through {@link exportToFile | exportToFile()} are not
|
|
2356
|
+
* affected by this setting and include all logs at `Debug` level and above.
|
|
2328
2357
|
*/
|
|
2329
2358
|
static get minimumLogLevel() {
|
|
2330
2359
|
return loggerMinimumLogLevelGet();
|
|
@@ -2353,10 +2382,14 @@ class Logger {
|
|
|
2353
2382
|
* unregister any previous callback and stop reporting log entries through
|
|
2354
2383
|
* callbacks.
|
|
2355
2384
|
*
|
|
2385
|
+
* @throws {TypeError} if `callback` is not a function or `undefined`.
|
|
2356
2386
|
* @throws {Error} if called in a React Native environment.
|
|
2357
2387
|
*/
|
|
2358
2388
|
static async setCustomLogCallback(callback) {
|
|
2359
|
-
if (callback) {
|
|
2389
|
+
if (callback != null && typeof callback !== 'function') {
|
|
2390
|
+
throw new TypeError(`Expected parameter 'callback' to be a function or undefined, but got ${typeof callback}.`);
|
|
2391
|
+
}
|
|
2392
|
+
if (callback != null) {
|
|
2360
2393
|
await loggerSetCustomLogCb(callback);
|
|
2361
2394
|
this._customLogCallback = callback;
|
|
2362
2395
|
}
|
|
@@ -2365,6 +2398,65 @@ class Logger {
|
|
|
2365
2398
|
delete this._customLogCallback;
|
|
2366
2399
|
}
|
|
2367
2400
|
}
|
|
2401
|
+
/**
|
|
2402
|
+
* Exports collected logs to a compressed and JSON-encoded file on the local
|
|
2403
|
+
* file system.
|
|
2404
|
+
*
|
|
2405
|
+
* Ditto's logger locally collects a limited amount of logs at `Debug` level
|
|
2406
|
+
* and above, periodically discarding older logs. This internal logger is
|
|
2407
|
+
* always enabled and works independently of the {@link Logger.enabled}
|
|
2408
|
+
* setting and the configured {@link Logger.minimumLogLevel}. Its logs can be
|
|
2409
|
+
* requested and downloaded from any peer that is active in a Ditto app using
|
|
2410
|
+
* the portal's device dashboard. This method provides an alternative way of
|
|
2411
|
+
* accessing those logs by exporting them to the local file system.
|
|
2412
|
+
*
|
|
2413
|
+
* The logs will be written as a gzip compressed file at the path specified by
|
|
2414
|
+
* the `path` parameter. When uncompressed, the file contains one JSON value
|
|
2415
|
+
* per line with the oldest entry on the first line (JSON lines format).
|
|
2416
|
+
*
|
|
2417
|
+
* Ditto limits the amount of logs it retains on disk to 15 MB and a maximum
|
|
2418
|
+
* age of three days. Older logs are periodically discarded once one of these
|
|
2419
|
+
* limits is reached.
|
|
2420
|
+
*
|
|
2421
|
+
* This method currently only exports logs from the most recently created
|
|
2422
|
+
* Ditto instance, even when multiple instances are running in the same
|
|
2423
|
+
* process.
|
|
2424
|
+
*
|
|
2425
|
+
* Not supported in browser environments.
|
|
2426
|
+
*
|
|
2427
|
+
* @param path The path of the file to write the logs to. The file must not
|
|
2428
|
+
* already exist, and the containing directory must exist. It is recommended
|
|
2429
|
+
* for the `path` to have the `.jsonl.gz` file extension but Ditto won't
|
|
2430
|
+
* enforce it, nor correct it.
|
|
2431
|
+
*
|
|
2432
|
+
* @returns The number of bytes written to the file.
|
|
2433
|
+
*
|
|
2434
|
+
* @throws `TypeError` if `path` is not a string.
|
|
2435
|
+
*
|
|
2436
|
+
* @throws {@link DittoError} `io/*` when the file cannot be written to disk.
|
|
2437
|
+
* Prevent this by ensuring that no file exists at the provided `path`, all
|
|
2438
|
+
* parent directories exists, sufficient permissions are granted, and that the
|
|
2439
|
+
* disk is not full.
|
|
2440
|
+
*
|
|
2441
|
+
* @throws {@link DittoError} `sdk/unsupported` when called in a browser
|
|
2442
|
+
* environment.
|
|
2443
|
+
*/
|
|
2444
|
+
static async exportToFile(path) {
|
|
2445
|
+
if (typeof path !== 'string') {
|
|
2446
|
+
throw new TypeError(`Expected parameter 'path' to be a string, but got ${typeof path}.`);
|
|
2447
|
+
}
|
|
2448
|
+
let normalizedPath = path;
|
|
2449
|
+
if (process.platform === 'win32' && !path.startsWith('\\\\?\\')) {
|
|
2450
|
+
if (path.length === 0) {
|
|
2451
|
+
throw new DittoError('io/not-found', 'The path must not be empty.');
|
|
2452
|
+
}
|
|
2453
|
+
// Normalize the path on Windows to prevent issues with long paths.
|
|
2454
|
+
// Windows has a hard limit of 260 characters for paths.
|
|
2455
|
+
// c.f. httpes://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation
|
|
2456
|
+
normalizedPath = `\\\\?\\${path}`;
|
|
2457
|
+
}
|
|
2458
|
+
return mapFFIErrorsAsync(() => loggerTryExportToFileAsync(normalizedPath));
|
|
2459
|
+
}
|
|
2368
2460
|
/**
|
|
2369
2461
|
* Logs the message for the given `level`.
|
|
2370
2462
|
*
|
|
@@ -3416,8 +3508,8 @@ const CBOR$1 = {
|
|
|
3416
3508
|
/** @internal */
|
|
3417
3509
|
class CBOR {
|
|
3418
3510
|
/** @internal */
|
|
3419
|
-
static encode(data
|
|
3420
|
-
const arrayBuffer = CBOR$1.encode(data
|
|
3511
|
+
static encode(data) {
|
|
3512
|
+
const arrayBuffer = CBOR$1.encode(data);
|
|
3421
3513
|
return new Uint8Array(arrayBuffer);
|
|
3422
3514
|
}
|
|
3423
3515
|
/** @internal */
|
|
@@ -3727,8 +3819,6 @@ class Handles {
|
|
|
3727
3819
|
* - {@link Ditto}: `Bridge.ditto`
|
|
3728
3820
|
* - {@link Document}: `Bridge.document`
|
|
3729
3821
|
* - {@link MutableDocument}: `Bridge.mutableDocument`
|
|
3730
|
-
* - {@link StaticTCPClient}: `Bridge.staticTCPClient`
|
|
3731
|
-
* - {@link WebsocketClient}: `Bridge.websocketClient`
|
|
3732
3822
|
*
|
|
3733
3823
|
* Use `Bridge.<type>.handleFor()` to obtain a handle, which is a wrapper around
|
|
3734
3824
|
* the raw pointer, and `Bridge.<type>.bridge()` to get or create the matching
|
|
@@ -4013,10 +4103,6 @@ Bridge.queryResult = new _a(queryResultFree);
|
|
|
4013
4103
|
/** @internal */
|
|
4014
4104
|
Bridge.queryResultItem = new _a(queryResultItemFree);
|
|
4015
4105
|
/** @internal */
|
|
4016
|
-
Bridge.staticTCPClient = new _a(staticTCPClientFreeHandle);
|
|
4017
|
-
/** @internal */
|
|
4018
|
-
Bridge.websocketClient = new _a(websocketClientFreeHandle);
|
|
4019
|
-
/** @internal */
|
|
4020
4106
|
Bridge.ditto = new _a(async (dittoPointer) => {
|
|
4021
4107
|
// HACK: quick and dirty, clear all presence callbacks. This covers presence
|
|
4022
4108
|
// v1 and v2 callbacks. v3 should be cleared properly by the `Presence`
|
|
@@ -4052,9 +4138,7 @@ class Attachment {
|
|
|
4052
4138
|
* Returns the attachment's data.
|
|
4053
4139
|
*/
|
|
4054
4140
|
data() {
|
|
4055
|
-
|
|
4056
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
4057
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
4141
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
4058
4142
|
{
|
|
4059
4143
|
const attachmentHandle = Bridge.attachment.handleFor(this);
|
|
4060
4144
|
const attachmentPath = dittoGetCompleteAttachmentPath(dittoHandle.deref(), attachmentHandle.deref());
|
|
@@ -4078,16 +4162,14 @@ class Attachment {
|
|
|
4078
4162
|
* @param path The path that the attachment should be copied to.
|
|
4079
4163
|
*/
|
|
4080
4164
|
copyToPath(path) {
|
|
4081
|
-
|
|
4082
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
4083
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
4165
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
4084
4166
|
{
|
|
4085
4167
|
const attachmentHandle = Bridge.attachment.handleFor(this);
|
|
4086
4168
|
const attachmentPath = dittoGetCompleteAttachmentPath(dittoHandle.deref(), attachmentHandle.deref());
|
|
4087
4169
|
const fs = require('fs').promises;
|
|
4088
4170
|
// If the file already exists, we fail. This is the same behavior as
|
|
4089
4171
|
// for the Swift/ObjC SDK.
|
|
4090
|
-
|
|
4172
|
+
await fs.copyFile(attachmentPath, path, fs.COPYFILE_EXCL);
|
|
4091
4173
|
}
|
|
4092
4174
|
});
|
|
4093
4175
|
}
|
|
@@ -4331,21 +4413,6 @@ function validateQuery(query, options = {}) {
|
|
|
4331
4413
|
return validatedQuery;
|
|
4332
4414
|
}
|
|
4333
4415
|
// -------------------------------------------------------------- Helpers ------
|
|
4334
|
-
/**
|
|
4335
|
-
* Generate a random hex-encoded token using the WebCrypto API.
|
|
4336
|
-
*
|
|
4337
|
-
* @internal */
|
|
4338
|
-
function generateEphemeralToken() {
|
|
4339
|
-
let webcrypto = undefined;
|
|
4340
|
-
let data = new Uint16Array(16);
|
|
4341
|
-
// Note: Replacing conditional with polymorphism. (#10731)
|
|
4342
|
-
{
|
|
4343
|
-
webcrypto = require('crypto').webcrypto;
|
|
4344
|
-
webcrypto.getRandomValues(data);
|
|
4345
|
-
}
|
|
4346
|
-
const doublets = Array.from(data);
|
|
4347
|
-
return doublets.map((doublet) => doublet.toString(16)).join('');
|
|
4348
|
-
}
|
|
4349
4416
|
/**
|
|
4350
4417
|
* Can be used to implement a custom Node.js `inspect` representation for
|
|
4351
4418
|
* objects that have a `value` property.
|
|
@@ -5123,8 +5190,7 @@ class BasePendingCursorOperation {
|
|
|
5123
5190
|
*/
|
|
5124
5191
|
async exec() {
|
|
5125
5192
|
const ditto = this.collection.store.ditto;
|
|
5126
|
-
|
|
5127
|
-
return ditto.deferCloseAsync(async () => {
|
|
5193
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5128
5194
|
const query = this.query;
|
|
5129
5195
|
const documentPointers = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
5130
5196
|
return await collectionExecQueryStr(dittoHandle.deref(), this.collection.name, null, query, this.queryArgsCBOR, this.orderBys, this.currentLimit, this.currentOffset);
|
|
@@ -5151,8 +5217,7 @@ class BasePendingCursorOperation {
|
|
|
5151
5217
|
*/
|
|
5152
5218
|
async updateWithTransaction(closure, writeTransactionX) {
|
|
5153
5219
|
const ditto = this.collection.store.ditto;
|
|
5154
|
-
|
|
5155
|
-
return ditto.deferCloseAsync(async () => {
|
|
5220
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5156
5221
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
5157
5222
|
const query = this.query;
|
|
5158
5223
|
const documentsX = await collectionExecQueryStr(dittoHandle.deref(), this.collection.name, writeTransactionX, query, this.queryArgsCBOR, this.orderBys, this.currentLimit, this.currentOffset);
|
|
@@ -5234,8 +5299,7 @@ class BasePendingIDSpecificOperation {
|
|
|
5234
5299
|
*/
|
|
5235
5300
|
async exec() {
|
|
5236
5301
|
const ditto = this.collection.store.ditto;
|
|
5237
|
-
|
|
5238
|
-
return ditto.deferCloseAsync(async () => {
|
|
5302
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5239
5303
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
5240
5304
|
const readTransactionX = await readTransaction(dittoHandle.deref());
|
|
5241
5305
|
const documentX = await collectionGet(dittoHandle.deref(), this.collection.name, this.documentIDCBOR, readTransactionX);
|
|
@@ -5286,9 +5350,7 @@ class ConnectionRequest {
|
|
|
5286
5350
|
/**
|
|
5287
5351
|
* Metadata associated with the remote peer.
|
|
5288
5352
|
*
|
|
5289
|
-
* This is an empty object if the remote peer has not set any metadata
|
|
5290
|
-
* when this request is for a WebSocket connection (which does not currently
|
|
5291
|
-
* support peer metadata).
|
|
5353
|
+
* This is an empty object if the remote peer has not set any metadata.
|
|
5292
5354
|
*
|
|
5293
5355
|
* Set peer metadata for the local peer using {@link Presence.peerMetadata} or
|
|
5294
5356
|
* {@link Presence.peerMetadataJSONString}.
|
|
@@ -5303,8 +5365,7 @@ class ConnectionRequest {
|
|
|
5303
5365
|
* JSON-encoded metadata associated with the remote peer.
|
|
5304
5366
|
*
|
|
5305
5367
|
* This is a JSON string representing an empty dictionary if the remote peer
|
|
5306
|
-
* has not set any metadata
|
|
5307
|
-
* connection.
|
|
5368
|
+
* has not set any metadata.
|
|
5308
5369
|
*
|
|
5309
5370
|
* Set peer metadata for the local peer using {@link Presence.peerMetadata} or
|
|
5310
5371
|
* {@link Presence.peerMetadataJSONString}.
|
|
@@ -5403,7 +5464,7 @@ class ObserverManager {
|
|
|
5403
5464
|
throw new Error(`Internal inconsistency, can't add '${this.id}' observer, observer mananger close()-ed.`);
|
|
5404
5465
|
}
|
|
5405
5466
|
this.registerIfNeeded();
|
|
5406
|
-
const token =
|
|
5467
|
+
const token = cryptoGenerateSecureRandomToken();
|
|
5407
5468
|
this.callbacksByToken[token] = callback;
|
|
5408
5469
|
(_a = this.keepAlive) === null || _a === void 0 ? void 0 : _a.retain(`${this.id}.${token}`);
|
|
5409
5470
|
return token;
|
|
@@ -5590,44 +5651,26 @@ class Authenticator {
|
|
|
5590
5651
|
class OnlineAuthenticator extends Authenticator {
|
|
5591
5652
|
async loginWithToken(token, provider) {
|
|
5592
5653
|
const ditto = this.ditto.deref();
|
|
5593
|
-
if (!ditto)
|
|
5594
|
-
return;
|
|
5595
|
-
}
|
|
5596
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
5597
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
5598
|
-
if (!dittoPointer) {
|
|
5654
|
+
if (!ditto || ditto.isClosed)
|
|
5599
5655
|
return;
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
await dittoAuthClientLoginWithToken(dittoPointer, token, provider);
|
|
5656
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5657
|
+
await dittoAuthClientLoginWithToken(dittoHandle.deref(), token, provider);
|
|
5603
5658
|
});
|
|
5604
5659
|
}
|
|
5605
5660
|
async loginWithUsernameAndPassword(username, password, provider) {
|
|
5606
5661
|
const ditto = this.ditto.deref();
|
|
5607
|
-
if (!ditto)
|
|
5608
|
-
return;
|
|
5609
|
-
}
|
|
5610
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
5611
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
5612
|
-
if (!dittoPointer) {
|
|
5662
|
+
if (!ditto || ditto.isClosed)
|
|
5613
5663
|
return;
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
await dittoAuthClientLoginWithUsernameAndPassword(dittoPointer, username, password, provider);
|
|
5664
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5665
|
+
await dittoAuthClientLoginWithUsernameAndPassword(dittoHandle.deref(), username, password, provider);
|
|
5617
5666
|
});
|
|
5618
5667
|
}
|
|
5619
5668
|
async logout(cleanupFn) {
|
|
5620
5669
|
const ditto = this.ditto.deref();
|
|
5621
|
-
if (!ditto)
|
|
5622
|
-
return;
|
|
5623
|
-
}
|
|
5624
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
5625
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
5626
|
-
if (!dittoPointer) {
|
|
5670
|
+
if (!ditto || ditto.isClosed)
|
|
5627
5671
|
return;
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
await dittoAuthClientLogout(dittoPointer);
|
|
5672
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5673
|
+
await dittoAuthClientLogout(dittoHandle.deref());
|
|
5631
5674
|
ditto.stopSync();
|
|
5632
5675
|
cleanupFn === null || cleanupFn === void 0 ? void 0 : cleanupFn(ditto);
|
|
5633
5676
|
});
|
|
@@ -6044,7 +6087,7 @@ class AttachmentFetcher {
|
|
|
6044
6087
|
this.ditto = ditto;
|
|
6045
6088
|
this.token = token;
|
|
6046
6089
|
this.manager = manager;
|
|
6047
|
-
this.id =
|
|
6090
|
+
this.id = cryptoGenerateSecureRandomToken();
|
|
6048
6091
|
const eventHandlerOrNoOp = eventHandler || function () { };
|
|
6049
6092
|
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
6050
6093
|
this.attachment = new Promise((resolve, reject) => {
|
|
@@ -6210,7 +6253,7 @@ class Subscription {
|
|
|
6210
6253
|
this.queryArgsCBOR = queryArgsCBOR;
|
|
6211
6254
|
this.collection = collection;
|
|
6212
6255
|
this.contextInfo = {
|
|
6213
|
-
id:
|
|
6256
|
+
id: cryptoGenerateSecureRandomToken(),
|
|
6214
6257
|
collectionName: collection.name,
|
|
6215
6258
|
query,
|
|
6216
6259
|
queryArgsCBOR,
|
|
@@ -6390,19 +6433,14 @@ class LiveQuery {
|
|
|
6390
6433
|
let liveQueryID = undefined;
|
|
6391
6434
|
const signalNext = async () => {
|
|
6392
6435
|
const ditto = weakDitto.deref();
|
|
6393
|
-
if (!ditto)
|
|
6394
|
-
return;
|
|
6395
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
6396
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
6397
|
-
if (!dittoPointer)
|
|
6436
|
+
if (!ditto || ditto.isClosed)
|
|
6398
6437
|
return;
|
|
6399
|
-
return ditto.deferCloseAsync(async () => {
|
|
6400
|
-
await liveQuerySignalAvailableNext(
|
|
6438
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6439
|
+
await liveQuerySignalAvailableNext(dittoHandle.deref(), liveQueryID);
|
|
6401
6440
|
});
|
|
6402
6441
|
};
|
|
6403
6442
|
const ditto = collection.store.ditto;
|
|
6404
|
-
|
|
6405
|
-
ditto.deferClose(() => {
|
|
6443
|
+
ditto.deferClose((dittoHandle) => {
|
|
6406
6444
|
liveQueryID = liveQueryRegister(dittoHandle.deref(), collectionName, query, queryArgsCBOR, this.orderBys, limit, offset, (cCBParams) => {
|
|
6407
6445
|
const documents = cCBParams.documents.map((ptr) => Bridge.document.bridge(ptr));
|
|
6408
6446
|
let event;
|
|
@@ -6427,18 +6465,6 @@ class LiveQuery {
|
|
|
6427
6465
|
}
|
|
6428
6466
|
this._liveQueryID = liveQueryID;
|
|
6429
6467
|
}
|
|
6430
|
-
/** @internal */
|
|
6431
|
-
async signalNext() {
|
|
6432
|
-
// IDEA: make this public?
|
|
6433
|
-
const ditto = this.collection.store.ditto;
|
|
6434
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
6435
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
6436
|
-
if (!dittoPointer)
|
|
6437
|
-
return;
|
|
6438
|
-
return ditto.deferCloseAsync(async () => {
|
|
6439
|
-
await liveQuerySignalAvailableNext(dittoHandle.deref(), this.liveQueryID);
|
|
6440
|
-
});
|
|
6441
|
-
}
|
|
6442
6468
|
}
|
|
6443
6469
|
|
|
6444
6470
|
//
|
|
@@ -6482,8 +6508,7 @@ class PendingCursorOperation extends BasePendingCursorOperation {
|
|
|
6482
6508
|
}
|
|
6483
6509
|
async remove() {
|
|
6484
6510
|
const ditto = this.collection.store.ditto;
|
|
6485
|
-
|
|
6486
|
-
return ditto.deferCloseAsync(async () => {
|
|
6511
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6487
6512
|
const query = this.query;
|
|
6488
6513
|
const documentsX = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
6489
6514
|
const writeTransactionX = await writeTransaction(dittoHandle.deref());
|
|
@@ -6498,8 +6523,7 @@ class PendingCursorOperation extends BasePendingCursorOperation {
|
|
|
6498
6523
|
}
|
|
6499
6524
|
async evict() {
|
|
6500
6525
|
const ditto = this.collection.store.ditto;
|
|
6501
|
-
|
|
6502
|
-
return ditto.deferCloseAsync(async () => {
|
|
6526
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6503
6527
|
const query = this.query;
|
|
6504
6528
|
const documentsX = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
6505
6529
|
const writeTransactionX = await writeTransaction(dittoHandle.deref());
|
|
@@ -6514,8 +6538,7 @@ class PendingCursorOperation extends BasePendingCursorOperation {
|
|
|
6514
6538
|
}
|
|
6515
6539
|
async update(closure) {
|
|
6516
6540
|
const ditto = this.collection.store.ditto;
|
|
6517
|
-
|
|
6518
|
-
return ditto.deferCloseAsync(async () => {
|
|
6541
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6519
6542
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
6520
6543
|
const writeTransactionX = await writeTransaction(dittoHandle.deref());
|
|
6521
6544
|
const results = await super.updateWithTransaction(closure, writeTransactionX);
|
|
@@ -6649,8 +6672,7 @@ class PendingCursorOperation extends BasePendingCursorOperation {
|
|
|
6649
6672
|
class PendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
6650
6673
|
async remove() {
|
|
6651
6674
|
const ditto = this.collection.store.ditto;
|
|
6652
|
-
|
|
6653
|
-
return ditto.deferCloseAsync(async () => {
|
|
6675
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6654
6676
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
6655
6677
|
const writeTransactionX = await writeTransaction(dittoHandle.deref());
|
|
6656
6678
|
const didRemove = await collectionRemove(dittoHandle.deref(), this.collection.name, writeTransactionX, this.documentIDCBOR);
|
|
@@ -6661,8 +6683,7 @@ class PendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
|
6661
6683
|
}
|
|
6662
6684
|
async evict() {
|
|
6663
6685
|
const ditto = this.collection.store.ditto;
|
|
6664
|
-
|
|
6665
|
-
return ditto.deferCloseAsync(async () => {
|
|
6686
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6666
6687
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
6667
6688
|
const writeTransactionX = await writeTransaction(dittoHandle.deref());
|
|
6668
6689
|
const didEvict = await collectionEvict(dittoHandle.deref(), this.collection.name, writeTransactionX, this.documentIDCBOR);
|
|
@@ -6673,8 +6694,7 @@ class PendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
|
6673
6694
|
}
|
|
6674
6695
|
async update(closure) {
|
|
6675
6696
|
const ditto = this.collection.store.ditto;
|
|
6676
|
-
|
|
6677
|
-
return ditto.deferCloseAsync(async () => {
|
|
6697
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6678
6698
|
const readTransactionX = await readTransaction(dittoHandle.deref());
|
|
6679
6699
|
const documentX = await collectionGet(dittoHandle.deref(), this.collection.name, this.documentIDCBOR, readTransactionX);
|
|
6680
6700
|
readTransactionFree(readTransactionX);
|
|
@@ -6864,9 +6884,7 @@ class Collection {
|
|
|
6864
6884
|
return new PendingIDSpecificOperation(documentID, this);
|
|
6865
6885
|
}
|
|
6866
6886
|
async upsert(value, options = {}) {
|
|
6867
|
-
|
|
6868
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
6869
|
-
return ditto.deferCloseAsync(async () => {
|
|
6887
|
+
return this.store.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6870
6888
|
var _a;
|
|
6871
6889
|
const writeStrategy = (_a = options.writeStrategy) !== null && _a !== void 0 ? _a : 'merge';
|
|
6872
6890
|
const documentValueJSON = desugarJSObject(value);
|
|
@@ -6908,8 +6926,7 @@ class Collection {
|
|
|
6908
6926
|
*/
|
|
6909
6927
|
async newAttachment(pathOrData, metadata = {}) {
|
|
6910
6928
|
const ditto = this.store.ditto;
|
|
6911
|
-
|
|
6912
|
-
return ditto.deferCloseAsync(async () => {
|
|
6929
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6913
6930
|
const { id, len, handle } = await (async () => {
|
|
6914
6931
|
if (typeof pathOrData === 'string') {
|
|
6915
6932
|
{
|
|
@@ -6984,6 +7001,8 @@ class Collection {
|
|
|
6984
7001
|
* {@link QueryResultItem} for each match.
|
|
6985
7002
|
*
|
|
6986
7003
|
* More info, such as metrics, will be provided in the near future.
|
|
7004
|
+
*
|
|
7005
|
+
* @template T The type of items in the query result.
|
|
6987
7006
|
*/
|
|
6988
7007
|
class QueryResult {
|
|
6989
7008
|
/**
|
|
@@ -7029,6 +7048,11 @@ class QueryResult {
|
|
|
7029
7048
|
*
|
|
7030
7049
|
* Create a store observer by calling
|
|
7031
7050
|
* {@link Store.registerObserver | `ditto.store.registerObserver()`}.
|
|
7051
|
+
*
|
|
7052
|
+
* @template T The type of items in query results. This is a convenience type
|
|
7053
|
+
* that is neither inferred from the store observer's
|
|
7054
|
+
* {@link StoreObserver.queryString | query} nor validated against it.
|
|
7055
|
+
* @template S The type of query arguments.
|
|
7032
7056
|
*/
|
|
7033
7057
|
class StoreObserver {
|
|
7034
7058
|
/**
|
|
@@ -7073,8 +7097,7 @@ class StoreObserver {
|
|
|
7073
7097
|
}
|
|
7074
7098
|
}
|
|
7075
7099
|
let storeObserverID;
|
|
7076
|
-
|
|
7077
|
-
this.ditto.deferClose(() => {
|
|
7100
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
7078
7101
|
const weakThis = new WeakRef(this);
|
|
7079
7102
|
function wrappedObservationHandler(cCBParams) {
|
|
7080
7103
|
const strongThis = weakThis.deref();
|
|
@@ -7100,20 +7123,16 @@ class StoreObserver {
|
|
|
7100
7123
|
/**
|
|
7101
7124
|
* Signals to Ditto Core that the observer is ready for the next event.
|
|
7102
7125
|
*/
|
|
7103
|
-
signalNext() {
|
|
7126
|
+
async signalNext() {
|
|
7104
7127
|
const ditto = this.ditto;
|
|
7105
7128
|
if (!ditto || ditto.isClosed)
|
|
7106
7129
|
return;
|
|
7107
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7108
|
-
const dittoPointer = dittoHandle.derefOrNull();
|
|
7109
|
-
if (!dittoPointer)
|
|
7110
|
-
return;
|
|
7111
7130
|
if (this.liveQueryID == null) {
|
|
7112
7131
|
throw new Error('live query ID is null while signaling ready for next event');
|
|
7113
7132
|
}
|
|
7114
|
-
return ditto.deferCloseAsync(async () => {
|
|
7133
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7115
7134
|
Logger.debug(`Signaling availability for live query ${this.liveQueryID}`);
|
|
7116
|
-
await liveQuerySignalAvailableNext(
|
|
7135
|
+
await liveQuerySignalAvailableNext(dittoHandle.deref(), this.liveQueryID);
|
|
7117
7136
|
});
|
|
7118
7137
|
}
|
|
7119
7138
|
}
|
|
@@ -7386,8 +7405,7 @@ class WriteTransactionPendingCursorOperation extends BasePendingCursorOperation
|
|
|
7386
7405
|
}
|
|
7387
7406
|
async remove() {
|
|
7388
7407
|
const ditto = this.collection.store.ditto;
|
|
7389
|
-
|
|
7390
|
-
return ditto.deferCloseAsync(async () => {
|
|
7408
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7391
7409
|
const query = this.query;
|
|
7392
7410
|
const transaction = this.collection.writeTransaction;
|
|
7393
7411
|
const documentsX = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => collectionRemoveQueryStr(dittoHandle.deref(), this.collection.name, transaction.writeTransactionPointer, query, this.queryArgsCBOR, this.orderBys, this.currentLimit, this.currentOffset));
|
|
@@ -7402,8 +7420,7 @@ class WriteTransactionPendingCursorOperation extends BasePendingCursorOperation
|
|
|
7402
7420
|
}
|
|
7403
7421
|
async evict() {
|
|
7404
7422
|
const ditto = this.collection.store.ditto;
|
|
7405
|
-
|
|
7406
|
-
return ditto.deferCloseAsync(async () => {
|
|
7423
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7407
7424
|
const query = this.query;
|
|
7408
7425
|
const transaction = this.collection.writeTransaction;
|
|
7409
7426
|
const documentsX = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => collectionEvictQueryStr(dittoHandle.deref(), this.collection.name, transaction.writeTransactionPointer, query, this.queryArgsCBOR, this.orderBys, this.currentLimit, this.currentOffset));
|
|
@@ -7437,8 +7454,7 @@ class WriteTransactionPendingCursorOperation extends BasePendingCursorOperation
|
|
|
7437
7454
|
class WriteTransactionPendingIDSpecificOperation extends BasePendingIDSpecificOperation {
|
|
7438
7455
|
async remove() {
|
|
7439
7456
|
const ditto = this.collection.store.ditto;
|
|
7440
|
-
|
|
7441
|
-
return ditto.deferCloseAsync(async () => {
|
|
7457
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7442
7458
|
const transaction = this.collection.writeTransaction;
|
|
7443
7459
|
const result = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => collectionRemove(dittoHandle.deref(), this.collection.name, transaction.writeTransactionPointer, this.documentIDCBOR));
|
|
7444
7460
|
transaction.addResult('removed', this.documentID, this.collection.name);
|
|
@@ -7447,8 +7463,7 @@ class WriteTransactionPendingIDSpecificOperation extends BasePendingIDSpecificOp
|
|
|
7447
7463
|
}
|
|
7448
7464
|
async evict() {
|
|
7449
7465
|
const ditto = this.collection.store.ditto;
|
|
7450
|
-
|
|
7451
|
-
return ditto.deferCloseAsync(async () => {
|
|
7466
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7452
7467
|
const transaction = this.collection.writeTransaction;
|
|
7453
7468
|
const result = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => await collectionEvict(dittoHandle.deref(), this.collection.name, transaction.writeTransactionPointer, this.documentIDCBOR));
|
|
7454
7469
|
transaction.addResult('evicted', this.documentID, this.collection.name);
|
|
@@ -7457,8 +7472,7 @@ class WriteTransactionPendingIDSpecificOperation extends BasePendingIDSpecificOp
|
|
|
7457
7472
|
}
|
|
7458
7473
|
async update(closure) {
|
|
7459
7474
|
const ditto = this.collection.store.ditto;
|
|
7460
|
-
|
|
7461
|
-
return ditto.deferCloseAsync(async () => {
|
|
7475
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7462
7476
|
const transaction = this.collection.writeTransaction;
|
|
7463
7477
|
const readTransactionX = await readTransaction(dittoHandle.deref());
|
|
7464
7478
|
const documentX = await collectionGet(dittoHandle.deref(), this.collection.name, this.documentIDCBOR, readTransactionX);
|
|
@@ -7531,8 +7545,7 @@ class WriteTransactionCollection {
|
|
|
7531
7545
|
}
|
|
7532
7546
|
async upsert(value, options = {}) {
|
|
7533
7547
|
const ditto = this.store.ditto;
|
|
7534
|
-
|
|
7535
|
-
return ditto.deferCloseAsync(async () => {
|
|
7548
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7536
7549
|
var _a;
|
|
7537
7550
|
const writeStrategy = (_a = options.writeStrategy) !== null && _a !== void 0 ? _a : 'merge';
|
|
7538
7551
|
const documentValueJSON = desugarJSObject(value);
|
|
@@ -7574,22 +7587,6 @@ class WriteTransactionCollection {
|
|
|
7574
7587
|
* Create a write transaction using {@link Store.write | ditto.store.write}.
|
|
7575
7588
|
*/
|
|
7576
7589
|
class WriteTransaction {
|
|
7577
|
-
/**
|
|
7578
|
-
* Initialise a write transaction given a Ditto instance.
|
|
7579
|
-
*
|
|
7580
|
-
* This is not implemented as a constructor in order to be able to use FFI
|
|
7581
|
-
* async functions. Users start transactions through {@link Store.write}.
|
|
7582
|
-
*
|
|
7583
|
-
* @param ditto an instance of Ditto
|
|
7584
|
-
* @internal
|
|
7585
|
-
*/
|
|
7586
|
-
static async init(ditto) {
|
|
7587
|
-
return ditto.deferCloseAsync(async () => {
|
|
7588
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7589
|
-
const writeTransactionPointer = await writeTransaction(dittoHandle.deref());
|
|
7590
|
-
return new WriteTransaction(ditto, writeTransactionPointer);
|
|
7591
|
-
});
|
|
7592
|
-
}
|
|
7593
7590
|
/**
|
|
7594
7591
|
* Creates a transaction-specific
|
|
7595
7592
|
* {@link WriteTransactionCollection | collection} object that will ensure
|
|
@@ -7604,20 +7601,36 @@ class WriteTransaction {
|
|
|
7604
7601
|
}
|
|
7605
7602
|
return new WriteTransactionCollection(toCollectionNamed, this.ditto.store, this);
|
|
7606
7603
|
}
|
|
7607
|
-
|
|
7604
|
+
/** @internal */
|
|
7605
|
+
constructor(ditto, cTransaction) {
|
|
7606
|
+
this.writeTransactionPointer = cTransaction;
|
|
7607
|
+
this.ditto = ditto;
|
|
7608
|
+
this.results = [];
|
|
7609
|
+
}
|
|
7610
|
+
/**
|
|
7611
|
+
* Initialise a write transaction given a Ditto instance.
|
|
7612
|
+
*
|
|
7613
|
+
* This is not implemented as a constructor in order to be able to use FFI
|
|
7614
|
+
* async functions. Users start transactions through {@link Store.write}.
|
|
7615
|
+
*
|
|
7616
|
+
* @param ditto an instance of Ditto
|
|
7617
|
+
* @internal
|
|
7618
|
+
*/
|
|
7619
|
+
static async init(ditto) {
|
|
7620
|
+
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7621
|
+
const writeTransactionPointer = await writeTransaction(dittoHandle.deref());
|
|
7622
|
+
return new WriteTransaction(ditto, writeTransactionPointer);
|
|
7623
|
+
});
|
|
7624
|
+
}
|
|
7608
7625
|
/** @internal */
|
|
7609
7626
|
async commit() {
|
|
7610
|
-
|
|
7611
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7612
|
-
return ditto.deferCloseAsync(async () => {
|
|
7627
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7613
7628
|
return writeTransactionCommit(dittoHandle.deref(), this.writeTransactionPointer);
|
|
7614
7629
|
});
|
|
7615
7630
|
}
|
|
7616
7631
|
/** @internal */
|
|
7617
7632
|
async rollback() {
|
|
7618
|
-
|
|
7619
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7620
|
-
return ditto.deferCloseAsync(async () => {
|
|
7633
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7621
7634
|
return writeTransactionRollback(dittoHandle.deref(), this.writeTransactionPointer);
|
|
7622
7635
|
});
|
|
7623
7636
|
}
|
|
@@ -7625,7 +7638,8 @@ class WriteTransaction {
|
|
|
7625
7638
|
* Adds an entry to the list of results that is returned at the end of a
|
|
7626
7639
|
* transaction.
|
|
7627
7640
|
*
|
|
7628
|
-
* @internal
|
|
7641
|
+
* @internal
|
|
7642
|
+
*/
|
|
7629
7643
|
addResult(type, docID, collectionName) {
|
|
7630
7644
|
this.results.push({
|
|
7631
7645
|
type,
|
|
@@ -7633,12 +7647,6 @@ class WriteTransaction {
|
|
|
7633
7647
|
collectionName,
|
|
7634
7648
|
});
|
|
7635
7649
|
}
|
|
7636
|
-
/** @internal */
|
|
7637
|
-
constructor(ditto, cTransaction) {
|
|
7638
|
-
this.writeTransactionPointer = cTransaction;
|
|
7639
|
-
this.ditto = ditto;
|
|
7640
|
-
this.results = [];
|
|
7641
|
-
}
|
|
7642
7650
|
}
|
|
7643
7651
|
|
|
7644
7652
|
//
|
|
@@ -7662,14 +7670,18 @@ class Store {
|
|
|
7662
7670
|
* triggered automatically instead of having to call the passed in
|
|
7663
7671
|
* `signalNext` function.
|
|
7664
7672
|
*
|
|
7665
|
-
* @param query
|
|
7666
|
-
* @param observationHandler
|
|
7667
|
-
* change. The function is passed a {@link QueryResult} containing a
|
|
7673
|
+
* @param query A string containing a valid query expressed in DQL.
|
|
7674
|
+
* @param observationHandler A function that is called whenever the query's
|
|
7675
|
+
* results change. The function is passed a {@link QueryResult} containing a
|
|
7668
7676
|
* {@link QueryResultItem} for each match.
|
|
7669
|
-
* @param queryArguments
|
|
7677
|
+
* @param queryArguments An object of values keyed by the placeholder name
|
|
7670
7678
|
* without the leading `:`. Example: `{ "name": "Joanna" }` for a query like
|
|
7671
7679
|
* `SELECT * FROM people WHERE name = :name`.
|
|
7672
|
-
* @
|
|
7680
|
+
* @template T The type of items returned by the query. This is a convenience
|
|
7681
|
+
* type that is neither inferred from the `query` parameter nor validated
|
|
7682
|
+
* against it.
|
|
7683
|
+
* @template U The type of the query arguments.
|
|
7684
|
+
* @returns A {@link StoreObserver} that can be used to cancel the
|
|
7673
7685
|
* observation.
|
|
7674
7686
|
* @throws {@link DittoError} `query/invalid`: if `query` argument is not a
|
|
7675
7687
|
* string or not valid DQL.
|
|
@@ -7706,14 +7718,18 @@ class Store {
|
|
|
7706
7718
|
* The first invocation of `observationHandler` will always happen after this
|
|
7707
7719
|
* method has returned.
|
|
7708
7720
|
*
|
|
7709
|
-
* @param query
|
|
7710
|
-
* @param observationHandler
|
|
7721
|
+
* @param query A string containing a valid query expressed in DQL.
|
|
7722
|
+
* @param observationHandler An observation handler function that is called
|
|
7711
7723
|
* whenever the query's results change. The function is passed a
|
|
7712
7724
|
* {@link QueryResult} containing a {@link QueryResultItem} for each match.
|
|
7713
|
-
* @param queryArguments
|
|
7725
|
+
* @param queryArguments An object of values keyed by the placeholder name
|
|
7714
7726
|
* without the leading `:`. Example: `{ "name": "Joanna" }` for a query like
|
|
7715
7727
|
* `SELECT * FROM people WHERE name = :name`.
|
|
7716
|
-
* @
|
|
7728
|
+
* @template T The type of items returned by the query. This is a convenience
|
|
7729
|
+
* type that is neither inferred from the `query` parameter nor validated
|
|
7730
|
+
* against it.
|
|
7731
|
+
* @template U The type of the query arguments
|
|
7732
|
+
* @returns A {@link StoreObserver} that can be used to cancel the
|
|
7717
7733
|
* observation.
|
|
7718
7734
|
* @throws {@link DittoError} `query/invalid`: if `query` argument is not a
|
|
7719
7735
|
* string or not valid DQL.
|
|
@@ -7736,8 +7752,7 @@ class Store {
|
|
|
7736
7752
|
// If we would await the call here, we could end up in a situation where
|
|
7737
7753
|
// the first callback to the event handler is emitted before we return from
|
|
7738
7754
|
// the method call that started the observer.
|
|
7739
|
-
|
|
7740
|
-
void this.ditto.deferCloseAsync(async () => {
|
|
7755
|
+
void this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7741
7756
|
return new Promise((resolve) => {
|
|
7742
7757
|
void step(async () => {
|
|
7743
7758
|
try {
|
|
@@ -7783,20 +7798,28 @@ class Store {
|
|
|
7783
7798
|
* related {@link Ditto} instance.
|
|
7784
7799
|
*/
|
|
7785
7800
|
collectionNames() {
|
|
7786
|
-
|
|
7787
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7788
|
-
return ditto.deferClose(() => {
|
|
7801
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
7789
7802
|
return mapFFIErrors(() => dittoGetCollectionNames(dittoHandle.deref()));
|
|
7790
7803
|
});
|
|
7791
7804
|
}
|
|
7792
7805
|
/**
|
|
7793
7806
|
* Executes a DQL query and returns matching items as a query result.
|
|
7794
7807
|
*
|
|
7795
|
-
*
|
|
7796
|
-
* @
|
|
7808
|
+
* **Note:** only returns results from the local store without waiting for any
|
|
7809
|
+
* {@link SyncSubscription | sync subscriptions} to have caught up with the
|
|
7810
|
+
* latest changes. Only use this method if your program must proceed with
|
|
7811
|
+
* immediate results. Use a {@link StoreObserver | store observer} to receive
|
|
7812
|
+
* updates to query results as soon as they have been synced to this peer.
|
|
7813
|
+
*
|
|
7814
|
+
* @param query A string containing a valid query expressed in DQL.
|
|
7815
|
+
* @param queryArguments An object of values keyed by the placeholder name
|
|
7797
7816
|
* without the leading `:`. Example: `{ "name": "John" }` for a query like
|
|
7798
7817
|
* `SELECT * FROM people WHERE name = :name`.
|
|
7799
|
-
* @
|
|
7818
|
+
* @template T The type of items returned by the query. This is a convenience
|
|
7819
|
+
* type that is neither inferred from the `query` parameter nor validated
|
|
7820
|
+
* against it.
|
|
7821
|
+
* @template U The type of the query arguments
|
|
7822
|
+
* @returns A promise for a {@link QueryResult} containing a
|
|
7800
7823
|
* {@link QueryResultItem} for each match.
|
|
7801
7824
|
* @throws {@link DittoError} `query/invalid`: if `query` argument is not a
|
|
7802
7825
|
* string or not valid DQL.
|
|
@@ -7808,8 +7831,7 @@ class Store {
|
|
|
7808
7831
|
if (typeof query !== 'string') {
|
|
7809
7832
|
throw new DittoError('query/invalid', `Expected parameter 'query' to be of type 'string', found: ${typeof query}`);
|
|
7810
7833
|
}
|
|
7811
|
-
|
|
7812
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
7834
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7813
7835
|
// A one-off query execution uses a transaction internally but a
|
|
7814
7836
|
// transaction API is not implemented yet.
|
|
7815
7837
|
const writeTransaction = null;
|
|
@@ -7914,12 +7936,10 @@ class Store {
|
|
|
7914
7936
|
* attachment from a file path in a web browser.
|
|
7915
7937
|
*/
|
|
7916
7938
|
async newAttachment(pathOrData, metadata) {
|
|
7917
|
-
const ditto = this.ditto;
|
|
7918
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
7919
7939
|
if (metadata != null) {
|
|
7920
7940
|
validateAttachmentMetadata(metadata);
|
|
7921
7941
|
}
|
|
7922
|
-
return ditto.deferCloseAsync(async () => {
|
|
7942
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
7923
7943
|
//
|
|
7924
7944
|
// Create inputs for the attachment token from either a file path or raw data.
|
|
7925
7945
|
//
|
|
@@ -7942,7 +7962,8 @@ class Store {
|
|
|
7942
7962
|
})();
|
|
7943
7963
|
const attachmentTokenJSON = { _id: id, _len: len, _meta: { ...metadata }, [DittoCRDTTypeKey]: DittoCRDTType.attachment };
|
|
7944
7964
|
const attachmentToken = new AttachmentToken(attachmentTokenJSON);
|
|
7945
|
-
|
|
7965
|
+
// this.ditto is safe to use because we are inside a deferCloseAsync block
|
|
7966
|
+
const attachment = new Attachment(this.ditto, attachmentToken);
|
|
7946
7967
|
return Bridge.attachment.bridge(handle, () => attachment);
|
|
7947
7968
|
});
|
|
7948
7969
|
}
|
|
@@ -8015,9 +8036,8 @@ class Store {
|
|
|
8015
8036
|
else {
|
|
8016
8037
|
attachmentToken = new AttachmentToken(token);
|
|
8017
8038
|
}
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
const attachmentFetcher = new AttachmentFetcher(ditto, attachmentToken, null, eventHandler);
|
|
8039
|
+
return this.ditto.deferClose(() => {
|
|
8040
|
+
const attachmentFetcher = new AttachmentFetcher(this.ditto, attachmentToken, null, eventHandler);
|
|
8021
8041
|
// @ts-expect-error modifying readonly property
|
|
8022
8042
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
8023
8043
|
this.attachmentFetchers = Object.freeze([...this.attachmentFetchers, attachmentFetcher]);
|
|
@@ -8035,6 +8055,7 @@ class Store {
|
|
|
8035
8055
|
* observer and {@link StoreObserver.cancel | StoreObserver.cancel()} to
|
|
8036
8056
|
* remove an existing store observer.
|
|
8037
8057
|
*/
|
|
8058
|
+
// The type parameters are defined as `any` to avoid recursive type inference.
|
|
8038
8059
|
this.observers = Object.freeze([]);
|
|
8039
8060
|
/**
|
|
8040
8061
|
* All currently active attachment fetchers.
|
|
@@ -8074,9 +8095,8 @@ class Store {
|
|
|
8074
8095
|
throw new DittoError('query/arguments-invalid', `Invalid query arguments: ${error.message}`);
|
|
8075
8096
|
}
|
|
8076
8097
|
}
|
|
8077
|
-
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
8078
8098
|
// prettier-ignore
|
|
8079
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
8099
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8080
8100
|
const webhookIDCBOR = await mapFFIErrorsAsync(async () => await tryRegisterStoreObserverWebhook(dittoHandle.deref(), query, queryArgumentsCBOR, url));
|
|
8081
8101
|
return new DocumentID(webhookIDCBOR, true);
|
|
8082
8102
|
});
|
|
@@ -8169,9 +8189,7 @@ class Store {
|
|
|
8169
8189
|
* @internal
|
|
8170
8190
|
*/
|
|
8171
8191
|
async registerLiveQueryWebhook(collectionName, query, url) {
|
|
8172
|
-
|
|
8173
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8174
|
-
return ditto.deferCloseAsync(async () => {
|
|
8192
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8175
8193
|
const validatedQuery = validateQuery(query);
|
|
8176
8194
|
const idCBOR = await liveQueryWebhookRegister(dittoHandle.deref(), collectionName, validatedQuery, [], 0, 0, url);
|
|
8177
8195
|
return new DocumentID(idCBOR, true);
|
|
@@ -8260,9 +8278,7 @@ class Presence {
|
|
|
8260
8278
|
* connections between them.
|
|
8261
8279
|
*/
|
|
8262
8280
|
get graph() {
|
|
8263
|
-
|
|
8264
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8265
|
-
return ditto.deferClose(() => {
|
|
8281
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
8266
8282
|
const graphJSONString = dittoPresenceV3(dittoHandle.deref());
|
|
8267
8283
|
return JSON.parse(graphJSONString);
|
|
8268
8284
|
});
|
|
@@ -8273,16 +8289,13 @@ class Presence {
|
|
|
8273
8289
|
* and when evaluating connection requests using
|
|
8274
8290
|
* {@link connectionRequestHandler | connectionRequestHandler()}.
|
|
8275
8291
|
*
|
|
8276
|
-
* This is not made available to peers only connected via WebSocket.
|
|
8277
|
-
*
|
|
8278
8292
|
* Uses UTF-8 encoding.
|
|
8279
8293
|
*
|
|
8280
8294
|
* @see {@link peerMetadata | peerMetadata()} for a convenience property that
|
|
8281
8295
|
* provides access to parsed metadata.
|
|
8282
8296
|
*/
|
|
8283
8297
|
get peerMetadataJSONString() {
|
|
8284
|
-
|
|
8285
|
-
return this.ditto.deferClose(() => {
|
|
8298
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
8286
8299
|
return mapFFIErrors(() => {
|
|
8287
8300
|
return presencePeerMetadataJSON(dittoHandle.deref());
|
|
8288
8301
|
});
|
|
@@ -8293,7 +8306,7 @@ class Presence {
|
|
|
8293
8306
|
*
|
|
8294
8307
|
* The metadata must not exceed 4 KB in size when JSON-encoded.
|
|
8295
8308
|
*
|
|
8296
|
-
* @param {string} jsonString
|
|
8309
|
+
* @param {string} jsonString JSON-encoded metadata.
|
|
8297
8310
|
*
|
|
8298
8311
|
* @throws {@link DittoError} `validation/invalid-json`: if `jsonString` does
|
|
8299
8312
|
* not contain valid JSON.
|
|
@@ -8308,8 +8321,7 @@ class Presence {
|
|
|
8308
8321
|
* on usage of metadata.
|
|
8309
8322
|
*/
|
|
8310
8323
|
async setPeerMetadataJSONString(jsonString) {
|
|
8311
|
-
|
|
8312
|
-
await this.ditto.deferCloseAsync(async () => {
|
|
8324
|
+
await this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8313
8325
|
return mapFFIErrorsAsync(async () => {
|
|
8314
8326
|
return presenceTrySetPeerMetadataJSON(dittoHandle.deref(), jsonString);
|
|
8315
8327
|
});
|
|
@@ -8377,16 +8389,12 @@ class Presence {
|
|
|
8377
8389
|
this.observerManager = new ObserverManager('PresenceObservation', {
|
|
8378
8390
|
keepAlive: ditto.keepAlive,
|
|
8379
8391
|
register: (callback) => {
|
|
8380
|
-
|
|
8381
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8382
|
-
ditto.deferClose(() => {
|
|
8392
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8383
8393
|
dittoRegisterPresenceV3Callback(dittoHandle.deref(), callback);
|
|
8384
8394
|
});
|
|
8385
8395
|
},
|
|
8386
8396
|
unregister: () => {
|
|
8387
|
-
|
|
8388
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8389
|
-
void ditto.deferCloseAsync(async () => {
|
|
8397
|
+
void ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8390
8398
|
return dittoClearPresenceV3Callback(dittoHandle.deref());
|
|
8391
8399
|
});
|
|
8392
8400
|
},
|
|
@@ -8416,8 +8424,6 @@ class LiveQueryManager {
|
|
|
8416
8424
|
}
|
|
8417
8425
|
/** @internal */
|
|
8418
8426
|
startLiveQuery(liveQuery) {
|
|
8419
|
-
const ditto = this.ditto;
|
|
8420
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8421
8427
|
// REFACTOR: the starting closure runs detached from here which is a smell.
|
|
8422
8428
|
// Can we make this whole starting mechanism non-async? The culprit is
|
|
8423
8429
|
// the workaround for a zalgo with `ditto_live_query_start()` FFI function:
|
|
@@ -8426,7 +8432,7 @@ class LiveQueryManager {
|
|
|
8426
8432
|
// (by definition). This is a classic zalgo case. Fix by making
|
|
8427
8433
|
// `ditto_live_query_start()` trigger the first live query callback `async`,
|
|
8428
8434
|
// just like the subsequent ones.
|
|
8429
|
-
void this.ditto.deferCloseAsync(async () => {
|
|
8435
|
+
void this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8430
8436
|
const liveQueryID = liveQuery.liveQueryID;
|
|
8431
8437
|
if (!liveQueryID) {
|
|
8432
8438
|
throw new Error("Internal inconsistency, tried to add a live query that doesn't have a live query ID (probably stopped).");
|
|
@@ -8439,7 +8445,7 @@ class LiveQueryManager {
|
|
|
8439
8445
|
this.liveQueriesByID[liveQueryID] = weakLiveQuery;
|
|
8440
8446
|
this.finalizationRegistry.register(liveQuery, liveQueryID, this.finalize);
|
|
8441
8447
|
liveQuery.liveQueryManager = this;
|
|
8442
|
-
ditto.keepAlive.retain(`LiveQuery.${liveQueryID}`);
|
|
8448
|
+
this.ditto.keepAlive.retain(`LiveQuery.${liveQueryID}`);
|
|
8443
8449
|
return new Promise((resolve, reject) => {
|
|
8444
8450
|
// not awaited on purpose; let the invocation of the initial observation
|
|
8445
8451
|
// happen in a "fire-and-forget" / detached / escaping fashion, to be
|
|
@@ -8472,9 +8478,7 @@ class LiveQueryManager {
|
|
|
8472
8478
|
}
|
|
8473
8479
|
}
|
|
8474
8480
|
stopLiveQueryWithID(liveQueryID) {
|
|
8475
|
-
|
|
8476
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8477
|
-
ditto.deferClose(() => {
|
|
8481
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8478
8482
|
liveQueryStop(dittoHandle.deref(), liveQueryID);
|
|
8479
8483
|
this.keepAlive.release(`LiveQuery.${liveQueryID}`);
|
|
8480
8484
|
delete this.liveQueriesByID[liveQueryID];
|
|
@@ -8508,7 +8512,7 @@ class PresenceManager {
|
|
|
8508
8512
|
throw new Error(`Internal inconsistency, can't add presence observer, observer mananger close()-ed.`);
|
|
8509
8513
|
}
|
|
8510
8514
|
this.registerIfNeeded();
|
|
8511
|
-
const token =
|
|
8515
|
+
const token = cryptoGenerateSecureRandomToken();
|
|
8512
8516
|
this.callbacksByPresenceToken[token] = callback;
|
|
8513
8517
|
this.ditto.keepAlive.retain(`PresenceObservation.${token}`);
|
|
8514
8518
|
// REFACTOR: make the initial callback call async, too (othewise we'd be
|
|
@@ -8553,9 +8557,7 @@ class PresenceManager {
|
|
|
8553
8557
|
return Object.keys(this.callbacksByPresenceToken).length > 0;
|
|
8554
8558
|
}
|
|
8555
8559
|
registerIfNeeded() {
|
|
8556
|
-
|
|
8557
|
-
const dittoHandle = Bridge.ditto.handleFor(this.ditto);
|
|
8558
|
-
ditto.deferClose(() => {
|
|
8560
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8559
8561
|
const needsToRegister = !this.isRegistered;
|
|
8560
8562
|
if (needsToRegister) {
|
|
8561
8563
|
this.isRegistered = true;
|
|
@@ -8566,9 +8568,7 @@ class PresenceManager {
|
|
|
8566
8568
|
});
|
|
8567
8569
|
}
|
|
8568
8570
|
unregisterIfNeeded() {
|
|
8569
|
-
|
|
8570
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8571
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
8571
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8572
8572
|
const needsToUnregister = !this.hasObservers() && this.isRegistered;
|
|
8573
8573
|
if (needsToUnregister) {
|
|
8574
8574
|
this.isRegistered = false;
|
|
@@ -8631,16 +8631,12 @@ class TransportConditionsManager extends ObserverManager {
|
|
|
8631
8631
|
this.ditto = ditto;
|
|
8632
8632
|
}
|
|
8633
8633
|
register(callback) {
|
|
8634
|
-
|
|
8635
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8636
|
-
return ditto.deferClose(() => {
|
|
8634
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
8637
8635
|
return dittoRegisterTransportConditionChangedCallback(dittoHandle.deref(), callback);
|
|
8638
8636
|
});
|
|
8639
8637
|
}
|
|
8640
8638
|
unregister() {
|
|
8641
|
-
|
|
8642
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8643
|
-
return ditto.deferClose(() => {
|
|
8639
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
8644
8640
|
return dittoRegisterTransportConditionChangedCallback(dittoHandle.deref(), null);
|
|
8645
8641
|
});
|
|
8646
8642
|
}
|
|
@@ -8723,6 +8719,8 @@ class TransportConditionsManager extends ObserverManager {
|
|
|
8723
8719
|
*
|
|
8724
8720
|
* Create a sync subscription by calling
|
|
8725
8721
|
* {@link Sync.registerSubscription | `ditto.sync.registerSubscription()`}.
|
|
8722
|
+
*
|
|
8723
|
+
* @template T The type of query arguments passed to the sync subscription.
|
|
8726
8724
|
*/
|
|
8727
8725
|
class SyncSubscription {
|
|
8728
8726
|
/**
|
|
@@ -8782,6 +8780,7 @@ class Sync {
|
|
|
8782
8780
|
* @param query a string containing a valid query expressed in DQL.
|
|
8783
8781
|
* @param queryArguments an object containing the arguments for the query.
|
|
8784
8782
|
* Example: `{mileage: 123}` for a query with `:mileage` placeholder.
|
|
8783
|
+
* @template T The type of the query arguments.
|
|
8785
8784
|
* @returns An active `SyncSubscription` for the passed in query and
|
|
8786
8785
|
* arguments. It will remain active until it is
|
|
8787
8786
|
* {@link SyncSubscription.cancel | cancelled} or the {@link Ditto} instance
|
|
@@ -8808,8 +8807,7 @@ class Sync {
|
|
|
8808
8807
|
throw new DittoError('query/arguments-invalid', `Unable to encode query arguments: ${error.message}`);
|
|
8809
8808
|
}
|
|
8810
8809
|
}
|
|
8811
|
-
|
|
8812
|
-
this.ditto.deferClose(() => {
|
|
8810
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8813
8811
|
mapFFIErrors(() => tryAddSyncSubscription(dittoHandle.deref(), query, queryArgumentsCBOR));
|
|
8814
8812
|
});
|
|
8815
8813
|
const subscription = new SyncSubscription(this.ditto, query, queryArguments || null, queryArgumentsCBOR);
|
|
@@ -8877,8 +8875,7 @@ class Sync {
|
|
|
8877
8875
|
newSyncSubscriptions.splice(indexToDelete, 1);
|
|
8878
8876
|
// @ts-expect-error modifying readonly property
|
|
8879
8877
|
this.subscriptions = Object.freeze(newSyncSubscriptions);
|
|
8880
|
-
|
|
8881
|
-
this.ditto.deferClose(() => {
|
|
8878
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8882
8879
|
// prettier-ignore
|
|
8883
8880
|
mapFFIErrors(() => tryRemoveSyncSubscription(dittoHandle.deref(), syncSubscription.queryString, syncSubscription.queryArgumentsCBOR));
|
|
8884
8881
|
});
|
|
@@ -8917,9 +8914,7 @@ class Sync {
|
|
|
8917
8914
|
// already be cleaned up properly.
|
|
8918
8915
|
}
|
|
8919
8916
|
updatePeerToPeerBluetoothLE(stateOld, stateNew) {
|
|
8920
|
-
|
|
8921
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8922
|
-
ditto.deferClose(() => {
|
|
8917
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8923
8918
|
const bluetoothLEOld = stateOld.effectiveTransportConfig.peerToPeer.bluetoothLE;
|
|
8924
8919
|
const bluetoothLENew = stateNew.effectiveTransportConfig.peerToPeer.bluetoothLE;
|
|
8925
8920
|
const shouldStart = !bluetoothLEOld.isEnabled && bluetoothLENew.isEnabled;
|
|
@@ -8958,9 +8953,7 @@ class Sync {
|
|
|
8958
8953
|
});
|
|
8959
8954
|
}
|
|
8960
8955
|
updatePeerToPeerAWDL(stateOld, stateNew) {
|
|
8961
|
-
|
|
8962
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8963
|
-
ditto.deferClose(() => {
|
|
8956
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8964
8957
|
const awdlOld = stateOld.effectiveTransportConfig.peerToPeer.awdl;
|
|
8965
8958
|
const awdlNew = stateNew.effectiveTransportConfig.peerToPeer.awdl;
|
|
8966
8959
|
const shouldStart = !awdlOld.isEnabled && awdlNew.isEnabled;
|
|
@@ -8980,9 +8973,7 @@ class Sync {
|
|
|
8980
8973
|
});
|
|
8981
8974
|
}
|
|
8982
8975
|
updatePeerToPeerLAN(stateOld, stateNew) {
|
|
8983
|
-
|
|
8984
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
8985
|
-
ditto.deferClose(() => {
|
|
8976
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
8986
8977
|
const lanOld = stateOld.effectiveTransportConfig.peerToPeer.lan;
|
|
8987
8978
|
const lanNew = stateNew.effectiveTransportConfig.peerToPeer.lan;
|
|
8988
8979
|
// HACK: quick & dirty Linux & Windows hack. A proper implementation
|
|
@@ -9041,9 +9032,7 @@ class Sync {
|
|
|
9041
9032
|
});
|
|
9042
9033
|
}
|
|
9043
9034
|
updateListenTCP(stateOld, stateNew) {
|
|
9044
|
-
|
|
9045
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9046
|
-
ditto.deferClose(() => {
|
|
9035
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9047
9036
|
const tcpOld = stateOld.effectiveTransportConfig.listen.tcp;
|
|
9048
9037
|
const tcpNew = stateNew.effectiveTransportConfig.listen.tcp;
|
|
9049
9038
|
if (TransportConfig.areListenTCPsEqual(tcpNew, tcpOld))
|
|
@@ -9055,9 +9044,7 @@ class Sync {
|
|
|
9055
9044
|
});
|
|
9056
9045
|
}
|
|
9057
9046
|
updateListenHTTP(stateOld, stateNew) {
|
|
9058
|
-
|
|
9059
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9060
|
-
ditto.deferClose(() => {
|
|
9047
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9061
9048
|
const httpOld = stateOld.effectiveTransportConfig.listen.http;
|
|
9062
9049
|
const httpNew = stateNew.effectiveTransportConfig.listen.http;
|
|
9063
9050
|
if (TransportConfig.areListenHTTPsEqual(httpOld, httpNew))
|
|
@@ -9072,35 +9059,27 @@ class Sync {
|
|
|
9072
9059
|
});
|
|
9073
9060
|
}
|
|
9074
9061
|
updateConnectTCPServers(stateOld, stateNew) {
|
|
9075
|
-
|
|
9076
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9077
|
-
ditto.deferClose(() => {
|
|
9062
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9078
9063
|
const tcpServers = stateNew.effectiveTransportConfig.connect.tcpServers;
|
|
9079
9064
|
dittoSetStaticTCPClients(dittoHandle.deref(), tcpServers);
|
|
9080
9065
|
});
|
|
9081
9066
|
}
|
|
9082
9067
|
updateConnectWebsocketURLs(stateOld, stateNew) {
|
|
9083
|
-
|
|
9084
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9085
|
-
ditto.deferClose(() => {
|
|
9068
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9086
9069
|
const websocketURLs = stateNew.effectiveTransportConfig.connect.websocketURLs;
|
|
9087
9070
|
const routingHint = stateNew.effectiveTransportConfig.global.routingHint;
|
|
9088
9071
|
dittoSetStaticWebsocketClients(dittoHandle.deref(), websocketURLs, routingHint);
|
|
9089
9072
|
});
|
|
9090
9073
|
}
|
|
9091
9074
|
updateGlobal(stateOld, stateNew) {
|
|
9092
|
-
|
|
9093
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9094
|
-
ditto.deferClose(() => {
|
|
9075
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9095
9076
|
if (stateOld.effectiveTransportConfig.global.syncGroup !== stateNew.effectiveTransportConfig.global.syncGroup) {
|
|
9096
9077
|
dittoSetSyncGroup(dittoHandle.deref(), stateNew.effectiveTransportConfig.global.syncGroup);
|
|
9097
9078
|
}
|
|
9098
9079
|
});
|
|
9099
9080
|
}
|
|
9100
9081
|
updateConnectRetryInterval(stateOld, stateNew) {
|
|
9101
|
-
|
|
9102
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9103
|
-
ditto.deferClose(() => {
|
|
9082
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9104
9083
|
dittoSetConnectRetryInterval(dittoHandle.deref(), stateNew.effectiveTransportConfig.connect.retryInterval);
|
|
9105
9084
|
});
|
|
9106
9085
|
}
|
|
@@ -9173,8 +9152,7 @@ function stateFrom(parameters) {
|
|
|
9173
9152
|
* @private
|
|
9174
9153
|
*/
|
|
9175
9154
|
function validateEnabledTransportsAvailable(ditto, transportConfig) {
|
|
9176
|
-
|
|
9177
|
-
return ditto.deferClose(() => {
|
|
9155
|
+
return ditto.deferClose((dittoHandle) => {
|
|
9178
9156
|
// - BLE
|
|
9179
9157
|
// - AWDL
|
|
9180
9158
|
// - LAN / mDNS
|
|
@@ -9230,10 +9208,8 @@ class SubscriptionManager {
|
|
|
9230
9208
|
* @internal
|
|
9231
9209
|
*/
|
|
9232
9210
|
add(subscription) {
|
|
9233
|
-
const ditto = this.ditto;
|
|
9234
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9235
9211
|
const contextInfo = subscription.contextInfo;
|
|
9236
|
-
ditto.deferClose(() => {
|
|
9212
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9237
9213
|
this.subscriptions[contextInfo.id] = new WeakRef(subscription);
|
|
9238
9214
|
this.finalizationRegistry.register(subscription, subscription.contextInfo, subscription);
|
|
9239
9215
|
addSubscription(dittoHandle.deref(), contextInfo.collectionName, contextInfo.query, contextInfo.queryArgsCBOR, contextInfo.orderBys, contextInfo.limit, contextInfo.offset);
|
|
@@ -9271,9 +9247,7 @@ class SubscriptionManager {
|
|
|
9271
9247
|
* @internal
|
|
9272
9248
|
*/
|
|
9273
9249
|
removeWithContextInfo(contextInfo) {
|
|
9274
|
-
|
|
9275
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto);
|
|
9276
|
-
ditto.deferClose(() => {
|
|
9250
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9277
9251
|
delete this.subscriptions[contextInfo.id];
|
|
9278
9252
|
removeSubscription(dittoHandle.deref(), contextInfo.collectionName, contextInfo.query, contextInfo.queryArgsCBOR, contextInfo.orderBys, contextInfo.limit, contextInfo.offset);
|
|
9279
9253
|
});
|
|
@@ -9373,8 +9347,7 @@ class AttachmentFetcherManager {
|
|
|
9373
9347
|
* registry.
|
|
9374
9348
|
*/
|
|
9375
9349
|
stopWithContextInfo(contextInfo) {
|
|
9376
|
-
|
|
9377
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
9350
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
9378
9351
|
// Remove the manager's own record of the context info.
|
|
9379
9352
|
if (this.contextInfoByID[contextInfo.id] == null) {
|
|
9380
9353
|
throw new Error(`Internal inconsistency: attachment fetcher ${contextInfo.id} not found in active attachment fetchers.`);
|
|
@@ -9407,7 +9380,7 @@ class AttachmentFetcherManager {
|
|
|
9407
9380
|
class SmallPeerInfo {
|
|
9408
9381
|
/**
|
|
9409
9382
|
* Indicates whether small peer info collection is currently enabled, defaults
|
|
9410
|
-
* to `
|
|
9383
|
+
* to `true`.
|
|
9411
9384
|
*
|
|
9412
9385
|
* **Note**: whether the background ingestion process is enabled or not is a
|
|
9413
9386
|
* separate decision to whether this information is allowed to sync to other
|
|
@@ -9416,8 +9389,7 @@ class SmallPeerInfo {
|
|
|
9416
9389
|
* {@link setSyncScope | setSyncScope()}.
|
|
9417
9390
|
*/
|
|
9418
9391
|
get isEnabled() {
|
|
9419
|
-
|
|
9420
|
-
return this.ditto.deferClose(() => {
|
|
9392
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
9421
9393
|
return dittoSmallPeerInfoGetIsEnabled(dittoHandle.deref());
|
|
9422
9394
|
});
|
|
9423
9395
|
}
|
|
@@ -9430,8 +9402,7 @@ class SmallPeerInfo {
|
|
|
9430
9402
|
if (typeof newValue !== 'boolean') {
|
|
9431
9403
|
throw new TypeError(`Expected boolean, got ${typeof newValue}`);
|
|
9432
9404
|
}
|
|
9433
|
-
|
|
9434
|
-
void this.ditto.deferCloseAsync(async () => {
|
|
9405
|
+
void this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
9435
9406
|
return dittoSmallPeerInfoSetEnabled(dittoHandle.deref(), newValue);
|
|
9436
9407
|
});
|
|
9437
9408
|
}
|
|
@@ -9473,8 +9444,7 @@ class SmallPeerInfo {
|
|
|
9473
9444
|
* The metadata associated with the small peer info, as a JSON string.
|
|
9474
9445
|
*/
|
|
9475
9446
|
get metadataJSONString() {
|
|
9476
|
-
|
|
9477
|
-
return this.ditto.deferClose(() => {
|
|
9447
|
+
return this.ditto.deferClose((dittoHandle) => {
|
|
9478
9448
|
return dittoSmallPeerInfoGetMetadata(dittoHandle.deref());
|
|
9479
9449
|
});
|
|
9480
9450
|
}
|
|
@@ -9490,8 +9460,7 @@ class SmallPeerInfo {
|
|
|
9490
9460
|
if (typeof metadata !== 'string') {
|
|
9491
9461
|
throw new TypeError(`Expected string, got ${typeof metadata}`);
|
|
9492
9462
|
}
|
|
9493
|
-
|
|
9494
|
-
this.ditto.deferClose(() => {
|
|
9463
|
+
this.ditto.deferClose((dittoHandle) => {
|
|
9495
9464
|
// throws if any validation errors occur
|
|
9496
9465
|
dittoSmallPeerInfoSetMetadata(dittoHandle.deref(), metadata);
|
|
9497
9466
|
});
|
|
@@ -9504,8 +9473,7 @@ class SmallPeerInfo {
|
|
|
9504
9473
|
* `BigPeerOnly` to replicate collected info to the Big Peer.
|
|
9505
9474
|
*/
|
|
9506
9475
|
async getSyncScope() {
|
|
9507
|
-
|
|
9508
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
9476
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
9509
9477
|
return dittoSmallPeerInfoGetSyncScope(dittoHandle.deref());
|
|
9510
9478
|
});
|
|
9511
9479
|
}
|
|
@@ -9518,8 +9486,7 @@ class SmallPeerInfo {
|
|
|
9518
9486
|
* @throws when set to a value other than `BigPeerOnly` or `LocalPeerOnly`.
|
|
9519
9487
|
*/
|
|
9520
9488
|
async setSyncScope(syncScope) {
|
|
9521
|
-
|
|
9522
|
-
return this.ditto.deferCloseAsync(async () => {
|
|
9489
|
+
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
9523
9490
|
return dittoSmallPeerInfoSetSyncScope(dittoHandle.deref(), syncScope);
|
|
9524
9491
|
});
|
|
9525
9492
|
}
|
|
@@ -9570,8 +9537,7 @@ class Ditto {
|
|
|
9570
9537
|
}
|
|
9571
9538
|
/** Returns a string identifying the version of the Ditto SDK. */
|
|
9572
9539
|
get sdkVersion() {
|
|
9573
|
-
|
|
9574
|
-
return this.deferClose(() => {
|
|
9540
|
+
return this.deferClose((dittoHandle) => {
|
|
9575
9541
|
return dittoGetSDKVersion(dittoHandle.deref());
|
|
9576
9542
|
});
|
|
9577
9543
|
}
|
|
@@ -9644,6 +9610,7 @@ class Ditto {
|
|
|
9644
9610
|
if (!Ditto.isEnvironmentSupported()) {
|
|
9645
9611
|
throw new Error('Ditto does not support this JavaScript environment. Please consult the Ditto JavaScript documentation for a list of supported environments and browsers. You can use `Ditto.isEnvironmentSupported()` to run this check anytime.');
|
|
9646
9612
|
}
|
|
9613
|
+
loggerInit();
|
|
9647
9614
|
this.persistenceDirectory = Ditto.initPersistenceDirectory(persistenceDirectory);
|
|
9648
9615
|
const identityOrDefault = identity !== null && identity !== void 0 ? identity : { type: 'offlinePlayground', appID: '' };
|
|
9649
9616
|
const validIdentity = Object.freeze(this.validateIdentity(identityOrDefault));
|
|
@@ -9957,8 +9924,7 @@ class Ditto {
|
|
|
9957
9924
|
this.sync.update({ transportConfig: transportConfigNew, identity, isWebValid, isX509Valid, isSyncActive: this.isSyncActive, ditto: this });
|
|
9958
9925
|
const configSerializeReady = transportConfigToSerializable(transportConfigNew);
|
|
9959
9926
|
const configCBOR = CBOR.encode(configSerializeReady);
|
|
9960
|
-
|
|
9961
|
-
this.deferClose(() => {
|
|
9927
|
+
this.deferClose((dittoHandle) => {
|
|
9962
9928
|
dittoSmallPeerInfoCollectionSetTransportConfigData(dittoHandle.deref(), configCBOR);
|
|
9963
9929
|
});
|
|
9964
9930
|
}
|
|
@@ -9982,6 +9948,10 @@ class Ditto {
|
|
|
9982
9948
|
* customized with {@link updateTransportConfig | updateTransportConfig()}
|
|
9983
9949
|
* or replaced entirely with {@link setTransportConfig | setTransportConfig()}.
|
|
9984
9950
|
*
|
|
9951
|
+
* Performance of initial sync when bootstrapping new peers can be improved by
|
|
9952
|
+
* calling {@link disableSyncWithV3 | disableSyncWithV3()} before
|
|
9953
|
+
* {@link startSync | startSync()}. Only call that method when all peers in
|
|
9954
|
+
* the mesh are known to be running Ditto v4 or higher.
|
|
9985
9955
|
*
|
|
9986
9956
|
* Ditto will prevent the process from exiting until sync is stopped (not
|
|
9987
9957
|
* relevant when running in the browser).
|
|
@@ -10041,11 +10011,11 @@ class Ditto {
|
|
|
10041
10011
|
return new Observer(this.transportConditionsManager, token, { stopsWhenFinalized: true });
|
|
10042
10012
|
}
|
|
10043
10013
|
/**
|
|
10044
|
-
* Removes all sync metadata for
|
|
10045
|
-
*
|
|
10046
|
-
*
|
|
10047
|
-
*
|
|
10048
|
-
* optimal times.
|
|
10014
|
+
* Removes all sync metadata for remote peers that aren't currently connected.
|
|
10015
|
+
*
|
|
10016
|
+
* This method shouldn't usually be called. Manually running garbage
|
|
10017
|
+
* collection often will result in slower sync times. Ditto automatically runs
|
|
10018
|
+
* a garbage a collection process in the background at optimal times.
|
|
10049
10019
|
*
|
|
10050
10020
|
* Manually running garbage collection is typically only useful during testing
|
|
10051
10021
|
* if large amounts of data are being generated. Alternatively, if an entire
|
|
@@ -10053,28 +10023,31 @@ class Ditto {
|
|
|
10053
10023
|
* isn't necessary, then garbage collection could be run after evicting the
|
|
10054
10024
|
* old data.
|
|
10055
10025
|
*
|
|
10056
|
-
*
|
|
10026
|
+
* This method does not have any effect when running Ditto in a browser.
|
|
10057
10027
|
*/
|
|
10058
|
-
runGarbageCollection() {
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
dittoRunGarbageCollection(dittoHandle.deref());
|
|
10028
|
+
async runGarbageCollection() {
|
|
10029
|
+
return this.deferCloseAsync(async (dittoHandle) => {
|
|
10030
|
+
return dittoRunGarbageCollection(dittoHandle.deref());
|
|
10062
10031
|
});
|
|
10063
10032
|
}
|
|
10064
10033
|
/**
|
|
10065
|
-
*
|
|
10066
|
-
*
|
|
10034
|
+
* Disable sync with peers running version 3 or lower of the Ditto SDK.
|
|
10035
|
+
*
|
|
10036
|
+
* Required for the execution of mutating DQL statements.
|
|
10037
|
+
*
|
|
10038
|
+
* This setting spreads to other peers on connection. Those peers will in turn
|
|
10039
|
+
* spread it further until all peers in the mesh take on the same setting.
|
|
10040
|
+
* This is irreversible and will persist across restarts of the Ditto
|
|
10041
|
+
* instance.
|
|
10067
10042
|
*
|
|
10068
|
-
*
|
|
10069
|
-
*
|
|
10070
|
-
*
|
|
10071
|
-
* or has (transitively) had disabled, syncing with v3 SDK peers.
|
|
10043
|
+
* Calling this method before starting sync is recommended whenever possible.
|
|
10044
|
+
* This improves performance of initial sync when this peer has never before
|
|
10045
|
+
* connected to a Ditto mesh for which sync with v3 peers is disabled.
|
|
10072
10046
|
*
|
|
10073
10047
|
* @throws {Error} if called in a React Native environment.
|
|
10074
10048
|
*/
|
|
10075
10049
|
async disableSyncWithV3() {
|
|
10076
|
-
|
|
10077
|
-
return this.deferCloseAsync(async () => {
|
|
10050
|
+
return this.deferCloseAsync(async (dittoHandle) => {
|
|
10078
10051
|
await dittoDisableSyncWithV3(dittoHandle.deref());
|
|
10079
10052
|
});
|
|
10080
10053
|
}
|
|
@@ -10127,15 +10100,20 @@ class Ditto {
|
|
|
10127
10100
|
* Makes sure that the closure is executed only if the Ditto instance hasn't
|
|
10128
10101
|
* been closed yet.
|
|
10129
10102
|
*
|
|
10103
|
+
* The closure is given a {@link Handle | handle} to the Ditto instance that
|
|
10104
|
+
* is valid while the closure is executing.
|
|
10105
|
+
*
|
|
10130
10106
|
* @param closure the synchronous closure to execute.
|
|
10131
10107
|
* @returns the result of the closure.
|
|
10132
10108
|
* @throws if the Ditto instance was closed before calling this method.
|
|
10133
|
-
* @internal
|
|
10109
|
+
* @internal
|
|
10110
|
+
*/
|
|
10134
10111
|
deferClose(closure) {
|
|
10135
10112
|
if (!this.deferCloseAllowed) {
|
|
10136
10113
|
throw new Error(`Can't perform operation using a Ditto instance that has been closed.`);
|
|
10137
10114
|
}
|
|
10138
|
-
|
|
10115
|
+
const dittoHandle = Bridge.ditto.handleFor(this);
|
|
10116
|
+
return closure(dittoHandle);
|
|
10139
10117
|
}
|
|
10140
10118
|
/**
|
|
10141
10119
|
* Makes sure that the closure is executed to completion before the Ditto
|
|
@@ -10144,15 +10122,20 @@ class Ditto {
|
|
|
10144
10122
|
* Any calls to {@link close | `Ditto.close()`} will wait until the closure
|
|
10145
10123
|
* has completed before closing the Ditto instance.
|
|
10146
10124
|
*
|
|
10125
|
+
* The closure is given a {@link Handle | handle} to the Ditto instance that
|
|
10126
|
+
* is valid while the closure is executing.
|
|
10127
|
+
*
|
|
10147
10128
|
* @param closure the asynchronous closure to execute.
|
|
10148
10129
|
* @returns the result of the closure.
|
|
10149
10130
|
* @throws if the Ditto instance was closed before calling this method.
|
|
10150
|
-
* @internal
|
|
10131
|
+
* @internal
|
|
10132
|
+
*/
|
|
10151
10133
|
async deferCloseAsync(closure) {
|
|
10152
10134
|
if (!this.deferCloseAllowed) {
|
|
10153
10135
|
throw new Error(`Can't perform operation using a Ditto instance that has been closed.`);
|
|
10154
10136
|
}
|
|
10155
|
-
const
|
|
10137
|
+
const dittoHandle = Bridge.ditto.handleFor(this);
|
|
10138
|
+
const pendingOperation = closure(dittoHandle);
|
|
10156
10139
|
this.pendingOperations.add(pendingOperation);
|
|
10157
10140
|
let result;
|
|
10158
10141
|
try {
|
|
@@ -10214,8 +10197,7 @@ class Ditto {
|
|
|
10214
10197
|
return validIdentity;
|
|
10215
10198
|
}
|
|
10216
10199
|
setSyncActive(flag) {
|
|
10217
|
-
|
|
10218
|
-
this.deferClose(() => {
|
|
10200
|
+
this.deferClose((dittoHandle) => {
|
|
10219
10201
|
if (flag && IdentityTypesRequiringOfflineLicenseToken.includes(this.identity.type) && !this.isActivated) {
|
|
10220
10202
|
throw new Error('Sync could not be started because Ditto has not yet been activated. This can be achieved with a successful call to `setOfflineOnlyLicenseToken`. If you need to obtain a license token then please visit https://portal.ditto.live.');
|
|
10221
10203
|
}
|
|
@@ -10235,8 +10217,7 @@ class Ditto {
|
|
|
10235
10217
|
});
|
|
10236
10218
|
}
|
|
10237
10219
|
makeDefaultTransportConfig() {
|
|
10238
|
-
|
|
10239
|
-
return this.deferClose(() => {
|
|
10220
|
+
return this.deferClose((dittoHandle) => {
|
|
10240
10221
|
const transportConfig = new TransportConfig();
|
|
10241
10222
|
if (transportsBLEIsAvailable(dittoHandle.deref())) {
|
|
10242
10223
|
transportConfig.peerToPeer.bluetoothLE.isEnabled = true;
|
|
@@ -10349,12 +10330,14 @@ const CUSTOM_INSPECT_SYMBOL = Symbol.for('nodejs.util.inspect.custom');
|
|
|
10349
10330
|
* It’s a reference type serving as a “cursor”, allowing for efficient access of
|
|
10350
10331
|
* the underlying data in various formats.
|
|
10351
10332
|
*
|
|
10352
|
-
* The {@link QueryResultItem.value | value } property is lazily
|
|
10353
|
-
*
|
|
10354
|
-
*
|
|
10355
|
-
*
|
|
10356
|
-
* {@link QueryResultItem.dematerialize | dematerialize() } them
|
|
10357
|
-
*
|
|
10333
|
+
* The {@link QueryResultItem.value | value } property is lazily materialized
|
|
10334
|
+
* and kept in memory until it goes out of scope. To reduce the memory
|
|
10335
|
+
* footprint, structure your code such that items can be processed as a stream,
|
|
10336
|
+
* i.e. one by one (or in batches) and
|
|
10337
|
+
* {@link QueryResultItem.dematerialize | dematerialize() } them right after
|
|
10338
|
+
* use.
|
|
10339
|
+
*
|
|
10340
|
+
* @template T The type of the item's {@link QueryResultItem.value | value }.
|
|
10358
10341
|
*/
|
|
10359
10342
|
class QueryResultItem {
|
|
10360
10343
|
/**
|
|
@@ -10474,22 +10457,6 @@ function getBridgeLoad() {
|
|
|
10474
10457
|
return countsByType;
|
|
10475
10458
|
}
|
|
10476
10459
|
|
|
10477
|
-
//
|
|
10478
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
10479
|
-
//
|
|
10480
|
-
// HACK: don't export these publicly, only needed internally.
|
|
10481
|
-
/** @internal */
|
|
10482
|
-
class StaticTCPClient {
|
|
10483
|
-
}
|
|
10484
|
-
|
|
10485
|
-
//
|
|
10486
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
10487
|
-
//
|
|
10488
|
-
// HACK: don't export these publicly, only needed internally.
|
|
10489
|
-
/** @internal */
|
|
10490
|
-
class WebsocketClient {
|
|
10491
|
-
}
|
|
10492
|
-
|
|
10493
10460
|
//
|
|
10494
10461
|
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
10495
10462
|
//
|
|
@@ -10505,8 +10472,6 @@ Bridge.document.registerType(Document);
|
|
|
10505
10472
|
Bridge.queryResultItem.registerType(QueryResultItem);
|
|
10506
10473
|
Bridge.queryResult.registerType(QueryResult);
|
|
10507
10474
|
Bridge.mutableDocument.registerType(MutableDocument);
|
|
10508
|
-
Bridge.staticTCPClient.registerType(StaticTCPClient);
|
|
10509
|
-
Bridge.websocketClient.registerType(WebsocketClient);
|
|
10510
10475
|
Bridge.ditto.registerType(Ditto);
|
|
10511
10476
|
|
|
10512
10477
|
exports.Attachment = Attachment;
|