@dittolive/ditto 4.7.4 → 4.7.5-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/node/ditto.cjs.js +1 -1
- package/node/ditto.darwin-arm64.node +0 -0
- package/node/ditto.darwin-x64.node +0 -0
- package/node/ditto.linux-arm.node +0 -0
- package/node/ditto.linux-arm64.node +0 -0
- package/node/ditto.linux-x64.node +0 -0
- package/node/ditto.win32-x64.node +0 -0
- package/node/transports.darwin-arm64.node +0 -0
- package/node/transports.darwin-x64.node +0 -0
- package/package.json +2 -5
- package/web/ditto.es6.js +1 -1
- package/web/ditto.umd.js +1 -1
- package/web/ditto.wasm +0 -0
- package/DittoReactNative.podspec +0 -27
- package/react-native/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/react-native/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/react-native/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/react-native/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/react-native/android/.gradle/8.9/gc.properties +0 -0
- package/react-native/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/react-native/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/react-native/android/.gradle/vcs-1/gc.properties +0 -0
- package/react-native/android/CMakeLists.txt +0 -36
- package/react-native/android/build.gradle +0 -190
- package/react-native/android/cpp-adapter.cpp +0 -259
- package/react-native/android/gradle.properties +0 -5
- package/react-native/android/src/main/AndroidManifest.xml +0 -4
- package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.java +0 -120
- package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKPackage.java +0 -28
- package/react-native/cpp/include/Arc.hpp +0 -159
- package/react-native/cpp/include/Attachment.h +0 -20
- package/react-native/cpp/include/Authentication.h +0 -23
- package/react-native/cpp/include/Collection.h +0 -13
- package/react-native/cpp/include/ConnectionRequest.h +0 -18
- package/react-native/cpp/include/DQL.h +0 -21
- package/react-native/cpp/include/Document.h +0 -17
- package/react-native/cpp/include/FFIUtils.h +0 -16
- package/react-native/cpp/include/IO.h +0 -13
- package/react-native/cpp/include/Identity.h +0 -17
- package/react-native/cpp/include/Lifecycle.h +0 -16
- package/react-native/cpp/include/LiveQuery.h +0 -17
- package/react-native/cpp/include/Logger.h +0 -22
- package/react-native/cpp/include/Misc.h +0 -30
- package/react-native/cpp/include/Presence.h +0 -18
- package/react-native/cpp/include/SmallPeerInfo.h +0 -19
- package/react-native/cpp/include/Transports.h +0 -25
- package/react-native/cpp/include/TypedArray.hpp +0 -167
- package/react-native/cpp/include/Utils.h +0 -70
- package/react-native/cpp/include/main.h +0 -10
- package/react-native/cpp/src/Attachment.cpp +0 -272
- package/react-native/cpp/src/Authentication.cpp +0 -227
- package/react-native/cpp/src/Collection.cpp +0 -56
- package/react-native/cpp/src/ConnectionRequest.cpp +0 -123
- package/react-native/cpp/src/DQL.cpp +0 -256
- package/react-native/cpp/src/Document.cpp +0 -146
- package/react-native/cpp/src/FFIUtils.cpp +0 -122
- package/react-native/cpp/src/IO.cpp +0 -35
- package/react-native/cpp/src/Identity.cpp +0 -122
- package/react-native/cpp/src/Lifecycle.cpp +0 -93
- package/react-native/cpp/src/LiveQuery.cpp +0 -63
- package/react-native/cpp/src/Logger.cpp +0 -199
- package/react-native/cpp/src/Misc.cpp +0 -322
- package/react-native/cpp/src/Presence.cpp +0 -166
- package/react-native/cpp/src/SmallPeerInfo.cpp +0 -142
- package/react-native/cpp/src/Transports.cpp +0 -275
- package/react-native/cpp/src/TypedArray.cpp +0 -303
- package/react-native/cpp/src/Utils.cpp +0 -139
- package/react-native/cpp/src/main.cpp +0 -178
- package/react-native/dittoffi/dittoffi.h +0 -4873
- package/react-native/dittoffi/ifaddrs.cpp +0 -385
- package/react-native/dittoffi/ifaddrs.h +0 -206
- package/react-native/ios/DittoRNSDK.h +0 -7
- package/react-native/ios/DittoRNSDK.mm +0 -159
- package/react-native/ios/YeetJSIUtils.h +0 -60
- package/react-native/ios/YeetJSIUtils.mm +0 -196
- package/react-native/lib/commonjs/ditto.rn.js +0 -93
- package/react-native/lib/commonjs/ditto.rn.js.map +0 -1
- package/react-native/lib/commonjs/index.js +0 -61
- package/react-native/lib/commonjs/index.js.map +0 -1
- package/react-native/lib/module/ditto.rn.js +0 -89
- package/react-native/lib/module/ditto.rn.js.map +0 -1
- package/react-native/lib/module/index.js +0 -27
- package/react-native/lib/module/index.js.map +0 -1
- package/react-native/lib/typescript/ditto.rn.d.ts +0 -15
- package/react-native/lib/typescript/ditto.rn.d.ts.map +0 -1
- package/react-native/lib/typescript/index.d.ts +0 -1
- package/react-native/lib/typescript/index.d.ts.map +0 -1
- package/react-native/src/ditto.rn.ts +0 -123
- package/react-native/src/environment/environment.fallback.ts +0 -4
- package/react-native/src/index.ts +0 -29
- package/react-native/src/sources/@cbor-redux.ts +0 -2
- package/react-native/src/sources/@ditto.core.ts +0 -1
- package/react-native/src/sources/@environment.ts +0 -1
- package/react-native/src/sources/attachment-fetch-event.ts +0 -54
- package/react-native/src/sources/attachment-fetcher-manager.ts +0 -145
- package/react-native/src/sources/attachment-fetcher.ts +0 -265
- package/react-native/src/sources/attachment-token.ts +0 -129
- package/react-native/src/sources/attachment.ts +0 -121
- package/react-native/src/sources/augment.ts +0 -108
- package/react-native/src/sources/authenticator.ts +0 -314
- package/react-native/src/sources/base-pending-cursor-operation.ts +0 -255
- package/react-native/src/sources/base-pending-id-specific-operation.ts +0 -112
- package/react-native/src/sources/bridge.ts +0 -557
- package/react-native/src/sources/build-time-constants.ts +0 -8
- package/react-native/src/sources/cbor.ts +0 -20
- package/react-native/src/sources/collection-interface.ts +0 -73
- package/react-native/src/sources/collection.ts +0 -219
- package/react-native/src/sources/collections-event.ts +0 -99
- package/react-native/src/sources/connection-request.ts +0 -142
- package/react-native/src/sources/counter.ts +0 -82
- package/react-native/src/sources/ditto.ts +0 -991
- package/react-native/src/sources/document-id.ts +0 -163
- package/react-native/src/sources/document-path.ts +0 -308
- package/react-native/src/sources/document.ts +0 -237
- package/react-native/src/sources/epilogue.ts +0 -32
- package/react-native/src/sources/error-codes.ts +0 -114
- package/react-native/src/sources/error.ts +0 -256
- package/react-native/src/sources/essentials.ts +0 -81
- package/react-native/src/sources/ffi-error.ts +0 -134
- package/react-native/src/sources/ffi.ts +0 -2190
- package/react-native/src/sources/identity.ts +0 -163
- package/react-native/src/sources/init.ts +0 -71
- package/react-native/src/sources/internal.ts +0 -143
- package/react-native/src/sources/keep-alive.ts +0 -73
- package/react-native/src/sources/key-path.ts +0 -198
- package/react-native/src/sources/live-query-event.ts +0 -208
- package/react-native/src/sources/live-query-manager.ts +0 -110
- package/react-native/src/sources/live-query.ts +0 -167
- package/react-native/src/sources/logger.ts +0 -196
- package/react-native/src/sources/main.ts +0 -61
- package/react-native/src/sources/observer-manager.ts +0 -185
- package/react-native/src/sources/observer.ts +0 -79
- package/react-native/src/sources/pending-collections-operation.ts +0 -241
- package/react-native/src/sources/pending-cursor-operation.ts +0 -218
- package/react-native/src/sources/pending-id-specific-operation.ts +0 -218
- package/react-native/src/sources/presence-manager.ts +0 -170
- package/react-native/src/sources/presence.ts +0 -427
- package/react-native/src/sources/query-result-item.ts +0 -131
- package/react-native/src/sources/query-result.ts +0 -55
- package/react-native/src/sources/register.ts +0 -95
- package/react-native/src/sources/small-peer-info.ts +0 -166
- package/react-native/src/sources/static-tcp-client.ts +0 -8
- package/react-native/src/sources/store-observer.ts +0 -170
- package/react-native/src/sources/store.ts +0 -630
- package/react-native/src/sources/subscription-manager.ts +0 -99
- package/react-native/src/sources/subscription.ts +0 -89
- package/react-native/src/sources/sync-subscription.ts +0 -90
- package/react-native/src/sources/sync.ts +0 -561
- package/react-native/src/sources/test-helpers.ts +0 -24
- package/react-native/src/sources/transport-conditions-manager.ts +0 -104
- package/react-native/src/sources/transport-config.ts +0 -430
- package/react-native/src/sources/update-result.ts +0 -66
- package/react-native/src/sources/update-results-map.ts +0 -65
- package/react-native/src/sources/websocket-client.ts +0 -7
- package/react-native/src/sources/write-transaction-collection.ts +0 -122
- package/react-native/src/sources/write-transaction-pending-cursor-operation.ts +0 -101
- package/react-native/src/sources/write-transaction-pending-id-specific-operation.ts +0 -74
- package/react-native/src/sources/write-transaction.ts +0 -121
- package/react-native.config.js +0 -9
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as FFI from './ffi'
|
|
6
|
-
import { Bridge } from './bridge'
|
|
7
|
-
import { Logger } from './logger'
|
|
8
|
-
|
|
9
|
-
import type { Document } from './document'
|
|
10
|
-
|
|
11
|
-
// -----------------------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* An object that describes how a document's position in a live query's list of
|
|
15
|
-
* matching documents has changed since the previous live query event.
|
|
16
|
-
*/
|
|
17
|
-
export interface LiveQueryMove {
|
|
18
|
-
/**
|
|
19
|
-
* The index of the document in the list of matching documents from the
|
|
20
|
-
* previous live query event.
|
|
21
|
-
*/
|
|
22
|
-
readonly from: number
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The index of the document in the list of matching documents from the new
|
|
26
|
-
* live query event.
|
|
27
|
-
*/
|
|
28
|
-
readonly to: number
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// -----------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
/** @internal */
|
|
34
|
-
export interface LiveQueryEventUpdateParams {
|
|
35
|
-
oldDocuments: Document[]
|
|
36
|
-
insertions: number[]
|
|
37
|
-
deletions: number[]
|
|
38
|
-
updates: number[]
|
|
39
|
-
moves: LiveQueryMove[]
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// -----------------------------------------------------------------------------
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* First event fired immediately after registering a live query without any
|
|
46
|
-
* mutations. All subsequent events are of type {@link LiveQueryEventUpdate}.
|
|
47
|
-
*/
|
|
48
|
-
export class LiveQueryEventInitial {
|
|
49
|
-
/**
|
|
50
|
-
* Whether or not this is the initial event being delivered. Always `true`
|
|
51
|
-
* for `LiveQueryEventInitial`.
|
|
52
|
-
*/
|
|
53
|
-
readonly isInitial = true
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Returns a hash that represents the set of matching documents.
|
|
57
|
-
*
|
|
58
|
-
* @deprecated use {@link Document.hash | Document.hash()} instead.
|
|
59
|
-
*/
|
|
60
|
-
hash(documents: Document[]): BigInt {
|
|
61
|
-
Logger.warning('LiveQueryEventInitial.hash() is deprecated, use Document.hash() instead')
|
|
62
|
-
const documentHandles = Bridge.document.handlesFor(documents)
|
|
63
|
-
return FFI.documentsHash(documentHandles.deref())
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Returns a pattern of words that together create a mnemonic, which
|
|
68
|
-
* represents the set of matching documents.
|
|
69
|
-
*
|
|
70
|
-
* @deprecated use {@link Document.hashMnemonic | Document.hashMnemonic()} instead.
|
|
71
|
-
*/
|
|
72
|
-
hashMnemonic(documents: Document[]): string {
|
|
73
|
-
Logger.warning('LiveQueryEventInitial.hashMnemonic() is deprecated, use Document.hashMnemonic() instead')
|
|
74
|
-
const documentHandles = Bridge.document.handlesFor(documents)
|
|
75
|
-
return FFI.documentsHashMnemonic(documentHandles.deref())
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// -----------------------------------------------------------------------------
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Represents an update event describing all changes that occured for documents
|
|
83
|
-
* covered by a (live) query.
|
|
84
|
-
*/
|
|
85
|
-
export class LiveQueryEventUpdate {
|
|
86
|
-
/**
|
|
87
|
-
* Whether or not this is the initial event being delivered. Always `false`
|
|
88
|
-
* for `LiveQueryEventUpdate`.
|
|
89
|
-
*/
|
|
90
|
-
readonly isInitial = false
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* The documents that previously matched the query, before the latest event.
|
|
94
|
-
*/
|
|
95
|
-
readonly oldDocuments: Document[]
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* The indexes in the array of matching documents that accompany this event,
|
|
99
|
-
* which relate to a document that was not in the previous most recent list of
|
|
100
|
-
* matching documents.
|
|
101
|
-
*/
|
|
102
|
-
readonly insertions: number[]
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The indexes into the array {@link oldDocuments}, which relate to a document
|
|
106
|
-
* that was in the previous most recent list of matching documents but is no
|
|
107
|
-
* longer a matching document.
|
|
108
|
-
*/
|
|
109
|
-
readonly deletions: number[]
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* The indexes in the array of matching documents that accompany this event,
|
|
113
|
-
* which relate to a document that has been updated since the previous live
|
|
114
|
-
* query event.
|
|
115
|
-
*/
|
|
116
|
-
readonly updates: number[]
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Objects that describe how documents' positions in the list of matching
|
|
120
|
-
* documents have changed since the previous live query event.
|
|
121
|
-
*/
|
|
122
|
-
readonly moves: LiveQueryMove[]
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Returns a hash that represents the set of matching documents.
|
|
126
|
-
*
|
|
127
|
-
* @deprecated use {@link Document.hash | Document.hash()} instead.
|
|
128
|
-
*/
|
|
129
|
-
hash(documents: Document[]): BigInt {
|
|
130
|
-
Logger.warning('LiveQueryEventUpdate.hash() is deprecated, use Document.hash() instead')
|
|
131
|
-
const documentHandles = Bridge.document.handlesFor(documents)
|
|
132
|
-
return FFI.documentsHash(documentHandles.deref())
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Returns a pattern of words that together create a mnemonic, which
|
|
137
|
-
* represents the set of matching documents.
|
|
138
|
-
*
|
|
139
|
-
* @deprecated use {@link Document.hashMnemonic | Document.hashMnemonic()} instead.
|
|
140
|
-
*/
|
|
141
|
-
hashMnemonic(documents: Document[]): string {
|
|
142
|
-
Logger.warning('LiveQueryEventUpdate.hashMnemonic() is deprecated, use Document.hashMnemonic() instead')
|
|
143
|
-
const documentHandles = Bridge.document.handlesFor(documents)
|
|
144
|
-
return FFI.documentsHashMnemonic(documentHandles.deref())
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/** @internal */
|
|
148
|
-
constructor(params: LiveQueryEventUpdateParams) {
|
|
149
|
-
this.oldDocuments = params.oldDocuments
|
|
150
|
-
this.insertions = params.insertions
|
|
151
|
-
this.deletions = params.deletions
|
|
152
|
-
this.updates = params.updates
|
|
153
|
-
this.moves = params.moves
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// -----------------------------------------------------------------------------
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Represents events delivered by a {@link LiveQuery}, which can be initial
|
|
161
|
-
* (fired immediately upon registration) or an update (all subsequent events).
|
|
162
|
-
*/
|
|
163
|
-
export type LiveQueryEvent = LiveQueryEventInitial | LiveQueryEventUpdate
|
|
164
|
-
|
|
165
|
-
// -----------------------------------------------------------------------------
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Provides information about a live query event relating to a single document
|
|
169
|
-
* live query.
|
|
170
|
-
*/
|
|
171
|
-
export class SingleDocumentLiveQueryEvent {
|
|
172
|
-
/**
|
|
173
|
-
* Whether or not this is the initial event being delivered.
|
|
174
|
-
*/
|
|
175
|
-
readonly isInitial: boolean
|
|
176
|
-
|
|
177
|
-
/** The old representation of the document with the relveant document ID. */
|
|
178
|
-
readonly oldDocument?: Document
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Returns a hash that represents the set of matching documents.
|
|
182
|
-
*
|
|
183
|
-
* @deprecated use {@link Document.hash | Document.hash()} instead.
|
|
184
|
-
*/
|
|
185
|
-
hash(document: Document | null): BigInt {
|
|
186
|
-
Logger.warning('SingleDocumentLiveQueryEvent.hash() is deprecated, use Document.hash() instead')
|
|
187
|
-
const documentHandles = Bridge.document.handlesFor(document == null ? [] : [document])
|
|
188
|
-
return FFI.documentsHash(documentHandles.deref())
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Returns a pattern of words that together create a mnemonic, which
|
|
193
|
-
* represents the set of matching documents.
|
|
194
|
-
*
|
|
195
|
-
* @deprecated use {@link Document.hashMnemonic | Document.hashMnemonic()} instead.
|
|
196
|
-
*/
|
|
197
|
-
hashMnemonic(document: Document | null): string {
|
|
198
|
-
Logger.warning('SingleDocumentLiveQueryEvent.hashMnemonic() is deprecated, use Document.hashMnemonic() instead')
|
|
199
|
-
const documentHandles = Bridge.document.handlesFor(document == null ? [] : [document])
|
|
200
|
-
return FFI.documentsHashMnemonic(documentHandles.deref())
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/** @internal */
|
|
204
|
-
constructor(isInitial: boolean, oldDocument?: Document) {
|
|
205
|
-
this.isInitial = isInitial
|
|
206
|
-
this.oldDocument = oldDocument
|
|
207
|
-
}
|
|
208
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright © 2023 DittoLive Incorporated. All rights reserved.
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as FFI from './ffi'
|
|
6
|
-
import { Bridge } from './bridge'
|
|
7
|
-
import { KeepAlive } from './keep-alive'
|
|
8
|
-
import { LiveQuery } from './live-query'
|
|
9
|
-
import { step } from './internal'
|
|
10
|
-
|
|
11
|
-
import type { Ditto } from './ditto'
|
|
12
|
-
|
|
13
|
-
/** @internal */
|
|
14
|
-
export class LiveQueryManager {
|
|
15
|
-
readonly ditto: Ditto
|
|
16
|
-
readonly keepAlive: KeepAlive
|
|
17
|
-
|
|
18
|
-
/** @internal */
|
|
19
|
-
constructor(ditto: Ditto, keepAlive: KeepAlive) {
|
|
20
|
-
this.ditto = ditto
|
|
21
|
-
this.keepAlive = keepAlive
|
|
22
|
-
this.liveQueriesByID = {}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** @internal */
|
|
26
|
-
startLiveQuery(liveQuery: LiveQuery) {
|
|
27
|
-
const ditto = this.ditto
|
|
28
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto)
|
|
29
|
-
|
|
30
|
-
// REFACTOR: the starting closure runs detached from here which is a smell.
|
|
31
|
-
// Can we make this whole starting mechanism non-async? The culprit is
|
|
32
|
-
// the workaround for a zalgo with `ditto_live_query_start()` FFI function:
|
|
33
|
-
// It immediately triggers the live query handler making it run "in-line"
|
|
34
|
-
// when creating a live query, while subsequent invocations are async
|
|
35
|
-
// (by definition). This is a classic zalgo case. Fix by making
|
|
36
|
-
// `ditto_live_query_start()` trigger the first live query callback `async`,
|
|
37
|
-
// just like the subsequent ones.
|
|
38
|
-
|
|
39
|
-
void this.ditto.deferCloseAsync(async () => {
|
|
40
|
-
const liveQueryID = liveQuery.liveQueryID
|
|
41
|
-
if (!liveQueryID) {
|
|
42
|
-
throw new Error("Internal inconsistency, tried to add a live query that doesn't have a live query ID (probably stopped).")
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const existingLiveQuery = this.liveQueriesByID[liveQueryID]
|
|
46
|
-
if (existingLiveQuery) {
|
|
47
|
-
throw new Error('Internal inconsistency, tried to add a live query with an ID that has already been added.')
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const weakLiveQuery = new WeakRef(liveQuery)
|
|
51
|
-
this.liveQueriesByID[liveQueryID] = weakLiveQuery
|
|
52
|
-
this.finalizationRegistry.register(liveQuery, liveQueryID, this.finalize)
|
|
53
|
-
liveQuery.liveQueryManager = this
|
|
54
|
-
|
|
55
|
-
ditto.keepAlive.retain(`LiveQuery.${liveQueryID}`)
|
|
56
|
-
|
|
57
|
-
return new Promise<void>((resolve, reject) => {
|
|
58
|
-
// not awaited on purpose; let the invocation of the initial observation
|
|
59
|
-
// happen in a "fire-and-forget" / detached / escaping fashion, to be
|
|
60
|
-
// consistent with the subsequent invocations.
|
|
61
|
-
void step(async () => {
|
|
62
|
-
await FFI.liveQueryStart(dittoHandle.deref(), liveQueryID)
|
|
63
|
-
resolve()
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** @internal */
|
|
70
|
-
stopLiveQuery(liveQuery: LiveQuery) {
|
|
71
|
-
this.finalizationRegistry.unregister(liveQuery)
|
|
72
|
-
const liveQueryID = liveQuery.liveQueryID
|
|
73
|
-
if (!liveQueryID) {
|
|
74
|
-
throw new Error("Internal inconsistency, tried to remove a live query that doesn't have a live query ID (probably stopped).")
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
liveQuery.liveQueryManager = null
|
|
78
|
-
this.stopLiveQueryWithID(liveQueryID)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** @internal */
|
|
82
|
-
close() {
|
|
83
|
-
for (const liveQueryID in this.liveQueriesByID) {
|
|
84
|
-
const weakLiveQuery = this.liveQueriesByID[liveQueryID]
|
|
85
|
-
const liveQuery = weakLiveQuery.deref()
|
|
86
|
-
if (liveQuery) {
|
|
87
|
-
this.stopLiveQuery(liveQuery)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ------------------------------------------------------------ Private ------
|
|
93
|
-
|
|
94
|
-
private liveQueriesByID: { [key: number]: WeakRef<LiveQuery> }
|
|
95
|
-
private finalizationRegistry = new FinalizationRegistry(this.finalize)
|
|
96
|
-
|
|
97
|
-
private stopLiveQueryWithID(liveQueryID: number) {
|
|
98
|
-
const ditto = this.ditto
|
|
99
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto)
|
|
100
|
-
ditto.deferClose(() => {
|
|
101
|
-
FFI.liveQueryStop(dittoHandle.deref(), liveQueryID)
|
|
102
|
-
this.keepAlive.release(`LiveQuery.${liveQueryID}`)
|
|
103
|
-
delete this.liveQueriesByID[liveQueryID]
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private finalize(liveQueryID: number) {
|
|
108
|
-
this.stopLiveQueryWithID(liveQueryID)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as FFI from './ffi'
|
|
6
|
-
|
|
7
|
-
import { Bridge } from './bridge'
|
|
8
|
-
|
|
9
|
-
import { LiveQueryEventInitial } from './live-query-event'
|
|
10
|
-
import { LiveQueryEventUpdate } from './live-query-event'
|
|
11
|
-
|
|
12
|
-
import type { Collection } from './collection'
|
|
13
|
-
import type { QueryArguments } from './essentials'
|
|
14
|
-
import type { LiveQueryEvent } from './live-query-event'
|
|
15
|
-
import type { LiveQueryManager } from './live-query-manager'
|
|
16
|
-
import type { QueryObservationHandler } from './pending-cursor-operation'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* The type that is returned when calling
|
|
20
|
-
* {@link PendingCursorOperation.observeLocal | observeLocal()} on a
|
|
21
|
-
* {@link PendingCursorOperation} object. It handles the logic for calling the
|
|
22
|
-
* event handler that is provided to `observeLocal()` calls.
|
|
23
|
-
*
|
|
24
|
-
* Ditto will prevent the process from exiting as long as there are active live
|
|
25
|
-
* queries (not relevant when running in the browser).
|
|
26
|
-
*
|
|
27
|
-
* `LiveQuery` objects must be kept in scope for as long as you wish to have
|
|
28
|
-
* your event handler be called when there is an update to a document matching
|
|
29
|
-
* the query you provide. When you no longer want to receive updates about
|
|
30
|
-
* documents matching a query then you must call {@link stop | stop()}.
|
|
31
|
-
*/
|
|
32
|
-
export class LiveQuery {
|
|
33
|
-
/** The query that the live query is based on. */
|
|
34
|
-
readonly query: string
|
|
35
|
-
|
|
36
|
-
/** The arguments belonging to {@link query}. */
|
|
37
|
-
readonly queryArgs: QueryArguments | null
|
|
38
|
-
|
|
39
|
-
/** The name of the collection that the live query is based on. */
|
|
40
|
-
get collectionName(): string {
|
|
41
|
-
return this.collection.name
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Returns true if the receiver has been stopped. */
|
|
45
|
-
get isStopped(): boolean {
|
|
46
|
-
return !this.liveQueryManager
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Stop the live query from delivering updates.
|
|
51
|
-
*/
|
|
52
|
-
stop() {
|
|
53
|
-
if (!this.isStopped) {
|
|
54
|
-
;(this.liveQueryManager as LiveQueryManager).stopLiveQuery(this)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// ----------------------------------------------------------- Internal ------
|
|
59
|
-
|
|
60
|
-
/** @internal */
|
|
61
|
-
orderBys: FFI.OrderBy[]
|
|
62
|
-
|
|
63
|
-
/** @internal */
|
|
64
|
-
queryArgsCBOR: Uint8Array | null
|
|
65
|
-
|
|
66
|
-
/** @internal */
|
|
67
|
-
readonly limit: number
|
|
68
|
-
|
|
69
|
-
/** @internal */
|
|
70
|
-
readonly offset: number
|
|
71
|
-
|
|
72
|
-
/** @internal */
|
|
73
|
-
readonly collection: Collection
|
|
74
|
-
|
|
75
|
-
/** @internal */
|
|
76
|
-
readonly handler: QueryObservationHandler
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* This field is only populated while a live query is active and set to null
|
|
80
|
-
* when the live query is stopped.
|
|
81
|
-
*
|
|
82
|
-
* @internal
|
|
83
|
-
*/
|
|
84
|
-
liveQueryManager: LiveQueryManager | null
|
|
85
|
-
|
|
86
|
-
get liveQueryID(): number {
|
|
87
|
-
return this._liveQueryID
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** @internal */
|
|
91
|
-
constructor(query: string, queryArgs: QueryArguments | null, queryArgsCBOR: Uint8Array | null, orderBys: FFI.OrderBy[], limit: number, offset: number, collection: Collection, handler: QueryObservationHandler) {
|
|
92
|
-
// Query should be validated at this point.
|
|
93
|
-
this.query = query
|
|
94
|
-
this.queryArgs = queryArgs ? Object.freeze({ ...queryArgs }) : null
|
|
95
|
-
this.queryArgsCBOR = queryArgsCBOR
|
|
96
|
-
this.orderBys = orderBys
|
|
97
|
-
this.limit = limit
|
|
98
|
-
this.offset = offset
|
|
99
|
-
this.collection = collection
|
|
100
|
-
this.handler = handler
|
|
101
|
-
this.liveQueryManager = null
|
|
102
|
-
|
|
103
|
-
const collectionName = collection.name
|
|
104
|
-
const weakDitto = new WeakRef(collection.store.ditto)
|
|
105
|
-
|
|
106
|
-
let liveQueryID: number | undefined = undefined
|
|
107
|
-
const signalNext = async () => {
|
|
108
|
-
const ditto = weakDitto.deref()
|
|
109
|
-
if (!ditto) return
|
|
110
|
-
|
|
111
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto)
|
|
112
|
-
const dittoPointer = dittoHandle.derefOrNull()
|
|
113
|
-
if (!dittoPointer) return
|
|
114
|
-
|
|
115
|
-
return ditto.deferCloseAsync(async () => {
|
|
116
|
-
await FFI.liveQuerySignalAvailableNext(dittoPointer, liveQueryID as number)
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const ditto = collection.store.ditto
|
|
121
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto)
|
|
122
|
-
ditto.deferClose(() => {
|
|
123
|
-
liveQueryID = FFI.liveQueryRegister(dittoHandle.deref(), collectionName, query, queryArgsCBOR, this.orderBys, limit, offset, (cCBParams) => {
|
|
124
|
-
const documents = cCBParams.documents.map((ptr) => Bridge.document.bridge(ptr))
|
|
125
|
-
|
|
126
|
-
let event: LiveQueryEvent
|
|
127
|
-
if (cCBParams.is_initial) {
|
|
128
|
-
event = new LiveQueryEventInitial()
|
|
129
|
-
} else {
|
|
130
|
-
event = new LiveQueryEventUpdate({
|
|
131
|
-
oldDocuments: cCBParams.old_documents.map((ptr) => Bridge.document.bridge(ptr)),
|
|
132
|
-
insertions: cCBParams.insertions,
|
|
133
|
-
deletions: cCBParams.deletions,
|
|
134
|
-
updates: cCBParams.updates,
|
|
135
|
-
moves: cCBParams.moves.map((move) => ({ from: move[0], to: move[1] })),
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// We discard the return promise because error-handling is not supported.
|
|
140
|
-
void handler(documents, event, signalNext)
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
if (!liveQueryID) {
|
|
145
|
-
throw new Error("Internal inconsistency, couldn't create a valid live query ID.")
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this._liveQueryID = liveQueryID as number
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** @internal */
|
|
152
|
-
async signalNext() {
|
|
153
|
-
// IDEA: make this public?
|
|
154
|
-
const ditto = this.collection.store.ditto
|
|
155
|
-
const dittoHandle = Bridge.ditto.handleFor(ditto)
|
|
156
|
-
const dittoPointer = dittoHandle.derefOrNull()
|
|
157
|
-
if (!dittoPointer) return
|
|
158
|
-
|
|
159
|
-
return ditto.deferCloseAsync(async () => {
|
|
160
|
-
await FFI.liveQuerySignalAvailableNext(dittoHandle.deref(), this.liveQueryID)
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// ------------------------------------------------------------ Private ------
|
|
165
|
-
|
|
166
|
-
private _liveQueryID: number
|
|
167
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright © 2021 DittoLive Incorporated. All rights reserved.
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import * as Environment from './@environment'
|
|
6
|
-
import * as FFI from './ffi'
|
|
7
|
-
|
|
8
|
-
/** The log levels supported by Ditto. */
|
|
9
|
-
export type LogLevel = 'Error' | 'Warning' | 'Info' | 'Debug' | 'Verbose'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Closure that {@link Logger.setCustomLogCallback} can be set as a custom
|
|
13
|
-
* log callback on {@link Logger}.
|
|
14
|
-
*/
|
|
15
|
-
export type CustomLogCallback = (logLevel: LogLevel, message: string) => void
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Class with static methods to customize the logging behavior from Ditto and
|
|
19
|
-
* log messages with the Ditto logging infrastructure.
|
|
20
|
-
*/
|
|
21
|
-
export class Logger {
|
|
22
|
-
/**
|
|
23
|
-
* Registers a file path where logs will be written to, whenever Ditto wants
|
|
24
|
-
* to issue a log (on _top_ of emitting the log to the console).
|
|
25
|
-
*/
|
|
26
|
-
static get logFile(): string | undefined {
|
|
27
|
-
return this._logFile
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* On Node, registers a file path where logs will be written to, whenever
|
|
32
|
-
* Ditto wants to issue a log (on _top_ of emitting the log to the console).
|
|
33
|
-
* In the browser, this method has no effect.
|
|
34
|
-
*
|
|
35
|
-
* @param path can be `null`, in which case the current logging file, if any,
|
|
36
|
-
* is unregistered, otherwise, the file path must be within an already
|
|
37
|
-
* existing directory.
|
|
38
|
-
*/
|
|
39
|
-
static setLogFile(path: string | null) {
|
|
40
|
-
if (path) {
|
|
41
|
-
FFI.loggerSetLogFile(path)
|
|
42
|
-
this._logFile = path
|
|
43
|
-
} else {
|
|
44
|
-
FFI.loggerSetLogFile(undefined)
|
|
45
|
-
delete this._logFile
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Convenience method, takes the path part of the URL and calls
|
|
51
|
-
* {@link setLogFile | setLogFile()} with it.
|
|
52
|
-
*/
|
|
53
|
-
static setLogFileURL(url: URL | undefined) {
|
|
54
|
-
this.setLogFile(url?.pathname ?? null)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Whether the logger is currently enabled. */
|
|
58
|
-
static get enabled(): boolean {
|
|
59
|
-
return FFI.loggerEnabledGet()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Enables or disables logging. */
|
|
63
|
-
static set enabled(enabled: boolean) {
|
|
64
|
-
FFI.loggerEnabled(enabled)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Represents whether or not emojis should be used as the log level
|
|
69
|
-
* indicator in the logs.
|
|
70
|
-
*/
|
|
71
|
-
static get emojiLogLevelHeadingsEnabled(): boolean {
|
|
72
|
-
return FFI.loggerEmojiHeadingsEnabledGet()
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Represents whether or not emojis should be used as the log level
|
|
77
|
-
* indicator in the logs.
|
|
78
|
-
*/
|
|
79
|
-
static set emojiLogLevelHeadingsEnabled(emojiLogLevelHeadingsEnabled: boolean) {
|
|
80
|
-
FFI.loggerEmojiHeadingsEnabled(emojiLogLevelHeadingsEnabled)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* The minimum log level at which logs will be logged.
|
|
85
|
-
*
|
|
86
|
-
* For example if this is set to `Warning`, then only logs that are logged
|
|
87
|
-
* with the `Warning` or `Error` log levels will be shown.
|
|
88
|
-
*/
|
|
89
|
-
static get minimumLogLevel(): LogLevel {
|
|
90
|
-
return FFI.loggerMinimumLogLevelGet()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* The minimum log level at which logs will be logged.
|
|
95
|
-
*
|
|
96
|
-
* For example if this is set to `Warning`, then only logs that are logged
|
|
97
|
-
* with the `Warning` or `Error` log levels will be shown.
|
|
98
|
-
*/
|
|
99
|
-
static set minimumLogLevel(minimumLogLevel: LogLevel) {
|
|
100
|
-
FFI.loggerMinimumLogLevel(minimumLogLevel)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Returns the current custom log callback, `undefined` by default. See
|
|
105
|
-
* {@link setCustomLogCallback | setCustomLogCallback()} for a detailed
|
|
106
|
-
* description.
|
|
107
|
-
*/
|
|
108
|
-
static get customLogCallback(): CustomLogCallback | undefined {
|
|
109
|
-
return this._customLogCallback
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Registers a custom callback that will be called to report each log entry.
|
|
114
|
-
*
|
|
115
|
-
* @param callback function called for each log entry. `undefined` will
|
|
116
|
-
* unregister any previous callback and stop reporting log entries through
|
|
117
|
-
* callbacks.
|
|
118
|
-
*
|
|
119
|
-
* @throws {Error} if called in a React Native environment.
|
|
120
|
-
*/
|
|
121
|
-
static async setCustomLogCallback(callback: CustomLogCallback | undefined): Promise<void> {
|
|
122
|
-
if (Environment.isReactNativeBuild) {
|
|
123
|
-
throw new Error('Logger custom callback is currently not implemented for React Native.')
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (callback) {
|
|
127
|
-
await FFI.loggerSetCustomLogCb(callback)
|
|
128
|
-
this._customLogCallback = callback
|
|
129
|
-
} else {
|
|
130
|
-
await FFI.loggerSetCustomLogCb(null)
|
|
131
|
-
delete this._customLogCallback
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Logs the message for the given `level`.
|
|
137
|
-
*
|
|
138
|
-
* @see {@link error | error()}
|
|
139
|
-
* @see {@link warning | warning()}
|
|
140
|
-
* @see {@link info | info()}
|
|
141
|
-
* @see {@link debug | debug()}
|
|
142
|
-
* @see {@link verbose | verbose()}
|
|
143
|
-
*/
|
|
144
|
-
static log(level: LogLevel, message: string) {
|
|
145
|
-
FFI.log(level, message)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Convenience method, same as calling {@link log | log()} with
|
|
150
|
-
* {@link LogLevel} `Error`.
|
|
151
|
-
*/
|
|
152
|
-
static error(message: string) {
|
|
153
|
-
this.log('Error', message)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Convenience method, same as calling {@link log | log()} with
|
|
158
|
-
* {@link LogLevel} `Warning`.
|
|
159
|
-
*/
|
|
160
|
-
static warning(message: string) {
|
|
161
|
-
this.log('Warning', message)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Convenience method, same as calling {@link log | log()} with
|
|
166
|
-
* {@link LogLevel} `Info`.
|
|
167
|
-
*/
|
|
168
|
-
static info(message: string) {
|
|
169
|
-
this.log('Info', message)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Convenience method, same as calling {@link log | log()} with
|
|
174
|
-
* {@link LogLevel} `Debug`.
|
|
175
|
-
*/
|
|
176
|
-
static debug(message: string) {
|
|
177
|
-
this.log('Debug', message)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Convenience method, same as calling {@link log | log()} with
|
|
182
|
-
* {@link LogLevel} `Verbose`.
|
|
183
|
-
*/
|
|
184
|
-
static verbose(message: string) {
|
|
185
|
-
this.log('Verbose', message)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// ------------------------------------------------------------ Private ------
|
|
189
|
-
|
|
190
|
-
private static _logFile?: string
|
|
191
|
-
private static _customLogCallback?: CustomLogCallback
|
|
192
|
-
|
|
193
|
-
private constructor() {
|
|
194
|
-
throw new Error("Logger can't be instantiated, use its static properties & methods directly instead.")
|
|
195
|
-
}
|
|
196
|
-
}
|