@ragestudio/scylla-odm 0.22.2 → 0.22.3

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 (153) hide show
  1. package/batch/index.d.ts +3 -3
  2. package/batch/index.d.ts.map +1 -1
  3. package/client.d.ts +6 -5
  4. package/client.d.ts.map +1 -1
  5. package/client.js +7 -7
  6. package/client.js.map +1 -1
  7. package/cql_gen/create_table.d.ts +1 -1
  8. package/cql_gen/create_table.d.ts.map +1 -1
  9. package/document/index.d.ts +3 -3
  10. package/document/index.d.ts.map +1 -1
  11. package/driver/LICENSE.txt +177 -0
  12. package/driver/NOTICE.txt +67 -0
  13. package/driver/auth/index.d.ts +37 -0
  14. package/driver/auth/index.js +37 -0
  15. package/driver/auth/no-auth-provider.js +73 -0
  16. package/driver/auth/plain-text-auth-provider.js +81 -0
  17. package/driver/auth/provider.js +77 -0
  18. package/driver/client-options.js +442 -0
  19. package/driver/client.js +1267 -0
  20. package/driver/concurrent/index.d.ts +49 -0
  21. package/driver/concurrent/index.js +366 -0
  22. package/driver/connection.js +1034 -0
  23. package/driver/control-connection.js +1282 -0
  24. package/driver/encoder.js +2316 -0
  25. package/driver/errors.js +223 -0
  26. package/driver/execution-options.js +612 -0
  27. package/driver/execution-profile.js +274 -0
  28. package/driver/host-connection-pool.js +587 -0
  29. package/driver/host.js +699 -0
  30. package/driver/index.d.ts +387 -0
  31. package/driver/index.js +81 -0
  32. package/driver/mapping/cache.js +214 -0
  33. package/driver/mapping/doc-info-adapter.js +171 -0
  34. package/driver/mapping/index.d.ts +219 -0
  35. package/driver/mapping/index.js +57 -0
  36. package/driver/mapping/mapper.js +225 -0
  37. package/driver/mapping/mapping-handler.js +641 -0
  38. package/driver/mapping/model-batch-item.js +215 -0
  39. package/driver/mapping/model-batch-mapper.js +141 -0
  40. package/driver/mapping/model-mapper.js +315 -0
  41. package/driver/mapping/model-mapping-info.js +225 -0
  42. package/driver/mapping/object-selector.js +417 -0
  43. package/driver/mapping/q.js +156 -0
  44. package/driver/mapping/query-generator.js +556 -0
  45. package/driver/mapping/result-mapper.js +123 -0
  46. package/driver/mapping/result.js +139 -0
  47. package/driver/mapping/table-mappings.js +133 -0
  48. package/driver/mapping/tree.js +160 -0
  49. package/driver/metadata/aggregate.js +79 -0
  50. package/driver/metadata/client-state.js +119 -0
  51. package/driver/metadata/data-collection.js +182 -0
  52. package/driver/metadata/event-debouncer.js +174 -0
  53. package/driver/metadata/index.d.ts +276 -0
  54. package/driver/metadata/index.js +1156 -0
  55. package/driver/metadata/materialized-view.js +49 -0
  56. package/driver/metadata/schema-function.js +98 -0
  57. package/driver/metadata/schema-index.js +166 -0
  58. package/driver/metadata/schema-parser.js +1399 -0
  59. package/driver/metadata/table-metadata.js +77 -0
  60. package/driver/operation-state.js +206 -0
  61. package/driver/policies/address-resolution.js +145 -0
  62. package/driver/policies/index.d.ts +241 -0
  63. package/driver/policies/index.js +110 -0
  64. package/driver/policies/load-balancing.js +970 -0
  65. package/driver/policies/reconnection.js +166 -0
  66. package/driver/policies/retry.js +326 -0
  67. package/driver/policies/speculative-execution.js +150 -0
  68. package/driver/policies/timestamp-generation.js +176 -0
  69. package/driver/prepare-handler.js +347 -0
  70. package/driver/promise-utils.js +191 -0
  71. package/driver/readers.js +624 -0
  72. package/driver/request-execution.js +644 -0
  73. package/driver/request-handler.js +332 -0
  74. package/driver/requests.js +618 -0
  75. package/driver/stream-id-stack.js +209 -0
  76. package/driver/streams.js +745 -0
  77. package/driver/token.js +325 -0
  78. package/driver/tokenizer.js +631 -0
  79. package/driver/types/big-decimal.js +282 -0
  80. package/driver/types/duration.js +576 -0
  81. package/driver/types/index.d.ts +486 -0
  82. package/driver/types/index.js +733 -0
  83. package/driver/types/inet-address.js +262 -0
  84. package/driver/types/integer.js +818 -0
  85. package/driver/types/local-date.js +280 -0
  86. package/driver/types/local-time.js +299 -0
  87. package/driver/types/mutable-long.js +385 -0
  88. package/driver/types/protocol-version.js +391 -0
  89. package/driver/types/result-set.js +287 -0
  90. package/driver/types/result-stream.js +164 -0
  91. package/driver/types/row.js +85 -0
  92. package/driver/types/time-uuid.js +414 -0
  93. package/driver/types/tuple.js +103 -0
  94. package/driver/types/uuid.js +160 -0
  95. package/driver/types/vector.js +130 -0
  96. package/driver/types/version-number.js +153 -0
  97. package/driver/utils.js +1485 -0
  98. package/driver/writers.js +350 -0
  99. package/global.d.ts +1 -1
  100. package/global.d.ts.map +1 -1
  101. package/index.d.ts +6 -6
  102. package/index.d.ts.map +1 -1
  103. package/index.js +6 -6
  104. package/index.js.map +1 -1
  105. package/migrate/index.d.ts +1 -1
  106. package/migrate/index.d.ts.map +1 -1
  107. package/migrate/index.js +1 -1
  108. package/migrate/index.js.map +1 -1
  109. package/model/index.d.ts +6 -6
  110. package/model/index.d.ts.map +1 -1
  111. package/model/index.js +10 -10
  112. package/model/index.js.map +1 -1
  113. package/operations/countAll.d.ts +1 -1
  114. package/operations/countAll.d.ts.map +1 -1
  115. package/operations/delete.d.ts +3 -4
  116. package/operations/delete.d.ts.map +1 -1
  117. package/operations/delete.js +1 -1
  118. package/operations/delete.js.map +1 -1
  119. package/operations/find.d.ts +2 -2
  120. package/operations/find.d.ts.map +1 -1
  121. package/operations/find.js +1 -1
  122. package/operations/find.js.map +1 -1
  123. package/operations/findOne.d.ts +2 -2
  124. package/operations/findOne.d.ts.map +1 -1
  125. package/operations/findOne.js +1 -1
  126. package/operations/findOne.js.map +1 -1
  127. package/operations/insert.d.ts +3 -3
  128. package/operations/insert.d.ts.map +1 -1
  129. package/operations/insert.js +2 -2
  130. package/operations/insert.js.map +1 -1
  131. package/operations/sync.d.ts +1 -1
  132. package/operations/sync.d.ts.map +1 -1
  133. package/operations/sync.js +1 -1
  134. package/operations/sync.js.map +1 -1
  135. package/operations/tableExists.d.ts +1 -1
  136. package/operations/tableExists.d.ts.map +1 -1
  137. package/operations/update.d.ts +3 -3
  138. package/operations/update.d.ts.map +1 -1
  139. package/operations/update.js +2 -2
  140. package/operations/update.js.map +1 -1
  141. package/package.json +4 -12
  142. package/schema/index.d.ts +1 -1
  143. package/schema/index.d.ts.map +1 -1
  144. package/types.d.ts +4 -4
  145. package/types.d.ts.map +1 -1
  146. package/utils/queryParser.d.ts +1 -1
  147. package/utils/queryParser.d.ts.map +1 -1
  148. package/utils/queryParser.js +1 -1
  149. package/utils/queryParser.js.map +1 -1
  150. package/utils/typeChecker.d.ts +1 -1
  151. package/utils/typeChecker.d.ts.map +1 -1
  152. package/utils/typeChecker.js +1 -1
  153. package/utils/typeChecker.js.map +1 -1
