gremlin 3.6.0 → 3.6.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 (113) hide show
  1. package/.eslintrc.js +3 -2
  2. package/NOTICE +1 -1
  3. package/doc/AnonymousTraversalSource.html +2 -2
  4. package/doc/Authenticator.html +2 -2
  5. package/doc/Bytecode.html +2 -2
  6. package/doc/Client.html +174 -9
  7. package/doc/Connection.html +43 -10
  8. package/doc/DriverRemoteConnection.html +144 -12
  9. package/doc/EdgeLabelVerificationStrategy.html +2 -2
  10. package/doc/Graph.html +2 -2
  11. package/doc/GraphSON2Reader.html +2 -2
  12. package/doc/GraphSON2Writer.html +2 -2
  13. package/doc/GraphSON3Reader.html +2 -2
  14. package/doc/GraphSON3Writer.html +2 -2
  15. package/doc/GraphTraversal.html +112 -112
  16. package/doc/GraphTraversalSource.html +19 -19
  17. package/doc/HaltedTraverserStrategy.html +2 -2
  18. package/doc/MatchAlgorithmStrategy.html +2 -2
  19. package/doc/P.html +2 -2
  20. package/doc/PartitionStrategy.html +2 -2
  21. package/doc/Path.html +2 -2
  22. package/doc/PlainTextSaslAuthenticator.html +2 -2
  23. package/doc/ProductiveByStrategy.html +2 -2
  24. package/doc/RemoteConnection.html +2 -2
  25. package/doc/RemoteStrategy.html +2 -2
  26. package/doc/RemoteTraversal.html +2 -2
  27. package/doc/ReservedKeysVerificationStrategy.html +2 -2
  28. package/doc/ResponseError.html +2 -2
  29. package/doc/ResultSet.html +2 -2
  30. package/doc/SaslAuthenticator.html +2 -2
  31. package/doc/SaslMechanismBase.html +2 -2
  32. package/doc/SaslMechanismPlain.html +2 -2
  33. package/doc/SeedStrategy.html +2 -2
  34. package/doc/SubgraphStrategy.html +2 -2
  35. package/doc/TextP.html +2 -2
  36. package/doc/Transaction.html +2 -2
  37. package/doc/Translator.html +2 -2
  38. package/doc/TraversalStrategies.html +2 -2
  39. package/doc/TraversalStrategy.html +2 -2
  40. package/doc/TypeSerializer.html +2 -2
  41. package/doc/driver_auth_authenticator.js.html +2 -2
  42. package/doc/driver_auth_mechanisms_sasl-mechanism-base.js.html +2 -2
  43. package/doc/driver_auth_mechanisms_sasl-mechanism-plain.js.html +2 -2
  44. package/doc/driver_auth_plain-text-sasl-authenticator.js.html +2 -2
  45. package/doc/driver_auth_sasl-authenticator.js.html +2 -2
  46. package/doc/driver_client.js.html +7 -2
  47. package/doc/driver_connection.js.html +49 -13
  48. package/doc/driver_driver-remote-connection.js.html +6 -2
  49. package/doc/driver_remote-connection.js.html +2 -2
  50. package/doc/driver_response-error.js.html +2 -2
  51. package/doc/driver_result-set.js.html +2 -2
  52. package/doc/global.html +68 -4
  53. package/doc/index.html +2 -2
  54. package/doc/module.exports.html +301 -0
  55. package/doc/process_anonymous-traversal.js.html +2 -2
  56. package/doc/process_bytecode.js.html +2 -2
  57. package/doc/process_graph-traversal.js.html +25 -13
  58. package/doc/process_transaction.js.html +2 -2
  59. package/doc/process_translator.js.html +2 -2
  60. package/doc/process_traversal-strategy.js.html +3 -3
  61. package/doc/process_traversal.js.html +4 -4
  62. package/doc/structure_graph.js.html +2 -2
  63. package/doc/structure_io_binary_internals_DataType.js.html +149 -0
  64. package/doc/structure_io_binary_internals_GraphBinaryReader.js.html +131 -0
  65. package/doc/structure_io_binary_internals_GraphBinaryWriter.js.html +134 -0
  66. package/doc/structure_io_graph-serializer.js.html +2 -2
  67. package/doc/structure_io_type-serializers.js.html +2 -2
  68. package/docker-compose.yml +62 -0
  69. package/index.js +1 -0
  70. package/lib/driver/client.js +5 -0
  71. package/lib/driver/connection.js +47 -11
  72. package/lib/driver/driver-remote-connection.js +4 -0
  73. package/lib/process/graph-traversal.js +23 -11
  74. package/lib/process/traversal-strategy.js +1 -1
  75. package/lib/process/traversal.js +2 -2
  76. package/lib/structure/io/binary/GraphBinary.js +109 -0
  77. package/lib/structure/io/binary/internals/AnySerializer.js +95 -0
  78. package/lib/structure/io/binary/internals/ArraySerializer.js +135 -0
  79. package/lib/structure/io/binary/internals/BigIntegerSerializer.js +151 -0
  80. package/lib/structure/io/binary/internals/BooleanSerializer.js +103 -0
  81. package/lib/structure/io/binary/internals/BulkSetSerializer.js +124 -0
  82. package/lib/structure/io/binary/internals/ByteBufferSerializer.js +124 -0
  83. package/lib/structure/io/binary/internals/ByteSerializer.js +95 -0
  84. package/lib/structure/io/binary/internals/BytecodeSerializer.js +249 -0
  85. package/lib/structure/io/binary/internals/DataType.js +98 -0
  86. package/lib/structure/io/binary/internals/DateSerializer.js +103 -0
  87. package/lib/structure/io/binary/internals/DoubleSerializer.js +99 -0
  88. package/lib/structure/io/binary/internals/EdgeSerializer.js +215 -0
  89. package/lib/structure/io/binary/internals/EnumSerializer.js +149 -0
  90. package/lib/structure/io/binary/internals/FloatSerializer.js +99 -0
  91. package/lib/structure/io/binary/internals/GraphBinaryReader.js +80 -0
  92. package/lib/structure/io/binary/internals/GraphBinaryWriter.js +83 -0
  93. package/lib/structure/io/binary/internals/IntSerializer.js +112 -0
  94. package/lib/structure/io/binary/internals/LambdaSerializer.js +70 -0
  95. package/lib/structure/io/binary/internals/LongSerializer.js +107 -0
  96. package/lib/structure/io/binary/internals/LongSerializerNg.js +102 -0
  97. package/lib/structure/io/binary/internals/MapSerializer.js +153 -0
  98. package/lib/structure/io/binary/internals/NumberSerializationStrategy.js +68 -0
  99. package/lib/structure/io/binary/internals/PSerializer.js +151 -0
  100. package/lib/structure/io/binary/internals/PathSerializer.js +123 -0
  101. package/lib/structure/io/binary/internals/PropertySerializer.js +141 -0
  102. package/lib/structure/io/binary/internals/ShortSerializer.js +99 -0
  103. package/lib/structure/io/binary/internals/StringSerializer.js +114 -0
  104. package/lib/structure/io/binary/internals/TextPSerializer.js +145 -0
  105. package/lib/structure/io/binary/internals/TraversalStrategySerializer.js +72 -0
  106. package/lib/structure/io/binary/internals/TraverserSerializer.js +123 -0
  107. package/lib/structure/io/binary/internals/UnspecifiedNullSerializer.js +75 -0
  108. package/lib/structure/io/binary/internals/UuidSerializer.js +119 -0
  109. package/lib/structure/io/binary/internals/VertexPropertySerializer.js +172 -0
  110. package/lib/structure/io/binary/internals/VertexSerializer.js +135 -0
  111. package/lib/structure/io/binary/internals/utils.js +59 -0
  112. package/lib/utils.js +29 -0
  113. package/package.json +22 -12
