@dittolive/ditto 4.7.3 → 4.7.4-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.
Files changed (152) hide show
  1. package/README.md +2 -2
  2. package/node/ditto.cjs.js +1 -1
  3. package/node/ditto.darwin-arm64.node +0 -0
  4. package/node/ditto.darwin-x64.node +0 -0
  5. package/node/ditto.linux-arm.node +0 -0
  6. package/node/ditto.linux-arm64.node +0 -0
  7. package/node/ditto.linux-x64.node +0 -0
  8. package/node/ditto.win32-x64.node +0 -0
  9. package/node/transports.darwin-arm64.node +0 -0
  10. package/node/transports.darwin-x64.node +0 -0
  11. package/package.json +10 -5
  12. package/web/ditto.es6.js +1 -1
  13. package/web/ditto.umd.js +1 -1
  14. package/web/ditto.wasm +0 -0
  15. package/DittoReactNative.podspec +0 -27
  16. package/react-native/android/CMakeLists.txt +0 -36
  17. package/react-native/android/build.gradle +0 -190
  18. package/react-native/android/cpp-adapter.cpp +0 -259
  19. package/react-native/android/gradle.properties +0 -5
  20. package/react-native/android/src/main/AndroidManifest.xml +0 -4
  21. package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKModule.java +0 -120
  22. package/react-native/android/src/main/java/com/dittolive/rnsdk/DittoRNSDKPackage.java +0 -28
  23. package/react-native/cpp/include/Arc.hpp +0 -159
  24. package/react-native/cpp/include/Attachment.h +0 -20
  25. package/react-native/cpp/include/Authentication.h +0 -23
  26. package/react-native/cpp/include/Collection.h +0 -13
  27. package/react-native/cpp/include/ConnectionRequest.h +0 -18
  28. package/react-native/cpp/include/DQL.h +0 -21
  29. package/react-native/cpp/include/Document.h +0 -17
  30. package/react-native/cpp/include/FFIUtils.h +0 -16
  31. package/react-native/cpp/include/IO.h +0 -13
  32. package/react-native/cpp/include/Identity.h +0 -17
  33. package/react-native/cpp/include/Lifecycle.h +0 -16
  34. package/react-native/cpp/include/LiveQuery.h +0 -17
  35. package/react-native/cpp/include/Logger.h +0 -22
  36. package/react-native/cpp/include/Misc.h +0 -30
  37. package/react-native/cpp/include/Presence.h +0 -18
  38. package/react-native/cpp/include/SmallPeerInfo.h +0 -19
  39. package/react-native/cpp/include/Transports.h +0 -25
  40. package/react-native/cpp/include/TypedArray.hpp +0 -167
  41. package/react-native/cpp/include/Utils.h +0 -70
  42. package/react-native/cpp/include/main.h +0 -10
  43. package/react-native/cpp/src/Attachment.cpp +0 -272
  44. package/react-native/cpp/src/Authentication.cpp +0 -227
  45. package/react-native/cpp/src/Collection.cpp +0 -56
  46. package/react-native/cpp/src/ConnectionRequest.cpp +0 -123
  47. package/react-native/cpp/src/DQL.cpp +0 -256
  48. package/react-native/cpp/src/Document.cpp +0 -146
  49. package/react-native/cpp/src/FFIUtils.cpp +0 -122
  50. package/react-native/cpp/src/IO.cpp +0 -35
  51. package/react-native/cpp/src/Identity.cpp +0 -122
  52. package/react-native/cpp/src/Lifecycle.cpp +0 -93
  53. package/react-native/cpp/src/LiveQuery.cpp +0 -63
  54. package/react-native/cpp/src/Logger.cpp +0 -199
  55. package/react-native/cpp/src/Misc.cpp +0 -322
  56. package/react-native/cpp/src/Presence.cpp +0 -166
  57. package/react-native/cpp/src/SmallPeerInfo.cpp +0 -142
  58. package/react-native/cpp/src/Transports.cpp +0 -275
  59. package/react-native/cpp/src/TypedArray.cpp +0 -303
  60. package/react-native/cpp/src/Utils.cpp +0 -139
  61. package/react-native/cpp/src/main.cpp +0 -178
  62. package/react-native/dittoffi/dittoffi.h +0 -4873
  63. package/react-native/dittoffi/ifaddrs.cpp +0 -385
  64. package/react-native/dittoffi/ifaddrs.h +0 -206
  65. package/react-native/ios/DittoRNSDK.h +0 -7
  66. package/react-native/ios/DittoRNSDK.mm +0 -159
  67. package/react-native/ios/YeetJSIUtils.h +0 -60
  68. package/react-native/ios/YeetJSIUtils.mm +0 -196
  69. package/react-native/lib/commonjs/ditto.rn.js +0 -93
  70. package/react-native/lib/commonjs/ditto.rn.js.map +0 -1
  71. package/react-native/lib/commonjs/index.js +0 -61
  72. package/react-native/lib/commonjs/index.js.map +0 -1
  73. package/react-native/lib/module/ditto.rn.js +0 -89
  74. package/react-native/lib/module/ditto.rn.js.map +0 -1
  75. package/react-native/lib/module/index.js +0 -27
  76. package/react-native/lib/module/index.js.map +0 -1
  77. package/react-native/lib/typescript/ditto.rn.d.ts +0 -15
  78. package/react-native/lib/typescript/ditto.rn.d.ts.map +0 -1
  79. package/react-native/lib/typescript/index.d.ts +0 -1
  80. package/react-native/lib/typescript/index.d.ts.map +0 -1
  81. package/react-native/src/ditto.rn.ts +0 -123
  82. package/react-native/src/environment/environment.fallback.ts +0 -4
  83. package/react-native/src/index.ts +0 -29
  84. package/react-native/src/sources/@cbor-redux.ts +0 -2
  85. package/react-native/src/sources/@ditto.core.ts +0 -1
  86. package/react-native/src/sources/@environment.ts +0 -1
  87. package/react-native/src/sources/attachment-fetch-event.ts +0 -54
  88. package/react-native/src/sources/attachment-fetcher-manager.ts +0 -145
  89. package/react-native/src/sources/attachment-fetcher.ts +0 -265
  90. package/react-native/src/sources/attachment-token.ts +0 -129
  91. package/react-native/src/sources/attachment.ts +0 -121
  92. package/react-native/src/sources/augment.ts +0 -108
  93. package/react-native/src/sources/authenticator.ts +0 -314
  94. package/react-native/src/sources/base-pending-cursor-operation.ts +0 -255
  95. package/react-native/src/sources/base-pending-id-specific-operation.ts +0 -112
  96. package/react-native/src/sources/bridge.ts +0 -557
  97. package/react-native/src/sources/build-time-constants.ts +0 -8
  98. package/react-native/src/sources/cbor.ts +0 -20
  99. package/react-native/src/sources/collection-interface.ts +0 -73
  100. package/react-native/src/sources/collection.ts +0 -219
  101. package/react-native/src/sources/collections-event.ts +0 -99
  102. package/react-native/src/sources/connection-request.ts +0 -142
  103. package/react-native/src/sources/counter.ts +0 -82
  104. package/react-native/src/sources/ditto.ts +0 -991
  105. package/react-native/src/sources/document-id.ts +0 -163
  106. package/react-native/src/sources/document-path.ts +0 -308
  107. package/react-native/src/sources/document.ts +0 -237
  108. package/react-native/src/sources/epilogue.ts +0 -32
  109. package/react-native/src/sources/error-codes.ts +0 -114
  110. package/react-native/src/sources/error.ts +0 -256
  111. package/react-native/src/sources/essentials.ts +0 -81
  112. package/react-native/src/sources/ffi-error.ts +0 -134
  113. package/react-native/src/sources/ffi.ts +0 -2190
  114. package/react-native/src/sources/identity.ts +0 -163
  115. package/react-native/src/sources/init.ts +0 -71
  116. package/react-native/src/sources/internal.ts +0 -143
  117. package/react-native/src/sources/keep-alive.ts +0 -73
  118. package/react-native/src/sources/key-path.ts +0 -198
  119. package/react-native/src/sources/live-query-event.ts +0 -208
  120. package/react-native/src/sources/live-query-manager.ts +0 -110
  121. package/react-native/src/sources/live-query.ts +0 -167
  122. package/react-native/src/sources/logger.ts +0 -196
  123. package/react-native/src/sources/main.ts +0 -61
  124. package/react-native/src/sources/observer-manager.ts +0 -185
  125. package/react-native/src/sources/observer.ts +0 -79
  126. package/react-native/src/sources/pending-collections-operation.ts +0 -241
  127. package/react-native/src/sources/pending-cursor-operation.ts +0 -218
  128. package/react-native/src/sources/pending-id-specific-operation.ts +0 -218
  129. package/react-native/src/sources/presence-manager.ts +0 -170
  130. package/react-native/src/sources/presence.ts +0 -427
  131. package/react-native/src/sources/query-result-item.ts +0 -131
  132. package/react-native/src/sources/query-result.ts +0 -55
  133. package/react-native/src/sources/register.ts +0 -95
  134. package/react-native/src/sources/small-peer-info.ts +0 -166
  135. package/react-native/src/sources/static-tcp-client.ts +0 -8
  136. package/react-native/src/sources/store-observer.ts +0 -170
  137. package/react-native/src/sources/store.ts +0 -630
  138. package/react-native/src/sources/subscription-manager.ts +0 -99
  139. package/react-native/src/sources/subscription.ts +0 -89
  140. package/react-native/src/sources/sync-subscription.ts +0 -90
  141. package/react-native/src/sources/sync.ts +0 -561
  142. package/react-native/src/sources/test-helpers.ts +0 -24
  143. package/react-native/src/sources/transport-conditions-manager.ts +0 -104
  144. package/react-native/src/sources/transport-config.ts +0 -430
  145. package/react-native/src/sources/update-result.ts +0 -66
  146. package/react-native/src/sources/update-results-map.ts +0 -65
  147. package/react-native/src/sources/websocket-client.ts +0 -7
  148. package/react-native/src/sources/write-transaction-collection.ts +0 -122
  149. package/react-native/src/sources/write-transaction-pending-cursor-operation.ts +0 -101
  150. package/react-native/src/sources/write-transaction-pending-id-specific-operation.ts +0 -74
  151. package/react-native/src/sources/write-transaction.ts +0 -121
  152. package/react-native.config.js +0 -9
