neo4j-driver 2.0.0-alpha03 → 3.8.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.
Files changed (104) hide show
  1. package/.babelrc +1 -1
  2. package/README.md +386 -155
  3. package/examples/neo4j.html +11 -8
  4. package/examples/node.js +7 -7
  5. package/lib/browser/neo4j-web.esm.js +33956 -0
  6. package/lib/browser/neo4j-web.esm.min.js +1 -0
  7. package/lib/browser/neo4j-web.js +33955 -16863
  8. package/lib/browser/neo4j-web.min.js +1 -1
  9. package/lib/docs.js +37 -0
  10. package/lib/driver.js +66 -222
  11. package/lib/index.js +505 -389
  12. package/lib/internal/retry-logic-rx.js +91 -0
  13. package/lib/internal/server-version.js +80 -119
  14. package/lib/result-rx.js +379 -0
  15. package/lib/session-rx.js +239 -0
  16. package/lib/transaction-managed-rx.js +64 -0
  17. package/lib/transaction-rx.js +122 -0
  18. package/lib/version.js +5 -10
  19. package/package.json +43 -63
  20. package/spec/support/jasmine.json +0 -1
  21. package/tsconfig.json +6 -2
  22. package/types/driver.d.ts +14 -53
  23. package/types/index.d.ts +181 -72
  24. package/types/{statement-runner.d.ts → query-runner.d.ts} +6 -7
  25. package/{lib/internal/constants.js → types/result-rx.d.ts} +19 -12
  26. package/types/session-rx.d.ts +67 -0
  27. package/types/{transaction.d.ts → transaction-managed-rx.d.ts} +6 -11
  28. package/types/{spatial-types.d.ts → transaction-rx.d.ts} +13 -12
  29. package/.eslintrc.json +0 -23
  30. package/CONTRIBUTING.md +0 -60
  31. package/ISSUE_TEMPLATE.md +0 -53
  32. package/lib/error.js +0 -99
  33. package/lib/graph-types.js +0 -231
  34. package/lib/integer.js +0 -1150
  35. package/lib/internal/bolt-protocol-util.js +0 -62
  36. package/lib/internal/bolt-protocol-v1.js +0 -227
  37. package/lib/internal/bolt-protocol-v2.js +0 -68
  38. package/lib/internal/bolt-protocol-v3.js +0 -157
  39. package/lib/internal/bolt-protocol-v4.js +0 -94
  40. package/lib/internal/bookmark.js +0 -193
  41. package/lib/internal/browser/browser-buf.js +0 -118
  42. package/lib/internal/browser/browser-channel.js +0 -351
  43. package/lib/internal/browser/browser-host-name-resolver.js +0 -59
  44. package/lib/internal/browser/browser-utf8.js +0 -59
  45. package/lib/internal/browser/index.js +0 -57
  46. package/lib/internal/buf/base-buf.js +0 -517
  47. package/lib/internal/buf/combined-buf.js +0 -111
  48. package/lib/internal/channel-config.js +0 -103
  49. package/lib/internal/chunking.js +0 -271
  50. package/lib/internal/connection-channel.js +0 -617
  51. package/lib/internal/connection-delegate.js +0 -141
  52. package/lib/internal/connection-error-handler.js +0 -98
  53. package/lib/internal/connection-holder.js +0 -226
  54. package/lib/internal/connection-provider-direct.js +0 -79
  55. package/lib/internal/connection-provider-pooled.js +0 -175
  56. package/lib/internal/connection-provider-routing.js +0 -417
  57. package/lib/internal/connection-provider-single.js +0 -65
  58. package/lib/internal/connection-provider.js +0 -53
  59. package/lib/internal/connection.js +0 -167
  60. package/lib/internal/connectivity-verifier.js +0 -101
  61. package/lib/internal/least-connected-load-balancing-strategy.js +0 -119
  62. package/lib/internal/load-balancing-strategy.js +0 -69
  63. package/lib/internal/logger.js +0 -268
  64. package/lib/internal/node/index.js +0 -57
  65. package/lib/internal/node/node-buf.js +0 -124
  66. package/lib/internal/node/node-channel.js +0 -313
  67. package/lib/internal/node/node-host-name-resolver.js +0 -74
  68. package/lib/internal/node/node-utf8.js +0 -114
  69. package/lib/internal/packstream-v1.js +0 -831
  70. package/lib/internal/packstream-v2.js +0 -512
  71. package/lib/internal/pool-config.js +0 -73
  72. package/lib/internal/pool.js +0 -435
  73. package/lib/internal/protocol-handshaker.js +0 -146
  74. package/lib/internal/rediscovery.js +0 -106
  75. package/lib/internal/request-message.js +0 -343
  76. package/lib/internal/resolver/base-host-name-resolver.js +0 -57
  77. package/lib/internal/resolver/configured-custom-resolver.js +0 -67
  78. package/lib/internal/round-robin-array-index.js +0 -70
  79. package/lib/internal/routing-table.js +0 -116
  80. package/lib/internal/routing-util.js +0 -185
  81. package/lib/internal/server-address.js +0 -94
  82. package/lib/internal/stream-observer.js +0 -220
  83. package/lib/internal/temporal-util.js +0 -613
  84. package/lib/internal/transaction-executor.js +0 -239
  85. package/lib/internal/tx-config.js +0 -134
  86. package/lib/internal/url-util.js +0 -230
  87. package/lib/internal/util.js +0 -156
  88. package/lib/record.js +0 -165
  89. package/lib/result-summary.js +0 -437
  90. package/lib/result.js +0 -217
  91. package/lib/routing-driver.js +0 -120
  92. package/lib/session.js +0 -380
  93. package/lib/spatial-types.js +0 -88
  94. package/lib/temporal-types.js +0 -459
  95. package/lib/transaction.js +0 -387
  96. package/support/inject-browser-transform.js +0 -20
  97. package/types/error.d.ts +0 -39
  98. package/types/graph-types.d.ts +0 -84
  99. package/types/integer.d.ts +0 -147
  100. package/types/record.d.ts +0 -41
  101. package/types/result-summary.d.ts +0 -117
  102. package/types/result.d.ts +0 -39
  103. package/types/session.d.ts +0 -58
  104. package/types/temporal-types.d.ts +0 -156
