@dittolive/ditto 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,10 +3,10 @@
3
3
  *Ditto is a cross platform SDK that allows mobile, web, and IoT apps to sync
4
4
  with and even without connectivity.*
5
5
 
6
- Version: **4.1.0**
6
+ Version: **4.1.1**
7
7
 
8
8
  Please visit [ditto.live](https://ditto.live) for more info as well as the
9
- [API Reference](https://software.ditto.live/js/Ditto/4.1.0/api-reference/) for this particular version.
9
+ [API Reference](https://software.ditto.live/js/Ditto/4.1.1/api-reference/) for this particular version.
10
10
 
11
11
  --------------------------------------------------------------------------------
12
12
 
package/node/ditto.cjs.js CHANGED
@@ -379,10 +379,12 @@ function ditto_validate_document_id(...args) { return ditto.ditto_validate_docum
379
379
  function ditto_write_transaction(...args) { return ditto.ditto_write_transaction(...args) }
380
380
  function ditto_write_transaction_commit(...args) { return ditto.ditto_write_transaction_commit(...args) }
381
381
  function ditto_write_transaction_rollback(...args) { return ditto.ditto_write_transaction_rollback(...args) }
382
+ function getDeadlockTimeout$1(...args) { return ditto.getDeadlockTimeout(...args) }
382
383
  function jsDocsToCDocs(...args) { return ditto.jsDocsToCDocs(...args) }
383
384
  function mdns_client_free_handle(...args) { return ditto.mdns_client_free_handle(...args) }
384
385
  function mdns_server_free_handle(...args) { return ditto.mdns_server_free_handle(...args) }
385
386
  function refCStringToString(...args) { return ditto.refCStringToString(...args) }
387
+ function setDeadlockTimeout$1(...args) { return ditto.setDeadlockTimeout(...args) }
386
388
  function static_tcp_client_free_handle(...args) { return ditto.static_tcp_client_free_handle(...args) }
387
389
  function uninitialized_ditto_make(...args) { return ditto.uninitialized_ditto_make(...args) }
388
390
  function verify_license(...args) { return ditto.verify_license(...args) }
@@ -650,9 +652,10 @@ onError) {
650
652
  ensureInitialized();
651
653
  const collectionNameBuffer = bytesFromString(collectionName);
652
654
  const queryBuffer = bytesFromString(query);
653
- // Note(Daniel): the callback is now registered to be called in a detached manner:
654
- // if the FFI / Rust does `cb()`, then when that call returns, the js callback itself may not
655
- // have completed. This is fine, since `signalNext()` shall be the proper way to achieve this.
655
+ // Note(Daniel): the callback is now registered to be called in a detached
656
+ // manner: if the FFI / Rust does `cb()`, then when that call returns, the js
657
+ // callback itself may not have completed. This is fine, since `signalNext()`
658
+ // shall be the proper way to achieve this.
656
659
  const { status_code: errorCode, i64: id } = ditto_live_query_register_str_detached(ditto, collectionNameBuffer, queryBuffer, queryArgsCBOR, orderBy, limit, offset, wrapBackgroundCbForFFI(onError, eventHandler));
657
660
  if (errorCode !== 0)
658
661
  throw new Error(errorMessage() || `\`ditto_live_query_register_str()\` failed with error code: ${errorCode}`);
@@ -948,6 +951,16 @@ function dittoFree(self) {
948
951
  return ditto_free(self);
949
952
  }
950
953
  /** @internal */
954
+ function getDeadlockTimeout() {
955
+ ensureInitialized();
956
+ return getDeadlockTimeout$1();
957
+ }
958
+ /** @internal */
959
+ function setDeadlockTimeout(duration) {
960
+ ensureInitialized();
961
+ setDeadlockTimeout$1(duration);
962
+ }
963
+ /** @internal */
951
964
  async function dittoRegisterPresenceV1Callback(self, cb) {
952
965
  ensureInitialized();
953
966
  ditto_register_presence_v1_callback(self, wrapBackgroundCbForFFI((err) => console.error(`The registered presence callback v1 errored with ${err}`), (cJsonStr) => {
@@ -1439,7 +1452,7 @@ function awdlDestroy(awdl) {
1439
1452
 
1440
1453
  // NOTE: this is patched up with the actual build version by Jake task
1441
1454
  // build:package and has to be a valid semantic version as defined here: https://semver.org.
1442
- const fullBuildVersionString = '4.1.0';
1455
+ const fullBuildVersionString = '4.1.1';
1443
1456
 
1444
1457
  //
1445
1458
  /**
@@ -2749,6 +2762,11 @@ function augmentJSONValue(json, mutDoc, workingPath) {
2749
2762
  return json;
2750
2763
  }
2751
2764
  }
2765
+ /**
2766
+ * Converts objects that may contain instances of classes of this SDK, i.e.
2767
+ * `DocumentID`, `Counter`, `Register` and `Attachment`, into plain JS objects
2768
+ * that can be passed to the FFI layer.
2769
+ */
2752
2770
  function desugarJSObject(jsObj, atRoot = false) {
2753
2771
  if (jsObj && typeof jsObj === 'object') {
2754
2772
  if (Array.isArray(jsObj)) {
@@ -2786,8 +2804,25 @@ function desugarJSObject(jsObj, atRoot = false) {
2786
2804
  }
2787
2805
  }
2788
2806
  else {
2807
+ checkForUnsupportedValues(jsObj);
2789
2808
  return jsObj;
2790
2809
  }
2810
+ }
2811
+ /**
2812
+ * Throws an error if input is a non-finite float value.
2813
+ *
2814
+ * Workaround while we don't have a reliable way of receiving error messages
2815
+ * from `dittoCore.ditto_collection_insert_value()`.
2816
+ *
2817
+ * See https://github.com/getditto/ditto/issues/8657 for details.
2818
+ *
2819
+ * @param jsObj The object to check.
2820
+ * @throws {Error} If `jsObj` is a non-finite float value.
2821
+ */
2822
+ function checkForUnsupportedValues(jsObj) {
2823
+ if (Number.isNaN(jsObj) || jsObj === Infinity || jsObj === -Infinity) {
2824
+ throw new Error('Non-finite float values are not supported');
2825
+ }
2791
2826
  }
2792
2827
 
2793
2828
  //
@@ -6762,12 +6797,59 @@ class Ditto {
6762
6797
  this.attachmentFetcherManager = new AttachmentFetcherManager(this);
6763
6798
  this.transportConditionsManager = new TransportConditionsManager(this);
6764
6799
  this.subscriptionManager = new SubscriptionManager(this);
6800
+ disableDeadlockTimeoutWhenDebugging();
6765
6801
  // WORKAROUND: see description above where the
6766
6802
  // secondsRemainingUntilAuthenticationExpires variable is declared.
6767
6803
  if (secondsRemainingUntilAuthenticationExpires !== null) {
6768
6804
  this.auth['@ditto.authenticationExpiring'](secondsRemainingUntilAuthenticationExpires);
6769
6805
  }
6770
6806
  }
6807
+ /**
6808
+ * Don't terminate the process when callbacks are pending for a long time.
6809
+ *
6810
+ * Some methods in the Ditto library accept asynchronous functions as callback
6811
+ * parameters. If these asynchronous functions do not resolve within a certain
6812
+ * period of time after having been invoked by Ditto, deadlock detection gets
6813
+ * triggered, resulting in the termination of the process.
6814
+ *
6815
+ * When Ditto is executed in a Node.js environment with an interactive
6816
+ * debugger attached, this deadlock detection might get activated upon
6817
+ * encountering a breakpoint. Calling `Ditto.disableDeadlockDetection()`
6818
+ * disables this behavior, thus allowing the use of an interactive debugger
6819
+ * without triggering the deadlock detection.
6820
+ *
6821
+ * This feature is not available in the browser.
6822
+ */
6823
+ static disableDeadlockDetection() {
6824
+ {
6825
+ const current = getDeadlockTimeout();
6826
+ if (current !== 0) {
6827
+ try {
6828
+ setDeadlockTimeout(0);
6829
+ }
6830
+ catch (e) {
6831
+ throw new Error(`Failed to disable deadlock detection: ${e === null || e === void 0 ? void 0 : e.message}`);
6832
+ }
6833
+ }
6834
+ }
6835
+ }
6836
+ /**
6837
+ * Returns `true` if deadlock detection is enabled.
6838
+ *
6839
+ * See
6840
+ * {@link Ditto.disableDeadlockDetection | Ditto.disableDeadlockDetection()}
6841
+ * for more information.
6842
+ *
6843
+ * This method always returns `false` in the browser where deadlock detection
6844
+ * is not available.
6845
+ *
6846
+ * @returns `true` if deadlock detection is enabled
6847
+ */
6848
+ static hasDeadlockDetection() {
6849
+ {
6850
+ return getDeadlockTimeout() !== 0;
6851
+ }
6852
+ }
6771
6853
  /**
6772
6854
  * Check if the current environment supports running Ditto.
6773
6855
  *
@@ -6779,7 +6861,7 @@ class Ditto {
6779
6861
  *
6780
6862
  * Internet Explorer is not supported.
6781
6863
  *
6782
- * @returns true if the environment is supported
6864
+ * @returns `true` if the environment is supported
6783
6865
  */
6784
6866
  static isEnvironmentSupported() {
6785
6867
  // From https://stackoverflow.com/questions/21825157/internet-explorer-11-detection
@@ -7130,6 +7212,31 @@ const checkAPIs = (_globalObject) => {
7130
7212
  const requiredBrowserAPIs = ['BigInt', 'WeakRef', 'FinalizationRegistry'];
7131
7213
  const globalObject = _globalObject || globalThis || global || window;
7132
7214
  return requiredBrowserAPIs.every((apiName) => !!globalObject[apiName]);
7215
+ };
7216
+ /**
7217
+ * Disable deadlock timeout when Node.js is running with `--inspect` parameter.
7218
+ *
7219
+ * This heuristic is not failsafe as debugging mode can also be enabled by
7220
+ * sending a `SIGUSR1` signal to the process.
7221
+ *
7222
+ * @internal
7223
+ */
7224
+ const disableDeadlockTimeoutWhenDebugging = () => {
7225
+ var _a, _b;
7226
+ {
7227
+ const hasInspector = process && ((_a = process === null || process === void 0 ? void 0 : process.execArgv) === null || _a === void 0 ? void 0 : _a.some((arg) => arg.includes('--inspect') || arg.includes('--debug')));
7228
+ // @ts-ignore - v8debug may be undefined
7229
+ const hasLegacyDebugMode = (process && ((_b = process === null || process === void 0 ? void 0 : process.execArgv) === null || _b === void 0 ? void 0 : _b.some((arg) => arg.includes('--debug')))) || typeof v8debug === 'object';
7230
+ if (hasInspector || hasLegacyDebugMode) {
7231
+ try {
7232
+ setDeadlockTimeout(0);
7233
+ Logger.warning('Detected Node running with inspector enabled, disabling deadlock timeout.');
7234
+ }
7235
+ catch (e) {
7236
+ Logger.error(`Detected Node running with inspector enabled but failed to disable deadlock timeout: ${e === null || e === void 0 ? void 0 : e.message}`);
7237
+ }
7238
+ }
7239
+ }
7133
7240
  };
7134
7241
 
7135
7242
  /**
@@ -7224,6 +7331,7 @@ exports.WriteTransactionPendingCursorOperation = WriteTransactionPendingCursorOp
7224
7331
  exports.WriteTransactionPendingIDSpecificOperation = WriteTransactionPendingIDSpecificOperation;
7225
7332
  exports.addressToString = addressToString;
7226
7333
  exports.checkAPIs = checkAPIs;
7334
+ exports.disableDeadlockTimeoutWhenDebugging = disableDeadlockTimeoutWhenDebugging;
7227
7335
  exports.getBridgeLoad = getBridgeLoad;
7228
7336
  exports.init = init;
7229
7337
  exports.validateDocumentIDCBOR = validateDocumentIDCBOR;
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dittolive/ditto",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "description": "Ditto is a cross-platform embeddable NoSQL database that can sync with or without an internet connection.",
5
5
  "homepage": "https://ditto.live",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
package/types/ditto.d.ts CHANGED
@@ -1919,6 +1919,36 @@ declare class Ditto {
1919
1919
  * @see {@link Ditto.path}
1920
1920
  */
1921
1921
  constructor(identity?: Identity, path?: string);
1922
+ /**
1923
+ * Don't terminate the process when callbacks are pending for a long time.
1924
+ *
1925
+ * Some methods in the Ditto library accept asynchronous functions as callback
1926
+ * parameters. If these asynchronous functions do not resolve within a certain
1927
+ * period of time after having been invoked by Ditto, deadlock detection gets
1928
+ * triggered, resulting in the termination of the process.
1929
+ *
1930
+ * When Ditto is executed in a Node.js environment with an interactive
1931
+ * debugger attached, this deadlock detection might get activated upon
1932
+ * encountering a breakpoint. Calling `Ditto.disableDeadlockDetection()`
1933
+ * disables this behavior, thus allowing the use of an interactive debugger
1934
+ * without triggering the deadlock detection.
1935
+ *
1936
+ * This feature is not available in the browser.
1937
+ */
1938
+ static disableDeadlockDetection(): void;
1939
+ /**
1940
+ * Returns `true` if deadlock detection is enabled.
1941
+ *
1942
+ * See
1943
+ * {@link Ditto.disableDeadlockDetection | Ditto.disableDeadlockDetection()}
1944
+ * for more information.
1945
+ *
1946
+ * This method always returns `false` in the browser where deadlock detection
1947
+ * is not available.
1948
+ *
1949
+ * @returns `true` if deadlock detection is enabled
1950
+ */
1951
+ static hasDeadlockDetection(): boolean;
1922
1952
  /**
1923
1953
  * Check if the current environment supports running Ditto.
1924
1954
  *
@@ -1930,7 +1960,7 @@ declare class Ditto {
1930
1960
  *
1931
1961
  * Internet Explorer is not supported.
1932
1962
  *
1933
- * @returns true if the environment is supported
1963
+ * @returns `true` if the environment is supported
1934
1964
  */
1935
1965
  static isEnvironmentSupported(): boolean;
1936
1966
  /**
@@ -2109,6 +2139,15 @@ declare class Ditto {
2109
2139
  }
2110
2140
  /** @internal */
2111
2141
  declare const checkAPIs: (_globalObject?: Window | typeof globalThis) => boolean;
2142
+ /**
2143
+ * Disable deadlock timeout when Node.js is running with `--inspect` parameter.
2144
+ *
2145
+ * This heuristic is not failsafe as debugging mode can also be enabled by
2146
+ * sending a `SIGUSR1` signal to the process.
2147
+ *
2148
+ * @internal
2149
+ */
2150
+ declare const disableDeadlockTimeoutWhenDebugging: () => void;
2112
2151
 
2113
2152
  /**
2114
2153
  * Represents an attachment and can be used to insert the associated attachment
@@ -3023,5 +3062,5 @@ declare class CBOR {
3023
3062
  static decode(data: Uint8Array): any;
3024
3063
  }
3025
3064
 
3026
- export { Address, Attachment, AttachmentFetchEvent, AttachmentFetchEventCompleted, AttachmentFetchEventDeleted, AttachmentFetchEventProgress, AttachmentFetchEventType, AttachmentFetcher, AttachmentToken, AuthenticationHandler, AuthenticationStatus, Authenticator, BasePendingCursorOperation, BasePendingIDSpecificOperation, CBOR, Collection, CollectionInterface, CollectionsEvent, CollectionsEventParams, CollectionsObservationHandler, ConditionSource, Connection, ConnectionType, Counter, CustomLogCallback, Ditto, Document, DocumentID, DocumentIDValue, DocumentPath, DocumentValue, ExperimentalStore, Identity, IdentityManual, IdentityOfflinePlayground, IdentityOnlinePlayground, IdentityOnlineWithAuthentication, IdentitySharedKey, IdentityTypesRequiringOfflineLicenseToken, InitOptions, KeepAlive, LiveQuery, LiveQueryEvent, LiveQueryEventInitial, LiveQueryEventUpdate, LiveQueryEventUpdateParams, LiveQueryMove, LogLevel, Logger, MutableCounter, MutableDocument, MutableDocumentPath, MutableRegister, NotAvailableAuthenticator, Observer, ObserverOptions, OnlineAuthenticator, Peer, PendingCollectionsOperation, PendingCursorOperation, PendingIDSpecificOperation, Presence, PresenceConnectionType, PresenceGraph, QueryArguments, QueryObservationHandler, Register, RemotePeer, SingleDocumentLiveQueryEvent, SingleObservationHandler, SortDirection, Store, Subscription, TransportCondition, TransportConfig, TransportConfigConnect, TransportConfigGlobal, TransportConfigLan, TransportConfigListen, TransportConfigListenHTTP, TransportConfigListenTCP, TransportConfigPeerToPeer, UpdateResult, UpdateResultType, UpdateResultsMap, UpsertOptions, Value, WebAssemblyModule, WriteStrategy, WriteTransaction, WriteTransactionCollection, WriteTransactionPendingCursorOperation, WriteTransactionPendingIDSpecificOperation, WriteTransactionResult, addressToString, checkAPIs, getBridgeLoad, init, validateDocumentIDCBOR, validateDocumentIDValue };
3065
+ export { Address, Attachment, AttachmentFetchEvent, AttachmentFetchEventCompleted, AttachmentFetchEventDeleted, AttachmentFetchEventProgress, AttachmentFetchEventType, AttachmentFetcher, AttachmentToken, AuthenticationHandler, AuthenticationStatus, Authenticator, BasePendingCursorOperation, BasePendingIDSpecificOperation, CBOR, Collection, CollectionInterface, CollectionsEvent, CollectionsEventParams, CollectionsObservationHandler, ConditionSource, Connection, ConnectionType, Counter, CustomLogCallback, Ditto, Document, DocumentID, DocumentIDValue, DocumentPath, DocumentValue, ExperimentalStore, Identity, IdentityManual, IdentityOfflinePlayground, IdentityOnlinePlayground, IdentityOnlineWithAuthentication, IdentitySharedKey, IdentityTypesRequiringOfflineLicenseToken, InitOptions, KeepAlive, LiveQuery, LiveQueryEvent, LiveQueryEventInitial, LiveQueryEventUpdate, LiveQueryEventUpdateParams, LiveQueryMove, LogLevel, Logger, MutableCounter, MutableDocument, MutableDocumentPath, MutableRegister, NotAvailableAuthenticator, Observer, ObserverOptions, OnlineAuthenticator, Peer, PendingCollectionsOperation, PendingCursorOperation, PendingIDSpecificOperation, Presence, PresenceConnectionType, PresenceGraph, QueryArguments, QueryObservationHandler, Register, RemotePeer, SingleDocumentLiveQueryEvent, SingleObservationHandler, SortDirection, Store, Subscription, TransportCondition, TransportConfig, TransportConfigConnect, TransportConfigGlobal, TransportConfigLan, TransportConfigListen, TransportConfigListenHTTP, TransportConfigListenTCP, TransportConfigPeerToPeer, UpdateResult, UpdateResultType, UpdateResultsMap, UpsertOptions, Value, WebAssemblyModule, WriteStrategy, WriteTransaction, WriteTransactionCollection, WriteTransactionPendingCursorOperation, WriteTransactionPendingIDSpecificOperation, WriteTransactionResult, addressToString, checkAPIs, disableDeadlockTimeoutWhenDebugging, getBridgeLoad, init, validateDocumentIDCBOR, validateDocumentIDValue };
3027
3066
  //# sourceMappingURL=ditto.d.ts.map