datastore-api 1.1.2 → 1.5.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,38 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.5.0](https://github.com/mdornseif/datastore-api/compare/v1.4.0...v1.5.0) (2022-01-06)
6
+
7
+
8
+ ### Features
9
+
10
+ * provide _keyStr also in queries ([fe7e90b](https://github.com/mdornseif/datastore-api/commit/fe7e90b3011e08de552e1b4e35b1ad110efa6b1b))
11
+
12
+ ## [1.4.0](https://github.com/mdornseif/datastore-api/compare/v1.3.0...v1.4.0) (2022-01-04)
13
+
14
+
15
+ ### Features
16
+
17
+ * save() adds _keyStr the same way get() does ([f4f6452](https://github.com/mdornseif/datastore-api/commit/f4f6452c77046c0ee8d0b6ddfe2ec6744a4968bd))
18
+
19
+ ## [1.3.0](https://github.com/mdornseif/datastore-api/compare/v1.2.0...v1.3.0) (2022-01-03)
20
+
21
+
22
+ ### Features
23
+
24
+ * Set excludeLargeProperties by default. ([289cd28](https://github.com/mdornseif/datastore-api/commit/289cd289651b0c34f36098370b3dfbe249790c5a))
25
+
26
+ ## [1.2.0](https://github.com/mdornseif/datastore-api/compare/v1.1.3...v1.2.0) (2021-12-30)
27
+
28
+
29
+ ### Features
30
+
31
+ * add `query(... selection)` ([e9f8053](https://github.com/mdornseif/datastore-api/commit/e9f8053fa98f496e69ccf83e649e7c1502751f16))
32
+ * add KEYSYM ([d97eff0](https://github.com/mdornseif/datastore-api/commit/d97eff09f0c7dd60caa860eda45975438d369920))
33
+ * debug log; removed readonly from several types ([f1fcdb6](https://github.com/mdornseif/datastore-api/commit/f1fcdb62551c3c624fcfd67f550f40a5bbd38138))
34
+
35
+ ### [1.1.3](https://github.com/mdornseif/datastore-api/compare/v1.1.2...v1.1.3) (2021-12-29)
36
+
5
37
  ### [1.1.2](https://github.com/mdornseif/datastore-api/compare/v1.1.1...v1.1.2) (2021-12-29)
6
38
 
7
39
  ### [1.1.1](https://github.com/mdornseif/datastore-api/compare/v1.1.0...v1.1.1) (2021-12-29)
package/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ [![version](https://img.shields.io/npm/v/datastore-api.svg?style=flat-square)](https://npmjs.org/datastore-api)
2
+ [![license](https://img.shields.io/npm/l/datastore-api?color=%23007a1f&style=flat-square)](https://github.com/mdornseif/datastore-api/blob/master/LICENSE)
3
+ [![downloads](https://img.shields.io/npm/dm/datastore-api?style=flat-square&color=%23007a1f)](https://npmcharts.com/compare/datastore-api)
4
+
1
5
  # datastore-api
2
6
 
3
7
  Simplified, more consistent API for Google Cloud Datastore.
@@ -22,9 +26,9 @@ Main differences:
22
26
 
23
27
  Find the full documentation [here](http://mdornseif.io/datastore-api/classes/Dstore.html). In there also some of the idiosyncrasies of using the Datastore are explained.
24
28
 
25
- See [the API documentation](http://mdornseif.io/datastore-api/classes/Dstore.html) for Details.
29
+ See [the API documentation](http://mdornseif.io/datastore-api/classes/Dstore.html) for Details, [Github](https://github.com/mdornseif/datastore-api) for source.
26
30
 
27
- # See also
31
+ ## See also
28
32
 
29
33
  - Google Documentation
30
34
 
@@ -33,7 +37,7 @@ See [the API documentation](http://mdornseif.io/datastore-api/classes/Dstore.htm
33
37
  - Other [Hidden Auto-Generated Datastore API Documentation](https://googleapis.dev/nodejs/datastore/latest/) with better navigation. Seems to contain more on the lower level access.
34
38
  - [SDK Source](https://github.com/googleapis/nodejs-datastore)
35
39
  - [API reference](https://cloud.google.com/datastore/docs/reference/data/rpc) helps to understand under-documented SDK.
36
- - [grpc-js environment variables](https://github.com/grpc/grpc-node/blob/master/doc/environment_variables.md) - try[GRPC_VERBOSITY=DEBUG GRPC_TRACE=all yarn test](https://github.com/grpc/grpc-node/blob/master/TROUBLESHOOTING.md)
40
+ - [grpc-js environment variables](https://github.com/grpc/grpc-node/blob/master/doc/environment_variables.md) - try [GRPC_VERBOSITY=DEBUG GRPC_TRACE=all yarn test](https://github.com/grpc/grpc-node/blob/master/TROUBLESHOOTING.md)
37
41
 
38
42
  - API Simplification
39
43
  - [google-cloud-datastore-node](https://www.npmjs.com/package/google-cloud-datastore-node)
@@ -4,57 +4,60 @@ import { Operator, RunQueryResponse } from '@google-cloud/datastore/build/src/qu
4
4
  import { CommitResponse } from '@google-cloud/datastore/build/src/request';
5
5
  /** @ignore */
6
6
  export { Datastore, Key, PathType, Query, Transaction, } from '@google-cloud/datastore';
7
+ export declare const KEYSYM: symbol;
7
8
  export declare type IGqlFilterTypes = boolean | string | number;
8
9
  export declare type IGqlFilterSpec = {
9
10
  readonly eq: IGqlFilterTypes;
10
11
  };
11
12
  export declare type TGqlFilterList = Array<[string, Operator, DstorePropertyValues]>;
12
13
  /** Define what can be written into the Datastore */
13
- export declare type DstorePropertyValues = number | string | Date | boolean | null | undefined | Buffer | Key | readonly DstorePropertyValues[] | {
14
- readonly [key: string]: DstorePropertyValues;
14
+ export declare type DstorePropertyValues = number | string | Date | boolean | null | undefined | Buffer | Key | DstorePropertyValues[] | {
15
+ [key: string]: DstorePropertyValues;
15
16
  };
16
17
  export interface IDstoreEntryWithoutKey {
17
18
  /** All User Data stored in the Datastore */
18
- readonly [key: string]: DstorePropertyValues;
19
+ [key: string]: DstorePropertyValues;
19
20
  }
20
21
  /** Represents what is actually stored inside the Datastore, called "Entity" by Google
21
- [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) adds `[Datastore.KEY]`. Using ES6 Symbols presents all kinds of hurdles, especially when you try to serialize into a cache. So we add the property _keyStr which contains the encoded code. It is automatically used
22
- to reconstruct `[Datastore.KEY]`, if you use [[Dstore.readKey]].
22
+ [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) adds `[Datastore.KEY]`. Using ES6 Symbols presents all kinds of hurdles, especially when you try to serialize into a cache. So we add the property _keyStr which contains the encoded key. It is automatically used to reconstruct `[Datastore.KEY]`, if you use [[Dstore.readKey]].
23
23
  */
24
24
  export interface IDstoreEntry extends IDstoreEntryWithoutKey {
25
25
  readonly [Datastore.KEY]?: Key;
26
26
  /** [Datastore.KEY] key */
27
27
  _keyStr: string;
28
28
  /** All User Data stored in the Datastore */
29
- readonly [key: string]: DstorePropertyValues;
29
+ [key: string]: DstorePropertyValues;
30
30
  }
31
31
  /** Represents the thing you pass to the save method. Also called "Entity" by Google */
32
32
  export declare type DstoreSaveEntity = {
33
- readonly key: Key;
34
- readonly data: Omit<IDstoreEntry, '_keyStr' | Datastore['KEY']>;
35
- readonly method?: 'insert' | 'update' | 'upsert';
36
- readonly excludeLargeProperties?: boolean;
37
- readonly excludeFromIndexes?: readonly string[];
33
+ key: Key;
34
+ data: Omit<IDstoreEntry, '_keyStr' | Datastore['KEY']> & Partial<{
35
+ _keyStr: string;
36
+ [Datastore.KEY]: Key;
37
+ }>;
38
+ method?: 'insert' | 'update' | 'upsert';
39
+ excludeLargeProperties?: boolean;
40
+ excludeFromIndexes?: readonly string[];
38
41
  };
39
42
  declare type IDstore = {
40
43
  /** Accessible by Users of the library. Keep in mind that you will access outside transactions created by [[runInTransaction]]. */
41
44
  readonly datastore: Datastore;
42
- readonly key: (path: ReadonlyArray<PathType>) => Key;
43
- readonly keyFromSerialized: (text: string) => Key;
44
- readonly keySerialize: (key: Key) => string;
45
- readonly readKey: (entry: IDstoreEntry) => Key;
46
- readonly get: (key: Key) => Promise<IDstoreEntry | null>;
47
- readonly getMulti: (keys: ReadonlyArray<Key>) => Promise<ReadonlyArray<IDstoreEntry | undefined>>;
48
- readonly set: (key: Key, entry: IDstoreEntry) => Promise<Key>;
49
- readonly save: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
50
- readonly insert: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
51
- readonly update: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
52
- readonly delete: (keys: readonly Key[]) => Promise<CommitResponse | undefined>;
53
- readonly createQuery: (kind: string) => Query;
54
- readonly query: (kind: string, filters?: TGqlFilterList, limit?: number, orders?: readonly string[]) => Promise<RunQueryResponse>;
55
- readonly runQuery: (query: Query | Omit<Query, 'run'>) => Promise<RunQueryResponse>;
56
- readonly allocateOneId: (kindName: string) => Promise<string>;
57
- readonly runInTransaction: <T>(func: {
45
+ key: (path: ReadonlyArray<PathType>) => Key;
46
+ keyFromSerialized: (text: string) => Key;
47
+ keySerialize: (key: Key) => string;
48
+ readKey: (entry: IDstoreEntry) => Key;
49
+ get: (key: Key) => Promise<IDstoreEntry | null>;
50
+ getMulti: (keys: ReadonlyArray<Key>) => Promise<ReadonlyArray<IDstoreEntry | undefined>>;
51
+ set: (key: Key, entry: IDstoreEntry) => Promise<Key>;
52
+ save: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
53
+ insert: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
54
+ update: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
55
+ delete: (keys: readonly Key[]) => Promise<CommitResponse | undefined>;
56
+ createQuery: (kind: string) => Query;
57
+ query: (kind: string, filters?: TGqlFilterList, limit?: number, ordering?: readonly string[], selection?: readonly string[], cursor?: string) => Promise<RunQueryResponse>;
58
+ runQuery: (query: Query | Omit<Query, 'run'>) => Promise<RunQueryResponse>;
59
+ allocateOneId: (kindName: string) => Promise<string>;
60
+ runInTransaction: <T>(func: {
58
61
  (): Promise<T>;
59
62
  (): T;
60
63
  }) => Promise<T>;
@@ -64,18 +67,18 @@ declare type IDstore = {
64
67
  [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) is a strange beast: [The documentation is auto generated](https://cloud.google.com/nodejs/docs/reference/datastore/latest) and completely shy of documenting any advanced concepts.
65
68
  (Example: If you ask the datastore to auto-generate keys during save: how do you retrieve the generated key?) Generally I suggest to look at the Python 2.x [db](https://cloud.google.com/appengine/docs/standard/python/datastore/api-overview) and [ndb](https://cloud.google.com/appengine/docs/standard/python/ndb) documentation to get a better explanation of the workings of the datastore.
66
69
 
67
- Also the typings are strange. The Google provided type `Entities` can be the on disk representation, the same but including a key reference (`Datastore.KEY` - [[DstoreEntry]]), a list of these or a structured object containing the on disk representation under the `data` property and a `key` property and maybe some configuration like `excludeFromIndexes` ([[DstoreSaveEntity]]) or a list of these.
70
+ Also the typings are strange. The Google provided type `Entities` can be the on disk representation, the same but including a key reference (`Datastore.KEY` - [[IDstoreEntry]]), a list of these or a structured object containing the on disk representation under the `data` property and a `key` property and maybe some configuration like `excludeFromIndexes` ([[DstoreSaveEntity]]) or a list of these.
68
71
 
69
72
  KvStore tries to abstract away most surprises the datastore provides to you but als tries to stay as API compatible as possible to [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore).
70
73
 
71
74
  Main differences:
72
75
 
73
76
  - Everything asynchronous is Promise-based - no callbacks.
74
- - [[get]] always returns a single [[DstoreEntry]].
75
- - [[getMulti]] always returns an Array<[[DstoreEntry]]> of the same length as the input Array. Items not found are represented by null.
77
+ - [[get]] always returns a single [[IDstoreEntry]].
78
+ - [[getMulti]] always returns an Array<[[IDstoreEntry]]> of the same length as the input Array. Items not found are represented by null.
76
79
  - [[set]] is called with `(key, value)` and always returns the complete [[Key]] of the entity being written. Keys are normalized, numeric IDs are always encoded as strings.
77
80
  - [[key]] handles [[Key]] object instantiation for you.
78
- - [[readKey]] extracts the key from an [[DstoreEntry]] you have read without the need of fancy `Symbol`-based access to `entity[Datastore.KEY]`. If needed, it tries to deserialize `_keyStr` to create `entity[Datastore.KEY]`. This ist important when rehydrating an [[DstoreEntry]] from a serializing cache.
81
+ - [[readKey]] extracts the key from an [[IDstoreEntry]] you have read without the need of fancy `Symbol`-based access to `entity[Datastore.KEY]`. If needed, it tries to deserialize `_keyStr` to create `entity[Datastore.KEY]`. This ist important when rehydrating an [[IDstoreEntry]] from a serializing cache.
79
82
  - [[allocateOneId]] returns a single numeric string encoded unique datastore id without the need of fancy unpacking.
80
83
  - [[runInTransaction]] allows you to provide a function to be executed inside an transaction without the need of passing around the transaction object. This is modelled after Python 2.7 [ndb's `@ndb.transactional` feature](https://cloud.google.com/appengine/docs/standard/python/ndb/transactions). This is implemented via node's [AsyncLocalStorage](https://nodejs.org/docs/latest-v14.x/api/async_hooks.html).
81
84
  - [[keySerialize]] is synchronous.
@@ -130,24 +133,24 @@ export declare class Dstore implements IDstore {
130
133
  * @category Datastore Drop-In
131
134
  */
132
135
  keyFromSerialized(text: string): Key;
133
- /** `readKey()` extracts the [[Key]] from an [[DstoreEntry]].
136
+ /** `readKey()` extracts the [[Key]] from an [[IDstoreEntry]].
134
137
  *
135
138
  * Is is an alternative to `entity[Datastore.KEY]` which tends to fail in various contexts and also confuses older Typescript compilers.
136
- * It can extract the [[Key]] form a [[DstoreEntry]] which has been serialized to JSON by leveraging the property `_keyStr`.
139
+ * It can extract the [[Key]] form a [[IDstoreEntry]] which has been serialized to JSON by leveraging the property `_keyStr`.
137
140
  *
138
141
  * @category Additional
139
142
  */
140
143
  readKey(ent: IDstoreEntry): Key;
141
- /** `fixKeys()` is called for all [[DstoreEntry]]sa returned from [[Dstore]].
144
+ /** `fixKeys()` is called for all [[IDstoreEntry]]sa returned from [[Dstore]].
142
145
  *
143
146
  * Is ensures that besides `entity[Datastore.KEY]` there is `_keyStr` to be leveraged by [[readKey]].
144
147
  *
145
148
  * @internal
146
149
  */
147
150
  private fixKeys;
148
- /** `get()` reads a [[DstoreEntry]] from the Datastore.
151
+ /** `get()` reads a [[IDstoreEntry]] from the Datastore.
149
152
  *
150
- * It returns [[DstoreEntry]] or `null` if not found.
153
+ * It returns [[IDstoreEntry]] or `null` if not found.
151
154
 
152
155
  * The underlying Datastore API Call is [lookup](https://cloud.google.com/datastore/docs/reference/data/rest/v1/projects/lookup).
153
156
  *
@@ -156,14 +159,14 @@ export declare class Dstore implements IDstore {
156
159
  * Differences between [[Dstore.get]] and [[Datastore.get]]:
157
160
  *
158
161
  * - [Dstore.get]] takes a single [[Key]] as Parameter, no Array. Check [[getMulti]] if you want Arrays.
159
- * - [Dstore.get]] returns a single [[DstoreEntry]], no Array.
162
+ * - [Dstore.get]] returns a single [[IDstoreEntry]], no Array.
160
163
  *
161
164
  * @category Datastore Drop-In
162
165
  */
163
166
  get(key: Key): Promise<IDstoreEntry | null>;
164
- /** `getMulti()` reads several [[DstoreEntry]]s from the Datastore.
167
+ /** `getMulti()` reads several [[IDstoreEntry]]s from the Datastore.
165
168
  *
166
- * It returns a list of [[DstoreEntry]]s or `null` if not found.
169
+ * It returns a list of [[IDstoreEntry]]s or `null` if not found.
167
170
 
168
171
  * The underlying Datastore API Call is [lookup](https://cloud.google.com/datastore/docs/reference/data/rest/v1/projects/lookup).
169
172
  *
@@ -172,12 +175,12 @@ export declare class Dstore implements IDstore {
172
175
  * Differences between [[Dstore.getMulti]] and [[Datastore.get]]:
173
176
  *
174
177
  * - [[Dstore.getMulti]] always takes an Array of [[Key]]s as Parameter.
175
- * - [[Dstore.getMulti]] returns always a Array of [[DstoreEntry]], or null.
178
+ * - [[Dstore.getMulti]] returns always a Array of [[IDstoreEntry]], or null.
176
179
  * - [[Datastore.get]] has many edge cases - e.g. when not being able to find any of the provided keys - which return surprising results. [[Dstore.getMulti]] always returns an Array. TODO: return a Array with the same length as the Input.
177
180
  *
178
181
  * @category Datastore Drop-In
179
182
  */
180
- getMulti(keys: readonly Key[]): Promise<ReadonlyArray<IDstoreEntry | undefined>>;
183
+ getMulti(keys: readonly Key[]): Promise<Array<IDstoreEntry | undefined>>;
181
184
  /** `set()` is addition to [[Datastore]]. It provides a classic Key-value Interface.
182
185
  *
183
186
  * Instead providing a nested [[DstoreSaveEntity]] to [[save]] you can call set directly as `set( key, value)`.
@@ -210,7 +213,21 @@ export declare class Dstore implements IDstore {
210
213
  *
211
214
  * If the Datastore generates a new ID because of an incomplete [[Key]] *on first save* it will return an large integer as [[Key.id]].
212
215
  * On every subsequent `save()` an string encoded number representation is returned.
213
- * Dstore normalizes that and always returns an string encoded number representation.
216
+ * @todo Dstore should normalizes that and always return an string encoded number representation.
217
+ *
218
+ * Each [[DstoreSaveEntity]] can have an `excludeFromIndexes` property which is somewhat underdocumented.
219
+ * It can use something like JSON-Path notation
220
+ * ([Source](https://github.com/googleapis/nodejs-datastore/blob/2941f2f0f132b41534e303d441d837051ce88fd7/src/index.ts#L948))
221
+ * [.*](https://github.com/googleapis/nodejs-datastore/blob/406b15d2014087172df617c6e0a397a2c0902c5f/test/index.ts#L1598),
222
+ * [parent[]](https://github.com/googleapis/nodejs-datastore/blob/406b15d2014087172df617c6e0a397a2c0902c5f/test/index.ts#L1672),
223
+ * [parent.*](https://github.com/googleapis/nodejs-datastore/blob/406b15d2014087172df617c6e0a397a2c0902c5f/test/index.ts#L1672),
224
+ * [parent[].*](https://github.com/googleapis/nodejs-datastore/blob/406b15d2014087172df617c6e0a397a2c0902c5f/test/index.ts#L1672)
225
+ * and [more complex patterns](https://github.com/googleapis/nodejs-datastore/blob/406b15d2014087172df617c6e0a397a2c0902c5f/test/index.ts#L1754)
226
+ * seem to be supported patterns.
227
+ *
228
+ * If the caller has not provided an `excludeLargeProperties` in a [[DstoreSaveEntity]] we will default it
229
+ * to `excludeLargeProperties: true`. Without this you can not store strings longer than 1500 bytes easily
230
+ * ([source](https://github.com/googleapis/nodejs-datastore/blob/c7a08a8382c6706ccbfbbf77950babf40bac757c/src/entity.ts#L961)).
214
231
  *
215
232
  * @category Datastore Drop-In
216
233
  */
@@ -225,6 +242,8 @@ export declare class Dstore implements IDstore {
225
242
  *
226
243
  * For handling of incomplete [[Key]]s see [[save]].
227
244
  *
245
+ * This function can be completely emulated by using [[save]] with `method: 'insert'` inside each [[DstoreSaveEntity]].
246
+ *
228
247
  * @throws [[DstoreError]]
229
248
  * @category Datastore Drop-In
230
249
  */
@@ -239,15 +258,17 @@ export declare class Dstore implements IDstore {
239
258
  * It throws an [[DstoreError]] if there is no Entity with the same [[Key]] in the Datastore. `update()` *overwrites all existing data* for that [[Key]].
240
259
  * There was an alpha functionality called `merge()` in the Datastore which read an Entity, merged it with the new data and wrote it back, but this was never documented.
241
260
  *
242
- * `update()` is idempotent. Deleting the same [[Key]] twice is no error.
261
+ * `update()` is idempotent. Updating the same [[Key]] twice is no error.
262
+ *
263
+ * This function can be completely emulated by using [[save]] with `method: 'update'` inside each [[DstoreSaveEntity]].
243
264
  *
244
265
  * @throws [[DstoreError]]
245
266
  * @category Datastore Drop-In
246
267
  */
247
268
  update(entities: readonly DstoreSaveEntity[]): Promise<CommitResponse | undefined>;
248
- /** `delete()` is compatible to [Datastore.update()].
269
+ /** `delete()` is compatible to [Datastore.delete()].
249
270
  *
250
- * Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.update()].
271
+ * Unfortunately currently (late 2021) there is no formal documentation from Google on [Datastore.delete()].
251
272
  *
252
273
  * The single Parameter is a list of [[Key]]s.
253
274
  * If called within a transaction it returns `undefined`.
@@ -266,9 +287,10 @@ export declare class Dstore implements IDstore {
266
287
  * @param kind Name of the [[Datastore]][Kind](https://cloud.google.com/datastore/docs/concepts/entities#kinds_and_identifiers) ("Table") which should be searched.
267
288
  *
268
289
  * @category Datastore Drop-In
269
- */ createQuery(kind: string): Query;
290
+ */
291
+ createQuery(kind: string): Query;
270
292
  runQuery(query: Query | Omit<Query, 'run'>): Promise<RunQueryResponse>;
271
- query(kindName: string, filters?: TGqlFilterList, limit?: number, orders?: readonly string[]): Promise<RunQueryResponse>;
293
+ query(kindName: string, filters?: TGqlFilterList, limit?: number, ordering?: readonly string[], selection?: string[], cursor?: string): Promise<RunQueryResponse>;
272
294
  /** Allocate one ID in the Datastore.
273
295
  *
274
296
  * Currently (late 2021) there is no documentation provided by Google for the underlying node function.
@@ -283,16 +305,18 @@ export declare class Dstore implements IDstore {
283
305
  allocateOneId(kindName?: string): Promise<string>;
284
306
  /** This tries to give high level access to transactions.
285
307
 
286
- Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
287
-
288
308
  So called "Gross Group Transactions" are always enabled. Transactions are never Cross Project. `runInTransaction()` works only if you use the same [[KvStore] instance for all access within the Transaction.
289
309
 
290
310
  [[runInTransaction]] is modelled after Python 2.7 [ndb's `@ndb.transactional` feature](https://cloud.google.com/appengine/docs/standard/python/ndb/transactions). This is based on node's [AsyncLocalStorage](https://nodejs.org/docs/latest-v14.x/api/async_hooks.html).
291
311
 
292
- Transactions frequently fail if you try to access the same data via in a transaction. See the [Documentation on Locking](https://cloud.google.com/datastore/docs/concepts/transactions#transaction_locks) for further reference. You are advised to use [p-limit](https://github.com/sindresorhus/p-limit)(1) to seralize transactions touching the same resource. This should work nicely with node's single process model. It is a much bigger problem on shared-nothing approaches, like Python on App Engine.
312
+ Transactions frequently fail if you try to access the same data via in a transaction. See the [Documentation on Locking](https://cloud.google.com/datastore/docs/concepts/transactions#transaction_locks) for further reference. You are advised to use [p-limit](https://github.com/sindresorhus/p-limit)(1) to serialize transactions touching the same resource. This should work nicely with node's single process model. It is a much bigger problem on shared-nothing approaches, like Python on App Engine.
293
313
 
294
314
  Transactions might be wrapped in [p-retry](https://github.com/sindresorhus/p-retry) to implement automatically retrying them with exponential back-off should they fail due to contention.
295
- */
315
+
316
+ Be aware that Transactions differ considerable between Master-Slave Datastore (very old), High Replication Datastore (old, later called [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/cloud-datastore-transactions)) and [Firestore in Datastore Mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode) (current).
317
+
318
+ Most Applications today are running on "Firestore in Datastore Mode". Beware that the Datastore-Emulator fails with `error: 3 INVALID_ARGUMENT: Only ancestor queries are allowed inside transactions.` during [[runQuery]] while the Datastore on Google Infrastructure does not have such an restriction anymore as of 2022.
319
+ */
296
320
  runInTransaction<T>(func: () => Promise<T>): Promise<T>;
297
321
  }
298
322
  export declare class DstoreError extends Error {