@@ -0,0 +1,164 @@
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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import { Readable } from "stream"
20
+ import utils from "../utils.js"
21
+ import errors from "../errors.js"
22
+ import clientOptions from "../client-options.js"
23
+
24
+ /** @module types */
25
+ /**
26
+ * Readable stream using to yield data from a result or a field
27
+ */
28
+ class ResultStream extends Readable {
29
+ constructor(opt) {
30
+ super(opt)
31
+ this.buffer = []
32
+ this.paused = true
33
+ this._cancelAllowed = false
34
+ this._handlersObject = null
35
+ this._highWaterMarkRows = 0
36
+ }
37
+
38
+ _read() {
39
+ this.paused = false
40
+ if (this.buffer.length === 0) {
41
+ this._readableState.reading = false
42
+ }
43
+ while (!this.paused && this.buffer.length > 0) {
44
+ this.paused = !this.push(this.buffer.shift())
45
+ }
46
+ this._checkBelowHighWaterMark()
47
+ if (!this.paused && !this.buffer.length && this._readNext) {
48
+ this._readNext()
49
+ this._readNext = null
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Allows for throttling, helping nodejs keep the internal buffers reasonably sized.
55
+ * @param {function} readNext function that triggers reading the next result chunk
56
+ * @ignore
57
+ */
58
+ _valve(readNext) {
59
+ this._readNext = null
60
+ if (!readNext) {
61
+ return
62
+ }
63
+ if (this.paused || this.buffer.length) {
64
+ this._readNext = readNext
65
+ } else {
66
+ readNext()
67
+ }
68
+ }
69
+
70
+ add(chunk) {
71
+ const length = this.buffer.push(chunk)
72
+ this.read(0)
73
+ this._checkAboveHighWaterMark()
74
+ return length
75
+ }
76
+
77
+ _checkAboveHighWaterMark() {
78
+ if (
79
+ !this._handlersObject ||
80
+ !this._handlersObject.resumeReadingHandler
81
+ ) {
82
+ return
83
+ }
84
+ if (
85
+ this._highWaterMarkRows === 0 ||
86
+ this.buffer.length !== this._highWaterMarkRows
87
+ ) {
88
+ return
89
+ }
90
+ this._handlersObject.resumeReadingHandler(false)
91
+ }
92
+
93
+ _checkBelowHighWaterMark() {
94
+ if (
95
+ !this._handlersObject ||
96
+ !this._handlersObject.resumeReadingHandler
97
+ ) {
98
+ return
99
+ }
100
+ if (
101
+ this._highWaterMarkRows === 0 ||
102
+ this.buffer.length >= this._highWaterMarkRows
103
+ ) {
104
+ return
105
+ }
106
+ // The consumer has dequeued below the watermark
107
+ this._handlersObject.resumeReadingHandler(true)
108
+ }
109
+
110
+ /**
111
+ * When continuous paging is enabled, allows the client to notify to the server to stop pushing further pages.
112
+ * <p>Note: This is not part of the public API yet.</p>
113
+ * @param {Function} [callback] The cancel method accepts an optional callback.
114
+ * @example <caption>Cancelling a continuous paging execution</caption>
115
+ * const stream = client.stream(query, params, { prepare: true, continuousPaging: true });
116
+ * // ...
117
+ * // Ask the server to stop pushing rows.
118
+ * stream.cancel();
119
+ * @ignore
120
+ */
121
+ cancel(callback) {
122
+ if (!this._cancelAllowed) {
123
+ const err = new Error(
124
+ "You can only cancel streaming executions when continuous paging is enabled",
125
+ )
126
+ if (!callback) {
127
+ throw err
128
+ }
129
+ return callback(err)
130
+ }
131
+ if (!this._handlersObject) {
132
+ throw new errors.DriverInternalError(
133
+ "ResultStream cancel is allowed but the cancel options were not set",
134
+ )
135
+ }
136
+ callback = callback || utils.noop
137
+ if (!this._handlersObject.cancelHandler) {
138
+ // The handler is not yet set
139
+ // Set the callback as a flag to identify that the cancel handler must be invoked when set
140
+ this._handlersObject.cancelHandler = callback
141
+ return
142
+ }
143
+ this._handlersObject.cancelHandler(callback)
144
+ }
145
+
146
+ /**
147
+ * Sets the pointer to the handler to be used to cancel the continuous page execution.
148
+ * @param options
149
+ * @internal
150
+ * @ignore
151
+ */
152
+ setHandlers(options) {
153
+ if (!options.continuousPaging) {
154
+ return
155
+ }
156
+ this._cancelAllowed = true
157
+ this._handlersObject = options
158
+ this._highWaterMarkRows =
159
+ options.continuousPaging.highWaterMarkRows ||
160
+ clientOptions.continuousPageDefaultHighWaterMark
161
+ }
162
+ }
163
+
164
+ export default ResultStream
@@ -0,0 +1,85 @@
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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ /** @module types */
19
+ /**
20
+ * Represents a result row
21
+ * @param {Array} columns
22
+ * @constructor
23
+ */
24
+ function Row(columns) {
25
+ if (!columns) {
26
+ throw new Error("Columns not defined")
27
+ }
28
+ //Private non-enumerable properties, with double underscore to avoid interfering with column names
29
+ Object.defineProperty(this, "__columns", {
30
+ value: columns,
31
+ enumerable: false,
32
+ writable: false,
33
+ })
34
+ }
35
+
36
+ /**
37
+ * Returns the cell value.
38
+ * @param {String|Number} columnName Name or index of the column
39
+ */
40
+ Row.prototype.get = function (columnName) {
41
+ if (typeof columnName === "number") {
42
+ //its an index
43
+ return this[this.__columns[columnName].name]
44
+ }
45
+ return this[columnName]
46
+ }
47
+
48
+ /**
49
+ * Returns an array of the values of the row
50
+ * @returns {Array}
51
+ */
52
+ Row.prototype.values = function () {
53
+ const valuesArray = []
54
+ this.forEach(function (val) {
55
+ valuesArray.push(val)
56
+ })
57
+ return valuesArray
58
+ }
59
+
60
+ /**
61
+ * Returns an array of the column names of the row
62
+ * @returns {Array}
63
+ */
64
+ Row.prototype.keys = function () {
65
+ const keysArray = []
66
+ this.forEach(function (val, key) {
67
+ keysArray.push(key)
68
+ })
69
+ return keysArray
70
+ }
71
+
72
+ /**
73
+ * Executes the callback for each field in the row, containing the value as first parameter followed by the columnName
74
+ * @param {Function} callback
75
+ */
76
+ Row.prototype.forEach = function (callback) {
77
+ for (const columnName in this) {
78
+ if (!this.hasOwnProperty(columnName)) {
79
+ continue
80
+ }
81
+ callback(this[columnName], columnName)
82
+ }
83
+ }
84
+
85
+ export default Row
@@ -0,0 +1,414 @@
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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ import util from "util"
19
+ import crypto from "crypto"
20
+ import Long from "long"
21
+
22
+ import Uuid from "./uuid.js"
23
+ import utils from "../utils.js"
24
+
25
+ /** @module types */
26
+ /**
27
+ * Oct 15, 1582 in milliseconds since unix epoch
28
+ * @const
29
+ * @private
30
+ */
31
+ const _unixToGregorian = 12219292800000
32
+ /**
33
+ * 10,000 ticks in a millisecond
34
+ * @const
35
+ * @private
36
+ */
37
+ const _ticksInMs = 10000
38
+
39
+ const minNodeId = utils.allocBufferFromString("808080808080", "hex")
40
+ const minClockId = utils.allocBufferFromString("8080", "hex")
41
+ const maxNodeId = utils.allocBufferFromString("7f7f7f7f7f7f", "hex")
42
+ const maxClockId = utils.allocBufferFromString("7f7f", "hex")
43
+
44
+ /**
45
+ * Counter used to generate up to 10000 different timeuuid values with the same Date
46
+ * @private
47
+ * @type {number}
48
+ */
49
+ let _ticks = 0
50
+ /**
51
+ * Counter used to generate ticks for the current time
52
+ * @private
53
+ * @type {number}
54
+ */
55
+ let _ticksForCurrentTime = 0
56
+ /**
57
+ * Remember the last time when a ticks for the current time so that it can be reset
58
+ * @private
59
+ * @type {number}
60
+ */
61
+ let _lastTimestamp = 0
62
+
63
+ /**
64
+ * Creates a new instance of Uuid based on the parameters provided according to rfc4122.
65
+ * If any of the arguments is not provided, it will be randomly generated, except for the date that will use the current
66
+ * date.
67
+ * <p>
68
+ * Note that when nodeId and/or clockId portions are not provided, the constructor will generate them using
69
+ * <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
70
+ * recommended that you use the callback-based version of the static methods <code>fromDate()</code> or
71
+ * <code>now()</code> in that case.
72
+ * </p>
73
+ * @class
74
+ * @classdesc Represents an immutable version 1 universally unique identifier (UUID). A UUID represents a 128-bit value.
75
+ * <p>Usage: <code>TimeUuid.now()</code></p>
76
+ * @extends module:types~Uuid
77
+ * @param {Date} [value] The datetime for the instance, if not provided, it will use the current Date.
78
+ * @param {Number} [ticks] A number from 0 to 10000 representing the 100-nanoseconds units for this instance to fill in the information not available in the Date,
79
+ * as Ecmascript Dates have only milliseconds precision.
80
+ * @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
81
+ * @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
82
+ * @constructor
83
+ */
84
+ function TimeUuid(value, ticks, nodeId, clockId) {
85
+ let buffer
86
+ if (value instanceof Buffer) {
87
+ if (value.length !== 16) {
88
+ throw new Error("Buffer for v1 uuid not valid")
89
+ }
90
+ buffer = value
91
+ } else {
92
+ buffer = generateBuffer(value, ticks, nodeId, clockId)
93
+ }
94
+ Uuid.call(this, buffer)
95
+ }
96
+
97
+ util.inherits(TimeUuid, Uuid)
98
+
99
+ /**
100
+ * Generates a TimeUuid instance based on the Date provided using random node and clock values.
101
+ * @param {Date} date Date to generate the v1 uuid.
102
+ * @param {Number} [ticks] A number from 0 to 10000 representing the 100-nanoseconds units for this instance to fill in the information not available in the Date,
103
+ * as Ecmascript Dates have only milliseconds precision.
104
+ * @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
105
+ * If not provided, a random nodeId will be generated.
106
+ * @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
107
+ * If not provided a random clockId will be generated.
108
+ * @param {Function} [callback] An optional callback to be invoked with the error as first parameter and the created
109
+ * <code>TimeUuid</code> as second parameter. When a callback is provided, the random portions of the
110
+ * <code>TimeUuid</code> instance are created asynchronously.
111
+ * <p>
112
+ * When nodeId and/or clockId portions are not provided, this method will generate them using
113
+ * <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
114
+ * recommended that you use the callback-based version of this method in that case.
115
+ * </p>
116
+ * @example <caption>Generate a TimeUuid from a ECMAScript Date</caption>
117
+ * const timeuuid = TimeUuid.fromDate(new Date());
118
+ * @example <caption>Generate a TimeUuid from a Date with ticks portion</caption>
119
+ * const timeuuid = TimeUuid.fromDate(new Date(), 1203);
120
+ * @example <caption>Generate a TimeUuid from a Date without any random portion</caption>
121
+ * const timeuuid = TimeUuid.fromDate(new Date(), 1203, 'host01', '02');
122
+ * @example <caption>Generate a TimeUuid from a Date with random node and clock identifiers</caption>
123
+ * TimeUuid.fromDate(new Date(), 1203, function (err, timeuuid) {
124
+ * // do something with the generated timeuuid
125
+ * });
126
+ */
127
+ TimeUuid.fromDate = function (date, ticks, nodeId, clockId, callback) {
128
+ if (typeof ticks === "function") {
129
+ callback = ticks
130
+ ticks = nodeId = clockId = null
131
+ } else if (typeof nodeId === "function") {
132
+ callback = nodeId
133
+ nodeId = clockId = null
134
+ } else if (typeof clockId === "function") {
135
+ callback = clockId
136
+ clockId = null
137
+ }
138
+
139
+ if (!callback) {
140
+ return new TimeUuid(date, ticks, nodeId, clockId)
141
+ }
142
+
143
+ utils.parallel(
144
+ [
145
+ (next) =>
146
+ getOrGenerateRandom(nodeId, 6, (err, buffer) =>
147
+ next(err, (nodeId = buffer)),
148
+ ),
149
+ (next) =>
150
+ getOrGenerateRandom(clockId, 2, (err, buffer) =>
151
+ next(err, (clockId = buffer)),
152
+ ),
153
+ ],
154
+ (err) => {
155
+ if (err) {
156
+ return callback(err)
157
+ }
158
+
159
+ let timeUuid
160
+ try {
161
+ timeUuid = new TimeUuid(date, ticks, nodeId, clockId)
162
+ } catch (e) {
163
+ return callback(e)
164
+ }
165
+
166
+ callback(null, timeUuid)
167
+ },
168
+ )
169
+ }
170
+
171
+ /**
172
+ * Parses a string representation of a TimeUuid
173
+ * @param {String} value
174
+ * @returns {TimeUuid}
175
+ */
176
+ TimeUuid.fromString = function (value) {
177
+ return new TimeUuid(Uuid.fromString(value).getBuffer())
178
+ }
179
+
180
+ /**
181
+ * Returns the smaller possible type 1 uuid with the provided Date.
182
+ */
183
+ TimeUuid.min = function (date, ticks) {
184
+ return new TimeUuid(date, ticks, minNodeId, minClockId)
185
+ }
186
+
187
+ /**
188
+ * Returns the biggest possible type 1 uuid with the provided Date.
189
+ */
190
+ TimeUuid.max = function (date, ticks) {
191
+ return new TimeUuid(date, ticks, maxNodeId, maxClockId)
192
+ }
193
+
194
+ /**
195
+ * Generates a TimeUuid instance based on the current date using random node and clock values.
196
+ * @param {String|Buffer} [nodeId] A 6-length Buffer or string of 6 ascii characters representing the node identifier, ie: 'host01'.
197
+ * If not provided, a random nodeId will be generated.
198
+ * @param {String|Buffer} [clockId] A 2-length Buffer or string of 6 ascii characters representing the clock identifier.
199
+ * If not provided a random clockId will be generated.
200
+ * @param {Function} [callback] An optional callback to be invoked with the error as first parameter and the created
201
+ * <code>TimeUuid</code> as second parameter. When a callback is provided, the random portions of the
202
+ * <code>TimeUuid</code> instance are created asynchronously.
203
+ * <p>
204
+ * When nodeId and/or clockId portions are not provided, this method will generate them using
205
+ * <code>crypto.randomBytes()</code>. As it's possible that <code>crypto.randomBytes()</code> might block, it's
206
+ * recommended that you use the callback-based version of this method in that case.
207
+ * </p>
208
+ * @example <caption>Generate a TimeUuid from a Date without any random portion</caption>
209
+ * const timeuuid = TimeUuid.now('host01', '02');
210
+ * @example <caption>Generate a TimeUuid with random node and clock identifiers</caption>
211
+ * TimeUuid.now(function (err, timeuuid) {
212
+ * // do something with the generated timeuuid
213
+ * });
214
+ * @example <caption>Generate a TimeUuid based on the current date (might block)</caption>
215
+ * const timeuuid = TimeUuid.now();
216
+ */
217
+ TimeUuid.now = function (nodeId, clockId, callback) {
218
+ return TimeUuid.fromDate(null, null, nodeId, clockId, callback)
219
+ }
220
+
221
+ /**
222
+ * Gets the Date and 100-nanoseconds units representation of this instance.
223
+ * @returns {{date: Date, ticks: Number}}
224
+ */
225
+ TimeUuid.prototype.getDatePrecision = function () {
226
+ const timeLow = this.buffer.readUInt32BE(0)
227
+
228
+ let timeHigh = 0
229
+ timeHigh |= (this.buffer[4] & 0xff) << 8
230
+ timeHigh |= this.buffer[5] & 0xff
231
+ timeHigh |= (this.buffer[6] & 0x0f) << 24
232
+ timeHigh |= (this.buffer[7] & 0xff) << 16
233
+
234
+ const val = Long.fromBits(timeLow, timeHigh)
235
+ const ticksInMsLong = Long.fromNumber(_ticksInMs)
236
+ const ticks = val.modulo(ticksInMsLong)
237
+ const time = val
238
+ .div(ticksInMsLong)
239
+ .subtract(Long.fromNumber(_unixToGregorian))
240
+ return { date: new Date(time.toNumber()), ticks: ticks.toNumber() }
241
+ }
242
+
243
+ /**
244
+ * Gets the Date representation of this instance.
245
+ * @returns {Date}
246
+ */
247
+ TimeUuid.prototype.getDate = function () {
248
+ return this.getDatePrecision().date
249
+ }
250
+
251
+ /**
252
+ * Returns the node id this instance
253
+ * @returns {Buffer}
254
+ */
255
+ TimeUuid.prototype.getNodeId = function () {
256
+ return this.buffer.slice(10)
257
+ }
258
+
259
+ /**
260
+ * Returns the clock id this instance, with the variant applied (first 2 msb being 1 and 0).
261
+ * @returns {Buffer}
262
+ */
263
+ TimeUuid.prototype.getClockId = function () {
264
+ return this.buffer.slice(8, 10)
265
+ }
266
+
267
+ /**
268
+ * Returns the node id this instance as an ascii string
269
+ * @returns {String}
270
+ */
271
+ TimeUuid.prototype.getNodeIdString = function () {
272
+ return this.buffer.slice(10).toString("ascii")
273
+ }
274
+
275
+ function writeTime(buffer, time, ticks) {
276
+ //value time expressed in ticks precision
277
+ const val = Long.fromNumber(time + _unixToGregorian)
278
+ .multiply(Long.fromNumber(10000))
279
+ .add(Long.fromNumber(ticks))
280
+ const timeHigh = val.getHighBitsUnsigned()
281
+ buffer.writeUInt32BE(val.getLowBitsUnsigned(), 0)
282
+ buffer.writeUInt16BE(timeHigh & 0xffff, 4)
283
+ buffer.writeUInt16BE((timeHigh >>> 16) & 0xffff, 6)
284
+ }
285
+
286
+ /**
287
+ * Returns a buffer of length 2 representing the clock identifier
288
+ * @param {String|Buffer} clockId
289
+ * @returns {Buffer}
290
+ * @private
291
+ */
292
+ function getClockId(clockId) {
293
+ let buffer = clockId
294
+ if (typeof clockId === "string") {
295
+ buffer = utils.allocBufferFromString(clockId, "ascii")
296
+ }
297
+ if (!(buffer instanceof Buffer)) {
298
+ //Generate
299
+ buffer = getRandomBytes(2)
300
+ } else if (buffer.length !== 2) {
301
+ throw new Error("Clock identifier must have 2 bytes")
302
+ }
303
+ return buffer
304
+ }
305
+
306
+ /**
307
+ * Returns a buffer of length 6 representing the clock identifier
308
+ * @param {String|Buffer} nodeId
309
+ * @returns {Buffer}
310
+ * @private
311
+ */
312
+ function getNodeId(nodeId) {
313
+ let buffer = nodeId
314
+ if (typeof nodeId === "string") {
315
+ buffer = utils.allocBufferFromString(nodeId, "ascii")
316
+ }
317
+ if (!(buffer instanceof Buffer)) {
318
+ //Generate
319
+ buffer = getRandomBytes(6)
320
+ } else if (buffer.length !== 6) {
321
+ throw new Error("Node identifier must have 6 bytes")
322
+ }
323
+ return buffer
324
+ }
325
+
326
+ /**
327
+ * Returns the ticks portion of a timestamp. If the ticks are not provided an internal counter is used that gets reset at 10000.
328
+ * @private
329
+ * @param {Number} [ticks]
330
+ * @returns {Number}
331
+ */
332
+ function getTicks(ticks) {
333
+ if (typeof ticks !== "number" || ticks >= _ticksInMs) {
334
+ _ticks++
335
+ if (_ticks >= _ticksInMs) {
336
+ _ticks = 0
337
+ }
338
+ ticks = _ticks
339
+ }
340
+ return ticks
341
+ }
342
+
343
+ /**
344
+ * Returns an object with the time representation of the date expressed in milliseconds since unix epoch
345
+ * and a ticks property for the 100-nanoseconds precision.
346
+ * @private
347
+ * @returns {{time: Number, ticks: Number}}
348
+ */
349
+ function getTimeWithTicks(date, ticks) {
350
+ if (!(date instanceof Date) || isNaN(date.getTime())) {
351
+ // time with ticks for the current time
352
+ date = new Date()
353
+ const time = date.getTime()
354
+ _ticksForCurrentTime++
355
+ if (_ticksForCurrentTime > _ticksInMs || time > _lastTimestamp) {
356
+ _ticksForCurrentTime = 0
357
+ _lastTimestamp = time
358
+ }
359
+ ticks = _ticksForCurrentTime
360
+ }
361
+ return {
362
+ time: date.getTime(),
363
+ ticks: getTicks(ticks),
364
+ }
365
+ }
366
+
367
+ function getRandomBytes(length) {
368
+ return crypto.randomBytes(length)
369
+ }
370
+
371
+ function getOrGenerateRandom(id, length, callback) {
372
+ if (id) {
373
+ return callback(null, id)
374
+ }
375
+ crypto.randomBytes(length, callback)
376
+ }
377
+
378
+ /**
379
+ * Generates a 16-length Buffer instance
380
+ * @private
381
+ * @param {Date} date
382
+ * @param {Number} ticks
383
+ * @param {String|Buffer} nodeId
384
+ * @param {String|Buffer} clockId
385
+ * @returns {Buffer}
386
+ */
387
+ function generateBuffer(date, ticks, nodeId, clockId) {
388
+ const timeWithTicks = getTimeWithTicks(date, ticks)
389
+ nodeId = getNodeId(nodeId)
390
+ clockId = getClockId(clockId)
391
+ const buffer = utils.allocBufferUnsafe(16)
392
+ //Positions 0-7 Timestamp
393
+ writeTime(buffer, timeWithTicks.time, timeWithTicks.ticks)
394
+ //Position 8-9 Clock
395
+ clockId.copy(buffer, 8, 0)
396
+ //Positions 10-15 Node
397
+ nodeId.copy(buffer, 10, 0)
398
+ //Version Byte: Time based
399
+ //0001xxxx
400
+ //turn off first 4 bits
401
+ buffer[6] = buffer[6] & 0x0f
402
+ //turn on fifth bit
403
+ buffer[6] = buffer[6] | 0x10
404
+
405
+ //IETF Variant Byte: 1.0.x
406
+ //10xxxxxx
407
+ //turn off first 2 bits
408
+ buffer[8] = buffer[8] & 0x3f
409
+ //turn on first bit
410
+ buffer[8] = buffer[8] | 0x80
411
+ return buffer
412
+ }
413
+
414
+ export default TimeUuid