@@ -28,6 +28,7 @@ const WebSocket = require('ws');
28
28
  const util = require('util');
29
29
  const utils = require('../utils');
30
30
  const serializer = require('../structure/io/graph-serializer');
31
+ const { graphBinaryReader, graphBinaryWriter } = require('../structure/io/binary/GraphBinary');
31
32
  const ResultSet = require('./result-set');
32
33
  const ResponseError = require('./response-error');
33
34
 
@@ -40,6 +41,7 @@ const responseStatusCode = {
40
41
 
41
42
  const defaultMimeType = 'application/vnd.gremlin-v3.0+json';
42
43
  const graphSON2MimeType = 'application/vnd.gremlin-v2.0+json';
44
+ const graphBinaryMimeType = 'application/vnd.graphbinary-v1.0';
43
45
 
44
46
  const pingIntervalDelay = 60 * 1000;
45
47
  const pongTimeoutDelay = 30 * 1000;
@@ -62,10 +64,11 @@ class Connection extends EventEmitter {
62
64
  * @param {GraphSONWriter} [options.writer] The writer to use.
63
65
  * @param {Authenticator} [options.authenticator] The authentication handler to use.
64
66
  * @param {Object} [options.headers] An associative array containing the additional header key/values for the initial request.
67
+ * @param {Boolean} [options.enableUserAgentOnConnect] Determines if a user agent will be sent during connection handshake. Defaults to: true
65
68
  * @param {Boolean} [options.pingEnabled] Setup ping interval. Defaults to: true.
66
69
  * @param {Number} [options.pingInterval] Ping request interval in ms if ping enabled. Defaults to: 60000.
67
70
  * @param {Number} [options.pongTimeout] Timeout of pong response in ms after sending a ping. Defaults to: 30000.
68
- * @param {Boolean} [options.connectOnStartup] Open websocket on startup. Defaults to: true.
71
+ * @param {Boolean} [options.connectOnStartup] Deprecated and non-functional. Open websocket on startup.
69
72
  * @constructor
70
73
  */
71
74
  constructor(url, options) {
@@ -80,7 +83,7 @@ class Connection extends EventEmitter {
80
83
  */
81
84
  this.mimeType = options.mimeType || defaultMimeType;
82
85
 
83
- // A map containing the request id and the handler
86
+ // A map containing the request id and the handler. The id should be in lower case to prevent string comparison issues.
84
87
  this._responseHandlers = {};
85
88
  this._reader = options.reader || this._getDefaultReader(this.mimeType);
86
89
  this._writer = options.writer || this._getDefaultWriter(this.mimeType);
@@ -96,13 +99,16 @@ class Connection extends EventEmitter {
96
99
  this.isOpen = false;
97
100
  this.traversalSource = options.traversalSource || 'g';
98
101
  this._authenticator = options.authenticator;
102
+ this._enableUserAgentOnConnect = options.enableUserAgentOnConnect !== false;
99
103
 
100
104
  this._pingEnabled = this.options.pingEnabled === false ? false : true;
101
105
  this._pingIntervalDelay = this.options.pingInterval || pingIntervalDelay;
102
106
  this._pongTimeoutDelay = this.options.pongTimeout || pongTimeoutDelay;
103
107
 
104
- if (this.options.connectOnStartup !== false) {
105
- this.open();
108
+ if (this.options.connectOnStartup) {
109
+ console.warn(
110
+ 'connectOnStartup is now deprecated and non-functional. To open a connection, please call open() after instantiating connection object.',
111
+ );
106
112
  }
107
113
  }
108
114
 
@@ -119,9 +125,16 @@ class Connection extends EventEmitter {
119
125
  }
120
126
 
121
127
  this.emit('log', 'ws open');
128
+ let headers = this.options.headers;
129
+ if (this._enableUserAgentOnConnect) {
130
+ if (!headers) {
131
+ headers = [];
132
+ }
133
+ headers[utils.getUserAgentHeader()] = utils.getUserAgent();
134
+ }
122
135
 
123
136
  this._ws = new WebSocket(this.url, {
124
- headers: this.options.headers,
137
+ headers: headers,
125
138
  ca: this.options.ca,
126
139
  cert: this.options.cert,
127
140
  pfx: this.options.pfx,
@@ -160,7 +173,8 @@ class Connection extends EventEmitter {
160
173
 
161
174
  /** @override */
162
175
  submit(processor, op, args, requestId) {
163
- const rid = requestId || utils.getUuid();
176
+ // TINKERPOP-2847: Use lower case to prevent string comparison issues.
177
+ const rid = (requestId || utils.getUuid()).toLowerCase();
164
178
  return this.open().then(
165
179
  () =>
166
180
  new Promise((resolve, reject) => {
@@ -180,7 +194,7 @@ class Connection extends EventEmitter {
180
194
  };
181
195
 
182
196
  const request_buf = this._writer.writeRequest(request);
183
- const message = Buffer.concat([this._header_buf, request_buf], this._header_buf.length + request_buf.length);
197
+ const message = Buffer.concat([this._header_buf, request_buf]);
184
198
  this._ws.send(message);
185
199
  }),
186
200
  );
@@ -188,7 +202,8 @@ class Connection extends EventEmitter {
188
202
 
189
203
  /** @override */
190
204
  stream(processor, op, args, requestId) {
191
- const rid = requestId || utils.getUuid();
205
+ // TINKERPOP-2847: Use lower case to prevent string comparison issues.
206
+ const rid = (requestId || utils.getUuid()).toLowerCase();
192
207
 
193
208
  const readableStream = new Stream.Readable({
194
209
  objectMode: true,
@@ -211,7 +226,7 @@ class Connection extends EventEmitter {
211
226
  };
212
227
 
213
228
  const request_buf = this._writer.writeRequest(request);
214
- const message = Buffer.concat([this._header_buf, request_buf], this._header_buf.length + request_buf.length);
229
+ const message = Buffer.concat([this._header_buf, request_buf]);
215
230
  this._ws.send(message);
216
231
  })
217
232
  .catch((err) => readableStream.destroy(err));
@@ -220,10 +235,18 @@ class Connection extends EventEmitter {
220
235
  }
221
236
 
222
237
  _getDefaultReader(mimeType) {
238
+ if (mimeType === graphBinaryMimeType) {
239
+ return graphBinaryReader;
240
+ }
241
+
223
242
  return mimeType === graphSON2MimeType ? new serializer.GraphSON2Reader() : new serializer.GraphSONReader();
224
243
  }
225
244
 
226
245
  _getDefaultWriter(mimeType) {
246
+ if (mimeType === graphBinaryMimeType) {
247
+ return graphBinaryWriter;
248
+ }
249
+
227
250
  return mimeType === graphSON2MimeType ? new serializer.GraphSON2Writer() : new serializer.GraphSONWriter();
228
251
  }
229
252
 
@@ -252,7 +275,7 @@ class Connection extends EventEmitter {
252
275
 
253
276
  _handleError(err) {
254
277
  this.emit('log', `ws error ${err}`);
255
- this._cleanupWebsocket();
278
+ this._cleanupWebsocket(err);
256
279
  this.emit('socketError', err);
257
280
  }
258
281
 
@@ -294,6 +317,8 @@ class Connection extends EventEmitter {
294
317
  return;
295
318
  }
296
319
 
320
+ // TINKERPOP-2847: Use lower case to prevent string comparison issues.
321
+ response.requestId = response.requestId.toLowerCase();
297
322
  const handler = this._responseHandlers[response.requestId];
298
323
 
299
324
  if (!handler) {
@@ -356,7 +381,7 @@ class Connection extends EventEmitter {
356
381
  /**
357
382
  * clean websocket context
358
383
  */
359
- _cleanupWebsocket() {
384
+ _cleanupWebsocket(err) {
360
385
  if (this._pingInterval) {
361
386
  clearInterval(this._pingInterval);
362
387
  }
@@ -366,6 +391,17 @@ class Connection extends EventEmitter {
366
391
  }
367
392
  this._pongTimeout = null;
368
393
 
394
+ // Invoke waiting callbacks to complete Promises when closing the websocket
395
+ Object.keys(this._responseHandlers).forEach((requestId) => {
396
+ const handler = this._responseHandlers[requestId];
397
+ const isStreamingResponse = handler.result instanceof Stream.Readable;
398
+ if (isStreamingResponse) {
399
+ handler.callback(null);
400
+ } else {
401
+ const cause = err ? err : new Error('Connection has been closed.');
402
+ handler.callback(cause);
403
+ }
404
+ });
369
405
  this._ws.removeAllListeners();
370
406
  this._openPromise = null;
371
407
  this._closePromise = null;
@@ -48,6 +48,10 @@ class DriverRemoteConnection extends RemoteConnection {
48
48
  * @param {GraphSONWriter} [options.writer] The writer to use.
49
49
  * @param {Authenticator} [options.authenticator] The authentication handler to use.
50
50
  * @param {Object} [options.headers] An associative array containing the additional header key/values for the initial request.
51
+ * @param {Boolean} [options.enableUserAgentOnConnect] Determines if a user agent will be sent during connection handshake. Defaults to: true
52
+ * @param {Boolean} [options.pingEnabled] Setup ping interval. Defaults to: true.
53
+ * @param {Number} [options.pingInterval] Ping request interval in ms if ping enabled. Defaults to: 60000.
54
+ * @param {Number} [options.pongTimeout] Timeout of pong response in ms after sending a ping. Defaults to: 30000.
51
55
  * @constructor
52
56
  */
53
57
  constructor(url, options = {}) {
@@ -94,17 +94,29 @@ class GraphTraversalSource {
94
94
  * @returns {GraphTraversalSource}
95
95
  */
96
96
  withComputer(graphComputer, workers, result, persist, vertices, edges, configuration) {
97
- return this.withStrategies(
98
- new VertexProgramStrategy({
99
- graphComputer: graphComputer,
100
- workers: workers,
101
- result: result,
102
- persist: persist,
103
- vertices: vertices,
104
- edges: edges,
105
- configuration: configuration,
106
- }),
107
- );
97
+ const m = {};
98
+ if (graphComputer !== undefined) {
99
+ m.graphComputer = graphComputer;
100
+ }
101
+ if (workers !== undefined) {
102
+ m.workers = workers;
103
+ }
104
+ if (result !== undefined) {
105
+ m.result = result;
106
+ }
107
+ if (persist !== undefined) {
108
+ m.graphComputer = persist;
109
+ }
110
+ if (vertices !== undefined) {
111
+ m.vertices = vertices;
112
+ }
113
+ if (edges !== undefined) {
114
+ m.edges = edges;
115
+ }
116
+ if (configuration !== undefined) {
117
+ m.configuration = configuration;
118
+ }
119
+ return this.withStrategies(new VertexProgramStrategy(m));
108
120
  }
109
121
 
110
122
  /**
@@ -295,7 +295,7 @@ class ReservedKeysVerificationStrategy extends TraversalStrategy {
295
295
  * @param {Array<String>} keys the list of reserved keys to verify
296
296
  */
297
297
  constructor(logWarnings = false, throwException = false, keys = ['id', 'label']) {
298
- super('org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.EdgeLabelVerificationStrategy', {
298
+ super('org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReservedKeysVerificationStrategy', {
299
299
  logWarnings: logWarnings,
300
300
  throwException: throwException,
301
301
  keys: keys,
@@ -496,10 +496,10 @@ module.exports = {
496
496
  barrier: toEnum('Barrier', 'normSack'),
497
497
  cardinality: toEnum('Cardinality', 'list set single'),
498
498
  column: toEnum('Column', 'keys values'),
499
- direction: toEnum('Direction', 'BOTH IN OUT'),
499
+ direction: toEnum('Direction', 'BOTH IN OUT from_ to'),
500
500
  graphSONVersion: toEnum('GraphSONVersion', 'V1_0 V2_0 V3_0'),
501
501
  gryoVersion: toEnum('GryoVersion', 'V1_0 V3_0'),
502
- merge: toEnum('Merge', 'onCreate onMatch'),
502
+ merge: toEnum('Merge', 'onCreate onMatch outV inV'),
503
503
  operator: toEnum('Operator', 'addAll and assign div max min minus mult or sum sumLong'),
504
504
  order: toEnum('Order', 'asc desc shuffle'),
505
505
  pick: toEnum('Pick', 'any none'),
@@ -0,0 +1,109 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ /**
21
+ * GraphBinary 1.0 support implementation.
22
+ *
23
+ * The officially expected entrypoint is GraphBinaryReader/GraphBinaryWriter pair of classes,
24
+ * examine lib/driver/** for use cases.
25
+ *
26
+ * See AnySerializer.serialize() for the mechanism of serializer selection for a given JavaScript value,
27
+ * also consider AnySerializer.serialize() unit tests for real examples.
28
+ * See NumberSerializationStrategy to understand how it deals with JavaScript numbers' serialization.
29
+ *
30
+ * Consider AnySerializer.serialize()/deserialize() unit tests to see what is not implemented,
31
+ * what is ignored, what is not expected to be (de)serialized, etc.
32
+ *
33
+ * TODO: it has the following open topics:
34
+ * - [] Should we do anything for application/vnd.graphbinary-v1.0-stringd mime type support?
35
+ * Core Data Types support:
36
+ * - [] 0x22: BigDecimal
37
+ * - [] 0x2b: Tree
38
+ * - [] 0x2c: Metrics
39
+ * - [] 0x2d: TraversalMetrics
40
+ * - [] 0x00: Custom
41
+ * Extended Types support:
42
+ * - [] 0x80: Char
43
+ * - [] 0x81: Duration
44
+ * - [] 0x82: InetAddress
45
+ * - [] 0x83: Instant
46
+ * - [] 0x84: LocalDate
47
+ * - [] 0x85: LocalDateTime
48
+ * - [] 0x86: LocalTime
49
+ * - [] 0x87: MonthDay
50
+ * - [] 0x88: OffsetDateTime
51
+ * - [] 0x89: OffsetTime
52
+ * - [] 0x8a: Period
53
+ * - [] 0x8b: Year
54
+ * - [] 0x8c: YearMonth
55
+ * - [] 0x8d: ZonedDateTime
56
+ * - [] 0x8e: ZoneOffset
57
+ *
58
+ * @author Igor Ostapenko
59
+ */
60
+ /*eslint-disable*/
61
+ 'use strict';
62
+
63
+ const ioc = {};
64
+
65
+ ioc.DataType = require('./internals/DataType');
66
+ ioc.utils = require('./internals/utils');
67
+
68
+ ioc.serializers = {};
69
+
70
+ ioc.intSerializer = new (require('./internals/IntSerializer'))(ioc);
71
+ ioc.longSerializer = new (require('./internals/LongSerializer'))(ioc);
72
+ ioc.longSerializerNg = new (require('./internals/LongSerializerNg'))(ioc);
73
+ ioc.stringSerializer = new (require('./internals/StringSerializer'))(ioc, ioc.DataType.STRING);
74
+ ioc.dateSerializer = new (require('./internals/DateSerializer'))(ioc, ioc.DataType.DATE);
75
+ ioc.timestampSerializer = new (require('./internals/DateSerializer'))(ioc, ioc.DataType.TIMESTAMP);
76
+ ioc.classSerializer = new (require('./internals/StringSerializer'))(ioc, ioc.DataType.CLASS);
77
+ ioc.doubleSerializer = new (require('./internals/DoubleSerializer'))(ioc);
78
+ ioc.floatSerializer = new (require('./internals/FloatSerializer'))(ioc);
79
+ ioc.listSerializer = new (require('./internals/ArraySerializer'))(ioc, ioc.DataType.LIST);
80
+ ioc.mapSerializer = new (require('./internals/MapSerializer'))(ioc);
81
+ ioc.setSerializer = new (require('./internals/ArraySerializer'))(ioc, ioc.DataType.SET);
82
+ ioc.uuidSerializer = new (require('./internals/UuidSerializer'))(ioc);
83
+ ioc.edgeSerializer = new (require('./internals/EdgeSerializer'))(ioc);
84
+ ioc.pathSerializer = new (require('./internals/PathSerializer'))(ioc);
85
+ ioc.propertySerializer = new (require('./internals/PropertySerializer'))(ioc);
86
+ ioc.vertexSerializer = new (require('./internals/VertexSerializer'))(ioc);
87
+ ioc.vertexPropertySerializer = new (require('./internals/VertexPropertySerializer'))(ioc);
88
+ ioc.bytecodeSerializer = new (require('./internals/BytecodeSerializer'))(ioc);
89
+ ioc.pSerializer = new (require('./internals/PSerializer'))(ioc);
90
+ ioc.traverserSerializer = new (require('./internals/TraverserSerializer'))(ioc);
91
+ ioc.enumSerializer = new (require('./internals/EnumSerializer'))(ioc);
92
+ ioc.lambdaSerializer = new (require('./internals/LambdaSerializer'))(ioc);
93
+ ioc.bigIntegerSerializer = new (require('./internals/BigIntegerSerializer'))(ioc);
94
+ ioc.byteSerializer = new (require('./internals/ByteSerializer'))(ioc);
95
+ ioc.byteBufferSerializer = new (require('./internals/ByteBufferSerializer'))(ioc);
96
+ ioc.shortSerializer = new (require('./internals/ShortSerializer'))(ioc);
97
+ ioc.booleanSerializer = new (require('./internals/BooleanSerializer'))(ioc);
98
+ ioc.textPSerializer = new (require('./internals/TextPSerializer'))(ioc);
99
+ ioc.traversalStrategySerializer = new (require('./internals/TraversalStrategySerializer'))(ioc);
100
+ ioc.bulkSetSerializer = new (require('./internals/BulkSetSerializer'))(ioc);
101
+ ioc.unspecifiedNullSerializer = new (require('./internals/UnspecifiedNullSerializer'))(ioc);
102
+
103
+ ioc.numberSerializationStrategy = new (require('./internals/NumberSerializationStrategy'))(ioc);
104
+ ioc.anySerializer = new (require('./internals/AnySerializer'))(ioc);
105
+
106
+ ioc.graphBinaryReader = new (require('./internals/GraphBinaryReader.js'))(ioc);
107
+ ioc.graphBinaryWriter = new (require('./internals/GraphBinaryWriter'))(ioc);
108
+
109
+ module.exports = ioc;
@@ -0,0 +1,95 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ /**
21
+ * @author Igor Ostapenko
22
+ */
23
+ 'use strict';
24
+
25
+ module.exports = class AnySerializer {
26
+ constructor(ioc) {
27
+ this.ioc = ioc;
28
+
29
+ // specifically ordered, the first canBeUsedFor=true wins
30
+ this.serializers = [
31
+ ioc.unspecifiedNullSerializer,
32
+
33
+ ioc.numberSerializationStrategy,
34
+
35
+ ioc.booleanSerializer,
36
+ ioc.dateSerializer,
37
+ ioc.bytecodeSerializer,
38
+ ioc.pSerializer,
39
+ ioc.traverserSerializer,
40
+ ioc.enumSerializer,
41
+ ioc.listSerializer,
42
+ ioc.uuidSerializer,
43
+ ioc.edgeSerializer,
44
+ ioc.pathSerializer,
45
+ ioc.propertySerializer,
46
+ ioc.vertexSerializer,
47
+ ioc.vertexPropertySerializer,
48
+ ioc.stringSerializer,
49
+ ioc.textPSerializer,
50
+ ioc.traversalStrategySerializer,
51
+
52
+ ioc.byteBufferSerializer, // Buffer instance
53
+ ioc.lambdaSerializer, // any function
54
+ ioc.mapSerializer, // Map or any Object
55
+ ];
56
+ }
57
+
58
+ getSerializerCanBeUsedFor(item) {
59
+ for (let i = 0; i < this.serializers.length; i++) {
60
+ if (this.serializers[i].canBeUsedFor(item)) {
61
+ return this.serializers[i];
62
+ }
63
+ }
64
+
65
+ throw new Error(
66
+ `No serializer found to support item where typeof(item)='${typeof item}' and String(item)='${String(item)}'.`,
67
+ );
68
+ }
69
+
70
+ serialize(item, fullyQualifiedFormat = true) {
71
+ return this.getSerializerCanBeUsedFor(item).serialize(item, fullyQualifiedFormat);
72
+ }
73
+
74
+ deserialize(buffer) {
75
+ // obviously, fullyQualifiedFormat always is true
76
+ try {
77
+ if (buffer === undefined || buffer === null || !(buffer instanceof Buffer)) {
78
+ throw new Error('buffer is missing');
79
+ }
80
+ if (buffer.length < 1) {
81
+ throw new Error('buffer is empty');
82
+ }
83
+
84
+ const type_code = buffer.readUInt8();
85
+ const serializer = this.ioc.serializers[type_code];
86
+ if (!serializer) {
87
+ throw new Error('unknown {type_code}');
88
+ }
89
+
90
+ return serializer.deserialize(buffer);
91
+ } catch (err) {
92
+ throw this.ioc.utils.des_error({ serializer: this, args: arguments, err });
93
+ }
94
+ }
95
+ };
@@ -0,0 +1,135 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one
3
+ * or more contributor license agreements. See the NOTICE file
4
+ * distributed with this work for additional information
5
+ * regarding copyright ownership. The ASF licenses this file
6
+ * to you under the Apache License, Version 2.0 (the
7
+ * "License"); you may not use this file except in compliance
8
+ * with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
18
+ */
19
+
20
+ /**
21
+ * @author Igor Ostapenko
22
+ */
23
+ 'use strict';
24
+
25
+ module.exports = class ArraySerializer {
26
+ constructor(ioc, ID) {
27
+ this.ioc = ioc;
28
+ this.ID = ID;
29
+ this.ioc.serializers[ID] = this;
30
+ }
31
+
32
+ canBeUsedFor(value) {
33
+ return Array.isArray(value);
34
+ }
35
+
36
+ serialize(item, fullyQualifiedFormat = true) {
37
+ if (item === undefined || item === null) {
38
+ if (fullyQualifiedFormat) {
39
+ return Buffer.from([this.ID, 0x01]);
40
+ }
41
+ return Buffer.from([0x00, 0x00, 0x00, 0x00]); // {length} = 0
42
+ }
43
+
44
+ const bufs = [];
45
+ if (fullyQualifiedFormat) {
46
+ bufs.push(Buffer.from([this.ID, 0x00]));
47
+ }
48
+
49
+ // {length}
50
+ let length = item.length;
51
+ if (length < 0) {
52
+ length = 0; // TODO: test it
53
+ }
54
+ if (length > this.ioc.intSerializer.INT32_MAX) {
55
+ throw new Error(
56
+ `Array length=${length} is greater than supported max_length=${this.ioc.intSerializer.INT32_MAX}.`,
57
+ );
58
+ }
59
+ bufs.push(this.ioc.intSerializer.serialize(length, false));
60
+
61
+ // {item_0}...{item_n}
62
+ for (let i = 0; i < length; i++) {
63
+ bufs.push(this.ioc.anySerializer.serialize(item[i]));
64
+ }
65
+
66
+ return Buffer.concat(bufs);
67
+ }
68
+
69
+ deserialize(buffer, fullyQualifiedFormat = true) {
70
+ let len = 0;
71
+ let cursor = buffer;
72
+
73
+ try {
74
+ if (buffer === undefined || buffer === null || !(buffer instanceof Buffer)) {
75
+ throw new Error('buffer is missing');
76
+ }
77
+ if (buffer.length < 1) {
78
+ throw new Error('buffer is empty');
79
+ }
80
+
81
+ if (fullyQualifiedFormat) {
82
+ const type_code = cursor.readUInt8();
83
+ len++;
84
+ if (type_code !== this.ID) {
85
+ throw new Error('unexpected {type_code}');
86
+ }
87
+ cursor = cursor.slice(1);
88
+
89
+ if (cursor.length < 1) {
90
+ throw new Error('{value_flag} is missing');
91
+ }
92
+ const value_flag = cursor.readUInt8();
93
+ len++;
94
+ if (value_flag === 1) {
95
+ return { v: null, len };
96
+ }
97
+ if (value_flag !== 0) {
98
+ throw new Error('unexpected {value_flag}');
99
+ }
100
+ cursor = cursor.slice(1);
101
+ }
102
+
103
+ let length, length_len;
104
+ try {
105
+ ({ v: length, len: length_len } = this.ioc.intSerializer.deserialize(cursor, false));
106
+ len += length_len;
107
+ } catch (err) {
108
+ err.message = '{length}: ' + err.message;
109
+ throw err;
110
+ }
111
+ if (length < 0) {
112
+ throw new Error('{length} is less than zero');
113
+ }
114
+ cursor = cursor.slice(length_len);
115
+
116
+ const v = [];
117
+ for (let i = 0; i < length; i++) {
118
+ let value, value_len;
119
+ try {
120
+ ({ v: value, len: value_len } = this.ioc.anySerializer.deserialize(cursor));
121
+ len += value_len;
122
+ } catch (err) {
123
+ err.message = `{item_${i}}: ` + err.message;
124
+ throw err;
125
+ }
126
+ cursor = cursor.slice(value_len);
127
+ v.push(value);
128
+ }
129
+
130
+ return { v, len };
131
+ } catch (err) {
132
+ throw this.ioc.utils.des_error({ serializer: this, args: arguments, cursor, err });
133
+ }
134
+ }
135
+ };