envio 2.31.0-alpha.0 → 2.31.0-alpha.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.
- package/package.json +5 -5
- package/src/Batch.res +400 -28
- package/src/Batch.res.js +286 -24
- package/src/EventRegister.res +9 -3
- package/src/EventRegister.res.js +6 -3
- package/src/EventRegister.resi +4 -1
- package/src/FetchState.res +116 -155
- package/src/FetchState.res.js +116 -106
- package/src/Internal.res +49 -0
- package/src/InternalConfig.res +1 -1
- package/src/Persistence.res +16 -1
- package/src/Persistence.res.js +1 -1
- package/src/PgStorage.res +49 -61
- package/src/PgStorage.res.js +44 -37
- package/src/Prometheus.res +7 -1
- package/src/Prometheus.res.js +8 -1
- package/src/ReorgDetection.res +222 -235
- package/src/ReorgDetection.res.js +34 -28
- package/src/SafeCheckpointTracking.res +132 -0
- package/src/SafeCheckpointTracking.res.js +95 -0
- package/src/Utils.res +64 -21
- package/src/Utils.res.js +61 -30
- package/src/db/EntityHistory.res +172 -294
- package/src/db/EntityHistory.res.js +98 -218
- package/src/db/InternalTable.gen.ts +13 -13
- package/src/db/InternalTable.res +286 -77
- package/src/db/InternalTable.res.js +160 -79
- package/src/db/Table.res +1 -0
- package/src/db/Table.res.js +1 -1
- package/src/sources/EventRouter.res +1 -1
- package/src/sources/Source.res +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// We need this module to effectively track safe checkpoint id
|
|
2
|
+
// this is very cheap to do in memory, while requires a lot of work on a db
|
|
3
|
+
// especially when save_full_history is enabled.
|
|
4
|
+
// The safe checkpoint id can be used to optimize checkpoints traverse logic and
|
|
5
|
+
// make pruning operation super cheap.
|
|
6
|
+
type t = {
|
|
7
|
+
checkpointIds: array<int>,
|
|
8
|
+
checkpointBlockNumbers: array<int>,
|
|
9
|
+
maxReorgDepth: int,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let make = (
|
|
13
|
+
~maxReorgDepth,
|
|
14
|
+
~shouldRollbackOnReorg,
|
|
15
|
+
~chainReorgCheckpoints: array<Internal.reorgCheckpoint>,
|
|
16
|
+
) => {
|
|
17
|
+
if maxReorgDepth > 0 && shouldRollbackOnReorg {
|
|
18
|
+
let checkpointIds = Belt.Array.makeUninitializedUnsafe(chainReorgCheckpoints->Array.length)
|
|
19
|
+
let checkpointBlockNumbers = Belt.Array.makeUninitializedUnsafe(
|
|
20
|
+
chainReorgCheckpoints->Array.length,
|
|
21
|
+
)
|
|
22
|
+
chainReorgCheckpoints->Js.Array2.forEachi((checkpoint, idx) => {
|
|
23
|
+
checkpointIds->Belt.Array.setUnsafe(idx, checkpoint.checkpointId)
|
|
24
|
+
checkpointBlockNumbers->Belt.Array.setUnsafe(idx, checkpoint.blockNumber)
|
|
25
|
+
})
|
|
26
|
+
Some({
|
|
27
|
+
checkpointIds,
|
|
28
|
+
checkpointBlockNumbers,
|
|
29
|
+
maxReorgDepth,
|
|
30
|
+
})
|
|
31
|
+
} else {
|
|
32
|
+
None
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int) => {
|
|
37
|
+
let safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth
|
|
38
|
+
|
|
39
|
+
if safeCheckpointTracking.checkpointBlockNumbers->Belt.Array.getUnsafe(0) > safeBlockNumber {
|
|
40
|
+
0
|
|
41
|
+
} else {
|
|
42
|
+
let trackingCheckpointsCount = safeCheckpointTracking.checkpointBlockNumbers->Array.length
|
|
43
|
+
switch trackingCheckpointsCount {
|
|
44
|
+
| 1 => safeCheckpointTracking.checkpointIds->Belt.Array.getUnsafe(0)
|
|
45
|
+
| _ => {
|
|
46
|
+
let result = ref(None)
|
|
47
|
+
let idx = ref(1)
|
|
48
|
+
|
|
49
|
+
while idx.contents < trackingCheckpointsCount && result.contents === None {
|
|
50
|
+
if (
|
|
51
|
+
safeCheckpointTracking.checkpointBlockNumbers->Belt.Array.getUnsafe(idx.contents) >
|
|
52
|
+
safeBlockNumber
|
|
53
|
+
) {
|
|
54
|
+
result :=
|
|
55
|
+
Some(safeCheckpointTracking.checkpointIds->Belt.Array.getUnsafe(idx.contents - 1))
|
|
56
|
+
}
|
|
57
|
+
idx := idx.contents + 1
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
switch result.contents {
|
|
61
|
+
| Some(checkpointId) => checkpointId
|
|
62
|
+
| None =>
|
|
63
|
+
safeCheckpointTracking.checkpointIds->Belt.Array.getUnsafe(trackingCheckpointsCount - 1)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let updateOnNewBatch = (
|
|
71
|
+
safeCheckpointTracking: t,
|
|
72
|
+
~sourceBlockNumber: int,
|
|
73
|
+
~chainId: int,
|
|
74
|
+
~batchCheckpointIds: array<int>,
|
|
75
|
+
~batchCheckpointBlockNumbers: array<int>,
|
|
76
|
+
~batchCheckpointChainIds: array<int>,
|
|
77
|
+
) => {
|
|
78
|
+
let safeCheckpointId = getSafeCheckpointId(safeCheckpointTracking, ~sourceBlockNumber)
|
|
79
|
+
|
|
80
|
+
let mutCheckpointIds = []
|
|
81
|
+
let mutCheckpointBlockNumbers = []
|
|
82
|
+
|
|
83
|
+
// Copy + Clean up old checkpoints
|
|
84
|
+
for idx in 0 to safeCheckpointTracking.checkpointIds->Array.length - 1 {
|
|
85
|
+
let checkpointId = safeCheckpointTracking.checkpointIds->Belt.Array.getUnsafe(idx)
|
|
86
|
+
if checkpointId >= safeCheckpointId {
|
|
87
|
+
mutCheckpointIds->Js.Array2.push(checkpointId)->ignore
|
|
88
|
+
mutCheckpointBlockNumbers
|
|
89
|
+
->Js.Array2.push(safeCheckpointTracking.checkpointBlockNumbers->Belt.Array.getUnsafe(idx))
|
|
90
|
+
->ignore
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Append new checkpoints
|
|
95
|
+
for idx in 0 to batchCheckpointIds->Array.length - 1 {
|
|
96
|
+
if batchCheckpointChainIds->Belt.Array.getUnsafe(idx) === chainId {
|
|
97
|
+
mutCheckpointIds->Js.Array2.push(batchCheckpointIds->Belt.Array.getUnsafe(idx))->ignore
|
|
98
|
+
mutCheckpointBlockNumbers
|
|
99
|
+
->Js.Array2.push(batchCheckpointBlockNumbers->Belt.Array.getUnsafe(idx))
|
|
100
|
+
->ignore
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
checkpointIds: mutCheckpointIds,
|
|
106
|
+
checkpointBlockNumbers: mutCheckpointBlockNumbers,
|
|
107
|
+
maxReorgDepth: safeCheckpointTracking.maxReorgDepth,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let rollback = (safeCheckpointTracking: t, ~targetBlockNumber: int) => {
|
|
112
|
+
let mutCheckpointIds = []
|
|
113
|
+
let mutCheckpointBlockNumbers = []
|
|
114
|
+
|
|
115
|
+
for idx in 0 to safeCheckpointTracking.checkpointIds->Array.length - 1 {
|
|
116
|
+
let blockNumber = safeCheckpointTracking.checkpointBlockNumbers->Belt.Array.getUnsafe(idx)
|
|
117
|
+
if blockNumber <= targetBlockNumber {
|
|
118
|
+
mutCheckpointIds
|
|
119
|
+
->Js.Array2.push(safeCheckpointTracking.checkpointIds->Belt.Array.getUnsafe(idx))
|
|
120
|
+
->ignore
|
|
121
|
+
mutCheckpointBlockNumbers
|
|
122
|
+
->Js.Array2.push(safeCheckpointTracking.checkpointBlockNumbers->Belt.Array.getUnsafe(idx))
|
|
123
|
+
->ignore
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
{
|
|
128
|
+
checkpointIds: mutCheckpointIds,
|
|
129
|
+
checkpointBlockNumbers: mutCheckpointBlockNumbers,
|
|
130
|
+
maxReorgDepth: safeCheckpointTracking.maxReorgDepth,
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
function make(maxReorgDepth, shouldRollbackOnReorg, chainReorgCheckpoints) {
|
|
6
|
+
if (!(maxReorgDepth > 0 && shouldRollbackOnReorg)) {
|
|
7
|
+
return ;
|
|
8
|
+
}
|
|
9
|
+
var checkpointIds = new Array(chainReorgCheckpoints.length);
|
|
10
|
+
var checkpointBlockNumbers = new Array(chainReorgCheckpoints.length);
|
|
11
|
+
chainReorgCheckpoints.forEach(function (checkpoint, idx) {
|
|
12
|
+
checkpointIds[idx] = checkpoint.id;
|
|
13
|
+
checkpointBlockNumbers[idx] = checkpoint.block_number;
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
checkpointIds: checkpointIds,
|
|
17
|
+
checkpointBlockNumbers: checkpointBlockNumbers,
|
|
18
|
+
maxReorgDepth: maxReorgDepth
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber) {
|
|
23
|
+
var safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth | 0;
|
|
24
|
+
if (safeCheckpointTracking.checkpointBlockNumbers[0] > safeBlockNumber) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
var trackingCheckpointsCount = safeCheckpointTracking.checkpointBlockNumbers.length;
|
|
28
|
+
if (trackingCheckpointsCount === 1) {
|
|
29
|
+
return safeCheckpointTracking.checkpointIds[0];
|
|
30
|
+
}
|
|
31
|
+
var result;
|
|
32
|
+
var idx = 1;
|
|
33
|
+
while(idx < trackingCheckpointsCount && result === undefined) {
|
|
34
|
+
if (safeCheckpointTracking.checkpointBlockNumbers[idx] > safeBlockNumber) {
|
|
35
|
+
result = safeCheckpointTracking.checkpointIds[idx - 1 | 0];
|
|
36
|
+
}
|
|
37
|
+
idx = idx + 1 | 0;
|
|
38
|
+
};
|
|
39
|
+
var checkpointId = result;
|
|
40
|
+
if (checkpointId !== undefined) {
|
|
41
|
+
return checkpointId;
|
|
42
|
+
} else {
|
|
43
|
+
return safeCheckpointTracking.checkpointIds[trackingCheckpointsCount - 1 | 0];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function updateOnNewBatch(safeCheckpointTracking, sourceBlockNumber, chainId, batchCheckpointIds, batchCheckpointBlockNumbers, batchCheckpointChainIds) {
|
|
48
|
+
var safeCheckpointId = getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber);
|
|
49
|
+
var mutCheckpointIds = [];
|
|
50
|
+
var mutCheckpointBlockNumbers = [];
|
|
51
|
+
for(var idx = 0 ,idx_finish = safeCheckpointTracking.checkpointIds.length; idx < idx_finish; ++idx){
|
|
52
|
+
var checkpointId = safeCheckpointTracking.checkpointIds[idx];
|
|
53
|
+
if (checkpointId >= safeCheckpointId) {
|
|
54
|
+
mutCheckpointIds.push(checkpointId);
|
|
55
|
+
mutCheckpointBlockNumbers.push(safeCheckpointTracking.checkpointBlockNumbers[idx]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
for(var idx$1 = 0 ,idx_finish$1 = batchCheckpointIds.length; idx$1 < idx_finish$1; ++idx$1){
|
|
60
|
+
if (batchCheckpointChainIds[idx$1] === chainId) {
|
|
61
|
+
mutCheckpointIds.push(batchCheckpointIds[idx$1]);
|
|
62
|
+
mutCheckpointBlockNumbers.push(batchCheckpointBlockNumbers[idx$1]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
checkpointIds: mutCheckpointIds,
|
|
68
|
+
checkpointBlockNumbers: mutCheckpointBlockNumbers,
|
|
69
|
+
maxReorgDepth: safeCheckpointTracking.maxReorgDepth
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function rollback(safeCheckpointTracking, targetBlockNumber) {
|
|
74
|
+
var mutCheckpointIds = [];
|
|
75
|
+
var mutCheckpointBlockNumbers = [];
|
|
76
|
+
for(var idx = 0 ,idx_finish = safeCheckpointTracking.checkpointIds.length; idx < idx_finish; ++idx){
|
|
77
|
+
var blockNumber = safeCheckpointTracking.checkpointBlockNumbers[idx];
|
|
78
|
+
if (blockNumber <= targetBlockNumber) {
|
|
79
|
+
mutCheckpointIds.push(safeCheckpointTracking.checkpointIds[idx]);
|
|
80
|
+
mutCheckpointBlockNumbers.push(safeCheckpointTracking.checkpointBlockNumbers[idx]);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
checkpointIds: mutCheckpointIds,
|
|
86
|
+
checkpointBlockNumbers: mutCheckpointBlockNumbers,
|
|
87
|
+
maxReorgDepth: safeCheckpointTracking.maxReorgDepth
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exports.make = make;
|
|
92
|
+
exports.getSafeCheckpointId = getSafeCheckpointId;
|
|
93
|
+
exports.updateOnNewBatch = updateOnNewBatch;
|
|
94
|
+
exports.rollback = rollback;
|
|
95
|
+
/* No side effect */
|
package/src/Utils.res
CHANGED
|
@@ -97,30 +97,66 @@ module Dict = {
|
|
|
97
97
|
@val
|
|
98
98
|
external mergeInPlace: (dict<'a>, dict<'a>) => dict<'a> = "Object.assign"
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
for
|
|
104
|
-
|
|
105
|
-
newDict->Js.Dict.set(key, fn(dict->Js.Dict.unsafeGet(key)))
|
|
100
|
+
// Use %raw to support for..in which is a ~10% faster than .forEach
|
|
101
|
+
let mapValues: (dict<'a>, 'a => 'b) => dict<'b> = %raw(`(dict, f) => {
|
|
102
|
+
var target = {}, i;
|
|
103
|
+
for (i in dict) {
|
|
104
|
+
target[i] = f(dict[i]);
|
|
106
105
|
}
|
|
107
|
-
|
|
108
|
-
}
|
|
106
|
+
return target;
|
|
107
|
+
}`)
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
// Use %raw to support for..in which is a ~10% faster than .forEach
|
|
110
|
+
let filterMapValues: (dict<'a>, 'a => option<'b>) => dict<'b> = %raw(`(dict, f) => {
|
|
111
|
+
var target = {}, i, v;
|
|
112
|
+
for (i in dict) {
|
|
113
|
+
v = f(dict[i]);
|
|
114
|
+
if (v !== undefined) {
|
|
115
|
+
target[i] = v;
|
|
116
|
+
}
|
|
114
117
|
}
|
|
115
|
-
|
|
118
|
+
return target;
|
|
119
|
+
}`)
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
// Use %raw to support for..in which is a ~10% faster than .forEach
|
|
122
|
+
let mapValuesToArray: (dict<'a>, 'a => 'b) => array<'b> = %raw(`(dict, f) => {
|
|
123
|
+
var target = [], i;
|
|
124
|
+
for (i in dict) {
|
|
125
|
+
target.push(f(dict[i]));
|
|
122
126
|
}
|
|
123
|
-
|
|
127
|
+
return target;
|
|
128
|
+
}`)
|
|
129
|
+
|
|
130
|
+
// Use %raw to support for..in which is a ~10% faster than .forEach
|
|
131
|
+
let forEach: (dict<'a>, 'a => unit) => unit = %raw(`(dict, f) => {
|
|
132
|
+
for (var i in dict) {
|
|
133
|
+
f(dict[i]);
|
|
134
|
+
}
|
|
135
|
+
}`)
|
|
136
|
+
|
|
137
|
+
// Use %raw to support for..in which is a ~10% faster than .forEach
|
|
138
|
+
let forEachWithKey: (dict<'a>, ('a, string) => unit) => unit = %raw(`(dict, f) => {
|
|
139
|
+
for (var i in dict) {
|
|
140
|
+
f(dict[i], i);
|
|
141
|
+
}
|
|
142
|
+
}`)
|
|
143
|
+
|
|
144
|
+
// Use %raw to support for..in which is a ~10% faster than Object.keys
|
|
145
|
+
let size: dict<'a> => int = %raw(`(dict) => {
|
|
146
|
+
var size = 0, i;
|
|
147
|
+
for (i in dict) {
|
|
148
|
+
size++;
|
|
149
|
+
}
|
|
150
|
+
return size;
|
|
151
|
+
}`)
|
|
152
|
+
|
|
153
|
+
// Use %raw to support for..in which is a 2x faster than Object.keys
|
|
154
|
+
let isEmpty: dict<'a> => bool = %raw(`(dict) => {
|
|
155
|
+
for (var _ in dict) {
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
return true
|
|
159
|
+
}`)
|
|
124
160
|
|
|
125
161
|
let deleteInPlace: (dict<'a>, string) => unit = %raw(`(dict, key) => {
|
|
126
162
|
delete dict[key];
|
|
@@ -135,8 +171,6 @@ module Dict = {
|
|
|
135
171
|
|
|
136
172
|
let shallowCopy: dict<'a> => dict<'a> = %raw(`(dict) => ({...dict})`)
|
|
137
173
|
|
|
138
|
-
let size = dict => dict->Js.Dict.keys->Js.Array2.length
|
|
139
|
-
|
|
140
174
|
@set_index
|
|
141
175
|
external setByInt: (dict<'a>, int, 'a) => unit = ""
|
|
142
176
|
|
|
@@ -155,6 +189,15 @@ module Math = {
|
|
|
155
189
|
}
|
|
156
190
|
}
|
|
157
191
|
|
|
192
|
+
// This is a microoptimization to avoid int32 safeguards
|
|
193
|
+
module UnsafeIntOperators = {
|
|
194
|
+
external \"*": (int, int) => int = "%mulfloat"
|
|
195
|
+
|
|
196
|
+
external \"+": (int, int) => int = "%addfloat"
|
|
197
|
+
|
|
198
|
+
external \"-": (int, int) => int = "%subfloat"
|
|
199
|
+
}
|
|
200
|
+
|
|
158
201
|
module Array = {
|
|
159
202
|
@send
|
|
160
203
|
external forEachAsync: (array<'a>, 'a => promise<unit>) => unit = "forEach"
|
package/src/Utils.res.js
CHANGED
|
@@ -93,30 +93,59 @@ function pushMany(dict, key, values) {
|
|
|
93
93
|
|
|
94
94
|
var merge = ((dictA, dictB) => ({...dictA, ...dictB}));
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
return newDict;
|
|
104
|
-
}
|
|
96
|
+
var mapValues = ((dict, f) => {
|
|
97
|
+
var target = {}, i;
|
|
98
|
+
for (i in dict) {
|
|
99
|
+
target[i] = f(dict[i]);
|
|
100
|
+
}
|
|
101
|
+
return target;
|
|
102
|
+
});
|
|
105
103
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
var filterMapValues = ((dict, f) => {
|
|
105
|
+
var target = {}, i, v;
|
|
106
|
+
for (i in dict) {
|
|
107
|
+
v = f(dict[i]);
|
|
108
|
+
if (v !== undefined) {
|
|
109
|
+
target[i] = v;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return target;
|
|
113
|
+
});
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
115
|
+
var mapValuesToArray = ((dict, f) => {
|
|
116
|
+
var target = [], i;
|
|
117
|
+
for (i in dict) {
|
|
118
|
+
target.push(f(dict[i]));
|
|
119
|
+
}
|
|
120
|
+
return target;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
var forEach = ((dict, f) => {
|
|
124
|
+
for (var i in dict) {
|
|
125
|
+
f(dict[i]);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
var forEachWithKey = ((dict, f) => {
|
|
130
|
+
for (var i in dict) {
|
|
131
|
+
f(dict[i], i);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
var size = ((dict) => {
|
|
136
|
+
var size = 0, i;
|
|
137
|
+
for (i in dict) {
|
|
138
|
+
size++;
|
|
139
|
+
}
|
|
140
|
+
return size;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
var isEmpty = ((dict) => {
|
|
144
|
+
for (var _ in dict) {
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
return true
|
|
148
|
+
});
|
|
120
149
|
|
|
121
150
|
var deleteInPlace = ((dict, key) => {
|
|
122
151
|
delete dict[key];
|
|
@@ -126,10 +155,6 @@ var updateImmutable = ((dict, key, value) => ({...dict, [key]: value}));
|
|
|
126
155
|
|
|
127
156
|
var shallowCopy = ((dict) => ({...dict}));
|
|
128
157
|
|
|
129
|
-
function size(dict) {
|
|
130
|
-
return Object.keys(dict).length;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
158
|
var incrementByInt = ((dict, key) => {
|
|
134
159
|
dict[key]++
|
|
135
160
|
});
|
|
@@ -139,13 +164,16 @@ var Dict = {
|
|
|
139
164
|
push: push,
|
|
140
165
|
pushMany: pushMany,
|
|
141
166
|
merge: merge,
|
|
142
|
-
|
|
167
|
+
mapValues: mapValues,
|
|
168
|
+
filterMapValues: filterMapValues,
|
|
169
|
+
mapValuesToArray: mapValuesToArray,
|
|
143
170
|
forEach: forEach,
|
|
144
171
|
forEachWithKey: forEachWithKey,
|
|
172
|
+
size: size,
|
|
173
|
+
isEmpty: isEmpty,
|
|
145
174
|
deleteInPlace: deleteInPlace,
|
|
146
175
|
updateImmutable: updateImmutable,
|
|
147
176
|
shallowCopy: shallowCopy,
|
|
148
|
-
size: size,
|
|
149
177
|
incrementByInt: incrementByInt
|
|
150
178
|
};
|
|
151
179
|
|
|
@@ -169,6 +197,8 @@ var $$Math = {
|
|
|
169
197
|
minOptInt: minOptInt
|
|
170
198
|
};
|
|
171
199
|
|
|
200
|
+
var UnsafeIntOperators = {};
|
|
201
|
+
|
|
172
202
|
function mergeSorted(f, xs, ys) {
|
|
173
203
|
if (xs.length === 0) {
|
|
174
204
|
return ys;
|
|
@@ -251,7 +281,7 @@ function includes(arr, val) {
|
|
|
251
281
|
})));
|
|
252
282
|
}
|
|
253
283
|
|
|
254
|
-
function isEmpty(arr) {
|
|
284
|
+
function isEmpty$1(arr) {
|
|
255
285
|
return arr.length === 0;
|
|
256
286
|
}
|
|
257
287
|
|
|
@@ -320,7 +350,7 @@ var $$Array$1 = {
|
|
|
320
350
|
setIndexImmutable: setIndexImmutable,
|
|
321
351
|
transposeResults: transposeResults,
|
|
322
352
|
includes: includes,
|
|
323
|
-
isEmpty: isEmpty,
|
|
353
|
+
isEmpty: isEmpty$1,
|
|
324
354
|
notEmpty: notEmpty,
|
|
325
355
|
awaitEach: awaitEach,
|
|
326
356
|
removeAtIndex: removeAtIndex,
|
|
@@ -557,6 +587,7 @@ exports.$$Option = $$Option;
|
|
|
557
587
|
exports.Tuple = Tuple;
|
|
558
588
|
exports.Dict = Dict;
|
|
559
589
|
exports.$$Math = $$Math;
|
|
590
|
+
exports.UnsafeIntOperators = UnsafeIntOperators;
|
|
560
591
|
exports.$$Array = $$Array$1;
|
|
561
592
|
exports.$$String = $$String;
|
|
562
593
|
exports.Result = Result;
|