@@ -1,427 +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 { ConnectionRequestHandler } from './connection-request'
8
- import { Logger } from './logger'
9
- import { Observer } from './observer'
10
- import { ObserverManager } from './observer-manager'
11
- import { DittoError, mapFFIErrors, mapFFIErrorsAsync } from './error'
12
-
13
- import type { Ditto } from './ditto'
14
- import type { ConnectionRequestAuthorization } from './connection-request'
15
-
16
- /** Types of connections that can be established between two peers. */
17
- export type ConnectionType = 'P2PWiFi' | 'WebSocket' | 'AccessPoint' | 'Bluetooth'
18
-
19
- // -----------------------------------------------------------------------------
20
-
21
- /**
22
- * An opaque address uniquely identifying another peer on the Ditto mesh
23
- * network.
24
- *
25
- * IMPORTANT: You should not rely on the individual components of the address,
26
- * those can change at any time. Please use
27
- * {@link addressToString | addressToString()} to compare individual addresses
28
- * with each other.
29
- */
30
- export type Address = {
31
- siteId: number | BigInt
32
- pubkey: Uint8Array
33
- }
34
-
35
- // -----------------------------------------------------------------------------
36
-
37
- /**
38
- * Returns a string representation of the given address. Use this function
39
- * to compare multiple addresses or whenever you need the address to be a key
40
- * in a hash object.
41
- */
42
- export function addressToString(address: Address) {
43
- return `${address.siteId}-${address.pubkey}`
44
- }
45
-
46
- // -----------------------------------------------------------------------------
47
-
48
- /** Represents a connection between two peers on the Ditto mesh network. */
49
- export type Connection = {
50
- /** Unique identifier for the connection.
51
- *
52
- * These IDs are stable for any two peer keys and a given connection type.
53
- *
54
- * **Example ID**
55
- *
56
- * "1<->2:Bluetooth"
57
- */
58
- id: string
59
-
60
- /** Type of transport enabling this connection. */
61
- connectionType: ConnectionType
62
-
63
- /**
64
- * Peer key of the peer at one end of the connection.
65
- *
66
- * This peer key is lexicographically smaller than `peer2`.
67
- */
68
- peer1: Uint8Array
69
-
70
- /**
71
- * Peer key of the peer at the other end of the connection.
72
- *
73
- * This peer key is lexicographically larger than `peer1`.
74
- */
75
- peer2: Uint8Array
76
-
77
- /*
78
- * Gets an estimate of distance to the remote peer. This value is inaccurate.
79
- * The environment, hardware, and several other factors can greatly affect
80
- * this value. It is currently derived from RSSI. Can be (yet) unknown and
81
- * therefore not set.
82
- */
83
- approximateDistanceInMeters?: number
84
- }
85
-
86
- // -----------------------------------------------------------------------------
87
-
88
- /** An instance of Ditto taking part in the Ditto mesh network. */
89
- export type Peer = {
90
- /**
91
- * Address to contact this peer via Ditto Bus, unique with a Ditto mesh
92
- * network.
93
- */
94
- address: Address
95
-
96
- /**
97
- * The peer key is a unique identifier for a given peer, equal to or derived
98
- * from the cryptographic public key used to authenticate it.
99
- *
100
- * NOTE: This will be be empty when a peer is not updated to the latest
101
- * version of the SDK.
102
- *
103
- * @deprecated Use {@link peerKeyString} instead.
104
- */
105
- peerKey: Uint8Array
106
-
107
- /**
108
- * The peer key is a unique identifier for a given peer, equal to or
109
- * derived from the cryptographic public key used to authenticate it.
110
- *
111
- * NOTE: This will be be empty when a peer is not updated to the latest
112
- * version of the SDK.
113
- */
114
- peerKeyString: string
115
-
116
- /**
117
- * Metadata associated with the peer, empty dictionary by default.
118
- *
119
- * Use `ditto.presence.setPeerMetadata()` or
120
- * `ditto.presence.setPeerMetadataJSONData()` to set this value.
121
- *
122
- * This will be empty when a peer is only connected via a WebSocket
123
- * connection.
124
- *
125
- * @see {@link Presence.peerMetadata | `ditto.presence.peerMetadata`} for
126
- * details on usage of metadata.
127
- */
128
- peerMetadata: Record<string, any>
129
-
130
- /**
131
- * Metadata associated with the peer by the identity service.
132
- *
133
- * Use an authentication webhook to set this value. See Ditto's online
134
- * documentation for more information on how to configure an authentication
135
- * webhook.
136
- */
137
- identityServiceMetadata: Record<string, any>
138
-
139
- /**
140
- * The human-readable device name of the peer. This defaults to the hostname
141
- * but can be manually set by the application developer of the other peer.
142
- * It is not necessarily unique.
143
- */
144
- deviceName: string
145
-
146
- /**
147
- * Currently active connections of the peer.
148
- */
149
- connections: Connection[]
150
-
151
- /**
152
- * Indicates whether the peer is connected to Ditto Cloud.
153
- */
154
- isConnectedToDittoCloud: boolean
155
-
156
- /** The operating system the peer is running on, `undefined` if (yet) unknown. */
157
- os?: string
158
-
159
- /** The Ditto SDK version the peer is running with, `undefined` if (yet) unknown. */
160
- dittoSDKVersion?: string
161
- }
162
-
163
- // -----------------------------------------------------------------------------
164
-
165
- /**
166
- * Represents the Ditto mesh network of peers and their connections between each
167
- * other. The `localPeer` is the entry point, all others are remote peers known
168
- * by the local peer (either directly or via other remote peers).
169
- */
170
- export type PresenceGraph = {
171
- /**
172
- * Returns the local peer (usually the peer that is represented by the
173
- * currently running Ditto instance). The `localPeer` is the entry point, all
174
- * others are remote peers known by the local peer (either directly or via
175
- * other remote peers).
176
- */
177
- localPeer: Peer
178
-
179
- /**
180
- * Returns all remote peers known by the `localPeer`, either directly or via
181
- * other remote peers.
182
- */
183
- remotePeers: Peer[]
184
-
185
- /**
186
- * Returns the underlying CBOR data if the presence graph has been initialized
187
- * with CBOR. All of Ditto API returning a presence graph has this property
188
- * set.
189
- */
190
- underlyingCBOR?: Uint8Array
191
- }
192
-
193
- // -----------------------------------------------------------------------------
194
-
195
- /**
196
- * The entrypoint for all actions that relate presence of other peers known by
197
- * the current peer, either directly or through other peers.
198
- *
199
- * You don't create one directly but can access it from a particular `Ditto`
200
- * instance via its `presence` property.
201
- */
202
- export class Presence {
203
- /** The Ditto instance this object belongs to. */
204
- readonly ditto: Ditto
205
-
206
- /**
207
- * Set this handler to control which peers in a Ditto mesh can connect to the
208
- * current peer.
209
- *
210
- * Each peer in a Ditto mesh will attempt to connect to other peers that it
211
- * can reach. By default, the mesh will try and establish connections that
212
- * optimize for the best overall connectivity between peers. However, you can
213
- * set this handler to assert some control over which peers you connect to.
214
- *
215
- * If set, this handler is called for every incoming connection request from a
216
- * remote peer and is passed the other peer's `peerKey`, `peerMetadata`, and
217
- * `identityServiceMetadata`. The handler can then accept or reject the
218
- * request by returning an according {@link ConnectionRequestAuthorization}
219
- * value. When the connection request is rejected, the remote peer may retry
220
- * the connection request after a short delay.
221
- *
222
- * Connection request handlers must reliably respond to requests within a
223
- * short time. If a handler takes too long to respond or throws an exception,
224
- * the connection request will be denied. The response timeout is currently 10
225
- * seconds but may be subject to change in future releases.
226
- *
227
- * @see {@link peerMetadata | peerMetadata()}
228
- */
229
- get connectionRequestHandler(): ConnectionRequestHandler | null {
230
- return this._connectionRequestHandler
231
- }
232
-
233
- /**
234
- * @throws TypeError: if the given handler is not a function.
235
- */
236
- set connectionRequestHandler(handler: ConnectionRequestHandler | null) {
237
- let wrappedHandler = null
238
-
239
- if (handler != null) {
240
- if (typeof handler !== 'function') {
241
- throw new TypeError(`Expected parameter 'handler' to be a function but got ${typeof handler} instead`)
242
- }
243
-
244
- wrappedHandler = async (connectionRequest: FFI.Pointer<FFI.FFIConnectionRequest>) => {
245
- const request = Bridge.connectionRequest.bridge(connectionRequest)
246
-
247
- // Any errors will be caught by ffi.ts and passed to `handleError` below
248
- const authorization = await handler(request)
249
-
250
- if (authorization !== 'allow' && authorization !== 'deny') {
251
- Logger.error(`The connection request handler must return "allow" or "deny" but returned "${authorization}" instead. The connection request will be denied.`)
252
- return 'Deny'
253
- }
254
-
255
- FFI.connectionRequestAuthorize(connectionRequest, authorization === 'allow' ? 'Allow' : 'Deny')
256
- }
257
- }
258
-
259
- this._connectionRequestHandler = handler
260
-
261
- const handleError = (error: any) => {
262
- Logger.error(`The connection request handler threw an error while handling a connection request, the connection request will be denied. ${error}`)
263
- }
264
-
265
- const dittoHandle = Bridge.ditto.handleFor(this.ditto)
266
- this.ditto.deferClose(() => {
267
- FFI.presenceSetConnectionRequestHandler(dittoHandle.deref(), wrappedHandler, handleError)
268
- })
269
- }
270
-
271
- /**
272
- * Returns the current presence graph capturing all known peers and
273
- * connections between them.
274
- */
275
- get graph(): PresenceGraph {
276
- const ditto = this.ditto
277
- const dittoHandle = Bridge.ditto.handleFor(ditto)
278
- return ditto.deferClose(() => {
279
- const graphJSONString = FFI.dittoPresenceV3(dittoHandle.deref())
280
- return JSON.parse(graphJSONString)
281
- })
282
- }
283
-
284
- /**
285
- * Metadata associated with the current peer. Other peers in the same mesh can
286
- * access this user-provided object of metadata via the presence {@link graph}
287
- * and when evaluating connection requests using
288
- * {@link connectionRequestHandler | connectionRequestHandler()}.
289
- *
290
- * This is not made available to peers only connected via WebSocket.
291
- *
292
- * Uses UTF-8 encoding.
293
- *
294
- * @see {@link peerMetadata | peerMetadata()} for a convenience property that
295
- * provides access to parsed metadata.
296
- */
297
- get peerMetadataJSONString(): string {
298
- const dittoHandle = Bridge.ditto.handleFor(this.ditto)
299
- return this.ditto.deferClose(() => {
300
- return mapFFIErrors(() => {
301
- return FFI.presencePeerMetadataJSON(dittoHandle.deref())
302
- })
303
- })
304
- }
305
-
306
- /**
307
- * Set arbitrary metadata to be associated with the current peer.
308
- *
309
- * The metadata must not exceed 4 KB in size when JSON-encoded.
310
- *
311
- * @param {string} jsonString: JSON-encoded metadata.
312
- *
313
- * @throws {@link DittoError} `validation/invalid-json`: if `jsonString` does
314
- * not contain valid JSON.
315
- *
316
- * @throws {@link DittoError} `validation/not-an-object`: if `jsonString` does
317
- * not contain an object.
318
- *
319
- * @throws {@link DittoError} `validation/size-limit-exceeded`: if the size
320
- * limit for `jsonString` has been exceeded.
321
- *
322
- * @see {@link peerMetadataJSONString | peerMetadataJSONString()} for details
323
- * on usage of metadata.
324
- */
325
- async setPeerMetadataJSONString(jsonString: string): Promise<void> {
326
- const dittoHandle = Bridge.ditto.handleFor(this.ditto)
327
- await this.ditto.deferCloseAsync(async () => {
328
- return mapFFIErrorsAsync(async () => {
329
- return FFI.presenceTrySetPeerMetadataJSON(dittoHandle.deref(), jsonString)
330
- })
331
- })
332
- }
333
-
334
- /**
335
- * This is a convenience property that wraps
336
- * {@link peerMetadataJSONString | peerMetadataJSONString()}.
337
- *
338
- * @see {@link peerMetadataJSONString | peerMetadataJSONString()} for details.
339
- */
340
- get peerMetadata(): Record<string, any> {
341
- return JSON.parse(this.peerMetadataJSONString)
342
- }
343
-
344
- /**
345
- * This is a convenience method that wraps
346
- * {@link setPeerMetadataJSONString | setPeerMetadataJSONString()}.
347
- *
348
- * @throws {@link DittoError} `validation/not-an-object`: if `peerMetadata` is
349
- * not an object.
350
- *
351
- * @throws {@link DittoError} `validation/not-json-compatible`: if
352
- * `peerMetadata` is not JSON serializable.
353
- *
354
- * @throws {@link DittoError} `validation/size-limit-exceeded`: if the size
355
- * limit for `peerMetadata` has been exceeded.
356
- *
357
- * @see {@link setPeerMetadataJSONString | setPeerMetadataJSONString()} for
358
- * details.
359
- */
360
- async setPeerMetadata(peerMetadata: Record<string, any>): Promise<void> {
361
- let jsonString: string
362
- try {
363
- jsonString = JSON.stringify(peerMetadata)
364
- } catch (error: any) {
365
- throw new DittoError('validation/not-json-compatible', `Failed encoding peer metadata to JSON. ${error}`)
366
- }
367
-
368
- await this.setPeerMetadataJSONString(jsonString)
369
- }
370
-
371
- /**
372
- * Request information about Ditto peers in range of this device.
373
- *
374
- * This method returns an observer which should be held as long as updates are
375
- * required. A newly registered observer will have a peers update delivered to
376
- * it immediately. From then on it will be invoked repeatedly when Ditto
377
- * devices come and go, or the active connections to them change.
378
- */
379
- observe(didChangeHandler: (presenceGraph: PresenceGraph) => void): Observer {
380
- const observerToken = this.observerManager.addObserver(didChangeHandler)
381
- const observer = new Observer(this.observerManager, observerToken, { stopsWhenFinalized: true })
382
-
383
- didChangeHandler(this.graph)
384
-
385
- return observer
386
- }
387
-
388
- // -----------------------------------------------------------------------------
389
-
390
- /** @internal */
391
- constructor(ditto: Ditto) {
392
- this.ditto = ditto
393
-
394
- this.observerManager = new ObserverManager('PresenceObservation', {
395
- keepAlive: ditto.keepAlive,
396
-
397
- register: (callback) => {
398
- const ditto = this.ditto
399
- const dittoHandle = Bridge.ditto.handleFor(ditto)
400
- ditto.deferClose(() => {
401
- FFI.dittoRegisterPresenceV3Callback(dittoHandle.deref(), callback)
402
- })
403
- },
404
-
405
- unregister: () => {
406
- const ditto = this.ditto
407
- const dittoHandle = Bridge.ditto.handleFor(ditto)
408
- void ditto.deferCloseAsync(async () => {
409
- return FFI.dittoClearPresenceV3Callback(dittoHandle.deref())
410
- })
411
- },
412
-
413
- process: (presenceGraphJSONString) => {
414
- const presenceGraph = JSON.parse(presenceGraphJSONString)
415
- return [presenceGraph]
416
- },
417
- })
418
- }
419
-
420
- /** @internal */
421
- close() {
422
- this.observerManager.close()
423
- }
424
-
425
- private observerManager: ObserverManager
426
- private _connectionRequestHandler: ConnectionRequestHandler | null = null
427
- }
@@ -1,131 +0,0 @@
1
- //
2
- // Copyright © 2023 DittoLive Incorporated. All rights reserved.
3
- //
4
-
5
- import * as FFI from './ffi'
6
- import { CBOR } from './cbor'
7
- import { Bridge } from './bridge'
8
- import { Document } from './document'
9
- import { customInspectRepresentation } from './internal'
10
-
11
- // Used to define a custom inspect function for Node.js that will be used when
12
- // the object is inspected with console.log() or util.inspect().
13
- const CUSTOM_INSPECT_SYMBOL = Symbol.for('nodejs.util.inspect.custom')
14
-
15
- /**
16
- * Represents a single match of a DQL query, similar to a “row” in SQL terms.
17
- * It’s a reference type serving as a “cursor”, allowing for efficient access of
18
- * the underlying data in various formats.
19
- *
20
- * The {@link QueryResultItem.value | value } property is lazily
21
- * materialized and kept in memory until it goes out of scope. To reduce the
22
- * memory footprint, structure your code such that items can be processed as a
23
- * stream, i.e. one by one (or in batches) and
24
- * {@link QueryResultItem.dematerialize | dematerialize() } them
25
- * right after use.
26
- */
27
- export class QueryResultItem {
28
- /**
29
- * Returns the content as a materialized object.
30
- *
31
- * The item's value is
32
- * {@link QueryResultItem.materialize | materialized() } on first access
33
- * and subsequently on each access after performing
34
- * {@link QueryResultItem.dematerialize | dematerialize() }. Once
35
- * materialized, the value is kept in memory until explicitly
36
- * {@link QueryResultItem.dematerialize | dematerialize() }-ed or the item
37
- * goes out of scope.
38
- *
39
- * Note: This property is very similar to {@link Document.value}.
40
- */
41
- get value(): any {
42
- this.materialize()
43
- if (this.materializedValue === undefined) {
44
- throw new Error('Internal Error: Materialized value is undefined')
45
- }
46
- return this.materializedValue
47
- }
48
-
49
- /**
50
- * Returns `true` if value is currently held materialized in memory, otherwise
51
- * returns `false`.
52
- *
53
- * See {@link QueryResultItem.materialize | materialize()} and
54
- * {@link QueryResultItem.dematerialize | dematerialize()}.
55
- */
56
- get isMaterialized(): boolean {
57
- return this.materializedValue !== undefined
58
- }
59
-
60
- /**
61
- * Loads the CBOR representation of the item's content, decodes it as an
62
- * object so it can be accessed via {@link QueryResultItem.value | value }.
63
- * Keeps the object in memory until
64
- * {@link QueryResultItem.dematerialize | dematerialize() } is called. No-op
65
- * if {@link QueryResultItem.value | value } is already materialized.
66
- */
67
- materialize(): void {
68
- if (!this.isMaterialized) {
69
- const cborValue = this.cborData()
70
- let materializedValue: any
71
- try {
72
- materializedValue = CBOR.decode(cborValue)
73
- } catch (error: any) {
74
- throw new Error(`Internal inconsistency: CBOR decoding error while materializing result item: ${error.message}`)
75
- }
76
-
77
- if (materializedValue === undefined) {
78
- throw new Error('Internal inconsistency: Materialized value is undefined')
79
- }
80
-
81
- this.materializedValue = materializedValue
82
- }
83
- }
84
-
85
- /**
86
- * Releases the materialized value from memory. No-op if item is not
87
- * materialized.
88
- */
89
- dematerialize(): void {
90
- this.materializedValue = undefined
91
- }
92
-
93
- /**
94
- * Returns the content of the item as CBOR data.
95
- *
96
- * Important: The returned CBOR data is not cached, make sure to call this
97
- * method once and keep it for as long as needed.
98
- */
99
- cborData(): Uint8Array {
100
- const resultItemHandle = Bridge.queryResultItem.handleFor(this)
101
- return FFI.queryResultItemCBOR(resultItemHandle.deref())
102
- }
103
-
104
- /**
105
- * Returns the content of the item as a JSON string.
106
- *
107
- * Important: The returned JSON string is not cached, make sure to call this
108
- * method once and keep it for as long as needed.
109
- */
110
- jsonString(): string {
111
- const resultItemHandle = Bridge.queryResultItem.handleFor(this)
112
- return FFI.queryResultItemJSON(resultItemHandle.deref())
113
- }
114
-
115
- // ----------------------------------------------------------- Internal ------
116
-
117
- /**
118
- * Defines a custom inspect representation for Node.js that will be used when
119
- * the object is inspected with console.log() or util.inspect().
120
- *
121
- * @internal
122
- */
123
- [CUSTOM_INSPECT_SYMBOL](_depth: number, _inspectOptions: any, inspect: any): string {
124
- return customInspectRepresentation(this, inspect)
125
- }
126
-
127
- private materializedValue: any
128
-
129
- /** @internal */
130
- constructor() {}
131
- }
@@ -1,55 +0,0 @@
1
- //
2
- // Copyright © 2023 DittoLive Incorporated. All rights reserved.
3
- //
4
- import * as FFI from './ffi'
5
-
6
- import { Bridge } from './bridge'
7
- import { QueryResultItem } from './query-result-item'
8
- import { DocumentID } from './document-id'
9
-
10
- import type { Store } from './store'
11
-
12
- /**
13
- * Represents results returned when executing a DQL query containing a
14
- * {@link QueryResultItem} for each match.
15
- *
16
- * More info, such as metrics, will be provided in the near future.
17
- */
18
- export class QueryResult {
19
- /**
20
- * Individual items matching a DQL query.
21
- */
22
- readonly items: QueryResultItem[]
23
-
24
- /**
25
- * IDs of documents that were mutated _locally_ by a _mutating_ DQL query
26
- * passed to {@link Store.execute | `execute()`}. Empty array if no documents
27
- * have been mutated.
28
- *
29
- * **Note: Query results received from a {@link StoreObserver} never contain
30
- * mutated document IDs because a store observer is always registered using a
31
- * non-mutating `SELECT` query.
32
- *
33
- * **Important:** The returned document IDs are not cached, make sure to call
34
- * this method once and keep the return value for as long as needed.
35
- *
36
- * @returns an array of document IDs
37
- */
38
- mutatedDocumentIDs(): DocumentID[] {
39
- const queryResultHandle = Bridge.queryResult.handleFor(this)
40
- const affectedCBORIDs = FFI.queryResultMutatedDocumentIDs(queryResultHandle.deref())
41
- return affectedCBORIDs.map((id) => new DocumentID(id, true))
42
- }
43
-
44
- // ----------------------------------------------------- Internal ------------
45
-
46
- /** @internal */
47
- constructor(queryResultPointer: FFI.Pointer<FFI.FFIQueryResult>) {
48
- if (queryResultPointer == null) {
49
- throw new Error('Internal inconsistency, failed to initialize query result without a response pointer')
50
- }
51
-
52
- const resultItems = FFI.queryResultItems(queryResultPointer)
53
- this.items = resultItems.map((r) => Bridge.queryResultItem.bridge(r))
54
- }
55
- }
@@ -1,95 +0,0 @@
1
- //
2
- // Copyright © 2022 DittoLive Incorporated. All rights reserved.
3
- //
4
-
5
- // NOTE: we use a token to detect private invocation of the constructor. This is
6
- // not secure and just to prevent accidental private invocation on the client
7
- // side.
8
- const privateToken = '@ditto.ff82dae89821c5ab822a8b539056bce4'
9
-
10
- /**
11
- * Represents a CRDT register that can be upserted as part of a document or
12
- * assigned to a property during an update of a document.
13
- */
14
- export class Register {
15
- /** Returns the value of the register. */
16
- get value(): any {
17
- return this['@ditto.value']
18
- }
19
-
20
- /**
21
- * Creates a new Register that can be used as part of a document's content.
22
- */
23
- constructor(value: any) {
24
- this['@ditto.value'] = value
25
- }
26
-
27
- /** @internal */
28
- static '@ditto.create'(mutableDocument, path, value) {
29
- const register = mutableDocument ? new (MutableRegister as any)(value, privateToken) : new Register(value)
30
- register['@ditto.mutableDocument'] = mutableDocument
31
- register['@ditto.path'] = path
32
- register['@ditto.value'] = value
33
- return register
34
- }
35
-
36
- /** @internal */
37
- protected '@ditto.mutableDocument': any
38
-
39
- /** @internal */
40
- protected '@ditto.path': any
41
-
42
- /** @internal */
43
- protected '@ditto.value': any
44
- }
45
-
46
- // -----------------------------------------------------------------------------
47
-
48
- /**
49
- * Represents a mutable CRDT register that can be set to a specific value when
50
- * updating a document.
51
- *
52
- * This class can't be instantiated directly, it's returned automatically for
53
- * any register property of a document within an update block via {@link MutableDocumentPath.register}.
54
- */
55
- export class MutableRegister extends Register {
56
- /** Returns the value of the register. */
57
- get value(): any {
58
- return super.value
59
- }
60
-
61
- /**
62
- * Convenience setter, equivalent to {@link set | set()}.
63
- */
64
- set value(value: any) {
65
- this.set(value)
66
- }
67
-
68
- /**
69
- * Sets the register to the provided value.
70
- *
71
- * Only valid within the `update` closure of
72
- * {@link PendingCursorOperation.update | PendingCursorOperation.update()} and
73
- * {@link PendingIDSpecificOperation.update | PendingIDSpecificOperation.update()},
74
- * otherwise an exception is thrown.
75
- */
76
- set(value: any) {
77
- const mutableDocument = this['@ditto.mutableDocument']
78
- const path = this['@ditto.path']
79
-
80
- mutableDocument.at(path)['@ditto.set'](value)
81
-
82
- // We also set the local value to make sure that the change is
83
- // reflected locally as well as in the underlying document.
84
- this['@ditto.value'] = value
85
- }
86
-
87
- /** @internal */
88
- constructor(value: any) {
89
- if (arguments[1] === privateToken) {
90
- super(value)
91
- } else {
92
- throw new Error(`MutableRegister constructor is for internal use only.`)
93
- }
94
- }
95
- }