envio 3.15.0 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -34
- package/evm.schema.json +11 -2
- package/fuel.schema.json +10 -1
- package/index.d.ts +6 -0
- package/licenses/README.md +1 -1
- package/package.json +8 -8
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/ChainState.res +48 -7
- package/src/ChainState.res.mjs +27 -11
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +10 -3
- package/src/Config.res.mjs +4 -2
- package/src/Core.res +4 -40
- package/src/EffectState.res +10 -2
- package/src/EffectState.res.mjs +8 -4
- package/src/EffectState.resi +3 -1
- package/src/EntityId.res +2 -7
- package/src/EntityId.res.mjs +1 -8
- package/src/EntityTables.res +4 -1
- package/src/EntityTables.res.mjs +1 -1
- package/src/FetchState.res +157 -69
- package/src/FetchState.res.mjs +144 -49
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/InMemoryTable.res +17 -16
- package/src/InMemoryTable.res.mjs +14 -15
- package/src/IndexerState.res +28 -4
- package/src/IndexerState.res.mjs +19 -6
- package/src/IndexerState.resi +4 -0
- package/src/Internal.res +0 -49
- package/src/Internal.res.mjs +1 -80
- package/src/LoadLayer.res +14 -8
- package/src/LoadLayer.res.mjs +8 -6
- package/src/Main.res.mjs +1 -1
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/StagedRows.res +106 -0
- package/src/StagedRows.res.mjs +102 -0
- package/src/Staging.res +32 -14
- package/src/Staging.res.mjs +17 -20
- package/src/Storage.res +277 -948
- package/src/Storage.res.mjs +215 -707
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/TestIndexer.res +22 -27
- package/src/TestIndexer.res.mjs +20 -17
- package/src/Throttler.res +15 -8
- package/src/Throttler.res.mjs +9 -6
- package/src/Throttler.resi +1 -1
- package/src/Utils.res +0 -6
- package/src/Utils.res.mjs +0 -5
- package/src/Writing.res +0 -1
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +0 -322
- package/src/bindings/ClickHouse.res.mjs +0 -338
- package/src/bindings/StorageClient.res +107 -174
- package/src/bindings/StorageClient.res.mjs +19 -8
- package/src/bindings/Vitest.res +0 -26
- package/src/bindings/Vitest.res.mjs +0 -3
- package/src/db/Table.res +24 -150
- package/src/db/Table.res.mjs +38 -272
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +3 -0
- package/src/sources/EvmChain.res.mjs +4 -2
- package/src/sources/EvmHyperSyncSource.res +2 -2
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/EvmRpcClient.res +13 -3
- package/src/sources/EvmRpcClient.res.mjs +4 -3
- package/src/sources/EvmRpcWs.res +4 -3
- package/src/sources/EvmRpcWs.res.mjs +2 -2
- package/src/sources/HeightFeed.res +31 -10
- package/src/sources/HeightFeed.res.mjs +10 -6
- package/src/sources/HeightStream.res +32 -17
- package/src/sources/HeightStream.res.mjs +10 -10
- package/src/sources/HyperSyncSSE.res +4 -6
- package/src/sources/HyperSyncSSE.res.mjs +2 -2
- package/src/sources/RpcSource.res +10 -1
- package/src/sources/RpcSource.res.mjs +4 -3
- package/src/sources/Source.res +3 -0
- package/src/sources/SourceManager.res +84 -77
- package/src/sources/SourceManager.res.mjs +17 -20
- package/src/sources/SourceManager.resi +3 -4
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/svm.schema.json +11 -2
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -67
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Values as the addon declares each staged field has to arrive, compiled once
|
|
2
|
+
// per layout and written into a stage.
|
|
3
|
+
|
|
4
|
+
@send external getTime: unknown => float = "getTime"
|
|
5
|
+
@send external toFixed: unknown => string = "toFixed"
|
|
6
|
+
@val @scope("Array") external isArray: unknown => bool = "isArray"
|
|
7
|
+
|
|
8
|
+
// A list element as its JSON: the encoding a scalar of its type would take,
|
|
9
|
+
// except that a boolean stays one and bytes become their values.
|
|
10
|
+
%%private(
|
|
11
|
+
let elementOf = (encoding: Staging.encoding, ~column): (unknown => unknown) =>
|
|
12
|
+
switch encoding {
|
|
13
|
+
| Number =>
|
|
14
|
+
value =>
|
|
15
|
+
value->Staging.toNumber->Staging.finiteOrThrow(~column)->(Utils.magic: float => unknown)
|
|
16
|
+
| Date => value => value->getTime->(Utils.magic: float => unknown)
|
|
17
|
+
| Digits => value => value->Staging.stringOf->(Utils.magic: string => unknown)
|
|
18
|
+
| Decimal => value => value->toFixed->(Utils.magic: string => unknown)
|
|
19
|
+
| Document => value => value->Sql.canonicalDocument->(Utils.magic: string => unknown)
|
|
20
|
+
| Bytes =>
|
|
21
|
+
value =>
|
|
22
|
+
value
|
|
23
|
+
->(Utils.magic: unknown => Array.arrayLike<int>)
|
|
24
|
+
->Array.fromArrayLike
|
|
25
|
+
->(Utils.magic: array<int> => unknown)
|
|
26
|
+
| Bool | Text | List => value => value
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
%%private(
|
|
31
|
+
let rec mapList = (value: unknown, element: unknown => unknown): unknown =>
|
|
32
|
+
if value->isArray {
|
|
33
|
+
value
|
|
34
|
+
->(Utils.magic: unknown => array<unknown>)
|
|
35
|
+
->Array.map(item => item->mapList(element))
|
|
36
|
+
->(Utils.magic: array<unknown> => unknown)
|
|
37
|
+
} else if value === %raw(`undefined`) || value === %raw(`null`) {
|
|
38
|
+
%raw(`null`)
|
|
39
|
+
} else {
|
|
40
|
+
element(value)
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
// What a present value becomes before it is written to its slot.
|
|
45
|
+
%%private(
|
|
46
|
+
let encoderOf = ({name, encoding, element}: Staging.stagedField): (unknown => unknown) =>
|
|
47
|
+
switch encoding {
|
|
48
|
+
| Bool =>
|
|
49
|
+
value => (value->(Utils.magic: unknown => bool) ? 1. : 0.)->(Utils.magic: float => unknown)
|
|
50
|
+
| Date => value => value->getTime->(Utils.magic: float => unknown)
|
|
51
|
+
| Decimal => value => value->toFixed->(Utils.magic: string => unknown)
|
|
52
|
+
| Document => value => value->Sql.canonicalDocument->(Utils.magic: string => unknown)
|
|
53
|
+
| List =>
|
|
54
|
+
let encode = elementOf(element, ~column=name)
|
|
55
|
+
// A document can be a list itself, so a list of them is one level deep.
|
|
56
|
+
let mapList = switch element {
|
|
57
|
+
| Document =>
|
|
58
|
+
(value, encode) =>
|
|
59
|
+
value
|
|
60
|
+
->(Utils.magic: unknown => array<unknown>)
|
|
61
|
+
->Array.map(item => item->Staging.isAbsent ? %raw(`null`) : encode(item))
|
|
62
|
+
->(Utils.magic: array<unknown> => unknown)
|
|
63
|
+
| _ => mapList
|
|
64
|
+
}
|
|
65
|
+
value =>
|
|
66
|
+
value
|
|
67
|
+
->mapList(encode)
|
|
68
|
+
->(Utils.magic: unknown => JSON.t)
|
|
69
|
+
->JSON.stringify
|
|
70
|
+
->Utils.replaceLoneSurrogateEscapes
|
|
71
|
+
->(Utils.magic: string => unknown)
|
|
72
|
+
| Number | Text | Digits | Bytes => value => value
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
// A layout's fields compiled once: the slot each takes and how a value of it
|
|
77
|
+
// is written there.
|
|
78
|
+
type writer = {field: Staging.stagedField, encode: unknown => unknown}
|
|
79
|
+
|
|
80
|
+
let writersOf = (fields: array<Staging.stagedField>) =>
|
|
81
|
+
fields->Array.map(field => {field, encode: encoderOf(field)})
|
|
82
|
+
|
|
83
|
+
let columnsOf = (writers: array<writer>): array<Staging.column> =>
|
|
84
|
+
writers->Array.map(({field}) => {
|
|
85
|
+
Staging.name: field.name,
|
|
86
|
+
kind: field.encoding->Staging.kindOf,
|
|
87
|
+
isNullable: field.isNullable,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// JSON `null` is a document of its own, which a column that can't be NULL
|
|
91
|
+
// stores as one. Left out, the value is no document and is refused like any
|
|
92
|
+
// other.
|
|
93
|
+
let writeField = (stage, ~writers: array<writer>, ~column, ~row, value: unknown) => {
|
|
94
|
+
let {field, encode} = writers->Array.getUnsafe(column)
|
|
95
|
+
if value->Staging.isAbsent {
|
|
96
|
+
stage->Staging.writeValue(
|
|
97
|
+
~column,
|
|
98
|
+
~row,
|
|
99
|
+
field.encoding === Staging.Document && !field.isNullable && value === %raw(`null`)
|
|
100
|
+
? "null"->(Utils.magic: string => unknown)
|
|
101
|
+
: value,
|
|
102
|
+
)
|
|
103
|
+
} else {
|
|
104
|
+
stage->Staging.writeValue(~column, ~row, encode(value))
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Sql from "./db/Sql.res.mjs";
|
|
4
|
+
import * as Utils from "./Utils.res.mjs";
|
|
5
|
+
import * as Staging from "./Staging.res.mjs";
|
|
6
|
+
|
|
7
|
+
function elementOf(encoding, column) {
|
|
8
|
+
switch (encoding) {
|
|
9
|
+
case "Number" :
|
|
10
|
+
return value => Staging.finiteOrThrow(Number(value), column);
|
|
11
|
+
case "Date" :
|
|
12
|
+
return value => value.getTime();
|
|
13
|
+
case "Digits" :
|
|
14
|
+
return value => String(value);
|
|
15
|
+
case "Decimal" :
|
|
16
|
+
return value => value.toFixed();
|
|
17
|
+
case "Document" :
|
|
18
|
+
return Sql.canonicalDocument;
|
|
19
|
+
case "Bytes" :
|
|
20
|
+
return value => Array.from(value);
|
|
21
|
+
default:
|
|
22
|
+
return value => value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function mapList(value, element) {
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
return value.map(item => mapList(item, element));
|
|
29
|
+
} else if (value === undefined || value === null) {
|
|
30
|
+
return null;
|
|
31
|
+
} else {
|
|
32
|
+
return element(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function encoderOf(param) {
|
|
37
|
+
let element = param.element;
|
|
38
|
+
switch (param.encoding) {
|
|
39
|
+
case "Bool" :
|
|
40
|
+
return value => {
|
|
41
|
+
if (value) {
|
|
42
|
+
return 1;
|
|
43
|
+
} else {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
case "Date" :
|
|
48
|
+
return value => value.getTime();
|
|
49
|
+
case "Decimal" :
|
|
50
|
+
return value => value.toFixed();
|
|
51
|
+
case "Document" :
|
|
52
|
+
return Sql.canonicalDocument;
|
|
53
|
+
case "List" :
|
|
54
|
+
let encode = elementOf(element, param.name);
|
|
55
|
+
let mapList$1;
|
|
56
|
+
mapList$1 = element === "Document" ? (value, encode) => value.map(item => {
|
|
57
|
+
if (Staging.isAbsent(item)) {
|
|
58
|
+
return null;
|
|
59
|
+
} else {
|
|
60
|
+
return encode(item);
|
|
61
|
+
}
|
|
62
|
+
}) : mapList;
|
|
63
|
+
return value => Utils.replaceLoneSurrogateEscapes(JSON.stringify(mapList$1(value, encode)));
|
|
64
|
+
default:
|
|
65
|
+
return value => value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function writersOf(fields) {
|
|
70
|
+
return fields.map(field => ({
|
|
71
|
+
field: field,
|
|
72
|
+
encode: encoderOf(field)
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function columnsOf(writers) {
|
|
77
|
+
return writers.map(param => {
|
|
78
|
+
let field = param.field;
|
|
79
|
+
return {
|
|
80
|
+
name: field.name,
|
|
81
|
+
kind: Staging.kindOf(field.encoding),
|
|
82
|
+
isNullable: field.isNullable
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function writeField(stage, writers, column, row, value) {
|
|
88
|
+
let match = writers[column];
|
|
89
|
+
let field = match.field;
|
|
90
|
+
if (Staging.isAbsent(value)) {
|
|
91
|
+
return Staging.writeValue(stage, column, row, field.encoding === "Document" && !field.isNullable && value === null ? "null" : value);
|
|
92
|
+
} else {
|
|
93
|
+
return Staging.writeValue(stage, column, row, match.encode(value));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
writersOf,
|
|
99
|
+
columnsOf,
|
|
100
|
+
writeField,
|
|
101
|
+
}
|
|
102
|
+
/* Sql Not a pure module */
|
package/src/Staging.res
CHANGED
|
@@ -10,16 +10,6 @@ type kind =
|
|
|
10
10
|
| @as(3) Text
|
|
11
11
|
| @as(4) Bytes
|
|
12
12
|
|
|
13
|
-
let kindOfOrdinal = ordinal =>
|
|
14
|
-
switch ordinal {
|
|
15
|
-
| 0 => F64
|
|
16
|
-
| 1 => U64
|
|
17
|
-
| 2 => I64
|
|
18
|
-
| 3 => Text
|
|
19
|
-
| 4 => Bytes
|
|
20
|
-
| unknown => JsError.throwWithMessage(`Unknown staged column kind ${unknown->Int.toString}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
13
|
// The replacer closes over nothing but the column's name, so it is built once
|
|
24
14
|
// with the column rather than once per column per batch.
|
|
25
15
|
type column = {name: string, kind: kind, isNullable: bool, replacer?: JSON.replacer}
|
|
@@ -28,7 +18,7 @@ type begun = {handle: int, buffers: array<ArrayBuffer.t>}
|
|
|
28
18
|
|
|
29
19
|
// What the addon exposes, so this module stays free of the storage's own API.
|
|
30
20
|
type arena = {
|
|
31
|
-
beginStage: (~
|
|
21
|
+
beginStage: (~rows: int) => begun,
|
|
32
22
|
growStage: (~handle: int, ~column: int, ~needed: int, ~stale: ArrayBuffer.t) => ArrayBuffer.t,
|
|
33
23
|
commitStage: (~handle: int, ~buffers: array<ArrayBuffer.t>) => unit,
|
|
34
24
|
abortStage: (~handle: int, ~buffers: array<ArrayBuffer.t>) => unit,
|
|
@@ -79,8 +69,8 @@ type t = {
|
|
|
79
69
|
builders: array<builder>,
|
|
80
70
|
}
|
|
81
71
|
|
|
82
|
-
let begin = (arena, ~
|
|
83
|
-
let {handle, buffers} = arena.beginStage(~
|
|
72
|
+
let begin = (arena, ~rows, ~columns: array<column>) => {
|
|
73
|
+
let {handle, buffers} = arena.beginStage(~rows)
|
|
84
74
|
let slot = ref(0)
|
|
85
75
|
let take = () => {
|
|
86
76
|
let buffer = buffers->Array.getUnsafe(slot.contents)
|
|
@@ -275,7 +265,7 @@ let toText = (value: unknown, ~replacer=?) =>
|
|
|
275
265
|
}
|
|
276
266
|
)
|
|
277
267
|
|
|
278
|
-
|
|
268
|
+
let isAbsent = (value: unknown) => value === %raw(`undefined`) || value === %raw(`null`)
|
|
279
269
|
|
|
280
270
|
// Writes one value of a row the handler set. `undefined`/`null` marks the row's
|
|
281
271
|
// null bit, which a column that accepts NULL stores as such — and which one that
|
|
@@ -317,3 +307,31 @@ let commit = stage => {
|
|
|
317
307
|
}
|
|
318
308
|
|
|
319
309
|
let abort = stage => stage.arena.abortStage(~handle=stage.handle, ~buffers=stage.buffers)
|
|
310
|
+
|
|
311
|
+
// How a staged value has to arrive, as the addon declares it for every field:
|
|
312
|
+
// `storage::schema::Encoding`.
|
|
313
|
+
type encoding =
|
|
314
|
+
| Number
|
|
315
|
+
| Bool
|
|
316
|
+
| Date
|
|
317
|
+
| Text
|
|
318
|
+
| Digits
|
|
319
|
+
| Decimal
|
|
320
|
+
| Document
|
|
321
|
+
| Bytes
|
|
322
|
+
| List
|
|
323
|
+
|
|
324
|
+
type stagedField = {
|
|
325
|
+
name: string,
|
|
326
|
+
encoding: encoding,
|
|
327
|
+
// What a list's elements are encoded as; the field's own for a scalar.
|
|
328
|
+
element: encoding,
|
|
329
|
+
isNullable: bool,
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
let kindOf = (encoding: encoding) =>
|
|
333
|
+
switch encoding {
|
|
334
|
+
| Number | Bool | Date => F64
|
|
335
|
+
| Text | Digits | Decimal | Document | List => Text
|
|
336
|
+
| Bytes => Bytes
|
|
337
|
+
}
|
package/src/Staging.res.mjs
CHANGED
|
@@ -4,27 +4,10 @@ import * as Utils from "./Utils.res.mjs";
|
|
|
4
4
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
5
5
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
6
|
|
|
7
|
-
function kindOfOrdinal(ordinal) {
|
|
8
|
-
switch (ordinal) {
|
|
9
|
-
case 0 :
|
|
10
|
-
return 0;
|
|
11
|
-
case 1 :
|
|
12
|
-
return 1;
|
|
13
|
-
case 2 :
|
|
14
|
-
return 2;
|
|
15
|
-
case 3 :
|
|
16
|
-
return 3;
|
|
17
|
-
case 4 :
|
|
18
|
-
return 4;
|
|
19
|
-
default:
|
|
20
|
-
return Stdlib_JsError.throwWithMessage(`Unknown staged column kind ` + ordinal.toString());
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
7
|
let encoder = new TextEncoder();
|
|
25
8
|
|
|
26
|
-
function begin(arena,
|
|
27
|
-
let match = arena.beginStage(
|
|
9
|
+
function begin(arena, rows, columns) {
|
|
10
|
+
let match = arena.beginStage(rows);
|
|
28
11
|
let buffers = match.buffers;
|
|
29
12
|
let slot = {
|
|
30
13
|
contents: 0
|
|
@@ -249,15 +232,29 @@ function abort(stage) {
|
|
|
249
232
|
stage.arena.abortStage(stage.handle, stage.buffers);
|
|
250
233
|
}
|
|
251
234
|
|
|
235
|
+
function kindOf(encoding) {
|
|
236
|
+
switch (encoding) {
|
|
237
|
+
case "Number" :
|
|
238
|
+
case "Bool" :
|
|
239
|
+
case "Date" :
|
|
240
|
+
return 0;
|
|
241
|
+
case "Bytes" :
|
|
242
|
+
return 4;
|
|
243
|
+
default:
|
|
244
|
+
return 3;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
252
248
|
export {
|
|
253
|
-
kindOfOrdinal,
|
|
254
249
|
begin,
|
|
255
250
|
finiteOrThrow,
|
|
256
251
|
toText,
|
|
252
|
+
isAbsent,
|
|
257
253
|
writeValue,
|
|
258
254
|
writeDeletedValue,
|
|
259
255
|
columnCount,
|
|
260
256
|
commit,
|
|
261
257
|
abort,
|
|
258
|
+
kindOf,
|
|
262
259
|
}
|
|
263
260
|
/* encoder Not a pure module */
|