@dittolive/ditto 4.12.0 → 5.0.0-experimental.js-cocoapods-publishing.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/node/ditto.cjs.js +247 -425
- package/node/ditto.darwin-arm64.node +0 -0
- package/node/ditto.darwin-x64.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 +1 -1
- package/react-native/android/dittoffi/src/ditto_c_string.i +33 -0
- package/react-native/android/dittoffi/src/dittoffi.h +68 -80
- package/react-native/android/dittoffi/src/dittoffi_java.cpp +761 -1174
- package/react-native/android/dittoffi/src/dittoffi_java.h +2 -8
- package/react-native/android/dittoffi/src/dittoffi_java.i +1 -0
- package/react-native/android/dittoffi/src/dittomesh_java.i +0 -9
- package/react-native/android/dittoffi/src/dittostore_java.i +12 -13
- package/react-native/android/dittoffi/src/presence.h +0 -36
- package/react-native/cpp/include/DQL.h +0 -2
- package/react-native/cpp/include/Presence.h +0 -2
- package/react-native/cpp/include/SyncSubscription.h +20 -0
- package/react-native/cpp/src/DQL.cpp +0 -59
- package/react-native/cpp/src/Lifecycle.cpp +1 -6
- package/react-native/cpp/src/Presence.cpp +0 -40
- package/react-native/cpp/src/SyncSubscription.cpp +180 -0
- package/react-native/cpp/src/main.cpp +27 -19
- package/react-native/ditto.es6.js +1 -1
- package/types/ditto.d.ts +44 -65
- package/web/ditto.es6.js +1 -1
- package/web/ditto.umd.js +1 -1
- package/web/ditto.wasm +0 -0
package/node/ditto.cjs.js
CHANGED
|
@@ -52,8 +52,7 @@ class KeepAlive {
|
|
|
52
52
|
}
|
|
53
53
|
/** @internal */
|
|
54
54
|
countForID(id) {
|
|
55
|
-
|
|
56
|
-
return (_a = this.countsByID[id]) !== null && _a !== void 0 ? _a : null;
|
|
55
|
+
return this.countsByID[id] ?? null;
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
KeepAlive.finalizationRegistry = new FinalizationRegistry(clearInterval);
|
|
@@ -387,11 +386,9 @@ function ditto_logger_set_custom_log_cb(...args) { return ditto.ditto_logger_set
|
|
|
387
386
|
function ditto_logger_set_log_file(...args) { return ditto.ditto_logger_set_log_file(...args) }
|
|
388
387
|
function ditto_new_attachment_from_bytes(...args) { return ditto.ditto_new_attachment_from_bytes(...args) }
|
|
389
388
|
function ditto_new_attachment_from_file(...args) { return ditto.ditto_new_attachment_from_file(...args) }
|
|
390
|
-
function ditto_presence_v1(...args) { return ditto.ditto_presence_v1(...args) }
|
|
391
389
|
function ditto_presence_v3(...args) { return ditto.ditto_presence_v3(...args) }
|
|
392
390
|
function ditto_read_transaction(...args) { return ditto.ditto_read_transaction(...args) }
|
|
393
391
|
function ditto_read_transaction_free(...args) { return ditto.ditto_read_transaction_free(...args) }
|
|
394
|
-
function ditto_register_presence_v1_callback(...args) { return ditto.ditto_register_presence_v1_callback(...args) }
|
|
395
392
|
function ditto_register_presence_v3_callback(...args) { return ditto.ditto_register_presence_v3_callback(...args) }
|
|
396
393
|
function ditto_register_transport_condition_changed_callback(...args) { return ditto.ditto_register_transport_condition_changed_callback(...args) }
|
|
397
394
|
function ditto_remove_subscription(...args) { return ditto.ditto_remove_subscription(...args) }
|
|
@@ -462,18 +459,23 @@ function dittoffi_query_result_mutated_document_id_at(...args) { return ditto.di
|
|
|
462
459
|
function dittoffi_query_result_mutated_document_id_count(...args) { return ditto.dittoffi_query_result_mutated_document_id_count(...args) }
|
|
463
460
|
function dittoffi_store_begin_transaction_async_throws(...args) { return ditto.dittoffi_store_begin_transaction_async_throws(...args) }
|
|
464
461
|
function dittoffi_store_transactions(...args) { return ditto.dittoffi_store_transactions(...args) }
|
|
462
|
+
function dittoffi_sync_register_subscription_throws(...args) { return ditto.dittoffi_sync_register_subscription_throws(...args) }
|
|
463
|
+
function dittoffi_sync_subscription_cancel(...args) { return ditto.dittoffi_sync_subscription_cancel(...args) }
|
|
464
|
+
function dittoffi_sync_subscription_free(...args) { return ditto.dittoffi_sync_subscription_free(...args) }
|
|
465
|
+
function dittoffi_sync_subscription_is_cancelled(...args) { return ditto.dittoffi_sync_subscription_is_cancelled(...args) }
|
|
466
|
+
function dittoffi_sync_subscription_query_arguments_cbor(...args) { return ditto.dittoffi_sync_subscription_query_arguments_cbor(...args) }
|
|
467
|
+
function dittoffi_sync_subscription_query_arguments_json(...args) { return ditto.dittoffi_sync_subscription_query_arguments_json(...args) }
|
|
468
|
+
function dittoffi_sync_subscription_query_string(...args) { return ditto.dittoffi_sync_subscription_query_string(...args) }
|
|
469
|
+
function dittoffi_sync_subscriptions(...args) { return ditto.dittoffi_sync_subscriptions(...args) }
|
|
465
470
|
function dittoffi_transaction_complete_async_throws(...args) { return ditto.dittoffi_transaction_complete_async_throws(...args) }
|
|
466
471
|
function dittoffi_transaction_execute_async_throws(...args) { return ditto.dittoffi_transaction_execute_async_throws(...args) }
|
|
467
472
|
function dittoffi_transaction_free(...args) { return ditto.dittoffi_transaction_free(...args) }
|
|
468
473
|
function dittoffi_transaction_info(...args) { return ditto.dittoffi_transaction_info(...args) }
|
|
469
|
-
function dittoffi_try_add_sync_subscription(...args) { return ditto.dittoffi_try_add_sync_subscription(...args) }
|
|
470
474
|
function dittoffi_try_base64_decode(...args) { return ditto.dittoffi_try_base64_decode(...args) }
|
|
471
475
|
function dittoffi_try_exec_statement(...args) { return ditto.dittoffi_try_exec_statement(...args) }
|
|
472
476
|
function dittoffi_try_experimental_register_change_observer_str_detached(...args) { return ditto.dittoffi_try_experimental_register_change_observer_str_detached(...args) }
|
|
473
|
-
function dittoffi_try_remove_sync_subscription(...args) { return ditto.dittoffi_try_remove_sync_subscription(...args) }
|
|
474
477
|
function dittoffi_try_verify_license(...args) { return ditto.dittoffi_try_verify_license(...args) }
|
|
475
478
|
function getDeadlockTimeout$1(...args) { return ditto.getDeadlockTimeout(...args) }
|
|
476
|
-
function jsDocsToCDocs(...args) { return ditto.jsDocsToCDocs(...args) }
|
|
477
479
|
function refCBytesIntoBuffer(...args) { return ditto.refCBytesIntoBuffer(...args) }
|
|
478
480
|
function refCStringToString(...args) { return ditto.refCStringToString(...args) }
|
|
479
481
|
function setDeadlockTimeout$1(...args) { return ditto.setDeadlockTimeout(...args) }
|
|
@@ -762,7 +764,7 @@ async function collectionInsertValue(ditto, collectionName, doc_cbor, writeStrat
|
|
|
762
764
|
default:
|
|
763
765
|
throw new Error(`Unsupported write strategy '${writeStrategy}' provided.`);
|
|
764
766
|
}
|
|
765
|
-
const { status_code: errorCode, id } = await ditto_collection_insert_value(ditto, collectionNameX, doc_cbor, strategy, null, writeTransaction
|
|
767
|
+
const { status_code: errorCode, id } = await ditto_collection_insert_value(ditto, collectionNameX, doc_cbor, strategy, null, writeTransaction ?? null);
|
|
766
768
|
if (errorCode !== 0) {
|
|
767
769
|
throw new Error(errorMessage() ||
|
|
768
770
|
`ditto_collection_insert_value() failed with error code: ${errorCode}`);
|
|
@@ -807,8 +809,7 @@ async function collectionUpdate(ditto, collectionName, writeTransaction, documen
|
|
|
807
809
|
async function collectionUpdateMultiple(ditto, collectionName, writeTransaction, documents) {
|
|
808
810
|
ensureInitialized();
|
|
809
811
|
const collectionNameX = bytesFromString(collectionName);
|
|
810
|
-
const
|
|
811
|
-
const errorCode = await ditto_collection_update_multiple(ditto, collectionNameX, writeTransaction, cDocuments);
|
|
812
|
+
const errorCode = await ditto_collection_update_multiple(ditto, collectionNameX, writeTransaction, documents);
|
|
812
813
|
if (errorCode !== 0) {
|
|
813
814
|
throw new Error(errorMessage() ||
|
|
814
815
|
`ditto_collection_update_multiple() failed with error code: ${errorCode}`);
|
|
@@ -873,18 +874,56 @@ function removeSubscription(ditto, collectionName, query, queryArgsCBOR, orderBy
|
|
|
873
874
|
}
|
|
874
875
|
}
|
|
875
876
|
/** @internal */
|
|
876
|
-
function
|
|
877
|
+
function syncRegisterSubscriptionThrows(dittoPointer, query, queryArgsCBOR) {
|
|
877
878
|
ensureInitialized();
|
|
878
879
|
const queryBuffer = bytesFromString(query);
|
|
879
|
-
const result =
|
|
880
|
-
throwOnErrorResult(result.error, '
|
|
880
|
+
const result = dittoffi_sync_register_subscription_throws(dittoPointer, queryBuffer, queryArgsCBOR);
|
|
881
|
+
throwOnErrorResult(result.error, 'dittoffi_sync_register_subscription_throws');
|
|
882
|
+
return result.success;
|
|
881
883
|
}
|
|
882
884
|
/** @internal */
|
|
883
|
-
function
|
|
885
|
+
function syncSubscriptions(dittoPointer) {
|
|
884
886
|
ensureInitialized();
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
887
|
+
return dittoffi_sync_subscriptions(dittoPointer);
|
|
888
|
+
}
|
|
889
|
+
/** @internal */
|
|
890
|
+
function syncSubscriptionQueryString(syncSubscriptionPointer) {
|
|
891
|
+
ensureInitialized();
|
|
892
|
+
const queryStringBytes = dittoffi_sync_subscription_query_string(syncSubscriptionPointer);
|
|
893
|
+
return boxCStringIntoString(queryStringBytes);
|
|
894
|
+
}
|
|
895
|
+
/** @internal */
|
|
896
|
+
function syncSubscriptionQueryArgumentsCBOR(syncSubscriptionPointer) {
|
|
897
|
+
ensureInitialized();
|
|
898
|
+
const queryArgsCBORBytes = dittoffi_sync_subscription_query_arguments_cbor(syncSubscriptionPointer);
|
|
899
|
+
if (queryArgsCBORBytes === null)
|
|
900
|
+
return null;
|
|
901
|
+
return boxCBytesIntoBuffer(queryArgsCBORBytes);
|
|
902
|
+
}
|
|
903
|
+
/** @internal */
|
|
904
|
+
function syncSubscriptionQueryArgumentsJSON(syncSubscriptionPointer) {
|
|
905
|
+
ensureInitialized();
|
|
906
|
+
const queryArgsJSONBytes = dittoffi_sync_subscription_query_arguments_json(syncSubscriptionPointer);
|
|
907
|
+
if (queryArgsJSONBytes === null)
|
|
908
|
+
return null;
|
|
909
|
+
const jsonBuffer = boxCBytesIntoBuffer(queryArgsJSONBytes);
|
|
910
|
+
const textDecoder = new TextDecoder();
|
|
911
|
+
return textDecoder.decode(jsonBuffer);
|
|
912
|
+
}
|
|
913
|
+
/** @internal */
|
|
914
|
+
function syncSubscriptionCancel(syncSubscriptionPointer) {
|
|
915
|
+
ensureInitialized();
|
|
916
|
+
dittoffi_sync_subscription_cancel(syncSubscriptionPointer);
|
|
917
|
+
}
|
|
918
|
+
/** @internal */
|
|
919
|
+
function syncSubscriptionIsCancelled(syncSubscriptionPointer) {
|
|
920
|
+
ensureInitialized();
|
|
921
|
+
return dittoffi_sync_subscription_is_cancelled(syncSubscriptionPointer);
|
|
922
|
+
}
|
|
923
|
+
/** @internal */
|
|
924
|
+
function syncSubscriptionFree(syncSubscriptionPointer) {
|
|
925
|
+
ensureInitialized();
|
|
926
|
+
dittoffi_sync_subscription_free(syncSubscriptionPointer);
|
|
888
927
|
}
|
|
889
928
|
// ----------------------------------------------------------- QueryResult ------
|
|
890
929
|
/**
|
|
@@ -1445,14 +1484,6 @@ function cryptoGenerateSecureRandomToken() {
|
|
|
1445
1484
|
return boxCStringIntoString(docIDString);
|
|
1446
1485
|
}
|
|
1447
1486
|
/** @internal */
|
|
1448
|
-
function dittoRegisterPresenceV1Callback(self, cb) {
|
|
1449
|
-
ensureInitialized();
|
|
1450
|
-
ditto_register_presence_v1_callback(self, wrapBackgroundCbForFFI((err) => log('Error', `The registered presence callback v1 errored with ${err}`), (cJsonStr) => {
|
|
1451
|
-
const jsonStr = refCStringToString(cJsonStr);
|
|
1452
|
-
cb(jsonStr);
|
|
1453
|
-
}));
|
|
1454
|
-
}
|
|
1455
|
-
/** @internal */
|
|
1456
1487
|
async function dittoClearPresenceCallback(self) {
|
|
1457
1488
|
ensureInitialized();
|
|
1458
1489
|
return ditto_clear_presence_callback(self);
|
|
@@ -1709,12 +1740,6 @@ function dittoGetSDKSemver() {
|
|
|
1709
1740
|
return boxCStringIntoString(cString);
|
|
1710
1741
|
}
|
|
1711
1742
|
/** @internal */
|
|
1712
|
-
function dittoPresenceV1(self) {
|
|
1713
|
-
ensureInitialized();
|
|
1714
|
-
const cString = ditto_presence_v1(self);
|
|
1715
|
-
return boxCStringIntoString(cString);
|
|
1716
|
-
}
|
|
1717
|
-
/** @internal */
|
|
1718
1743
|
function dittoPresenceV3(self) {
|
|
1719
1744
|
ensureInitialized();
|
|
1720
1745
|
const cString = ditto_presence_v3(self);
|
|
@@ -1867,7 +1892,8 @@ function defaultDeviceName() {
|
|
|
1867
1892
|
const NOT_FOUND_ERROR_CODE = -30798;
|
|
1868
1893
|
/** @internal */
|
|
1869
1894
|
function wrapBackgroundCbForFFI(onError, cb) {
|
|
1870
|
-
const errorHandler = onError
|
|
1895
|
+
const errorHandler = onError ??
|
|
1896
|
+
((err) => log('Error', `The registered callback failed with ${err}`));
|
|
1871
1897
|
return (ret_sender, ...args) => {
|
|
1872
1898
|
let ret;
|
|
1873
1899
|
try {
|
|
@@ -1886,7 +1912,8 @@ function wrapBackgroundCbForFFI(onError, cb) {
|
|
|
1886
1912
|
}
|
|
1887
1913
|
/** @internal */
|
|
1888
1914
|
function wrapAsyncBackgroundCbForFFI(onError, cb) {
|
|
1889
|
-
const errorHandler = onError
|
|
1915
|
+
const errorHandler = onError ??
|
|
1916
|
+
((err) => log('Error', `The registered callback failed with ${err}`));
|
|
1890
1917
|
return async (ret_sender, ...args) => {
|
|
1891
1918
|
let ret;
|
|
1892
1919
|
try {
|
|
@@ -2288,7 +2315,6 @@ async function mapFFIErrorsAsync(closure, statusCodeMapping, context) {
|
|
|
2288
2315
|
}
|
|
2289
2316
|
}
|
|
2290
2317
|
const translateFFIError = (ffiError, customStatusCodeMapping, context) => {
|
|
2291
|
-
var _a;
|
|
2292
2318
|
// Convert the status code to a string because it may be a negative number,
|
|
2293
2319
|
// which can't be used as an index into an object.
|
|
2294
2320
|
const statusCode = ffiError.code.toString();
|
|
@@ -2299,7 +2325,8 @@ const translateFFIError = (ffiError, customStatusCodeMapping, context) => {
|
|
|
2299
2325
|
}
|
|
2300
2326
|
else {
|
|
2301
2327
|
[code, message] =
|
|
2302
|
-
|
|
2328
|
+
DEFAULT_STATUS_CODE_MAPPING[statusCode] ??
|
|
2329
|
+
DEFAULT_STATUS_CODE_MAPPING.default;
|
|
2303
2330
|
}
|
|
2304
2331
|
return DittoError.fromFFIError(ffiError, code, message, context);
|
|
2305
2332
|
};
|
|
@@ -2349,6 +2376,10 @@ class AttachmentToken {
|
|
|
2349
2376
|
const id = jsObj['_id'];
|
|
2350
2377
|
if (!(id instanceof Uint8Array))
|
|
2351
2378
|
throw new Error('Invalid attachment token id');
|
|
2379
|
+
// Ensure that id is a true Uint8Array and not a Node.js Buffer so that
|
|
2380
|
+
// attachment tokens pass any deep equality checks. Buffer extends
|
|
2381
|
+
// Uint8Array but has a different constructor.
|
|
2382
|
+
const _id = id.constructor === Uint8Array ? id : new Uint8Array(id);
|
|
2352
2383
|
const len = jsObj['_len'];
|
|
2353
2384
|
if ((typeof len !== 'number' && typeof len !== 'bigint') || len < 0) {
|
|
2354
2385
|
throw new Error('Invalid attachment token length, must be a non-negative number or bigint');
|
|
@@ -2356,7 +2387,7 @@ class AttachmentToken {
|
|
|
2356
2387
|
const meta = jsObj['_meta'];
|
|
2357
2388
|
if (typeof meta !== 'object')
|
|
2358
2389
|
throw new Error('Invalid attachment token meta');
|
|
2359
|
-
return { id, len, meta };
|
|
2390
|
+
return { id: _id, len, meta };
|
|
2360
2391
|
}
|
|
2361
2392
|
/**
|
|
2362
2393
|
* Validate an untyped input value and return its contents.
|
|
@@ -2393,7 +2424,7 @@ class AttachmentToken {
|
|
|
2393
2424
|
|
|
2394
2425
|
// NOTE: this is patched up with the actual build version by Jake task
|
|
2395
2426
|
// build:package and has to be a valid semantic version as defined here: https://semver.org.
|
|
2396
|
-
const fullBuildVersionString = '
|
|
2427
|
+
const fullBuildVersionString = '5.0.0-experimental.js-cocoapods-publishing.3';
|
|
2397
2428
|
|
|
2398
2429
|
//
|
|
2399
2430
|
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
@@ -2495,8 +2526,7 @@ class Logger {
|
|
|
2495
2526
|
* @deprecated this method is deprecated and will be removed in a future version.
|
|
2496
2527
|
*/
|
|
2497
2528
|
static setLogFileURL(url) {
|
|
2498
|
-
|
|
2499
|
-
this.setLogFile((_a = url === null || url === void 0 ? void 0 : url.pathname) !== null && _a !== void 0 ? _a : null);
|
|
2529
|
+
this.setLogFile(url?.pathname ?? null);
|
|
2500
2530
|
}
|
|
2501
2531
|
/**
|
|
2502
2532
|
* Whether the logger is currently enabled.
|
|
@@ -3695,6 +3725,11 @@ class CBOR {
|
|
|
3695
3725
|
return new Uint8Array(arrayBuffer);
|
|
3696
3726
|
}
|
|
3697
3727
|
/** @internal */
|
|
3728
|
+
static encodeWithReplacer(data, replacer) {
|
|
3729
|
+
const arrayBuffer = CBOR$1.encode(data, replacer);
|
|
3730
|
+
return new Uint8Array(arrayBuffer);
|
|
3731
|
+
}
|
|
3732
|
+
/** @internal */
|
|
3698
3733
|
static decode(data, reviver) {
|
|
3699
3734
|
const arrayBuffer = data.buffer;
|
|
3700
3735
|
return CBOR$1.decode(arrayBuffer, reviver);
|
|
@@ -3833,7 +3868,7 @@ function validateDocumentIDValue(id) {
|
|
|
3833
3868
|
/** @internal */
|
|
3834
3869
|
function validateDocumentIDCBOR(idCBOR) {
|
|
3835
3870
|
const validatedIDCBOROrNull = validateDocumentID(idCBOR);
|
|
3836
|
-
return validatedIDCBOROrNull
|
|
3871
|
+
return validatedIDCBOROrNull ?? idCBOR;
|
|
3837
3872
|
}
|
|
3838
3873
|
|
|
3839
3874
|
//
|
|
@@ -3897,14 +3932,13 @@ class Handle {
|
|
|
3897
3932
|
* has been closed, garbage collected, or unregistered.
|
|
3898
3933
|
*/
|
|
3899
3934
|
derefOrNull() {
|
|
3900
|
-
var _b;
|
|
3901
3935
|
if (this.isClosed)
|
|
3902
3936
|
return null;
|
|
3903
3937
|
if (this.isFinalized)
|
|
3904
3938
|
return null;
|
|
3905
3939
|
if (this.isUnregistered)
|
|
3906
3940
|
return null;
|
|
3907
|
-
return
|
|
3941
|
+
return this.pointer ?? null;
|
|
3908
3942
|
}
|
|
3909
3943
|
/**
|
|
3910
3944
|
* Returns the object associated with this handle.
|
|
@@ -3930,13 +3964,12 @@ class Handle {
|
|
|
3930
3964
|
* has been closed, unregistered, or garbage collected.
|
|
3931
3965
|
*/
|
|
3932
3966
|
objectOrNull() {
|
|
3933
|
-
|
|
3934
|
-
return (_b = this.objectWeakRef.deref()) !== null && _b !== void 0 ? _b : null;
|
|
3967
|
+
return this.objectWeakRef.deref() ?? null;
|
|
3935
3968
|
}
|
|
3936
3969
|
/** @internal */
|
|
3937
3970
|
toString() {
|
|
3938
3971
|
const pointer = this.derefOrNull();
|
|
3939
|
-
return `{ Handle | type: ${this.bridge.type}, object: ${this.objectWeakRef.deref()}, FFI address: ${pointer
|
|
3972
|
+
return `{ Handle | type: ${this.bridge.type}, object: ${this.objectWeakRef.deref()}, FFI address: ${pointer?.addr}, FFI type: ${pointer?.type} }`;
|
|
3940
3973
|
}
|
|
3941
3974
|
/** @internal */
|
|
3942
3975
|
bridgeWillClose() {
|
|
@@ -4306,6 +4339,8 @@ Bridge.transaction = new _a(transactionFree);
|
|
|
4306
4339
|
/** @internal */
|
|
4307
4340
|
Bridge.differ = new _a(differFree);
|
|
4308
4341
|
/** @internal */
|
|
4342
|
+
Bridge.syncSubscription = new _a(syncSubscriptionFree);
|
|
4343
|
+
/** @internal */
|
|
4309
4344
|
Bridge.ditto = new _a(async (dittoPointer) => {
|
|
4310
4345
|
// HACK: quick and dirty, clear all presence callbacks. This covers presence
|
|
4311
4346
|
// v1 and v2 callbacks. v3 should be cleared properly by the `Presence`
|
|
@@ -4427,7 +4462,7 @@ function validateAttachmentMetadata(metadata) {
|
|
|
4427
4462
|
// represented by `Counter` objects and attachments get represented by
|
|
4428
4463
|
// `Attachment` objects.
|
|
4429
4464
|
function augmentJSONValue(json, mutDoc, workingPath) {
|
|
4430
|
-
if (json && typeof json === 'object') {
|
|
4465
|
+
if (json && !(json instanceof Uint8Array) && typeof json === 'object') {
|
|
4431
4466
|
if (Array.isArray(json)) {
|
|
4432
4467
|
return json.map((v, idx) => augmentJSONValue(v, mutDoc, `${workingPath}[${idx}]`));
|
|
4433
4468
|
}
|
|
@@ -4450,6 +4485,33 @@ function augmentJSONValue(json, mutDoc, workingPath) {
|
|
|
4450
4485
|
return json;
|
|
4451
4486
|
}
|
|
4452
4487
|
}
|
|
4488
|
+
/**
|
|
4489
|
+
* Takes any value and checks if it is an instance of `Attachment` or
|
|
4490
|
+
* `AttachmentToken`. If it is, it returns a plain JS object with the
|
|
4491
|
+
* attachment's ID, length and metadata. Otherwise, it returns the value
|
|
4492
|
+
* unchanged.
|
|
4493
|
+
*
|
|
4494
|
+
* This is intended to be used as the `replacer` function for
|
|
4495
|
+
* `JSON.stringify()` or CBOR.encode() and doesn't recursively traverse
|
|
4496
|
+
* objects or arrays like `desugarJSObject()` does.
|
|
4497
|
+
*/
|
|
4498
|
+
const desugarJSObjectV2 = (_key, value) => {
|
|
4499
|
+
if (value instanceof Attachment) {
|
|
4500
|
+
return {
|
|
4501
|
+
_id: value.token.idBytes,
|
|
4502
|
+
_len: value.token.len,
|
|
4503
|
+
_meta: value.token.metadata,
|
|
4504
|
+
};
|
|
4505
|
+
}
|
|
4506
|
+
else if (value instanceof AttachmentToken) {
|
|
4507
|
+
return {
|
|
4508
|
+
_id: value.idBytes,
|
|
4509
|
+
_len: value.len,
|
|
4510
|
+
_meta: value.metadata,
|
|
4511
|
+
};
|
|
4512
|
+
}
|
|
4513
|
+
return value;
|
|
4514
|
+
};
|
|
4453
4515
|
/**
|
|
4454
4516
|
* Converts objects that may contain instances of classes of this SDK, i.e.
|
|
4455
4517
|
* `DocumentID`, `Counter`, `Register` and `Attachment`, into plain JS objects
|
|
@@ -4461,7 +4523,7 @@ function augmentJSONValue(json, mutDoc, workingPath) {
|
|
|
4461
4523
|
* @throws {Error} If `jsObj` contains a non-finite float value.
|
|
4462
4524
|
*/
|
|
4463
4525
|
function desugarJSObject(jsObj) {
|
|
4464
|
-
if (jsObj && typeof jsObj === 'object') {
|
|
4526
|
+
if (jsObj && !(jsObj instanceof Uint8Array) && typeof jsObj === 'object') {
|
|
4465
4527
|
if (Array.isArray(jsObj)) {
|
|
4466
4528
|
return jsObj.map((v, idx) => desugarJSObject(v));
|
|
4467
4529
|
}
|
|
@@ -4489,6 +4551,15 @@ function desugarJSObject(jsObj) {
|
|
|
4489
4551
|
attachmentJSON[DittoCRDTTypeKey] = DittoCRDTType.attachment;
|
|
4490
4552
|
return attachmentJSON;
|
|
4491
4553
|
}
|
|
4554
|
+
else if (jsObj instanceof AttachmentToken) {
|
|
4555
|
+
const attachmentTokenJSON = {
|
|
4556
|
+
_id: jsObj.idBytes,
|
|
4557
|
+
_len: jsObj.len, // may be a BigInt
|
|
4558
|
+
_meta: jsObj.metadata,
|
|
4559
|
+
};
|
|
4560
|
+
attachmentTokenJSON[DittoCRDTTypeKey] = DittoCRDTType.attachment;
|
|
4561
|
+
return attachmentTokenJSON;
|
|
4562
|
+
}
|
|
4492
4563
|
else {
|
|
4493
4564
|
// Create a copy to not mutate the original object
|
|
4494
4565
|
const jsObjJSON = {};
|
|
@@ -4587,11 +4658,9 @@ function defaultAuthURL(appID) {
|
|
|
4587
4658
|
* `errorMessagePrefix`, which defaults to `"Number validation failed:"`.
|
|
4588
4659
|
*
|
|
4589
4660
|
* @internal
|
|
4590
|
-
* @deprecated
|
|
4591
4661
|
*/
|
|
4592
4662
|
function validateNumber(value, options = {}) {
|
|
4593
|
-
|
|
4594
|
-
const errorMessagePrefix = (_a = options['errorMessagePrefix']) !== null && _a !== void 0 ? _a : 'Number validation failed:';
|
|
4663
|
+
const errorMessagePrefix = options['errorMessagePrefix'] ?? 'Number validation failed:';
|
|
4595
4664
|
const integer = !!options['integer'];
|
|
4596
4665
|
const min = options['min'];
|
|
4597
4666
|
const max = options['max'];
|
|
@@ -4611,10 +4680,8 @@ function validateNumber(value, options = {}) {
|
|
|
4611
4680
|
throw new Error(`${errorMessagePrefix} '${value}' must be < ${maxX}.`);
|
|
4612
4681
|
return value;
|
|
4613
4682
|
}
|
|
4614
|
-
/** @deprecated */
|
|
4615
4683
|
function validateQuery(query, options = {}) {
|
|
4616
|
-
|
|
4617
|
-
const errorMessagePrefix = (_a = options['errorMessagePrefix']) !== null && _a !== void 0 ? _a : 'Query validation failed,';
|
|
4684
|
+
const errorMessagePrefix = options['errorMessagePrefix'] ?? 'Query validation failed,';
|
|
4618
4685
|
if (typeof query !== 'string')
|
|
4619
4686
|
throw new Error(`${errorMessagePrefix} query is not a string: ${query}`);
|
|
4620
4687
|
if (query === '')
|
|
@@ -4722,8 +4789,7 @@ class KeyPath {
|
|
|
4722
4789
|
* its syntax. Throws if syntax is invalid.
|
|
4723
4790
|
*/
|
|
4724
4791
|
static validate(keyPath, options = {}) {
|
|
4725
|
-
|
|
4726
|
-
const isInitial = (_a = options.isInitial) !== null && _a !== void 0 ? _a : false;
|
|
4792
|
+
const isInitial = options.isInitial ?? false;
|
|
4727
4793
|
if (typeof keyPath === 'number')
|
|
4728
4794
|
return Math.floor(Math.abs(keyPath));
|
|
4729
4795
|
if (typeof keyPath !== 'string') {
|
|
@@ -4742,8 +4808,7 @@ class KeyPath {
|
|
|
4742
4808
|
* @internal
|
|
4743
4809
|
*/
|
|
4744
4810
|
static evaluate(keyPath, object, options = {}) {
|
|
4745
|
-
|
|
4746
|
-
const stopAtLastContainer = (_a = options.stopAtLastContainer) !== null && _a !== void 0 ? _a : false;
|
|
4811
|
+
const stopAtLastContainer = options.stopAtLastContainer ?? false;
|
|
4747
4812
|
const evaluationResult = {
|
|
4748
4813
|
keyPath: keyPath,
|
|
4749
4814
|
object: object,
|
|
@@ -5614,7 +5679,8 @@ class BasePendingCursorOperation {
|
|
|
5614
5679
|
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5615
5680
|
return await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
5616
5681
|
const query = this.query;
|
|
5617
|
-
const transactionPointer = writeTransactionPointer
|
|
5682
|
+
const transactionPointer = writeTransactionPointer ??
|
|
5683
|
+
(await writeTransaction(dittoHandle.deref()));
|
|
5618
5684
|
const documentsX = await collectionExecQueryStr(dittoHandle.deref(), this.collection.name, transactionPointer, query, this.queryArgsCBOR, this.orderBys, this.currentLimit, this.currentOffset);
|
|
5619
5685
|
const mutableDocuments = documentsX.map((documentX) => {
|
|
5620
5686
|
return Bridge.mutableDocument.bridge(documentX, () => new MutableDocument());
|
|
@@ -5753,7 +5819,6 @@ class BasePendingIDSpecificOperation {
|
|
|
5753
5819
|
async updateWithClosure(closure, throwOnAsyncClosure, throwOnDocumentNotFound, publicAPIName, transaction) {
|
|
5754
5820
|
const ditto = this.collection.store.ditto;
|
|
5755
5821
|
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
5756
|
-
var _a;
|
|
5757
5822
|
let documentPointer = null;
|
|
5758
5823
|
if (transaction == null) {
|
|
5759
5824
|
const readTransactionPointer = await readTransaction(dittoHandle.deref());
|
|
@@ -5787,7 +5852,8 @@ class BasePendingIDSpecificOperation {
|
|
|
5787
5852
|
throw new TypeError(errorMessageAsyncClosure);
|
|
5788
5853
|
Logger.warning(errorMessageAsyncClosure);
|
|
5789
5854
|
}
|
|
5790
|
-
const writeTransactionPointer =
|
|
5855
|
+
const writeTransactionPointer = transaction?.writeTransactionPointer ??
|
|
5856
|
+
(await writeTransaction(dittoHandle.deref()));
|
|
5791
5857
|
// Ownership is transferred back to the FFI layer via collectionUpdate(),
|
|
5792
5858
|
// we therefore need to explicitly unregister the instance.
|
|
5793
5859
|
Bridge.mutableDocument.unregister(mutableDocument);
|
|
@@ -5907,11 +5973,10 @@ class ConnectionRequest {
|
|
|
5907
5973
|
class ObserverManager {
|
|
5908
5974
|
/** @internal */
|
|
5909
5975
|
constructor(id, options = {}) {
|
|
5910
|
-
|
|
5911
|
-
const
|
|
5912
|
-
const
|
|
5913
|
-
const
|
|
5914
|
-
const process = (_d = options.process) !== null && _d !== void 0 ? _d : null;
|
|
5976
|
+
const keepAlive = options.keepAlive ?? null;
|
|
5977
|
+
const register = options.register ?? null;
|
|
5978
|
+
const unregister = options.unregister ?? null;
|
|
5979
|
+
const process = options.process ?? null;
|
|
5915
5980
|
this.id = id;
|
|
5916
5981
|
this.keepAlive = keepAlive;
|
|
5917
5982
|
this.isClosed = false;
|
|
@@ -5926,7 +5991,6 @@ class ObserverManager {
|
|
|
5926
5991
|
}
|
|
5927
5992
|
/** @internal */
|
|
5928
5993
|
addObserver(callback) {
|
|
5929
|
-
var _a;
|
|
5930
5994
|
if (this.isClosed) {
|
|
5931
5995
|
// REFACTOR: throw a catchable error here, such that calling code
|
|
5932
5996
|
// can be more specific when forwarding it to the user.
|
|
@@ -5935,12 +5999,11 @@ class ObserverManager {
|
|
|
5935
5999
|
this.registerIfNeeded();
|
|
5936
6000
|
const token = cryptoGenerateSecureRandomToken();
|
|
5937
6001
|
this.callbacksByToken[token] = callback;
|
|
5938
|
-
|
|
6002
|
+
this.keepAlive?.retain(`${this.id}.${token}`);
|
|
5939
6003
|
return token;
|
|
5940
6004
|
}
|
|
5941
6005
|
/** @internal */
|
|
5942
6006
|
removeObserver(token) {
|
|
5943
|
-
var _a;
|
|
5944
6007
|
const callback = this.callbacksByToken[token];
|
|
5945
6008
|
if (typeof callback === 'undefined') {
|
|
5946
6009
|
throw new Error(`Can't remove '${this.id}' observer, token '${token}' has never been registered before.`);
|
|
@@ -5957,7 +6020,7 @@ class ObserverManager {
|
|
|
5957
6020
|
// observers that have been removed and observers that have
|
|
5958
6021
|
// never been registered before.
|
|
5959
6022
|
this.callbacksByToken[token] = null;
|
|
5960
|
-
|
|
6023
|
+
this.keepAlive?.release(`${this.id}.${token}`);
|
|
5961
6024
|
this.unregisterIfNeeded();
|
|
5962
6025
|
}
|
|
5963
6026
|
hasObserver(token) {
|
|
@@ -6123,12 +6186,6 @@ class Authenticator {
|
|
|
6123
6186
|
* @returns A promise that resolves to a `LoginResult` object.
|
|
6124
6187
|
*/
|
|
6125
6188
|
async login(token, provider) {
|
|
6126
|
-
if (typeof token !== 'string') {
|
|
6127
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6128
|
-
}
|
|
6129
|
-
if (typeof provider !== 'string') {
|
|
6130
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6131
|
-
}
|
|
6132
6189
|
throw new Error(`Authenticator.login() is abstract and must be implemented by subclasses.`);
|
|
6133
6190
|
}
|
|
6134
6191
|
/**
|
|
@@ -6141,12 +6198,6 @@ class Authenticator {
|
|
|
6141
6198
|
* provided by the authentication service.
|
|
6142
6199
|
*/
|
|
6143
6200
|
loginWithToken(token, provider) {
|
|
6144
|
-
if (typeof token !== 'string') {
|
|
6145
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6146
|
-
}
|
|
6147
|
-
if (typeof provider !== 'string') {
|
|
6148
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6149
|
-
}
|
|
6150
6201
|
throw new Error(`Authenticator.loginWithToken() is abstract and must be implemented by subclasses.`);
|
|
6151
6202
|
}
|
|
6152
6203
|
/**
|
|
@@ -6160,15 +6211,6 @@ class Authenticator {
|
|
|
6160
6211
|
* version.
|
|
6161
6212
|
*/
|
|
6162
6213
|
loginWithUsernameAndPassword(username, password, provider) {
|
|
6163
|
-
if (typeof username !== 'string') {
|
|
6164
|
-
throw new TypeError(`Expected parameter username to have type string, but got '${typeof username}'`);
|
|
6165
|
-
}
|
|
6166
|
-
if (typeof password !== 'string') {
|
|
6167
|
-
throw new TypeError(`Expected parameter password to have type string, but got '${typeof password}'`);
|
|
6168
|
-
}
|
|
6169
|
-
if (typeof provider !== 'string') {
|
|
6170
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6171
|
-
}
|
|
6172
6214
|
throw new Error(`Authenticator.loginWithUsernameAndPassword() is abstract and must be implemented by subclasses.`);
|
|
6173
6215
|
}
|
|
6174
6216
|
/**
|
|
@@ -6184,9 +6226,6 @@ class Authenticator {
|
|
|
6184
6226
|
* required cleanup of the store as part of the logout process.
|
|
6185
6227
|
*/
|
|
6186
6228
|
logout(cleanupFn) {
|
|
6187
|
-
if (cleanupFn !== undefined && typeof cleanupFn !== 'function') {
|
|
6188
|
-
throw new TypeError(`Expected parameter cleanupFn to have type function, but got '${typeof cleanupFn}'`);
|
|
6189
|
-
}
|
|
6190
6229
|
throw new Error(`Authenticator.logout() is abstract and must be implemented by subclasses.`);
|
|
6191
6230
|
}
|
|
6192
6231
|
/*
|
|
@@ -6195,9 +6234,6 @@ class Authenticator {
|
|
|
6195
6234
|
* you want to receive the updates.
|
|
6196
6235
|
*/
|
|
6197
6236
|
observeStatus(callback) {
|
|
6198
|
-
if (typeof callback !== 'function') {
|
|
6199
|
-
throw new TypeError(`Expected parameter callback to have type function, but got '${typeof callback}'`);
|
|
6200
|
-
}
|
|
6201
6237
|
const token = this.observerManager.addObserver(callback);
|
|
6202
6238
|
return new Observer(this.observerManager, token, {
|
|
6203
6239
|
stopsWhenFinalized: true,
|
|
@@ -6211,7 +6247,7 @@ class Authenticator {
|
|
|
6211
6247
|
this.observerManager = new ObserverManager('AuthenticationStatusObservation', { keepAlive });
|
|
6212
6248
|
}
|
|
6213
6249
|
/** @internal */
|
|
6214
|
-
'@ditto.authenticationExpiring'(
|
|
6250
|
+
'@ditto.authenticationExpiring'(number) {
|
|
6215
6251
|
throw new Error(`Authenticator['@ditto.authenticationExpiring']() is abstract and must be implemented by subclasses.`);
|
|
6216
6252
|
}
|
|
6217
6253
|
/** @internal */
|
|
@@ -6223,12 +6259,6 @@ class Authenticator {
|
|
|
6223
6259
|
/** @internal */
|
|
6224
6260
|
class OnlineAuthenticator extends Authenticator {
|
|
6225
6261
|
async login(token, provider) {
|
|
6226
|
-
if (typeof token !== 'string') {
|
|
6227
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6228
|
-
}
|
|
6229
|
-
if (typeof provider !== 'string') {
|
|
6230
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6231
|
-
}
|
|
6232
6262
|
const ditto = this.ditto.deref();
|
|
6233
6263
|
if (!ditto || ditto.isClosed) {
|
|
6234
6264
|
throw new DittoError('authentication/failed-to-authenticate', 'Ditto instance is closed');
|
|
@@ -6242,12 +6272,6 @@ class OnlineAuthenticator extends Authenticator {
|
|
|
6242
6272
|
});
|
|
6243
6273
|
}
|
|
6244
6274
|
async loginWithToken(token, provider) {
|
|
6245
|
-
if (typeof token !== 'string') {
|
|
6246
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6247
|
-
}
|
|
6248
|
-
if (typeof provider !== 'string') {
|
|
6249
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6250
|
-
}
|
|
6251
6275
|
const ditto = this.ditto.deref();
|
|
6252
6276
|
if (!ditto || ditto.isClosed)
|
|
6253
6277
|
return;
|
|
@@ -6256,15 +6280,6 @@ class OnlineAuthenticator extends Authenticator {
|
|
|
6256
6280
|
});
|
|
6257
6281
|
}
|
|
6258
6282
|
async loginWithUsernameAndPassword(username, password, provider) {
|
|
6259
|
-
if (typeof username !== 'string') {
|
|
6260
|
-
throw new TypeError(`Expected parameter username to have type string, but got '${typeof username}'`);
|
|
6261
|
-
}
|
|
6262
|
-
if (typeof password !== 'string') {
|
|
6263
|
-
throw new TypeError(`Expected parameter password to have type string, but got '${typeof password}'`);
|
|
6264
|
-
}
|
|
6265
|
-
if (typeof provider !== 'string') {
|
|
6266
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6267
|
-
}
|
|
6268
6283
|
const ditto = this.ditto.deref();
|
|
6269
6284
|
if (!ditto || ditto.isClosed)
|
|
6270
6285
|
return;
|
|
@@ -6273,16 +6288,13 @@ class OnlineAuthenticator extends Authenticator {
|
|
|
6273
6288
|
});
|
|
6274
6289
|
}
|
|
6275
6290
|
async logout(cleanupFn) {
|
|
6276
|
-
if (cleanupFn !== undefined && typeof cleanupFn !== 'function') {
|
|
6277
|
-
throw new TypeError(`Expected parameter cleanupFn to have type function, but got '${typeof cleanupFn}'`);
|
|
6278
|
-
}
|
|
6279
6291
|
const ditto = this.ditto.deref();
|
|
6280
6292
|
if (!ditto || ditto.isClosed)
|
|
6281
6293
|
return;
|
|
6282
6294
|
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6283
6295
|
await dittoAuthClientLogout(dittoHandle.deref());
|
|
6284
6296
|
ditto.stopSync();
|
|
6285
|
-
cleanupFn
|
|
6297
|
+
cleanupFn?.(ditto);
|
|
6286
6298
|
});
|
|
6287
6299
|
}
|
|
6288
6300
|
constructor(keepAlive, ditto, authenticationHandler) {
|
|
@@ -6328,14 +6340,13 @@ class OnlineAuthenticator extends Authenticator {
|
|
|
6328
6340
|
authenticationHandler.authenticationRequired(this);
|
|
6329
6341
|
}
|
|
6330
6342
|
authenticationStatusUpdated(authenticationStatus) {
|
|
6331
|
-
var _a;
|
|
6332
6343
|
const previousStatus = this.status;
|
|
6333
6344
|
this._status = authenticationStatus;
|
|
6334
6345
|
const sameStatus = !!previousStatus.isAuthenticated ===
|
|
6335
6346
|
!!authenticationStatus.isAuthenticated &&
|
|
6336
6347
|
previousStatus.userID === authenticationStatus.userID;
|
|
6337
6348
|
if (!sameStatus) {
|
|
6338
|
-
|
|
6349
|
+
this.authenticationHandler.authenticationStatusDidChange?.call(this.authenticationHandler, this);
|
|
6339
6350
|
this.observerManager.notify(authenticationStatus);
|
|
6340
6351
|
}
|
|
6341
6352
|
}
|
|
@@ -6380,9 +6391,6 @@ class OnlineAuthenticatorV2 extends Authenticator {
|
|
|
6380
6391
|
return this._expirationHandler;
|
|
6381
6392
|
}
|
|
6382
6393
|
async setExpirationHandler(handler) {
|
|
6383
|
-
if (handler !== null && typeof handler !== 'function') {
|
|
6384
|
-
throw new TypeError(`Expected parameter handler to have type function or null, but got '${typeof handler}'`);
|
|
6385
|
-
}
|
|
6386
6394
|
const ditto = this.ditto.deref();
|
|
6387
6395
|
if (!ditto || ditto.isClosed) {
|
|
6388
6396
|
Logger.error('Ditto instance is closed, cannot set authentication expiration handler.');
|
|
@@ -6426,12 +6434,6 @@ class OnlineAuthenticatorV2 extends Authenticator {
|
|
|
6426
6434
|
this.updateAndNotify(false);
|
|
6427
6435
|
}
|
|
6428
6436
|
async login(token, provider) {
|
|
6429
|
-
if (typeof token !== 'string') {
|
|
6430
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6431
|
-
}
|
|
6432
|
-
if (typeof provider !== 'string') {
|
|
6433
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6434
|
-
}
|
|
6435
6437
|
const ditto = this.ditto.deref();
|
|
6436
6438
|
if (!ditto || ditto.isClosed) {
|
|
6437
6439
|
throw new DittoError('authentication/failed-to-authenticate', 'Ditto instance is closed');
|
|
@@ -6445,12 +6447,6 @@ class OnlineAuthenticatorV2 extends Authenticator {
|
|
|
6445
6447
|
});
|
|
6446
6448
|
}
|
|
6447
6449
|
async loginWithToken(token, provider) {
|
|
6448
|
-
if (typeof token !== 'string') {
|
|
6449
|
-
throw new TypeError(`Expected parameter token to have type string, but got '${typeof token}'`);
|
|
6450
|
-
}
|
|
6451
|
-
if (typeof provider !== 'string') {
|
|
6452
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6453
|
-
}
|
|
6454
6450
|
const ditto = this.ditto.deref();
|
|
6455
6451
|
if (!ditto || ditto.isClosed)
|
|
6456
6452
|
return;
|
|
@@ -6459,15 +6455,6 @@ class OnlineAuthenticatorV2 extends Authenticator {
|
|
|
6459
6455
|
});
|
|
6460
6456
|
}
|
|
6461
6457
|
async loginWithUsernameAndPassword(username, password, provider) {
|
|
6462
|
-
if (typeof username !== 'string') {
|
|
6463
|
-
throw new TypeError(`Expected parameter username to have type string, but got '${typeof username}'`);
|
|
6464
|
-
}
|
|
6465
|
-
if (typeof password !== 'string') {
|
|
6466
|
-
throw new TypeError(`Expected parameter password to have type string, but got '${typeof password}'`);
|
|
6467
|
-
}
|
|
6468
|
-
if (typeof provider !== 'string') {
|
|
6469
|
-
throw new TypeError(`Expected parameter provider to have type string, but got '${typeof provider}'`);
|
|
6470
|
-
}
|
|
6471
6458
|
const ditto = this.ditto.deref();
|
|
6472
6459
|
if (!ditto || ditto.isClosed)
|
|
6473
6460
|
return;
|
|
@@ -6476,16 +6463,13 @@ class OnlineAuthenticatorV2 extends Authenticator {
|
|
|
6476
6463
|
});
|
|
6477
6464
|
}
|
|
6478
6465
|
async logout(cleanupFn) {
|
|
6479
|
-
if (cleanupFn !== undefined && typeof cleanupFn !== 'function') {
|
|
6480
|
-
throw new TypeError(`Expected parameter cleanupFn to have type function, but got '${typeof cleanupFn}'`);
|
|
6481
|
-
}
|
|
6482
6466
|
const ditto = this.ditto.deref();
|
|
6483
6467
|
if (!ditto || ditto.isClosed)
|
|
6484
6468
|
return;
|
|
6485
6469
|
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
6486
6470
|
await dittoAuthClientLogout(dittoHandle.deref());
|
|
6487
6471
|
ditto.stopSync();
|
|
6488
|
-
cleanupFn
|
|
6472
|
+
cleanupFn?.(ditto);
|
|
6489
6473
|
});
|
|
6490
6474
|
}
|
|
6491
6475
|
authenticationStatusUpdated(authenticationStatus) {
|
|
@@ -6593,9 +6577,8 @@ const IdentityTypesRequiringOfflineLicenseToken = [
|
|
|
6593
6577
|
* @deprecated
|
|
6594
6578
|
*/
|
|
6595
6579
|
function makeIdentityConfig(identity) {
|
|
6596
|
-
var _a, _b, _c;
|
|
6597
6580
|
if (identity.type === 'offlinePlayground') {
|
|
6598
|
-
return dittoIdentityConfigMakeOfflinePlayground(identity.appID,
|
|
6581
|
+
return dittoIdentityConfigMakeOfflinePlayground(identity.appID, identity.siteID ?? 0);
|
|
6599
6582
|
}
|
|
6600
6583
|
if (identity.type === 'manual') {
|
|
6601
6584
|
return dittoIdentityConfigMakeManual(identity.certificate);
|
|
@@ -6604,11 +6587,11 @@ function makeIdentityConfig(identity) {
|
|
|
6604
6587
|
return dittoIdentityConfigMakeSharedKey(identity.appID, identity.sharedKey, identity.siteID);
|
|
6605
6588
|
}
|
|
6606
6589
|
if (identity.type === 'onlinePlayground') {
|
|
6607
|
-
const authURL =
|
|
6590
|
+
const authURL = identity.customAuthURL ?? defaultAuthURL(identity.appID);
|
|
6608
6591
|
return dittoIdentityConfigMakeOnlinePlayground(identity.appID, identity.token, authURL);
|
|
6609
6592
|
}
|
|
6610
6593
|
if (identity.type === 'onlineWithAuthentication') {
|
|
6611
|
-
const authURL =
|
|
6594
|
+
const authURL = identity.customAuthURL ?? defaultAuthURL(identity.appID);
|
|
6612
6595
|
return dittoIdentityConfigMakeOnlineWithAuthentication(identity.appID, authURL);
|
|
6613
6596
|
}
|
|
6614
6597
|
}
|
|
@@ -6768,7 +6751,6 @@ class DittoConfig {
|
|
|
6768
6751
|
* @internal
|
|
6769
6752
|
*/
|
|
6770
6753
|
function toFFICBORData(config) {
|
|
6771
|
-
var _a;
|
|
6772
6754
|
let connectFFI;
|
|
6773
6755
|
if (config.connect.mode === 'server') {
|
|
6774
6756
|
connectFFI = {
|
|
@@ -6789,7 +6771,7 @@ function toFFICBORData(config) {
|
|
|
6789
6771
|
const ffiConfig = {
|
|
6790
6772
|
database_id: config.databaseID,
|
|
6791
6773
|
connect: connectFFI,
|
|
6792
|
-
persistence_directory:
|
|
6774
|
+
persistence_directory: config.persistenceDirectory ?? null, // MUST not be undefined
|
|
6793
6775
|
experimental: {}, // Currently no experimental features in JS SDK
|
|
6794
6776
|
};
|
|
6795
6777
|
return ffiConfig;
|
|
@@ -8089,7 +8071,7 @@ class Collection {
|
|
|
8089
8071
|
* @deprecated Use DQL (Ditto Query Language) instead. For more information see: https://ditto.com/link/dql-legacy-to-dql-adoption
|
|
8090
8072
|
*/
|
|
8091
8073
|
find(query, queryArgs) {
|
|
8092
|
-
return new PendingCursorOperation(query, queryArgs
|
|
8074
|
+
return new PendingCursorOperation(query, queryArgs ?? null, this);
|
|
8093
8075
|
}
|
|
8094
8076
|
/**
|
|
8095
8077
|
* @deprecated Use DQL (Ditto Query Language) instead. For more information see: https://ditto.com/link/dql-legacy-to-dql-adoption
|
|
@@ -8125,8 +8107,7 @@ class Collection {
|
|
|
8125
8107
|
`For more information see: ` +
|
|
8126
8108
|
`https://ditto.com/link/dql-legacy-to-dql-adoption`);
|
|
8127
8109
|
return this.store.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8128
|
-
|
|
8129
|
-
const writeStrategy = (_a = options.writeStrategy) !== null && _a !== void 0 ? _a : 'merge';
|
|
8110
|
+
const writeStrategy = options.writeStrategy ?? 'merge';
|
|
8130
8111
|
const documentValueJSON = desugarJSObject(value);
|
|
8131
8112
|
const documentValueCBOR = CBOR.encode(documentValueJSON);
|
|
8132
8113
|
const idCBOR = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
@@ -8873,7 +8854,7 @@ class WriteTransactionCollection {
|
|
|
8873
8854
|
* see: https://ditto.com/link/dql-legacy-to-dql-adoption
|
|
8874
8855
|
*/
|
|
8875
8856
|
find(query, queryArgs) {
|
|
8876
|
-
return new WriteTransactionPendingCursorOperation(query, queryArgs
|
|
8857
|
+
return new WriteTransactionPendingCursorOperation(query, queryArgs ?? null, this);
|
|
8877
8858
|
}
|
|
8878
8859
|
/**
|
|
8879
8860
|
* Convenience method, equivalent to calling {@link find | find()} and passing
|
|
@@ -8905,8 +8886,7 @@ class WriteTransactionCollection {
|
|
|
8905
8886
|
async upsert(value, options = {}) {
|
|
8906
8887
|
const ditto = this.store.ditto;
|
|
8907
8888
|
return ditto.deferCloseAsync(async (dittoHandle) => {
|
|
8908
|
-
|
|
8909
|
-
const writeStrategy = (_a = options.writeStrategy) !== null && _a !== void 0 ? _a : 'merge';
|
|
8889
|
+
const writeStrategy = options.writeStrategy ?? 'merge';
|
|
8910
8890
|
const documentValueJSON = desugarJSObject(value);
|
|
8911
8891
|
const documentValueCBOR = CBOR.encode(documentValueJSON);
|
|
8912
8892
|
const idCBOR = await performAsyncToWorkaroundNonAsyncFFIAPI(async () => {
|
|
@@ -9187,7 +9167,7 @@ class Store {
|
|
|
9187
9167
|
if (typeof query !== 'string') {
|
|
9188
9168
|
throw new DittoError('query/invalid', `Expected parameter 'query' to be of type 'string', found: ${typeof query}`);
|
|
9189
9169
|
}
|
|
9190
|
-
const storeObserver = new StoreObserver(this.ditto, query, queryArguments
|
|
9170
|
+
const storeObserver = new StoreObserver(this.ditto, query, queryArguments ?? null, observationHandler);
|
|
9191
9171
|
// @ts-expect-error modifying readonly property
|
|
9192
9172
|
this.observers = Object.freeze([...this.observers, storeObserver]);
|
|
9193
9173
|
// We have two requirements for this step: (1) we want to be able to wait
|
|
@@ -9303,7 +9283,7 @@ class Store {
|
|
|
9303
9283
|
}
|
|
9304
9284
|
catch (error) {
|
|
9305
9285
|
await transaction.rollback();
|
|
9306
|
-
Logger.warning(`Transaction rolled back due to an error: ${error
|
|
9286
|
+
Logger.warning(`Transaction rolled back due to an error: ${error?.message}`);
|
|
9307
9287
|
throw error;
|
|
9308
9288
|
}
|
|
9309
9289
|
await transaction.commit();
|
|
@@ -9660,9 +9640,9 @@ class Store {
|
|
|
9660
9640
|
*/
|
|
9661
9641
|
async transaction(scope, options = {}) {
|
|
9662
9642
|
return this.ditto.deferCloseAsync(async () => {
|
|
9663
|
-
if (
|
|
9643
|
+
if (options?.isReadOnly && typeof options.isReadOnly !== 'boolean')
|
|
9664
9644
|
throw new TypeError("Expected 'options.isReadOnly' to be a boolean");
|
|
9665
|
-
if (
|
|
9645
|
+
if (options?.hint && typeof options.hint !== 'string')
|
|
9666
9646
|
throw new TypeError("Expected 'options.hint' to be a string");
|
|
9667
9647
|
const transaction = await this.beginTransaction(options);
|
|
9668
9648
|
// REFACTOR: completing with action `rollback` should never fail even
|
|
@@ -9688,12 +9668,11 @@ class Store {
|
|
|
9688
9668
|
/** @internal */
|
|
9689
9669
|
async beginTransaction(options = {}) {
|
|
9690
9670
|
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
9691
|
-
var _a, _b;
|
|
9692
9671
|
// We explicitely set the default value here to maintain consistency with
|
|
9693
9672
|
// other API that we already have, while acknowledging that default values
|
|
9694
9673
|
// are generally better to be dictated from Core (via a factory method).
|
|
9695
|
-
const isReadOnly =
|
|
9696
|
-
const hint =
|
|
9674
|
+
const isReadOnly = options.isReadOnly ?? false;
|
|
9675
|
+
const hint = options.hint ?? null;
|
|
9697
9676
|
const storePointer = dittoPointerToStorePointer(dittoHandle.deref());
|
|
9698
9677
|
const transactionPointer = await storeBeginTransaction(storePointer, {
|
|
9699
9678
|
isReadOnly,
|
|
@@ -10009,137 +9988,6 @@ class LiveQueryManager {
|
|
|
10009
9988
|
}
|
|
10010
9989
|
}
|
|
10011
9990
|
|
|
10012
|
-
//
|
|
10013
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
10014
|
-
//
|
|
10015
|
-
/**
|
|
10016
|
-
* @internal
|
|
10017
|
-
* @deprecated Replaced by `Presence`.
|
|
10018
|
-
*/
|
|
10019
|
-
class PresenceManager {
|
|
10020
|
-
constructor(ditto) {
|
|
10021
|
-
this.ditto = ditto;
|
|
10022
|
-
this.isClosed = false;
|
|
10023
|
-
this.isRegistered = false;
|
|
10024
|
-
this.currentRemotePeers = [];
|
|
10025
|
-
this.callbacksByPresenceToken = {};
|
|
10026
|
-
}
|
|
10027
|
-
/** @internal */
|
|
10028
|
-
addObserver(callback) {
|
|
10029
|
-
if (this.isClosed) {
|
|
10030
|
-
// REFACTOR: throw a catchable error here, such that calling code
|
|
10031
|
-
// can be more specific when forwarding it to the user.
|
|
10032
|
-
throw new Error(`Internal inconsistency, can't add presence observer, observer mananger close()-ed.`);
|
|
10033
|
-
}
|
|
10034
|
-
this.registerIfNeeded();
|
|
10035
|
-
const token = cryptoGenerateSecureRandomToken();
|
|
10036
|
-
this.callbacksByPresenceToken[token] = callback;
|
|
10037
|
-
this.ditto.keepAlive.retain(`PresenceObservation.${token}`);
|
|
10038
|
-
// REFACTOR: make the initial callback call async, too (othewise we'd be
|
|
10039
|
-
// mixing sync with async, which is a bit problematic in general but might
|
|
10040
|
-
// be OK with single-threaded JS). This is a bit tricky, simply
|
|
10041
|
-
// setTimeout(..., 0) here could lead us to a situation where the initial
|
|
10042
|
-
// call would be sent AFTER the regular notification.
|
|
10043
|
-
callback(this.currentRemotePeers);
|
|
10044
|
-
return token;
|
|
10045
|
-
}
|
|
10046
|
-
/** @internal */
|
|
10047
|
-
async removeObserver(token) {
|
|
10048
|
-
const callback = this.callbacksByPresenceToken[token];
|
|
10049
|
-
if (typeof callback === 'undefined') {
|
|
10050
|
-
throw new Error(`Can't remove presence observer, token '${token}' has never been registered before.`);
|
|
10051
|
-
}
|
|
10052
|
-
if (callback === null) {
|
|
10053
|
-
// Observer has already been removed, no-op.
|
|
10054
|
-
return;
|
|
10055
|
-
}
|
|
10056
|
-
if (typeof this.callbacksByPresenceToken[token] != 'undefined') {
|
|
10057
|
-
this.ditto.keepAlive.release(`PresenceObservation.${token}`);
|
|
10058
|
-
// REFACTOR: not deleting the token here will keep eating up
|
|
10059
|
-
// memory over long periods of time. We actually need to track
|
|
10060
|
-
// the observer objects themselves and remove it from the table
|
|
10061
|
-
// as soon as the observer object is garbage collected.
|
|
10062
|
-
this.callbacksByPresenceToken[token] = null;
|
|
10063
|
-
return this.unregisterIfNeeded();
|
|
10064
|
-
}
|
|
10065
|
-
}
|
|
10066
|
-
/** @internal */
|
|
10067
|
-
hasObserver(token) {
|
|
10068
|
-
return typeof this.callbacksByPresenceToken[token] != 'undefined';
|
|
10069
|
-
}
|
|
10070
|
-
/** @internal */
|
|
10071
|
-
async close() {
|
|
10072
|
-
this.isClosed = true;
|
|
10073
|
-
const tokens = Object.keys(this.callbacksByPresenceToken);
|
|
10074
|
-
return Promise.all(tokens.map((token) => this.removeObserver(token)));
|
|
10075
|
-
}
|
|
10076
|
-
hasObservers() {
|
|
10077
|
-
return Object.keys(this.callbacksByPresenceToken).length > 0;
|
|
10078
|
-
}
|
|
10079
|
-
registerIfNeeded() {
|
|
10080
|
-
this.ditto.deferClose((dittoHandle) => {
|
|
10081
|
-
const needsToRegister = !this.isRegistered;
|
|
10082
|
-
if (needsToRegister) {
|
|
10083
|
-
this.isRegistered = true;
|
|
10084
|
-
const remotePeersJSONString = dittoPresenceV1(dittoHandle.deref());
|
|
10085
|
-
this.currentRemotePeers = this.decode(remotePeersJSONString).sort(this.compareRemotePeers);
|
|
10086
|
-
dittoRegisterPresenceV1Callback(dittoHandle.deref(), this.handlePresenceV1Callback.bind(this));
|
|
10087
|
-
}
|
|
10088
|
-
});
|
|
10089
|
-
}
|
|
10090
|
-
unregisterIfNeeded() {
|
|
10091
|
-
return this.ditto.deferCloseAsync(async (dittoHandle) => {
|
|
10092
|
-
const needsToUnregister = !this.hasObservers() && this.isRegistered;
|
|
10093
|
-
if (needsToUnregister) {
|
|
10094
|
-
this.isRegistered = false;
|
|
10095
|
-
await dittoClearPresenceCallback(dittoHandle.deref());
|
|
10096
|
-
this.currentRemotePeers = [];
|
|
10097
|
-
}
|
|
10098
|
-
});
|
|
10099
|
-
}
|
|
10100
|
-
handlePresenceV1Callback(remotePeersJSONString) {
|
|
10101
|
-
const remotePeers = this.decode(remotePeersJSONString).sort(this.compareRemotePeers);
|
|
10102
|
-
this.currentRemotePeers = remotePeers;
|
|
10103
|
-
this.notify();
|
|
10104
|
-
}
|
|
10105
|
-
notify() {
|
|
10106
|
-
if (this.isClosed) {
|
|
10107
|
-
// NOTE: we don't notify observers after closing.
|
|
10108
|
-
return;
|
|
10109
|
-
}
|
|
10110
|
-
for (const token in this.callbacksByPresenceToken) {
|
|
10111
|
-
const callback = this.callbacksByPresenceToken[token];
|
|
10112
|
-
if (callback)
|
|
10113
|
-
callback(this.currentRemotePeers);
|
|
10114
|
-
}
|
|
10115
|
-
}
|
|
10116
|
-
decode(remotePeersJSONString) {
|
|
10117
|
-
const remotePeersJSON = JSON.parse(remotePeersJSONString);
|
|
10118
|
-
return remotePeersJSON.map((remotePeerJSON) => {
|
|
10119
|
-
var _a, _b;
|
|
10120
|
-
return {
|
|
10121
|
-
networkID: remotePeerJSON['network_id'],
|
|
10122
|
-
deviceName: remotePeerJSON['device_name'],
|
|
10123
|
-
rssi: (_a = remotePeerJSON['rssi']) !== null && _a !== void 0 ? _a : undefined,
|
|
10124
|
-
approximateDistanceInMeters: (_b = remotePeerJSON['approximate_distance_in_meters']) !== null && _b !== void 0 ? _b : undefined,
|
|
10125
|
-
connections: remotePeerJSON['connections'],
|
|
10126
|
-
};
|
|
10127
|
-
});
|
|
10128
|
-
}
|
|
10129
|
-
compareRemotePeers(left, right) {
|
|
10130
|
-
// NOTE: we use the exact same sort order here as in the ObjC version.
|
|
10131
|
-
if (left.connections.length === 0 && right.connections.length > 0)
|
|
10132
|
-
return +1;
|
|
10133
|
-
if (left.connections.length > 0 && right.connections.length === 0)
|
|
10134
|
-
return -1;
|
|
10135
|
-
if (left.deviceName < right.deviceName)
|
|
10136
|
-
return -1;
|
|
10137
|
-
if (left.deviceName > right.deviceName)
|
|
10138
|
-
return +1;
|
|
10139
|
-
return 0;
|
|
10140
|
-
}
|
|
10141
|
-
}
|
|
10142
|
-
|
|
10143
9991
|
//
|
|
10144
9992
|
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
10145
9993
|
//
|
|
@@ -10242,16 +10090,69 @@ class TransportConditionsManager extends ObserverManager {
|
|
|
10242
10090
|
*
|
|
10243
10091
|
* Create a sync subscription by calling
|
|
10244
10092
|
* {@link Sync.registerSubscription | `ditto.sync.registerSubscription()`}.
|
|
10245
|
-
*
|
|
10246
|
-
* @template T The type of query arguments passed to the sync subscription.
|
|
10247
10093
|
*/
|
|
10248
10094
|
class SyncSubscription {
|
|
10095
|
+
/**
|
|
10096
|
+
* Documents matching this query will be included in the sync subscription.
|
|
10097
|
+
*/
|
|
10098
|
+
get queryString() {
|
|
10099
|
+
return syncSubscriptionQueryString(this.deref());
|
|
10100
|
+
}
|
|
10101
|
+
/**
|
|
10102
|
+
* The query arguments of the sync subscription (as passed when adding it to
|
|
10103
|
+
* the store).
|
|
10104
|
+
*
|
|
10105
|
+
* Note that this value is not guaranteed to be strictly equal to the value
|
|
10106
|
+
* used when registering the sync subscription. In particular, any
|
|
10107
|
+
* {@link Attachment} values in query arguments will be represented by that
|
|
10108
|
+
* attachment's {@link AttachmentToken} here.
|
|
10109
|
+
*
|
|
10110
|
+
* Also see {@link queryArgumentsCBORData} and
|
|
10111
|
+
* {@link queryArgumentsJSONString} for the raw serialized representations of
|
|
10112
|
+
* the query arguments.
|
|
10113
|
+
*/
|
|
10114
|
+
get queryArguments() {
|
|
10115
|
+
const queryArgumentsCBOR = this.queryArgumentsCBORData;
|
|
10116
|
+
if (queryArgumentsCBOR == null)
|
|
10117
|
+
return undefined;
|
|
10118
|
+
try {
|
|
10119
|
+
const queryArguments = CBOR.decode(queryArgumentsCBOR);
|
|
10120
|
+
return Object.freeze(queryArguments);
|
|
10121
|
+
}
|
|
10122
|
+
catch (error) {
|
|
10123
|
+
throw new DittoError('query/arguments-invalid', `Failed to decode query arguments: ${error.message}`);
|
|
10124
|
+
}
|
|
10125
|
+
}
|
|
10126
|
+
/**
|
|
10127
|
+
* The query arguments of the sync subscription, serialized as CBOR, (as
|
|
10128
|
+
* passed when adding it to the store).
|
|
10129
|
+
*
|
|
10130
|
+
* Note that any {@link Attachment} values passed in as query arguments when
|
|
10131
|
+
* creating this sync subscription will be represented by that attachment's
|
|
10132
|
+
* {@link AttachmentToken} here.
|
|
10133
|
+
*/
|
|
10134
|
+
get queryArgumentsCBORData() {
|
|
10135
|
+
const queryArgumentsCBOR = syncSubscriptionQueryArgumentsCBOR(this.deref());
|
|
10136
|
+
return queryArgumentsCBOR == null ? undefined : queryArgumentsCBOR;
|
|
10137
|
+
}
|
|
10138
|
+
/**
|
|
10139
|
+
* The query arguments of the sync subscription, serialized as JSON, (as
|
|
10140
|
+
* passed when adding it to the store).
|
|
10141
|
+
*
|
|
10142
|
+
* Note that any {@link Attachment} values passed in as query arguments when
|
|
10143
|
+
* creating this sync subscription will be represented by that attachment's
|
|
10144
|
+
* {@link AttachmentToken} here.
|
|
10145
|
+
*/
|
|
10146
|
+
get queryArgumentsJSONString() {
|
|
10147
|
+
const queryArgumentsJSON = syncSubscriptionQueryArgumentsJSON(this.deref());
|
|
10148
|
+
return queryArgumentsJSON == null ? undefined : queryArgumentsJSON;
|
|
10149
|
+
}
|
|
10249
10150
|
/**
|
|
10250
10151
|
* `true` when the sync subscription has been cancelled or the {@link Ditto}
|
|
10251
10152
|
* instance managing this subscription has been closed.
|
|
10252
10153
|
*/
|
|
10253
10154
|
get isCancelled() {
|
|
10254
|
-
return this.
|
|
10155
|
+
return syncSubscriptionIsCancelled(this.deref());
|
|
10255
10156
|
}
|
|
10256
10157
|
/**
|
|
10257
10158
|
* Cancels the sync subscription and unregisters it. No-op
|
|
@@ -10259,32 +10160,16 @@ class SyncSubscription {
|
|
|
10259
10160
|
* instance managing this subscription has been closed.
|
|
10260
10161
|
*/
|
|
10261
10162
|
cancel() {
|
|
10262
|
-
|
|
10263
|
-
return;
|
|
10264
|
-
this._isCancelled = true;
|
|
10265
|
-
this.ditto.sync.unregisterSubscription(this);
|
|
10163
|
+
syncSubscriptionCancel(this.deref());
|
|
10266
10164
|
}
|
|
10267
10165
|
// --------------------------- Internal --------------------------------------
|
|
10268
10166
|
/** @internal */
|
|
10269
|
-
constructor(ditto
|
|
10270
|
-
// --------------------------- Private --------------------------------------
|
|
10271
|
-
/**
|
|
10272
|
-
* `true` when the sync subscription has been cancelled.
|
|
10273
|
-
*
|
|
10274
|
-
* We mark the sync subscription as cancelled here as an optimization to avoid
|
|
10275
|
-
* a scan of all subscriptions in the store whenever the `isCancelled`
|
|
10276
|
-
* property is checked.
|
|
10277
|
-
*/
|
|
10278
|
-
this._isCancelled = false;
|
|
10279
|
-
if ((queryArguments == null) !== (queryArgumentsCBOR == null)) {
|
|
10280
|
-
throw new DittoError('internal', 'Internal inconsistency, query arguments and query arguments CBOR must be both null or both non-null', { queryArguments, queryArgumentsCBOR });
|
|
10281
|
-
}
|
|
10167
|
+
constructor(ditto) {
|
|
10282
10168
|
this.ditto = ditto;
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
this.queryArgumentsCBOR = queryArgumentsCBOR;
|
|
10169
|
+
}
|
|
10170
|
+
// --------------------------- Private --------------------------------------
|
|
10171
|
+
deref() {
|
|
10172
|
+
return Bridge.syncSubscription.handleFor(this).deref();
|
|
10288
10173
|
}
|
|
10289
10174
|
}
|
|
10290
10175
|
|
|
@@ -10297,6 +10182,19 @@ class SyncSubscription {
|
|
|
10297
10182
|
* Access this object via {@link Ditto.sync | Ditto.sync} on any Ditto instance.
|
|
10298
10183
|
*/
|
|
10299
10184
|
class Sync {
|
|
10185
|
+
/**
|
|
10186
|
+
* All currently active {@link SyncSubscription | sync subscriptions}.
|
|
10187
|
+
*
|
|
10188
|
+
* **Note:** Manage sync subscriptions using
|
|
10189
|
+
* {@link registerSubscription | registerSubscription()} to register a new
|
|
10190
|
+
* sync subscription and
|
|
10191
|
+
* {@link SyncSubscription.cancel | SyncSubscription.cancel()} to remove an
|
|
10192
|
+
* existing sync subscription.
|
|
10193
|
+
*/
|
|
10194
|
+
get subscriptions() {
|
|
10195
|
+
const ffiSyncSubscriptions = this.ditto.deferClose((dittoHandle) => mapFFIErrors(() => syncSubscriptions(dittoHandle.deref())));
|
|
10196
|
+
return ffiSyncSubscriptions.map((pointer) => Bridge.syncSubscription.bridge(pointer, () => new SyncSubscription(this.ditto)));
|
|
10197
|
+
}
|
|
10300
10198
|
/**
|
|
10301
10199
|
* Returns `true` if sync is active, otherwise returns `false`. Use
|
|
10302
10200
|
* {@link Sync.start | ditto.sync.start()} to activate and
|
|
@@ -10353,7 +10251,6 @@ class Sync {
|
|
|
10353
10251
|
* @param query a string containing a valid query expressed in DQL.
|
|
10354
10252
|
* @param queryArguments an object containing the arguments for the query.
|
|
10355
10253
|
* Example: `{mileage: 123}` for a query with `:mileage` placeholder.
|
|
10356
|
-
* @template T The type of the query arguments.
|
|
10357
10254
|
* @returns An active `SyncSubscription` for the passed in query and
|
|
10358
10255
|
* arguments. It will remain active until it is
|
|
10359
10256
|
* {@link SyncSubscription.cancel | cancelled} or the {@link Ditto} instance
|
|
@@ -10373,71 +10270,20 @@ class Sync {
|
|
|
10373
10270
|
let queryArgumentsCBOR = null;
|
|
10374
10271
|
if (queryArguments != null) {
|
|
10375
10272
|
try {
|
|
10376
|
-
|
|
10377
|
-
queryArgumentsCBOR = CBOR.encode(queryArgumentsJSON);
|
|
10273
|
+
queryArgumentsCBOR = CBOR.encodeWithReplacer(queryArguments, desugarJSObjectV2);
|
|
10378
10274
|
}
|
|
10379
10275
|
catch (error) {
|
|
10380
10276
|
throw new DittoError('query/arguments-invalid', `Unable to encode query arguments: ${error.message}`);
|
|
10381
10277
|
}
|
|
10382
10278
|
}
|
|
10383
|
-
this.ditto.deferClose((dittoHandle) =>
|
|
10384
|
-
|
|
10385
|
-
});
|
|
10386
|
-
const subscription = new SyncSubscription(this.ditto, query, queryArguments || null, queryArgumentsCBOR);
|
|
10387
|
-
// @ts-expect-error modifying readonly property
|
|
10388
|
-
this.subscriptions = Object.freeze([...this.subscriptions, subscription]);
|
|
10389
|
-
return subscription;
|
|
10279
|
+
const syncSubscriptionPointer = this.ditto.deferClose((dittoHandle) => mapFFIErrors(() => syncRegisterSubscriptionThrows(dittoHandle.deref(), query, queryArgumentsCBOR)));
|
|
10280
|
+
return Bridge.syncSubscription.bridge(syncSubscriptionPointer, () => new SyncSubscription(this.ditto));
|
|
10390
10281
|
}
|
|
10391
10282
|
// ---------------------------------------------------------- Internal ------
|
|
10392
10283
|
/** @internal */
|
|
10393
10284
|
constructor(ditto) {
|
|
10394
|
-
/**
|
|
10395
|
-
* All currently active {@link SyncSubscription | sync subscriptions}.
|
|
10396
|
-
*
|
|
10397
|
-
* **Note:** Manage sync subscriptions using
|
|
10398
|
-
* {@link registerSubscription | registerSubscription()} to register a new
|
|
10399
|
-
* sync subscription and
|
|
10400
|
-
* {@link SyncSubscription.cancel | SyncSubscription.cancel()} to remove an
|
|
10401
|
-
* existing sync subscription.
|
|
10402
|
-
*/
|
|
10403
|
-
this.subscriptions = Object.freeze([]);
|
|
10404
10285
|
this.ditto = ditto;
|
|
10405
10286
|
}
|
|
10406
|
-
/**
|
|
10407
|
-
* Removes the passed in `syncSubscription`, configuring Ditto to not receive
|
|
10408
|
-
* updates for documents matching the corresponding query anymore. No-op if
|
|
10409
|
-
* the passed in `syncSubscription` has already been removed.
|
|
10410
|
-
*
|
|
10411
|
-
* This must only be called by the sync subscription itself.
|
|
10412
|
-
*
|
|
10413
|
-
* @param syncSubscription the sync subscription to remove
|
|
10414
|
-
* @returns `true` if the passed in sync subscription could be found and has
|
|
10415
|
-
* been removed, otherwise returns `false`.
|
|
10416
|
-
* @throws {@link DittoError} `internal`: if the replication subscription does not
|
|
10417
|
-
* belong to this store
|
|
10418
|
-
* @throws {@link DittoError} `internal`: if the replication subscription has not
|
|
10419
|
-
* been cancelled yet
|
|
10420
|
-
* @internal
|
|
10421
|
-
*/
|
|
10422
|
-
unregisterSubscription(syncSubscription) {
|
|
10423
|
-
if (syncSubscription.ditto !== this.ditto) {
|
|
10424
|
-
throw new DittoError('internal', `Can't remove replication subscription that does not belong to this store`);
|
|
10425
|
-
}
|
|
10426
|
-
if (!syncSubscription.isCancelled) {
|
|
10427
|
-
throw new DittoError('internal', "Internal inconsistency, can't remove replication subscription that has not been cancelled");
|
|
10428
|
-
}
|
|
10429
|
-
const indexToDelete = this.subscriptions.findIndex((s) => s === syncSubscription);
|
|
10430
|
-
if (indexToDelete === -1)
|
|
10431
|
-
return false;
|
|
10432
|
-
const newSyncSubscriptions = [...this.subscriptions];
|
|
10433
|
-
newSyncSubscriptions.splice(indexToDelete, 1);
|
|
10434
|
-
// @ts-expect-error modifying readonly property
|
|
10435
|
-
this.subscriptions = Object.freeze(newSyncSubscriptions);
|
|
10436
|
-
this.ditto.deferClose((dittoHandle) => {
|
|
10437
|
-
mapFFIErrors(() => tryRemoveSyncSubscription(dittoHandle.deref(), syncSubscription.queryString, syncSubscription.queryArgumentsCBOR));
|
|
10438
|
-
});
|
|
10439
|
-
return true;
|
|
10440
|
-
}
|
|
10441
10287
|
/** @internal */
|
|
10442
10288
|
close() {
|
|
10443
10289
|
for (const subscription of this.subscriptions)
|
|
@@ -10497,7 +10343,7 @@ class SubscriptionManager {
|
|
|
10497
10343
|
this.ditto.deferClose(() => {
|
|
10498
10344
|
for (const subscriptionID in this.subscriptions) {
|
|
10499
10345
|
const subscription = this.subscriptions[subscriptionID].deref();
|
|
10500
|
-
subscription
|
|
10346
|
+
subscription?.cancel();
|
|
10501
10347
|
}
|
|
10502
10348
|
});
|
|
10503
10349
|
}
|
|
@@ -10924,7 +10770,6 @@ class ConfigOrParameters {
|
|
|
10924
10770
|
}
|
|
10925
10771
|
}
|
|
10926
10772
|
validateIdentity(identity) {
|
|
10927
|
-
var _a, _b;
|
|
10928
10773
|
if (!identity || typeof identity !== 'object') {
|
|
10929
10774
|
throw new TypeError('Expected `identity` to be an object, but got: ' + typeof identity);
|
|
10930
10775
|
}
|
|
@@ -10986,8 +10831,8 @@ class ConfigOrParameters {
|
|
|
10986
10831
|
if (authHandlerType !== 'object') {
|
|
10987
10832
|
throw new TypeError(`Property .authHandler on identity of type onlineWithAuthentication must be an object, but is of type '${authHandlerType}'.`);
|
|
10988
10833
|
}
|
|
10989
|
-
const expiringSoonType = typeof
|
|
10990
|
-
const authenticationRequiredType = typeof
|
|
10834
|
+
const expiringSoonType = typeof identity.authHandler?.authenticationExpiringSoon;
|
|
10835
|
+
const authenticationRequiredType = typeof identity.authHandler?.authenticationRequired;
|
|
10991
10836
|
if (expiringSoonType !== 'function') {
|
|
10992
10837
|
throw new TypeError(`Property .authHandler.authenticationExpiringSoon on identity of type onlineWithAuthentication must be a function, but is of type '${expiringSoonType}'.`);
|
|
10993
10838
|
}
|
|
@@ -11331,8 +11176,7 @@ class Ditto {
|
|
|
11331
11176
|
* `false`.
|
|
11332
11177
|
*/
|
|
11333
11178
|
get isClosed() {
|
|
11334
|
-
|
|
11335
|
-
return (_a = this._isClosed) !== null && _a !== void 0 ? _a : false;
|
|
11179
|
+
return this._isClosed ?? false;
|
|
11336
11180
|
}
|
|
11337
11181
|
/**
|
|
11338
11182
|
* Returns `true` if sync is active, otherwise returns `false`. Use
|
|
@@ -11375,7 +11219,6 @@ class Ditto {
|
|
|
11375
11219
|
// async part of making a new Ditto instance can be done in Ditto.open() and
|
|
11376
11220
|
// this constructor uses the outputs of that to set up the Ditto instance.
|
|
11377
11221
|
constructor(identity, persistenceDirectory) {
|
|
11378
|
-
var _a, _b, _c, _d, _e;
|
|
11379
11222
|
// ------------------------------------------------------------ Private ------
|
|
11380
11223
|
this.deferCloseAllowed = true;
|
|
11381
11224
|
this._isClosed = false;
|
|
@@ -11403,7 +11246,7 @@ class Ditto {
|
|
|
11403
11246
|
}
|
|
11404
11247
|
else {
|
|
11405
11248
|
// the constructor was called directly
|
|
11406
|
-
const identityOrDefault = identity
|
|
11249
|
+
const identityOrDefault = identity ?? DEFAULT_IDENTITY;
|
|
11407
11250
|
configOrParameters = new ConfigOrParameters(identityOrDefault, persistenceDirectory);
|
|
11408
11251
|
}
|
|
11409
11252
|
this.configOrParameters = configOrParameters.redactingSensitiveData();
|
|
@@ -11437,14 +11280,15 @@ class Ditto {
|
|
|
11437
11280
|
// set.
|
|
11438
11281
|
this.auth = new OnlineAuthenticatorV2(this.keepAlive, this);
|
|
11439
11282
|
}
|
|
11440
|
-
else if (
|
|
11283
|
+
else if (configOrParameters.identity?.type === 'onlineWithAuthentication') {
|
|
11441
11284
|
// IMPORTANT: Keeping the auth client around accumulates run-times and
|
|
11442
11285
|
// resources which becomes a problem specifically in tests (where we use one
|
|
11443
11286
|
// Ditto instance per test). We therefore keep it only if needed, i.e.
|
|
11444
11287
|
// _only_ for the onlineWithAuthentication and online identities and
|
|
11445
11288
|
// transfer ownership of it to the authenticator.
|
|
11446
11289
|
enableDittoCloudSync =
|
|
11447
|
-
|
|
11290
|
+
configOrParameters.identity
|
|
11291
|
+
?.enableDittoCloudSync ?? true;
|
|
11448
11292
|
this.auth = new OnlineAuthenticator(this.keepAlive, this, configOrParameters.identity.authHandler);
|
|
11449
11293
|
const weakThis = new WeakRef(this);
|
|
11450
11294
|
const loginProviderPointer = dittoAuthClientMakeLoginProvider(function (secondsRemaining) {
|
|
@@ -11468,9 +11312,9 @@ class Ditto {
|
|
|
11468
11312
|
// constructor finishes
|
|
11469
11313
|
void dittoAuthSetLoginProvider(dittoPointer, loginProviderPointer);
|
|
11470
11314
|
}
|
|
11471
|
-
else if (
|
|
11315
|
+
else if (configOrParameters.identity?.type === 'onlinePlayground') {
|
|
11472
11316
|
enableDittoCloudSync =
|
|
11473
|
-
|
|
11317
|
+
configOrParameters.identity.enableDittoCloudSync ?? true;
|
|
11474
11318
|
this.auth = new OnlineAuthenticator(this.keepAlive, this, {
|
|
11475
11319
|
authenticationRequired: function (authenticator) {
|
|
11476
11320
|
// No-op.
|
|
@@ -11494,7 +11338,6 @@ class Ditto {
|
|
|
11494
11338
|
this.store = new Store(this);
|
|
11495
11339
|
this.smallPeerInfo = new SmallPeerInfo(this);
|
|
11496
11340
|
this.presence = new Presence(this);
|
|
11497
|
-
this.presenceManager = new PresenceManager(this);
|
|
11498
11341
|
this.liveQueryManager = new LiveQueryManager(this, this.keepAlive);
|
|
11499
11342
|
this.attachmentFetcherManager = new AttachmentFetcherManager(this);
|
|
11500
11343
|
this.transportConditionsManager = new TransportConditionsManager(this);
|
|
@@ -11531,7 +11374,7 @@ class Ditto {
|
|
|
11531
11374
|
setDeadlockTimeout(0);
|
|
11532
11375
|
}
|
|
11533
11376
|
catch (e) {
|
|
11534
|
-
throw new Error(`Failed to disable deadlock detection: ${e
|
|
11377
|
+
throw new Error(`Failed to disable deadlock detection: ${e?.message}`);
|
|
11535
11378
|
}
|
|
11536
11379
|
}
|
|
11537
11380
|
}
|
|
@@ -11721,26 +11564,6 @@ class Ditto {
|
|
|
11721
11564
|
dittoStopSync(dittoHandle.deref());
|
|
11722
11565
|
});
|
|
11723
11566
|
}
|
|
11724
|
-
/**
|
|
11725
|
-
* Registers an observer for info about Ditto peers in range of this device.
|
|
11726
|
-
*
|
|
11727
|
-
* Ditto will prevent the process from exiting as long as there are active
|
|
11728
|
-
* peers observers (not relevant when running in the browser).
|
|
11729
|
-
*
|
|
11730
|
-
* @param callback called immediately with the current state of peers
|
|
11731
|
-
* in range and whenever that state changes. Then it will be invoked
|
|
11732
|
-
* repeatedly when Ditto devices come and go, or the active connections to
|
|
11733
|
-
* them change.
|
|
11734
|
-
*
|
|
11735
|
-
* @deprecated please use {@link Presence.observe | presence.observe()} instead.
|
|
11736
|
-
*/
|
|
11737
|
-
observePeers(callback) {
|
|
11738
|
-
Logger.warning('`ditto.observePeers()` is deprecated, please use `ditto.presence.observe()` instead.');
|
|
11739
|
-
const token = this.presenceManager.addObserver(callback);
|
|
11740
|
-
return new Observer(this.presenceManager, token, {
|
|
11741
|
-
stopsWhenFinalized: true,
|
|
11742
|
-
});
|
|
11743
|
-
}
|
|
11744
11567
|
/**
|
|
11745
11568
|
* Register observer for changes of underlying transport conditions.
|
|
11746
11569
|
*
|
|
@@ -11815,7 +11638,6 @@ class Ditto {
|
|
|
11815
11638
|
this.presence.close();
|
|
11816
11639
|
this.auth.close();
|
|
11817
11640
|
this.sync.close();
|
|
11818
|
-
await this.presenceManager.close();
|
|
11819
11641
|
this.liveQueryManager.close();
|
|
11820
11642
|
this.attachmentFetcherManager.close();
|
|
11821
11643
|
this.transportConditionsManager.close();
|
|
@@ -11925,11 +11747,10 @@ const checkAPIs = (_globalObject) => {
|
|
|
11925
11747
|
* @internal
|
|
11926
11748
|
*/
|
|
11927
11749
|
const disableDeadlockTimeoutWhenDebugging = () => {
|
|
11928
|
-
var _a, _b;
|
|
11929
11750
|
{
|
|
11930
11751
|
const hasInspector = process &&
|
|
11931
|
-
|
|
11932
|
-
const hasLegacyDebugMode = (process &&
|
|
11752
|
+
process?.execArgv?.some((arg) => arg.includes('--inspect') || arg.includes('--debug'));
|
|
11753
|
+
const hasLegacyDebugMode = (process && process?.execArgv?.some((arg) => arg.includes('--debug'))) ||
|
|
11933
11754
|
// @ts-ignore - v8debug may be undefined
|
|
11934
11755
|
typeof v8debug === 'object';
|
|
11935
11756
|
if (hasInspector || hasLegacyDebugMode) {
|
|
@@ -11938,7 +11759,7 @@ const disableDeadlockTimeoutWhenDebugging = () => {
|
|
|
11938
11759
|
Logger.warning('Detected Node running with inspector enabled, disabling deadlock timeout.');
|
|
11939
11760
|
}
|
|
11940
11761
|
catch (e) {
|
|
11941
|
-
Logger.error(`Detected Node running with inspector enabled but failed to disable deadlock timeout: ${e
|
|
11762
|
+
Logger.error(`Detected Node running with inspector enabled but failed to disable deadlock timeout: ${e?.message}`);
|
|
11942
11763
|
}
|
|
11943
11764
|
}
|
|
11944
11765
|
}
|
|
@@ -12149,13 +11970,14 @@ function getBridgeLoad() {
|
|
|
12149
11970
|
// immediately require the bridged type, oftentimes leading to an import cycle.
|
|
12150
11971
|
Bridge.attachment.registerType(Attachment);
|
|
12151
11972
|
Bridge.connectionRequest.registerType(ConnectionRequest);
|
|
11973
|
+
Bridge.differ.registerType(Differ);
|
|
11974
|
+
Bridge.ditto.registerType(Ditto);
|
|
12152
11975
|
Bridge.document.registerType(Document);
|
|
11976
|
+
Bridge.mutableDocument.registerType(MutableDocument);
|
|
11977
|
+
Bridge.queryResult.registerType(QueryResult);
|
|
12153
11978
|
Bridge.queryResultItem.registerType(QueryResultItem);
|
|
12154
|
-
Bridge.differ.registerType(Differ);
|
|
12155
11979
|
Bridge.transaction.registerType(Transaction);
|
|
12156
|
-
Bridge.
|
|
12157
|
-
Bridge.mutableDocument.registerType(MutableDocument);
|
|
12158
|
-
Bridge.ditto.registerType(Ditto);
|
|
11980
|
+
Bridge.syncSubscription.registerType(SyncSubscription);
|
|
12159
11981
|
|
|
12160
11982
|
exports.Attachment = Attachment;
|
|
12161
11983
|
exports.AttachmentFetcher = AttachmentFetcher;
|