package/README.md CHANGED
@@ -1,16 +1,26 @@
1
1
  # Neo4j Driver for JavaScript
2
2
 
3
- A database driver for Neo4j 3.0.0+.
3
+ This is the official Neo4j driver for JavaScript.
4
+
5
+ Starting with 5.0, the Neo4j Drivers will be moving to a monthly release cadence. A minor version will be released on the last Friday of each month so as to maintain versioning consistency with the core product (Neo4j DBMS) which has also moved to a monthly cadence.
6
+
7
+ As a policy, patch versions will not be released except on rare occasions. Bug fixes and updates will go into the latest minor version and users should upgrade to that. Driver upgrades within a major version will never contain breaking API changes.
8
+
9
+ See also: https://neo4j.com/developer/kb/neo4j-supported-versions/
4
10
 
5
11
  Resources to get you started:
6
12
 
7
- - [Detailed docs](http://neo4j.com/docs/api/javascript-driver/current/).
8
- - [Sample small project using the driver](https://github.com/neo4j-examples/movies-javascript-bolt)
9
- - [Sample application using the driver](https://github.com/neo4j-examples/neo4j-movies-template)
13
+ - [API Documentation](https://neo4j.com/docs/api/javascript-driver/current/)
10
14
  - [Neo4j Manual](https://neo4j.com/docs/)
11
15
  - [Neo4j Refcard](https://neo4j.com/docs/cypher-refcard/current/)
12
16
 
13
- ## Include module in Node.js application
17
+ ## What's New in 5.x
18
+
19
+ - [Changelog](https://github.com/neo4j/neo4j-javascript-driver/wiki/5.0-changelog)
20
+
21
+ ## Including the Driver
22
+
23
+ ### In Node.js application
14
24
 
15
25
  Stable channel:
16
26
 
@@ -34,12 +44,12 @@ var neo4j = require('neo4j-driver')
34
44
  Driver instance should be closed when Node.js application exits:
35
45
 
36
46
  ```javascript
37
- driver.close()
47
+ driver.close() // returns a Promise
38
48
  ```
39
49
 
40
50
  otherwise application shutdown might hang or it might exit with a non-zero exit code.
41
51
 
42
- ## Include in web browser
52
+ ### In web browser
43
53
 
44
54
  We build a special browser version of the driver, which supports connecting to Neo4j over WebSockets.
45
55
  It can be included in an HTML page using one of the following tags:
@@ -59,102 +69,217 @@ It can be included in an HTML page using one of the following tags:
59
69
  <script src="https://cdn.jsdelivr.net/npm/neo4j-driver@X.Y.Z/lib/browser/neo4j-web.min.js"></script>
60
70
  ```
61
71
 
62
- This will make a global `neo4j` object available, where you can access the driver API at `neo4j`\*:
72
+ This will make a global `neo4j` object available, where you can create a driver instance with `neo4j.driver`:
63
73
 
64
74
  ```javascript
65
75
  var driver = neo4j.driver(
66
- 'bolt://localhost',
67
- neo4j.auth.basic('neo4j', 'neo4j')
76
+ 'neo4j://localhost',
77
+ neo4j.auth.basic('neo4j', 'password')
68
78
  )
69
79
  ```
70
80
 
71
- \* Since 2.0, driver API is moved from `neo4j.v1` to `neo4j`.
81
+ From `5.4.0`, this version is also exported as ECMA Script Module.
82
+ It can be imported from a module using the following statements:
83
+
84
+ ```javascript
85
+ // Direct reference
86
+ import neo4j from 'lib/browser/neo4j-web.esm.min.js'
87
+
88
+ // unpkg CDN non-minified , version X.Y.Z where X.Y.Z >= 5.4.0
89
+ import neo4j from 'https://unpkg.com/neo4j-driver@X.Y.Z/lib/browser/neo4j-web.esm.js'
90
+
91
+ // unpkg CDN minified for production use, version X.Y.Z where X.Y.Z >= 5.4.0
92
+ import neo4j from 'https://unpkg.com/neo4j-driver@X.Y.Z/lib/browser/neo4j-web.esm.min.js'
93
+
94
+ // jsDelivr CDN non-minified, version X.Y.Z where X.Y.Z >= 5.4.0
95
+ import neo4j from 'https://cdn.jsdelivr.net/npm/neo4j-driver@X.Y.Z/lib/browser/neo4j-web.esm.js'
96
+
97
+ // jsDelivr CDN minified for production use, version X.Y.Z where X.Y.Z >= 5.4.0
98
+ import neo4j from 'https://cdn.jsdelivr.net/npm/neo4j-driver@X.Y.Z/lib/browser/neo4j-web.esm.min.js'
99
+
100
+ ```
72
101
 
73
102
  It is not required to explicitly close the driver on a web page. Web browser should gracefully close all open
74
103
  WebSockets when the page is unloaded. However, driver instance should be explicitly closed when it's lifetime
75
104
  is not the same as the lifetime of the web page:
76
105
 
77
106
  ```javascript
78
- driver.close()
107
+ driver.close() // returns a Promise
79
108
  ```
80
109
 
81
110
  ## Usage examples
82
111
 
83
- Driver lifecycle:
112
+ ### Constructing a Driver
84
113
 
85
114
  ```javascript
86
- // Create a driver instance, for the user neo4j with password neo4j.
115
+ // Create a driver instance, for the user `neo4j` with password `password`.
87
116
  // It should be enough to have a single driver per database per application.
88
117
  var driver = neo4j.driver(
89
- 'bolt://localhost',
90
- neo4j.auth.basic('neo4j', 'neo4j')
118
+ 'neo4j://localhost',
119
+ neo4j.auth.basic('neo4j', 'password')
91
120
  )
92
121
 
93
122
  // Close the driver when application exits.
94
123
  // This closes all used network connections.
95
- driver.close()
124
+ await driver.close()
96
125
  ```
97
126
 
98
- Session API:
127
+ ### Acquiring a Session
128
+
129
+ #### Regular Session
99
130
 
100
131
  ```javascript
101
132
  // Create a session to run Cypher statements in.
102
133
  // Note: Always make sure to close sessions when you are done using them!
103
134
  var session = driver.session()
135
+ ```
136
+
137
+ ##### with a Default Access Mode of `READ`
138
+
139
+ ```javascript
140
+ var session = driver.session({ defaultAccessMode: neo4j.session.READ })
141
+ ```
142
+
143
+ ##### with Bookmarks
144
+
145
+ ```javascript
146
+ var session = driver.session({
147
+ bookmarks: [bookmark1FromPreviousSession, bookmark2FromPreviousSession]
148
+ })
149
+ ```
150
+
151
+ ##### against a Database
152
+
153
+ ```javascript
154
+ var session = driver.session({
155
+ database: 'foo',
156
+ defaultAccessMode: neo4j.session.WRITE
157
+ })
158
+ ```
159
+
160
+ #### Reactive Session
161
+
162
+ ```javascript
163
+ // Create a reactive session to run Cypher statements in.
164
+ // Note: Always make sure to close sessions when you are done using them!
165
+ var rxSession = driver.rxSession()
166
+ ```
167
+
168
+ ##### with a Default Access Mode of `READ`
169
+
170
+ ```javascript
171
+ var rxSession = driver.rxSession({ defaultAccessMode: neo4j.session.READ })
172
+ ```
173
+
174
+ ##### with Bookmarks
175
+
176
+ ```javascript
177
+ var rxSession = driver.rxSession({
178
+ bookmarks: [bookmark1FromPreviousSession, bookmark2FromPreviousSession]
179
+ })
180
+ ```
181
+
182
+ ##### against a Database
183
+
184
+ ```javascript
185
+ var rxSession = driver.rxSession({
186
+ database: 'foo',
187
+ defaultAccessMode: neo4j.session.WRITE
188
+ })
189
+ ```
190
+
191
+ ### Executing Queries
104
192
 
193
+ #### Consuming Records with Streaming API
194
+
195
+ ```javascript
105
196
  // Run a Cypher statement, reading the result in a streaming manner as records arrive:
106
197
  session
107
- .run('MERGE (alice:Person {name : {nameParam} }) RETURN alice.name AS name', {
198
+ .run('MERGE (alice:Person {name : $nameParam}) RETURN alice.name AS name', {
108
199
  nameParam: 'Alice'
109
200
  })
110
201
  .subscribe({
111
- onNext: function(record) {
202
+ onKeys: keys => {
203
+ console.log(keys)
204
+ },
205
+ onNext: record => {
112
206
  console.log(record.get('name'))
113
207
  },
114
- onCompleted: function() {
115
- session.close()
208
+ onCompleted: () => {
209
+ session.close() // returns a Promise
116
210
  },
117
- onError: function(error) {
211
+ onError: error => {
118
212
  console.log(error)
119
213
  }
120
214
  })
215
+ ```
216
+
217
+ Subscriber API allows following combinations of `onKeys`, `onNext`, `onCompleted` and `onError` callback invocations:
218
+
219
+ - zero or one `onKeys`,
220
+ - zero or more `onNext` followed by `onCompleted` when operation was successful. `onError` will not be invoked in this case
221
+ - zero or more `onNext` followed by `onError` when operation failed. Callback `onError` might be invoked after couple `onNext` invocations because records are streamed lazily by the database. `onCompleted` will not be invoked in this case.
222
+
223
+ #### Consuming Records with Promise API
121
224
 
122
- // or
225
+ ```javascript
123
226
  // the Promise way, where the complete result is collected before we act on it:
124
227
  session
125
- .run('MERGE (james:Person {name : {nameParam} }) RETURN james.name AS name', {
228
+ .run('MERGE (james:Person {name : $nameParam}) RETURN james.name AS name', {
126
229
  nameParam: 'James'
127
230
  })
128
- .then(function(result) {
129
- result.records.forEach(function(record) {
231
+ .then(result => {
232
+ result.records.forEach(record => {
130
233
  console.log(record.get('name'))
131
234
  })
132
- session.close()
133
235
  })
134
- .catch(function(error) {
236
+ .catch(error => {
135
237
  console.log(error)
136
238
  })
239
+ .then(() => session.close())
137
240
  ```
138
241
 
139
- Transaction functions API:
242
+ #### Consuming Records with Reactive API
243
+
244
+ ```javascript
245
+ rxSession
246
+ .run('MERGE (james:Person {name: $nameParam}) RETURN james.name AS name', {
247
+ nameParam: 'Bob'
248
+ })
249
+ .records()
250
+ .pipe(
251
+ map(record => record.get('name')),
252
+ concatWith(rxSession.close())
253
+ )
254
+ .subscribe({
255
+ next: data => console.log(data),
256
+ complete: () => console.log('completed'),
257
+ error: err => console.log(err)
258
+ })
259
+ ```
260
+
261
+ ### Transaction functions
140
262
 
141
263
  ```javascript
142
264
  // Transaction functions provide a convenient API with minimal boilerplate and
143
265
  // retries on network fluctuations and transient errors. Maximum retry time is
144
266
  // configured on the driver level and is 30 seconds by default:
145
- neo4j.driver('bolt://localhost', neo4j.auth.basic('neo4j', 'neo4j'), {
267
+ // Applies both to standard and reactive sessions.
268
+ neo4j.driver('neo4j://localhost', neo4j.auth.basic('neo4j', 'password'), {
146
269
  maxTransactionRetryTime: 30000
147
270
  })
271
+ ```
272
+
273
+ #### Reading with Async Session
148
274
 
275
+ ```javascript
149
276
  // It is possible to execute read transactions that will benefit from automatic
150
277
  // retries on both single instance ('bolt' URI scheme) and Causal Cluster
151
278
  // ('neo4j' URI scheme) and will get automatic load balancing in cluster deployments
152
- var readTxResultPromise = session.readTransaction(function(transaction) {
279
+ var readTxResultPromise = session.readTransaction(txc => {
153
280
  // used transaction will be committed automatically, no need for explicit commit/rollback
154
281
 
155
- var result = transaction.run(
156
- 'MATCH (person:Person) RETURN person.name AS name'
157
- )
282
+ var result = txc.run('MATCH (person:Person) RETURN person.name AS name')
158
283
  // at this point it is possible to either return the result or process it and return the
159
284
  // result of processing it is also possible to run more statements in the same transaction
160
285
  return result
@@ -162,190 +287,209 @@ var readTxResultPromise = session.readTransaction(function(transaction) {
162
287
 
163
288
  // returned Promise can be later consumed like this:
164
289
  readTxResultPromise
165
- .then(function(result) {
166
- session.close()
290
+ .then(result => {
167
291
  console.log(result.records)
168
292
  })
169
- .catch(function(error) {
293
+ .catch(error => {
170
294
  console.log(error)
171
295
  })
296
+ .then(() => session.close())
297
+ ```
298
+
299
+ #### Reading with Reactive Session
300
+
301
+ ```javascript
302
+ rxSession
303
+ .readTransaction(txc =>
304
+ txc
305
+ .run('MATCH (person:Person) RETURN person.name AS name')
306
+ .records()
307
+ .pipe(map(record => record.get('name')))
308
+ )
309
+ .subscribe({
310
+ next: data => console.log(data),
311
+ complete: () => console.log('completed'),
312
+ error: err => console.log(error)
313
+ })
314
+ ```
315
+
316
+ #### Writing with Async Session
172
317
 
318
+ ```javascript
173
319
  // It is possible to execute write transactions that will benefit from automatic retries
174
320
  // on both single instance ('bolt' URI scheme) and Causal Cluster ('neo4j' URI scheme)
175
- var writeTxResultPromise = session.writeTransaction(function(transaction) {
321
+ var writeTxResultPromise = session.writeTransaction(async txc => {
176
322
  // used transaction will be committed automatically, no need for explicit commit/rollback
177
323
 
178
- var result = transaction.run(
179
- "MERGE (alice:Person {name : 'Alice' }) RETURN alice.name AS name"
324
+ var result = await txc.run(
325
+ "MERGE (alice:Person {name : 'Alice'}) RETURN alice.name AS name"
180
326
  )
181
327
  // at this point it is possible to either return the result or process it and return the
182
328
  // result of processing it is also possible to run more statements in the same transaction
183
- return result.records.map(function(record) {
184
- return record.get('name')
185
- })
329
+ return result.records.map(record => record.get('name'))
186
330
  })
187
331
 
188
332
  // returned Promise can be later consumed like this:
189
333
  writeTxResultPromise
190
- .then(function(namesArray) {
191
- session.close()
334
+ .then(namesArray => {
192
335
  console.log(namesArray)
193
336
  })
194
- .catch(function(error) {
337
+ .catch(error => {
195
338
  console.log(error)
196
339
  })
340
+ .then(() => session.close())
197
341
  ```
198
342
 
199
- Explicit transactions API:
343
+ #### Writing with Reactive Session
200
344
 
201
345
  ```javascript
202
- // run statement in a transaction
203
- var tx = session.beginTransaction()
204
-
205
- tx.run('MERGE (bob:Person {name : {nameParam} }) RETURN bob.name AS name', {
206
- nameParam: 'Bob'
207
- }).subscribe({
208
- onNext: function(record) {
209
- console.log(record.get('name'))
210
- },
211
- onCompleted: function() {
212
- console.log('First query completed')
213
- },
214
- onError: function(error) {
215
- console.log(error)
216
- }
217
- })
346
+ rxSession
347
+ .writeTransaction(txc =>
348
+ txc
349
+ .run("MERGE (alice:Person {name: 'James'}) RETURN alice.name AS name")
350
+ .records()
351
+ .pipe(map(record => record.get('name')))
352
+ )
353
+ .subscribe({
354
+ next: data => console.log(data),
355
+ complete: () => console.log('completed'),
356
+ error: error => console.log(error)
357
+ })
358
+ ```
218
359
 
219
- tx.run('MERGE (adam:Person {name : {nameParam} }) RETURN adam.name AS name', {
220
- nameParam: 'Adam'
221
- }).subscribe({
222
- onNext: function(record) {
223
- console.log(record.get('name'))
224
- },
225
- onCompleted: function() {
226
- console.log('Second query completed')
227
- },
228
- onError: function(error) {
229
- console.log(error)
230
- }
231
- })
360
+ ### Explicit Transactions
232
361
 
233
- //decide if the transaction should be committed or rolled back
234
- var success = false
362
+ #### With Async Session
235
363
 
236
- if (success) {
237
- tx.commit().subscribe({
238
- onCompleted: function() {
239
- // this transaction is now committed and session can be closed
240
- session.close()
241
- },
242
- onError: function(error) {
243
- console.log(error)
364
+ ```javascript
365
+ // run statement in a transaction
366
+ const txc = session.beginTransaction()
367
+ try {
368
+ const result1 = await txc.run(
369
+ 'MERGE (bob:Person {name: $nameParam}) RETURN bob.name AS name',
370
+ {
371
+ nameParam: 'Bob'
244
372
  }
245
- })
246
- } else {
247
- //transaction is rolled black and nothing is created in the database
373
+ )
374
+ result1.records.forEach(r => console.log(r.get('name')))
375
+ console.log('First query completed')
376
+
377
+ const result2 = await txc.run(
378
+ 'MERGE (adam:Person {name: $nameParam}) RETURN adam.name AS name',
379
+ {
380
+ nameParam: 'Adam'
381
+ }
382
+ )
383
+ result2.records.forEach(r => console.log(r.get('name')))
384
+ console.log('Second query completed')
385
+
386
+ await txc.commit()
387
+ console.log('committed')
388
+ } catch (error) {
389
+ console.log(error)
390
+ await txc.rollback()
248
391
  console.log('rolled back')
249
- tx.rollback()
392
+ } finally {
393
+ await session.close()
250
394
  }
251
395
  ```
252
396
 
253
- Subscriber API allows following combinations of `onNext`, `onCompleted` and `onError` callback invocations:
254
-
255
- - zero or more `onNext` followed by `onCompleted` when operation was successful. `onError` will not be invoked
256
- in this case
257
- - zero or more `onNext` followed by `onError` when operation failed. Callback `onError` might be invoked after
258
- couple `onNext` invocations because records are streamed lazily by the database. `onCompleted` will not be invoked
259
- in this case
397
+ #### With Reactive Session
260
398
 
261
- ## Parallelization
262
-
263
- In a single session, multiple queries will be executed serially. In order to parallelize queries, multiple sessions are required.
264
-
265
- ## Building
266
-
267
- npm install
268
- npm run build
269
-
270
- This produces browser-compatible standalone files under `lib/browser` and a Node.js module version under `lib/`.
271
- See files under `examples/` on how to use.
272
-
273
- ## Testing
274
-
275
- Tests **require** latest [Boltkit](https://github.com/neo4j-contrib/boltkit) to be installed in the system. It is needed to start, stop and configure local test database. Boltkit can be installed with the following command:
276
-
277
- pip install --upgrade boltkit
278
-
279
- To run tests against "default" Neo4j version:
280
-
281
- ./runTests.sh
282
-
283
- To run tests against specified Neo4j version:
284
-
285
- ./runTests.sh '-e 3.1.3'
286
-
287
- Simple `npm test` can also be used if you already have a running version of a compatible Neo4j server.
288
-
289
- For development, you can have the build tool rerun the tests each time you change
290
- the source code:
291
-
292
- gulp watch-n-test
399
+ ```javascript
400
+ rxSession
401
+ .beginTransaction()
402
+ .pipe(
403
+ mergeMap(txc =>
404
+ concatWith(
405
+ txc
406
+ .run(
407
+ 'MERGE (bob:Person {name: $nameParam}) RETURN bob.name AS name',
408
+ {
409
+ nameParam: 'Bob'
410
+ }
411
+ )
412
+ .records()
413
+ .pipe(map(r => r.get('name'))),
414
+ of('First query completed'),
415
+ txc
416
+ .run(
417
+ 'MERGE (adam:Person {name: $nameParam}) RETURN adam.name AS name',
418
+ {
419
+ nameParam: 'Adam'
420
+ }
421
+ )
422
+ .records()
423
+ .pipe(map(r => r.get('name'))),
424
+ of('Second query completed'),
425
+ txc.commit(),
426
+ of('committed')
427
+ ).pipe(catchError(err => txc.rollback().pipe(throwError(() => err))))
428
+ )
429
+ )
430
+ .subscribe({
431
+ next: data => console.log(data),
432
+ complete: () => console.log('completed'),
433
+ error: error => console.log(error)
434
+ })
435
+ ```
293
436
 
294
- ### Testing on windows
437
+ ### Numbers and the Integer type
295
438
 
296
- Running tests on windows requires PhantomJS installed and its bin folder added in windows system variable `Path`.
297
- To run the same test suite, run `.\runTest.ps1` instead in powershell with admin right.
298
- The admin right is required to start/stop Neo4j properly as a system service.
299
- While there is no need to grab admin right if you are running tests against an existing Neo4j server using `npm test`.
439
+ The Neo4j type system uses 64-bit signed integer values. The range of values is between `-(2`<sup>`64`</sup>`- 1)` and `(2`<sup>`63`</sup>`- 1)`.
300
440
 
301
- ## A note on numbers and the Integer type
441
+ However, JavaScript can only safely represent integers between `Number.MIN_SAFE_INTEGER` `-(2`<sup>`53`</sup>`- 1)` and `Number.MAX_SAFE_INTEGER` `(2`<sup>`53`</sup>`- 1)`.
302
442
 
303
- The Neo4j type system includes 64-bit integer values.
304
- However, JavaScript can only safely represent integers between `-(2`<sup>`53`</sup>`- 1)` and `(2`<sup>`53`</sup>`- 1)`.
305
443
  In order to support the full Neo4j type system, the driver will not automatically convert to javascript integers.
306
444
  Any time the driver receives an integer value from Neo4j, it will be represented with an internal integer type by the driver.
307
445
 
308
- ### Write integers
446
+ _**Any javascript number value passed as a parameter will be recognized as `Float` type.**_
447
+
448
+ #### Writing integers
449
+
450
+ Numbers written directly e.g. `session.run("CREATE (n:Node {age: $age})", {age: 22})` will be of type `Float` in Neo4j.
309
451
 
310
- Number written directly e.g. `session.run("CREATE (n:Node {age: {age}})", {age: 22})` will be of type `Float` in Neo4j.
311
452
  To write the `age` as an integer the `neo4j.int` method should be used:
312
453
 
313
454
  ```javascript
314
455
  var neo4j = require('neo4j-driver')
315
456
 
316
- session.run('CREATE (n {age: {myIntParam}})', { myIntParam: neo4j.int(22) })
457
+ session.run('CREATE (n {age: $myIntParam})', { myIntParam: neo4j.int(22) })
317
458
  ```
318
459
 
319
- To write integers larger than can be represented as JavaScript numbers, use a string argument to `neo4j.int`:
460
+ To write an integer value that are not within the range of `Number.MIN_SAFE_INTEGER` `-(2`<sup>`53`</sup>`- 1)` and `Number.MAX_SAFE_INTEGER` `(2`<sup>`53`</sup>`- 1)`, use a string argument to `neo4j.int`:
320
461
 
321
462
  ```javascript
322
- session.run('CREATE (n {age: {myIntParam}})', {
463
+ session.run('CREATE (n {age: $myIntParam})', {
323
464
  myIntParam: neo4j.int('9223372036854775807')
324
465
  })
325
466
  ```
326
467
 
327
- ### Read integers
468
+ #### Reading integers
469
+
470
+ In Neo4j, the type Integer can be larger what can be represented safely as an integer with JavaScript Number.
471
+
472
+ It is only safe to convert to a JavaScript Number if you know that the number will be in the range `Number.MIN_SAFE_INTEGER` `-(2`<sup>`53`</sup>`- 1)` and `Number.MAX_SAFE_INTEGER` `(2`<sup>`53`</sup>`- 1)`.
328
473
 
329
- Since Integers can be larger than can be represented as JavaScript numbers, it is only safe to convert to JavaScript numbers if you know that they will not exceed `(2`<sup>`53`</sup>`- 1)` in size.
330
474
  In order to facilitate working with integers the driver include `neo4j.isInt`, `neo4j.integer.inSafeRange`, `neo4j.integer.toNumber`, and `neo4j.integer.toString`.
331
475
 
332
476
  ```javascript
333
- var aSmallInteger = neo4j.int(123)
334
- if (neo4j.integer.inSafeRange(aSmallInteger)) {
335
- var aNumber = aSmallInteger.toNumber()
477
+ var smallInteger = neo4j.int(123)
478
+ if (neo4j.integer.inSafeRange(smallInteger)) {
479
+ var aNumber = smallInteger.toNumber()
336
480
  }
337
481
  ```
338
482
 
339
- If you will be handling integers larger than that, you should convert them to strings:
483
+ If you will be handling integers that is not within the JavaScript safe range of integers, you should convert the value to a string:
340
484
 
341
485
  ```javascript
342
- var aLargerInteger = neo4j.int('9223372036854775807')
343
- if (!neo4j.integer.inSafeRange(aLargerInteger)) {
344
- var integerAsString = aLargerInteger.toString()
486
+ var largeInteger = neo4j.int('9223372036854775807')
487
+ if (!neo4j.integer.inSafeRange(largeInteger)) {
488
+ var integerAsString = largeInteger.toString()
345
489
  }
346
490
  ```
347
491
 
348
- ### Enable native numbers
492
+ #### Enabling native numbers
349
493
 
350
494
  Starting from 1.6 version of the driver it is possible to configure it to only return native numbers instead of custom `Integer` objects.
351
495
  The configuration option affects all integers returned by the driver. **Enabling this option can result in a loss of precision and incorrect numeric
@@ -354,8 +498,95 @@ To enable potentially lossy integer values use the driver's configuration object
354
498
 
355
499
  ```javascript
356
500
  var driver = neo4j.driver(
357
- 'bolt://localhost',
358
- neo4j.auth.basic('neo4j', 'neo4j'),
501
+ 'neo4j://localhost',
502
+ neo4j.auth.basic('neo4j', 'password'),
359
503
  { disableLosslessIntegers: true }
360
504
  )
361
505
  ```
506
+
507
+ ## Building
508
+
509
+ ```
510
+ npm ci
511
+ npm run build
512
+ ```
513
+
514
+ This produces browser-compatible standalone files under `lib/browser` and a Node.js module version under `lib/`.
515
+ See files under `examples/` on how to use.
516
+
517
+ ## Testing
518
+
519
+ Tests **require** latest [Testkit 4.3](https://github.com/neo4j-drivers/testkit/tree/4.3), Python3 and Docker.
520
+
521
+ Testkit is needed to be cloned and configured to run against the Javascript Lite Driver. Use the following steps to configure Testkit.
522
+
523
+ 1. Clone the Testkit repository
524
+
525
+ ```
526
+ git clone https://github.com/neo4j-drivers/testkit.git
527
+ ```
528
+
529
+ 2. Under the Testkit folder, install the requirements.
530
+
531
+ ```
532
+ pip3 install -r requirements.txt
533
+ ```
534
+
535
+ 3. Define some enviroment variables to configure Testkit
536
+
537
+ ```
538
+ export TEST_DRIVER_NAME=javascript
539
+ export TEST_DRIVER_REPO=<path for the root folder of driver repository>
540
+ unset TEST_DRIVER_LITE
541
+ ```
542
+
543
+ To run test against against some Neo4j version:
544
+
545
+ ```
546
+ python3 main.py
547
+ ```
548
+
549
+ More details about how to use Teskit could be found on [its repository](https://github.com/neo4j-drivers/testkit/tree/4.3)
550
+
551
+ ## Testing (Legacy)
552
+
553
+ Tests **require** latest [Boltkit](https://github.com/neo4j-contrib/boltkit) and [Firefox](https://www.mozilla.org/firefox/) to be installed in the system.
554
+
555
+ Boltkit is needed to start, stop and configure local test database. Boltkit can be installed with the following command:
556
+
557
+ ```
558
+ pip3 install --upgrade boltkit
559
+ ```
560
+
561
+ To run tests against "default" Neo4j version:
562
+
563
+ ```
564
+ ./runTests.sh
565
+ ```
566
+
567
+ To run tests against specified Neo4j version:
568
+
569
+ ```
570
+ ./runTests.sh '-e 4.2.0'
571
+ ```
572
+
573
+ Simple `npm test` can also be used if you already have a running version of a compatible Neo4j server.
574
+
575
+ For development, you can have the build tool rerun the tests each time you change
576
+ the source code:
577
+
578
+ ```
579
+ gulp watch-n-test
580
+ ```
581
+
582
+ If the `gulp` command line tool is not available, you might need to install this globally:
583
+
584
+ ```
585
+ npm install -g gulp-cli
586
+ ```
587
+
588
+ ### Testing on windows
589
+
590
+ To run the same test suite, run `.\runTest.ps1` instead in powershell with admin right.
591
+ The admin right is required to start/stop Neo4j properly as a system service.
592
+ While there is no need to grab admin right if you are running tests against an existing Neo4j server using `npm test`.