envio 2.26.0-rc.2 → 2.27.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/evm.schema.json +16 -0
- package/fuel.schema.json +16 -0
- package/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/EventRegister.res +92 -0
- package/src/EventRegister.res.js +124 -0
- package/src/EventRegister.resi +21 -0
- package/src/FetchState.res +15 -44
- package/src/FetchState.res.js +12 -34
- package/src/Internal.gen.ts +15 -0
- package/src/Internal.res +26 -10
- package/src/Internal.res.js +1 -1
- package/src/Logging.res +1 -0
- package/src/Logging.res.js +2 -1
- package/src/Persistence.res +4 -0
- package/src/PgStorage.res +15 -10
- package/src/PgStorage.res.js +5 -2
- package/src/Utils.res +14 -5
- package/src/Utils.res.js +13 -5
- package/src/bindings/NodeJs.res +31 -0
- package/src/bindings/NodeJs.res.js +15 -1
- package/src/bindings/Promise.res +2 -0
package/evm.schema.json
CHANGED
|
@@ -106,6 +106,13 @@
|
|
|
106
106
|
"boolean",
|
|
107
107
|
"null"
|
|
108
108
|
]
|
|
109
|
+
},
|
|
110
|
+
"preload_handlers": {
|
|
111
|
+
"description": "Makes handlers run twice to enable preload optimisations. Removes handlerWithLoader API, since it's not needed. (recommended, default: false)",
|
|
112
|
+
"type": [
|
|
113
|
+
"boolean",
|
|
114
|
+
"null"
|
|
115
|
+
]
|
|
109
116
|
}
|
|
110
117
|
},
|
|
111
118
|
"additionalProperties": false,
|
|
@@ -576,6 +583,15 @@
|
|
|
576
583
|
"description": "A single address or a list of addresses to be indexed. This can be left as null in the case where this contracts addresses will be registered dynamically.",
|
|
577
584
|
"$ref": "#/$defs/Addresses"
|
|
578
585
|
},
|
|
586
|
+
"start_block": {
|
|
587
|
+
"description": "The block at which the indexer should start ingesting data for this specific contract. If not specified, uses the network start_block. Can be greater than the network start_block for more specific indexing.",
|
|
588
|
+
"type": [
|
|
589
|
+
"integer",
|
|
590
|
+
"null"
|
|
591
|
+
],
|
|
592
|
+
"format": "uint64",
|
|
593
|
+
"minimum": 0
|
|
594
|
+
},
|
|
579
595
|
"abi_file_path": {
|
|
580
596
|
"description": "Relative path (from config) to a json abi. If this is used then each configured event should simply be referenced by its name",
|
|
581
597
|
"type": [
|
package/fuel.schema.json
CHANGED
|
@@ -56,6 +56,13 @@
|
|
|
56
56
|
"boolean",
|
|
57
57
|
"null"
|
|
58
58
|
]
|
|
59
|
+
},
|
|
60
|
+
"preload_handlers": {
|
|
61
|
+
"description": "Makes handlers run twice to enable preload optimisations. Removes handlerWithLoader API, since it's not needed. (recommended, default: false)",
|
|
62
|
+
"type": [
|
|
63
|
+
"boolean",
|
|
64
|
+
"null"
|
|
65
|
+
]
|
|
59
66
|
}
|
|
60
67
|
},
|
|
61
68
|
"additionalProperties": false,
|
|
@@ -217,6 +224,15 @@
|
|
|
217
224
|
"description": "A single address or a list of addresses to be indexed. This can be left as null in the case where this contracts addresses will be registered dynamically.",
|
|
218
225
|
"$ref": "#/$defs/Addresses"
|
|
219
226
|
},
|
|
227
|
+
"start_block": {
|
|
228
|
+
"description": "The block at which the indexer should start ingesting data for this specific contract. If not specified, uses the network start_block. Can be greater than the network start_block for more specific indexing.",
|
|
229
|
+
"type": [
|
|
230
|
+
"integer",
|
|
231
|
+
"null"
|
|
232
|
+
],
|
|
233
|
+
"format": "uint64",
|
|
234
|
+
"minimum": 0
|
|
235
|
+
},
|
|
220
236
|
"abi_file_path": {
|
|
221
237
|
"description": "Relative path (from config) to a json abi.",
|
|
222
238
|
"type": "string"
|
package/index.d.ts
CHANGED
|
@@ -95,6 +95,7 @@ export function experimental_createEffect<
|
|
|
95
95
|
// Important! Should match the index.js file
|
|
96
96
|
export declare namespace S {
|
|
97
97
|
export type Output<T> = Sury.Output<T>;
|
|
98
|
+
export type Infer<T> = Sury.Output<T>;
|
|
98
99
|
export type Input<T> = Sury.Input<T>;
|
|
99
100
|
export type Schema<Output, Input = unknown> = Sury.Schema<Output, Input>;
|
|
100
101
|
export const string: typeof Sury.string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v2.
|
|
3
|
+
"version": "v2.27.0",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://envio.dev",
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"envio-linux-x64": "v2.
|
|
29
|
-
"envio-linux-arm64": "v2.
|
|
30
|
-
"envio-darwin-x64": "v2.
|
|
31
|
-
"envio-darwin-arm64": "v2.
|
|
28
|
+
"envio-linux-x64": "v2.27.0",
|
|
29
|
+
"envio-linux-arm64": "v2.27.0",
|
|
30
|
+
"envio-darwin-x64": "v2.27.0",
|
|
31
|
+
"envio-darwin-arm64": "v2.27.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@envio-dev/hypersync-client": "0.6.5",
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
type t = {
|
|
2
|
+
contractName: string,
|
|
3
|
+
eventName: string,
|
|
4
|
+
mutable handler: option<Internal.handler>,
|
|
5
|
+
mutable contractRegister: option<Internal.contractRegister>,
|
|
6
|
+
mutable eventOptions: option<Internal.eventOptions<Js.Json.t>>,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let getHandler = (t: t) => t.handler
|
|
10
|
+
|
|
11
|
+
let getContractRegister = (t: t) => t.contractRegister
|
|
12
|
+
|
|
13
|
+
let getEventFilters = (t: t) => t.eventOptions->Belt.Option.flatMap(value => value.eventFilters)
|
|
14
|
+
|
|
15
|
+
let isWildcard = (t: t) =>
|
|
16
|
+
t.eventOptions->Belt.Option.flatMap(value => value.wildcard)->Belt.Option.getWithDefault(false)
|
|
17
|
+
|
|
18
|
+
let hasRegistration = ({handler, contractRegister}) =>
|
|
19
|
+
handler->Belt.Option.isSome || contractRegister->Belt.Option.isSome
|
|
20
|
+
|
|
21
|
+
let make = (~contractName, ~eventName) => {
|
|
22
|
+
contractName,
|
|
23
|
+
eventName,
|
|
24
|
+
handler: None,
|
|
25
|
+
contractRegister: None,
|
|
26
|
+
eventOptions: None,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type eventNamespace = {contractName: string, eventName: string}
|
|
30
|
+
exception DuplicateEventRegistration(eventNamespace)
|
|
31
|
+
|
|
32
|
+
let setEventOptions = (t: t, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
33
|
+
switch eventOptions {
|
|
34
|
+
| Some(value) =>
|
|
35
|
+
let value =
|
|
36
|
+
value->(Utils.magic: Internal.eventOptions<'eventFilters> => Internal.eventOptions<Js.Json.t>)
|
|
37
|
+
switch t.eventOptions {
|
|
38
|
+
| None => t.eventOptions = Some(value)
|
|
39
|
+
| Some(existingValue) =>
|
|
40
|
+
if (
|
|
41
|
+
existingValue.wildcard !== value.wildcard ||
|
|
42
|
+
// TODO: Can improve the check by using deepEqual
|
|
43
|
+
existingValue.eventFilters !== value.eventFilters
|
|
44
|
+
) {
|
|
45
|
+
let eventNamespace = {contractName: t.contractName, eventName: t.eventName}
|
|
46
|
+
DuplicateEventRegistration(eventNamespace)->ErrorHandling.mkLogAndRaise(
|
|
47
|
+
~logger=Logging.createChildFrom(~logger, ~params=eventNamespace),
|
|
48
|
+
~msg="Duplicate eventOptions in handlers not allowed",
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
| None => ()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let setHandler = (t: t, handler, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
57
|
+
switch t.handler {
|
|
58
|
+
| None =>
|
|
59
|
+
t.handler =
|
|
60
|
+
handler
|
|
61
|
+
->(Utils.magic: Internal.genericHandler<'args> => Internal.handler)
|
|
62
|
+
->Some
|
|
63
|
+
| Some(_) =>
|
|
64
|
+
let eventNamespace = {contractName: t.contractName, eventName: t.eventName}
|
|
65
|
+
DuplicateEventRegistration(eventNamespace)->ErrorHandling.mkLogAndRaise(
|
|
66
|
+
~logger=Logging.createChildFrom(~logger, ~params=eventNamespace),
|
|
67
|
+
~msg="Duplicate registration of event handlers not allowed",
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
t->setEventOptions(~eventOptions, ~logger)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let setContractRegister = (t: t, contractRegister, ~eventOptions, ~logger=Logging.getLogger()) => {
|
|
75
|
+
switch t.contractRegister {
|
|
76
|
+
| None =>
|
|
77
|
+
t.contractRegister = Some(
|
|
78
|
+
contractRegister->(
|
|
79
|
+
Utils.magic: Internal.genericContractRegister<
|
|
80
|
+
Internal.genericContractRegisterArgs<'event, 'context>,
|
|
81
|
+
> => Internal.contractRegister
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
| Some(_) =>
|
|
85
|
+
let eventNamespace = {contractName: t.contractName, eventName: t.eventName}
|
|
86
|
+
DuplicateEventRegistration(eventNamespace)->ErrorHandling.mkLogAndRaise(
|
|
87
|
+
~logger=Logging.createChildFrom(~logger, ~params=eventNamespace),
|
|
88
|
+
~msg="Duplicate contractRegister handlers not allowed",
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
t->setEventOptions(~eventOptions, ~logger)
|
|
92
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var Logging = require("./Logging.res.js");
|
|
5
|
+
var Belt_Option = require("rescript/lib/js/belt_Option.js");
|
|
6
|
+
var ErrorHandling = require("./ErrorHandling.res.js");
|
|
7
|
+
var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
|
|
8
|
+
|
|
9
|
+
function getHandler(t) {
|
|
10
|
+
return t.handler;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getContractRegister(t) {
|
|
14
|
+
return t.contractRegister;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getEventFilters(t) {
|
|
18
|
+
return Belt_Option.flatMap(t.eventOptions, (function (value) {
|
|
19
|
+
return value.eventFilters;
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isWildcard(t) {
|
|
24
|
+
return Belt_Option.getWithDefault(Belt_Option.flatMap(t.eventOptions, (function (value) {
|
|
25
|
+
return value.wildcard;
|
|
26
|
+
})), false);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function hasRegistration(param) {
|
|
30
|
+
var handler = param.handler;
|
|
31
|
+
var contractRegister = param.contractRegister;
|
|
32
|
+
if (Belt_Option.isSome(handler)) {
|
|
33
|
+
return true;
|
|
34
|
+
} else {
|
|
35
|
+
return Belt_Option.isSome(contractRegister);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function make(contractName, eventName) {
|
|
40
|
+
return {
|
|
41
|
+
contractName: contractName,
|
|
42
|
+
eventName: eventName,
|
|
43
|
+
handler: undefined,
|
|
44
|
+
contractRegister: undefined,
|
|
45
|
+
eventOptions: undefined
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var DuplicateEventRegistration = /* @__PURE__ */Caml_exceptions.create("EventRegister.DuplicateEventRegistration");
|
|
50
|
+
|
|
51
|
+
function setEventOptions(t, eventOptions, loggerOpt) {
|
|
52
|
+
var logger = loggerOpt !== undefined ? loggerOpt : Logging.getLogger();
|
|
53
|
+
if (eventOptions === undefined) {
|
|
54
|
+
return ;
|
|
55
|
+
}
|
|
56
|
+
var existingValue = t.eventOptions;
|
|
57
|
+
if (existingValue === undefined) {
|
|
58
|
+
t.eventOptions = eventOptions;
|
|
59
|
+
return ;
|
|
60
|
+
}
|
|
61
|
+
if (!(existingValue.wildcard !== eventOptions.wildcard || existingValue.eventFilters !== eventOptions.eventFilters)) {
|
|
62
|
+
return ;
|
|
63
|
+
}
|
|
64
|
+
var eventNamespace_contractName = t.contractName;
|
|
65
|
+
var eventNamespace_eventName = t.eventName;
|
|
66
|
+
var eventNamespace = {
|
|
67
|
+
contractName: eventNamespace_contractName,
|
|
68
|
+
eventName: eventNamespace_eventName
|
|
69
|
+
};
|
|
70
|
+
ErrorHandling.mkLogAndRaise(Logging.createChildFrom(logger, eventNamespace), "Duplicate eventOptions in handlers not allowed", {
|
|
71
|
+
RE_EXN_ID: DuplicateEventRegistration,
|
|
72
|
+
_1: eventNamespace
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function setHandler(t, handler, eventOptions, loggerOpt) {
|
|
77
|
+
var logger = loggerOpt !== undefined ? loggerOpt : Logging.getLogger();
|
|
78
|
+
var match = t.handler;
|
|
79
|
+
if (match !== undefined) {
|
|
80
|
+
var eventNamespace_contractName = t.contractName;
|
|
81
|
+
var eventNamespace_eventName = t.eventName;
|
|
82
|
+
var eventNamespace = {
|
|
83
|
+
contractName: eventNamespace_contractName,
|
|
84
|
+
eventName: eventNamespace_eventName
|
|
85
|
+
};
|
|
86
|
+
ErrorHandling.mkLogAndRaise(Logging.createChildFrom(logger, eventNamespace), "Duplicate registration of event handlers not allowed", {
|
|
87
|
+
RE_EXN_ID: DuplicateEventRegistration,
|
|
88
|
+
_1: eventNamespace
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
t.handler = handler;
|
|
92
|
+
}
|
|
93
|
+
setEventOptions(t, eventOptions, logger);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function setContractRegister(t, contractRegister, eventOptions, loggerOpt) {
|
|
97
|
+
var logger = loggerOpt !== undefined ? loggerOpt : Logging.getLogger();
|
|
98
|
+
var match = t.contractRegister;
|
|
99
|
+
if (match !== undefined) {
|
|
100
|
+
var eventNamespace_contractName = t.contractName;
|
|
101
|
+
var eventNamespace_eventName = t.eventName;
|
|
102
|
+
var eventNamespace = {
|
|
103
|
+
contractName: eventNamespace_contractName,
|
|
104
|
+
eventName: eventNamespace_eventName
|
|
105
|
+
};
|
|
106
|
+
ErrorHandling.mkLogAndRaise(Logging.createChildFrom(logger, eventNamespace), "Duplicate contractRegister handlers not allowed", {
|
|
107
|
+
RE_EXN_ID: DuplicateEventRegistration,
|
|
108
|
+
_1: eventNamespace
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
t.contractRegister = contractRegister;
|
|
112
|
+
}
|
|
113
|
+
setEventOptions(t, eventOptions, logger);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
exports.make = make;
|
|
117
|
+
exports.setHandler = setHandler;
|
|
118
|
+
exports.setContractRegister = setContractRegister;
|
|
119
|
+
exports.getHandler = getHandler;
|
|
120
|
+
exports.getContractRegister = getContractRegister;
|
|
121
|
+
exports.getEventFilters = getEventFilters;
|
|
122
|
+
exports.isWildcard = isWildcard;
|
|
123
|
+
exports.hasRegistration = hasRegistration;
|
|
124
|
+
/* Logging Not a pure module */
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type t
|
|
2
|
+
let make: (~contractName: string, ~eventName: string) => t
|
|
3
|
+
let setHandler: (
|
|
4
|
+
t,
|
|
5
|
+
Internal.genericHandler<
|
|
6
|
+
Internal.genericHandlerArgs<'event, Internal.handlerContext, 'loaderReturn>,
|
|
7
|
+
>,
|
|
8
|
+
~eventOptions: option<Internal.eventOptions<'eventFilters>>,
|
|
9
|
+
~logger: Pino.t=?,
|
|
10
|
+
) => unit
|
|
11
|
+
let setContractRegister: (
|
|
12
|
+
t,
|
|
13
|
+
Internal.genericContractRegister<Internal.genericContractRegisterArgs<'event, 'context>>,
|
|
14
|
+
~eventOptions: option<Internal.eventOptions<'eventFilters>>,
|
|
15
|
+
~logger: Pino.t=?,
|
|
16
|
+
) => unit
|
|
17
|
+
let getHandler: t => option<Internal.handler>
|
|
18
|
+
let getContractRegister: t => option<Internal.contractRegister>
|
|
19
|
+
let getEventFilters: t => option<Js.Json.t>
|
|
20
|
+
let isWildcard: t => bool
|
|
21
|
+
let hasRegistration: t => bool
|
package/src/FetchState.res
CHANGED
|
@@ -966,8 +966,7 @@ let make = (
|
|
|
966
966
|
~startBlock,
|
|
967
967
|
~endBlock,
|
|
968
968
|
~eventConfigs: array<Internal.eventConfig>,
|
|
969
|
-
~
|
|
970
|
-
~dynamicContracts: array<indexingContract>,
|
|
969
|
+
~contracts: array<indexingContract>,
|
|
971
970
|
~maxAddrInPartition,
|
|
972
971
|
~chainId,
|
|
973
972
|
~blockLag=?,
|
|
@@ -1041,49 +1040,21 @@ let make = (
|
|
|
1041
1040
|
|
|
1042
1041
|
let pendingNormalPartition = ref(makePendingNormalPartition())
|
|
1043
1042
|
|
|
1044
|
-
|
|
1045
|
-
let
|
|
1046
|
-
switch pendingPartition.addressesByContractName->Utils.Dict.dangerouslyGetNonOption(
|
|
1047
|
-
contractName,
|
|
1048
|
-
) {
|
|
1049
|
-
| Some(addresses) => addresses->Array.push(address)
|
|
1050
|
-
| None => pendingPartition.addressesByContractName->Js.Dict.set(contractName, [address])
|
|
1051
|
-
}
|
|
1052
|
-
indexingContracts->Js.Dict.set(
|
|
1053
|
-
address->Address.toString,
|
|
1054
|
-
switch dc {
|
|
1055
|
-
| Some(dc) => dc
|
|
1056
|
-
| None => {
|
|
1057
|
-
address,
|
|
1058
|
-
contractName,
|
|
1059
|
-
startBlock,
|
|
1060
|
-
register: Config,
|
|
1061
|
-
}
|
|
1062
|
-
},
|
|
1063
|
-
)
|
|
1064
|
-
if (
|
|
1065
|
-
pendingPartition.addressesByContractName->addressesByContractNameCount ===
|
|
1066
|
-
maxAddrInPartition
|
|
1067
|
-
) {
|
|
1068
|
-
partitions->Array.push(pendingPartition)
|
|
1069
|
-
pendingNormalPartition := makePendingNormalPartition()
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
staticContracts
|
|
1074
|
-
->Js.Dict.entries
|
|
1075
|
-
->Array.forEach(((contractName, addresses)) => {
|
|
1076
|
-
if contractNamesWithNormalEvents->Utils.Set.has(contractName) {
|
|
1077
|
-
addresses->Array.forEach(a => {
|
|
1078
|
-
registerAddress(contractName, a)
|
|
1079
|
-
})
|
|
1080
|
-
}
|
|
1081
|
-
})
|
|
1082
|
-
|
|
1083
|
-
dynamicContracts->Array.forEach(dc => {
|
|
1084
|
-
let contractName = dc.contractName
|
|
1043
|
+
contracts->Array.forEach(contract => {
|
|
1044
|
+
let contractName = contract.contractName
|
|
1085
1045
|
if contractNamesWithNormalEvents->Utils.Set.has(contractName) {
|
|
1086
|
-
|
|
1046
|
+
let pendingPartition = pendingNormalPartition.contents
|
|
1047
|
+
pendingPartition.addressesByContractName->Utils.Dict.push(contractName, contract.address)
|
|
1048
|
+
indexingContracts->Js.Dict.set(contract.address->Address.toString, contract)
|
|
1049
|
+
if (
|
|
1050
|
+
pendingPartition.addressesByContractName->addressesByContractNameCount ===
|
|
1051
|
+
maxAddrInPartition
|
|
1052
|
+
) {
|
|
1053
|
+
// FIXME: should split into separate partitions
|
|
1054
|
+
// depending on the start block
|
|
1055
|
+
partitions->Array.push(pendingPartition)
|
|
1056
|
+
pendingNormalPartition := makePendingNormalPartition()
|
|
1057
|
+
}
|
|
1087
1058
|
}
|
|
1088
1059
|
})
|
|
1089
1060
|
|
package/src/FetchState.res.js
CHANGED
|
@@ -698,7 +698,7 @@ function getEarliestEvent(param) {
|
|
|
698
698
|
}
|
|
699
699
|
}
|
|
700
700
|
|
|
701
|
-
function make(startBlock, endBlock, eventConfigs,
|
|
701
|
+
function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition, chainId, blockLag) {
|
|
702
702
|
var latestFetchedBlock_blockNumber = startBlock - 1 | 0;
|
|
703
703
|
var latestFetchedBlock = {
|
|
704
704
|
blockNumber: latestFetchedBlock_blockNumber,
|
|
@@ -761,40 +761,18 @@ function make(startBlock, endBlock, eventConfigs, staticContracts, dynamicContra
|
|
|
761
761
|
var pendingNormalPartition = {
|
|
762
762
|
contents: makePendingNormalPartition()
|
|
763
763
|
};
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
addresses.push(address);
|
|
769
|
-
} else {
|
|
770
|
-
pendingPartition.addressesByContractName[contractName] = [address];
|
|
771
|
-
}
|
|
772
|
-
indexingContracts[address] = dc !== undefined ? dc : ({
|
|
773
|
-
address: address,
|
|
774
|
-
contractName: contractName,
|
|
775
|
-
startBlock: startBlock,
|
|
776
|
-
register: "Config"
|
|
777
|
-
});
|
|
778
|
-
if (addressesByContractNameCount(pendingPartition.addressesByContractName) === maxAddrInPartition) {
|
|
779
|
-
partitions.push(pendingPartition);
|
|
780
|
-
pendingNormalPartition.contents = makePendingNormalPartition();
|
|
781
|
-
return ;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
};
|
|
785
|
-
Belt_Array.forEach(Js_dict.entries(staticContracts), (function (param) {
|
|
786
|
-
var contractName = param[0];
|
|
787
|
-
if (contractNamesWithNormalEvents.has(contractName)) {
|
|
788
|
-
return Belt_Array.forEach(param[1], (function (a) {
|
|
789
|
-
registerAddress(contractName, a, undefined);
|
|
790
|
-
}));
|
|
764
|
+
Belt_Array.forEach(contracts, (function (contract) {
|
|
765
|
+
var contractName = contract.contractName;
|
|
766
|
+
if (!contractNamesWithNormalEvents.has(contractName)) {
|
|
767
|
+
return ;
|
|
791
768
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
769
|
+
var pendingPartition = pendingNormalPartition.contents;
|
|
770
|
+
Utils.Dict.push(pendingPartition.addressesByContractName, contractName, contract.address);
|
|
771
|
+
indexingContracts[contract.address] = contract;
|
|
772
|
+
if (addressesByContractNameCount(pendingPartition.addressesByContractName) === maxAddrInPartition) {
|
|
773
|
+
partitions.push(pendingPartition);
|
|
774
|
+
pendingNormalPartition.contents = makePendingNormalPartition();
|
|
775
|
+
return ;
|
|
798
776
|
}
|
|
799
777
|
|
|
800
778
|
}));
|
package/src/Internal.gen.ts
CHANGED
|
@@ -34,6 +34,14 @@ export type genericHandlerArgs<event,context,loaderReturn> = {
|
|
|
34
34
|
|
|
35
35
|
export type genericHandler<args> = (_1:args) => Promise<void>;
|
|
36
36
|
|
|
37
|
+
export type entityHandlerContext<entity> = {
|
|
38
|
+
readonly get: (_1:string) => Promise<(undefined | entity)>;
|
|
39
|
+
readonly getOrThrow: (_1:string, message:(undefined | string)) => Promise<entity>;
|
|
40
|
+
readonly getOrCreate: (_1:entity) => Promise<entity>;
|
|
41
|
+
readonly set: (_1:entity) => void;
|
|
42
|
+
readonly deleteUnsafe: (_1:string) => void
|
|
43
|
+
};
|
|
44
|
+
|
|
37
45
|
export type genericHandlerWithLoader<loader,handler,eventFilters> = {
|
|
38
46
|
readonly loader: loader;
|
|
39
47
|
readonly handler: handler;
|
|
@@ -43,6 +51,13 @@ export type genericHandlerWithLoader<loader,handler,eventFilters> = {
|
|
|
43
51
|
readonly preRegisterDynamicContracts?: boolean
|
|
44
52
|
};
|
|
45
53
|
|
|
54
|
+
export type eventOptions<eventFilters> = {
|
|
55
|
+
readonly wildcard?: boolean;
|
|
56
|
+
readonly eventFilters?: eventFilters;
|
|
57
|
+
/** @deprecated The option is removed starting from v2.19 since we made the default mode even faster than pre-registration. */
|
|
58
|
+
readonly preRegisterDynamicContracts?: boolean
|
|
59
|
+
};
|
|
60
|
+
|
|
46
61
|
export type fuelSupplyParams = { readonly subId: string; readonly amount: bigint };
|
|
47
62
|
|
|
48
63
|
export type fuelTransferParams = {
|
package/src/Internal.res
CHANGED
|
@@ -16,8 +16,6 @@ type event = genericEvent<eventParams, eventBlock, eventTransaction>
|
|
|
16
16
|
|
|
17
17
|
external fromGenericEvent: genericEvent<'a, 'b, 'c> => event = "%identity"
|
|
18
18
|
|
|
19
|
-
type loaderReturn
|
|
20
|
-
|
|
21
19
|
@genType
|
|
22
20
|
type genericLoaderArgs<'event, 'context> = {
|
|
23
21
|
event: 'event,
|
|
@@ -26,10 +24,6 @@ type genericLoaderArgs<'event, 'context> = {
|
|
|
26
24
|
@genType
|
|
27
25
|
type genericLoader<'args, 'loaderReturn> = 'args => promise<'loaderReturn>
|
|
28
26
|
|
|
29
|
-
type loaderContext
|
|
30
|
-
type loaderArgs = genericLoaderArgs<event, loaderContext>
|
|
31
|
-
type loader = genericLoader<loaderArgs, loaderReturn>
|
|
32
|
-
|
|
33
27
|
@genType
|
|
34
28
|
type genericContractRegisterArgs<'event, 'context> = {
|
|
35
29
|
event: 'event,
|
|
@@ -51,8 +45,21 @@ type genericHandlerArgs<'event, 'context, 'loaderReturn> = {
|
|
|
51
45
|
@genType
|
|
52
46
|
type genericHandler<'args> = 'args => promise<unit>
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
type
|
|
48
|
+
@genType
|
|
49
|
+
type entityHandlerContext<'entity> = {
|
|
50
|
+
get: string => promise<option<'entity>>,
|
|
51
|
+
getOrThrow: (string, ~message: string=?) => promise<'entity>,
|
|
52
|
+
getOrCreate: 'entity => promise<'entity>,
|
|
53
|
+
set: 'entity => unit,
|
|
54
|
+
deleteUnsafe: string => unit,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type loaderReturn
|
|
58
|
+
type handlerContext = private {isPreload: bool}
|
|
59
|
+
type handlerArgs = {
|
|
60
|
+
event: event,
|
|
61
|
+
context: handlerContext,
|
|
62
|
+
}
|
|
56
63
|
type handler = genericHandler<handlerArgs>
|
|
57
64
|
|
|
58
65
|
@genType
|
|
@@ -81,7 +88,6 @@ type eventConfig = private {
|
|
|
81
88
|
// Usually always false for wildcard events
|
|
82
89
|
// But might be true for wildcard event with dynamic event filter by addresses
|
|
83
90
|
dependsOnAddresses: bool,
|
|
84
|
-
loader: option<loader>,
|
|
85
91
|
handler: option<handler>,
|
|
86
92
|
contractRegister: option<contractRegister>,
|
|
87
93
|
paramsRawEventSchema: S.schema<eventParams>,
|
|
@@ -138,6 +144,16 @@ type eventItem = {
|
|
|
138
144
|
mutable loggerCache?: Pino.t,
|
|
139
145
|
}
|
|
140
146
|
|
|
147
|
+
@genType
|
|
148
|
+
type eventOptions<'eventFilters> = {
|
|
149
|
+
wildcard?: bool,
|
|
150
|
+
eventFilters?: 'eventFilters,
|
|
151
|
+
/**
|
|
152
|
+
@deprecated The option is removed starting from v2.19 since we made the default mode even faster than pre-registration.
|
|
153
|
+
*/
|
|
154
|
+
preRegisterDynamicContracts?: bool,
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
@genType
|
|
142
158
|
type fuelSupplyParams = {
|
|
143
159
|
subId: string,
|
|
@@ -214,7 +230,7 @@ let makeCacheTable = (~effectName) => {
|
|
|
214
230
|
cacheTablePrefix ++ effectName,
|
|
215
231
|
~fields=[
|
|
216
232
|
Table.mkField("id", Text, ~fieldSchema=S.string, ~isPrimaryKey=true),
|
|
217
|
-
Table.mkField("output", JsonB, ~fieldSchema=S.json(~validate=false)),
|
|
233
|
+
Table.mkField("output", JsonB, ~fieldSchema=S.json(~validate=false), ~isNullable=true),
|
|
218
234
|
],
|
|
219
235
|
~compositeIndices=[],
|
|
220
236
|
)
|
package/src/Internal.res.js
CHANGED
|
@@ -40,7 +40,7 @@ var cacheTablePrefix = "envio_effect_";
|
|
|
40
40
|
function makeCacheTable(effectName) {
|
|
41
41
|
return Table.mkTable(cacheTablePrefix + effectName, [], [
|
|
42
42
|
Table.mkField("id", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined),
|
|
43
|
-
Table.mkField("output", "JSONB", S$RescriptSchema.json(false), undefined, undefined,
|
|
43
|
+
Table.mkField("output", "JSONB", S$RescriptSchema.json(false), undefined, undefined, true, undefined, undefined, undefined)
|
|
44
44
|
]);
|
|
45
45
|
}
|
|
46
46
|
|
package/src/Logging.res
CHANGED
|
@@ -155,6 +155,7 @@ let getEventLogger = (eventItem: Internal.eventItem) => {
|
|
|
155
155
|
"chainId": eventItem.chain->ChainMap.Chain.toChainId,
|
|
156
156
|
"block": eventItem.blockNumber,
|
|
157
157
|
"logIndex": eventItem.logIndex,
|
|
158
|
+
"address": eventItem.event.srcAddress,
|
|
158
159
|
}->createChildParams,
|
|
159
160
|
)
|
|
160
161
|
eventItem.loggerCache = Some(l)
|
package/src/Logging.res.js
CHANGED
|
@@ -187,7 +187,8 @@ function getEventLogger(eventItem) {
|
|
|
187
187
|
eventName: eventItem.eventConfig.name,
|
|
188
188
|
chainId: eventItem.chain,
|
|
189
189
|
block: eventItem.blockNumber,
|
|
190
|
-
logIndex: eventItem.logIndex
|
|
190
|
+
logIndex: eventItem.logIndex,
|
|
191
|
+
address: eventItem.event.srcAddress
|
|
191
192
|
}));
|
|
192
193
|
eventItem.loggerCache = l$1;
|
|
193
194
|
return l$1;
|
package/src/Persistence.res
CHANGED
|
@@ -53,7 +53,11 @@ type storage = {
|
|
|
53
53
|
~items: array<Internal.effectCacheItem>,
|
|
54
54
|
~initialize: bool,
|
|
55
55
|
) => promise<unit>,
|
|
56
|
+
// This is to download cache from the database to .envio/cache
|
|
56
57
|
dumpEffectCache: unit => promise<unit>,
|
|
58
|
+
// This is not good, but the function does two things:
|
|
59
|
+
// - Gets info about existing cache tables
|
|
60
|
+
// - if withUpload is true, it also populates the cache from .envio/cache to the database
|
|
57
61
|
restoreEffectCache: (~withUpload: bool) => promise<array<effectCacheRecord>>,
|
|
58
62
|
}
|
|
59
63
|
|
package/src/PgStorage.res
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
let getCacheRowCountFnName = "get_cache_row_count"
|
|
2
|
+
|
|
1
3
|
let makeCreateIndexQuery = (~tableName, ~indexFields, ~pgSchema) => {
|
|
2
4
|
let indexName = tableName ++ "_" ++ indexFields->Js.Array2.joinWith("_")
|
|
3
5
|
let index = indexFields->Belt.Array.map(idx => `"${idx}"`)->Js.Array2.joinWith(", ")
|
|
@@ -133,15 +135,15 @@ GRANT ALL ON SCHEMA "${pgSchema}" TO public;`,
|
|
|
133
135
|
functionsQuery :=
|
|
134
136
|
functionsQuery.contents ++
|
|
135
137
|
"\n" ++
|
|
136
|
-
`CREATE OR REPLACE FUNCTION
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
`CREATE OR REPLACE FUNCTION ${getCacheRowCountFnName}(table_name text)
|
|
139
|
+
RETURNS integer AS $$
|
|
140
|
+
DECLARE
|
|
141
|
+
result integer;
|
|
142
|
+
BEGIN
|
|
143
|
+
EXECUTE format('SELECT COUNT(*) FROM "${pgSchema}".%I', table_name) INTO result;
|
|
144
|
+
RETURN result;
|
|
145
|
+
END;
|
|
146
|
+
$$ LANGUAGE plpgsql;`
|
|
145
147
|
|
|
146
148
|
[query.contents]->Js.Array2.concat(
|
|
147
149
|
functionsQuery.contents !== "" ? [functionsQuery.contents] : [],
|
|
@@ -445,7 +447,7 @@ type schemaCacheTableInfo = {
|
|
|
445
447
|
let makeSchemaCacheTableInfoQuery = (~pgSchema) => {
|
|
446
448
|
`SELECT
|
|
447
449
|
t.table_name,
|
|
448
|
-
|
|
450
|
+
${getCacheRowCountFnName}(t.table_name) as count
|
|
449
451
|
FROM information_schema.tables t
|
|
450
452
|
WHERE t.table_schema = '${pgSchema}'
|
|
451
453
|
AND t.table_name LIKE '${Internal.cacheTablePrefix}%';`
|
|
@@ -577,6 +579,7 @@ let make = (
|
|
|
577
579
|
queries->Js.Array2.map(query => sql->Postgres.unsafe(query))
|
|
578
580
|
})
|
|
579
581
|
|
|
582
|
+
// Integration with other tools like Hasura
|
|
580
583
|
switch onInitialize {
|
|
581
584
|
| Some(onInitialize) => await onInitialize()
|
|
582
585
|
| None => ()
|
|
@@ -694,6 +697,7 @@ let make = (
|
|
|
694
697
|
|
|
695
698
|
if initialize {
|
|
696
699
|
let _ = await sql->Postgres.unsafe(makeCreateTableQuery(table, ~pgSchema))
|
|
700
|
+
// Integration with other tools like Hasura
|
|
697
701
|
switch onNewTables {
|
|
698
702
|
| Some(onNewTables) => await onNewTables(~tableNames=[table.tableName])
|
|
699
703
|
| None => ()
|
|
@@ -828,6 +832,7 @@ let make = (
|
|
|
828
832
|
await sql->Postgres.unsafe(makeSchemaCacheTableInfoQuery(~pgSchema))
|
|
829
833
|
|
|
830
834
|
if withUpload && cacheTableInfo->Utils.Array.notEmpty {
|
|
835
|
+
// Integration with other tools like Hasura
|
|
831
836
|
switch onNewTables {
|
|
832
837
|
| Some(onNewTables) =>
|
|
833
838
|
await onNewTables(
|
package/src/PgStorage.res.js
CHANGED
|
@@ -21,6 +21,8 @@ var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
|
|
|
21
21
|
var S$RescriptSchema = require("rescript-schema/src/S.res.js");
|
|
22
22
|
var Caml_js_exceptions = require("rescript/lib/js/caml_js_exceptions.js");
|
|
23
23
|
|
|
24
|
+
var getCacheRowCountFnName = "get_cache_row_count";
|
|
25
|
+
|
|
24
26
|
function makeCreateIndexQuery(tableName, indexFields, pgSchema) {
|
|
25
27
|
var indexName = tableName + "_" + indexFields.join("_");
|
|
26
28
|
var index = Belt_Array.map(indexFields, (function (idx) {
|
|
@@ -111,7 +113,7 @@ function makeInitializeTransaction(pgSchema, pgUser, generalTablesOpt, entitiesO
|
|
|
111
113
|
query.contents = query.contents + "\n" + makeCreateIndexQuery(derivedFromField.derivedFromEntity, [indexField], pgSchema);
|
|
112
114
|
});
|
|
113
115
|
});
|
|
114
|
-
functionsQuery.contents = functionsQuery.contents + "\n" + ("CREATE OR REPLACE FUNCTION
|
|
116
|
+
functionsQuery.contents = functionsQuery.contents + "\n" + ("CREATE OR REPLACE FUNCTION " + getCacheRowCountFnName + "(table_name text) \nRETURNS integer AS $$\nDECLARE\n result integer;\nBEGIN\n EXECUTE format('SELECT COUNT(*) FROM \"" + pgSchema + "\".%I', table_name) INTO result;\n RETURN result;\nEND;\n$$ LANGUAGE plpgsql;");
|
|
115
117
|
return [query.contents].concat(functionsQuery.contents !== "" ? [functionsQuery.contents] : []);
|
|
116
118
|
}
|
|
117
119
|
|
|
@@ -299,7 +301,7 @@ function makeSchemaTableNamesQuery(pgSchema) {
|
|
|
299
301
|
var cacheTablePrefixLength = Internal.cacheTablePrefix.length;
|
|
300
302
|
|
|
301
303
|
function makeSchemaCacheTableInfoQuery(pgSchema) {
|
|
302
|
-
return "SELECT \n t.table_name,\n
|
|
304
|
+
return "SELECT \n t.table_name,\n " + getCacheRowCountFnName + "(t.table_name) as count\n FROM information_schema.tables t\n WHERE t.table_schema = '" + pgSchema + "' \n AND t.table_name LIKE '" + Internal.cacheTablePrefix + "%';";
|
|
303
305
|
}
|
|
304
306
|
|
|
305
307
|
var psqlExecState = {
|
|
@@ -613,6 +615,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, onI
|
|
|
613
615
|
|
|
614
616
|
var maxItemsPerQuery = 500;
|
|
615
617
|
|
|
618
|
+
exports.getCacheRowCountFnName = getCacheRowCountFnName;
|
|
616
619
|
exports.makeCreateIndexQuery = makeCreateIndexQuery;
|
|
617
620
|
exports.makeCreateTableIndicesQuery = makeCreateTableIndicesQuery;
|
|
618
621
|
exports.makeCreateTableQuery = makeCreateTableQuery;
|
package/src/Utils.res
CHANGED
|
@@ -516,6 +516,12 @@ module Proxy = {
|
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
module Hash = {
|
|
519
|
+
let fail = name => {
|
|
520
|
+
Js.Exn.raiseError(
|
|
521
|
+
`Failed to get hash for ${name}. If you're using a custom Sury schema make it based on the string type with a decoder: const myTypeSchema = S.transform(S.string, undefined, (yourType) => yourType.toString())`,
|
|
522
|
+
)
|
|
523
|
+
}
|
|
524
|
+
|
|
519
525
|
// Hash to JSON string. No specific reason for this,
|
|
520
526
|
// just to stick to at least some sort of spec.
|
|
521
527
|
// After Sury v11 is out we'll be able to do it with schema
|
|
@@ -546,13 +552,16 @@ module Hash = {
|
|
|
546
552
|
if constructor === %raw(`Object`) {
|
|
547
553
|
let hash = ref("{")
|
|
548
554
|
let keys = any->Js.Dict.keys->Js.Array2.sortInPlace
|
|
555
|
+
let isFirst = ref(true)
|
|
549
556
|
for i in 0 to keys->Js.Array2.length - 1 {
|
|
550
557
|
let key = keys->Js.Array2.unsafe_get(i)
|
|
551
558
|
let value = any->Js.Dict.unsafeGet(key)
|
|
552
|
-
if i !== 0 {
|
|
553
|
-
hash := hash.contents ++ ","
|
|
554
|
-
}
|
|
555
559
|
if value !== %raw(`undefined`) {
|
|
560
|
+
if isFirst.contents {
|
|
561
|
+
isFirst := false
|
|
562
|
+
} else {
|
|
563
|
+
hash := hash.contents ++ ","
|
|
564
|
+
}
|
|
556
565
|
// Ideally should escape and wrap the key in double quotes
|
|
557
566
|
// but since we don't need to decode the hash,
|
|
558
567
|
// it's fine to keep it super simple
|
|
@@ -563,13 +572,13 @@ module Hash = {
|
|
|
563
572
|
} else if constructor["name"] === "BigNumber" {
|
|
564
573
|
`"${(any->magic)["toString"]()}"`
|
|
565
574
|
} else {
|
|
566
|
-
|
|
575
|
+
fail((constructor->magic)["name"])
|
|
567
576
|
}
|
|
568
577
|
}
|
|
569
578
|
| "symbol"
|
|
570
579
|
| "function" =>
|
|
571
580
|
(any->magic)["toString"]()
|
|
572
|
-
| typeof =>
|
|
581
|
+
| typeof => fail(typeof)
|
|
573
582
|
}
|
|
574
583
|
}
|
|
575
584
|
}
|
package/src/Utils.res.js
CHANGED
|
@@ -452,6 +452,10 @@ var $$Map = {};
|
|
|
452
452
|
|
|
453
453
|
var $$Proxy = {};
|
|
454
454
|
|
|
455
|
+
function fail(name) {
|
|
456
|
+
return Js_exn.raiseError("Failed to get hash for " + name + ". If you're using a custom Sury schema make it based on the string type with a decoder: const myTypeSchema = S.transform(S.string, undefined, (yourType) => yourType.toString())");
|
|
457
|
+
}
|
|
458
|
+
|
|
455
459
|
function makeOrThrow(any) {
|
|
456
460
|
var $$typeof = typeof any;
|
|
457
461
|
switch ($$typeof) {
|
|
@@ -484,18 +488,21 @@ function makeOrThrow(any) {
|
|
|
484
488
|
if (constructor.name === "BigNumber") {
|
|
485
489
|
return "\"" + any.toString() + "\"";
|
|
486
490
|
} else {
|
|
487
|
-
return
|
|
491
|
+
return fail(constructor.name);
|
|
488
492
|
}
|
|
489
493
|
}
|
|
490
494
|
var hash$1 = "{";
|
|
491
495
|
var keys = Object.keys(any).sort();
|
|
496
|
+
var isFirst = true;
|
|
492
497
|
for(var i$1 = 0 ,i_finish$1 = keys.length; i$1 < i_finish$1; ++i$1){
|
|
493
498
|
var key = keys[i$1];
|
|
494
499
|
var value = any[key];
|
|
495
|
-
if (i$1 !== 0) {
|
|
496
|
-
hash$1 = hash$1 + ",";
|
|
497
|
-
}
|
|
498
500
|
if (value !== undefined) {
|
|
501
|
+
if (isFirst) {
|
|
502
|
+
isFirst = false;
|
|
503
|
+
} else {
|
|
504
|
+
hash$1 = hash$1 + ",";
|
|
505
|
+
}
|
|
499
506
|
hash$1 = hash$1 + ("\"" + key + "\":" + makeOrThrow(any[key]));
|
|
500
507
|
}
|
|
501
508
|
|
|
@@ -509,11 +516,12 @@ function makeOrThrow(any) {
|
|
|
509
516
|
case "undefined" :
|
|
510
517
|
return "null";
|
|
511
518
|
default:
|
|
512
|
-
return
|
|
519
|
+
return fail($$typeof);
|
|
513
520
|
}
|
|
514
521
|
}
|
|
515
522
|
|
|
516
523
|
var Hash = {
|
|
524
|
+
fail: fail,
|
|
517
525
|
makeOrThrow: makeOrThrow
|
|
518
526
|
};
|
|
519
527
|
|
package/src/bindings/NodeJs.res
CHANGED
|
@@ -4,6 +4,37 @@ type t
|
|
|
4
4
|
type exitCode = | @as(0) Success | @as(1) Failure
|
|
5
5
|
@send external exitWithCode: (t, exitCode) => unit = "exit"
|
|
6
6
|
|
|
7
|
+
module Util = {
|
|
8
|
+
@unboxed
|
|
9
|
+
type depth = Int(int) | @as(null) Null
|
|
10
|
+
@unboxed
|
|
11
|
+
type compact = Bool(bool) | Int(int)
|
|
12
|
+
@unboxed
|
|
13
|
+
type sorted = Bool(bool) | Fn((string, string) => int)
|
|
14
|
+
@unboxed
|
|
15
|
+
type getters = | @as(true) True | @as(false) False | @as("get") Get | @as("set") Set
|
|
16
|
+
|
|
17
|
+
@unbox
|
|
18
|
+
type inspectOptions = {
|
|
19
|
+
showHidden?: bool,
|
|
20
|
+
depth?: depth,
|
|
21
|
+
colors?: bool,
|
|
22
|
+
customInspect?: bool,
|
|
23
|
+
showProxy?: bool,
|
|
24
|
+
maxArrayLength?: int,
|
|
25
|
+
maxStringLength?: int,
|
|
26
|
+
breakLength?: int,
|
|
27
|
+
@as("compact") compact?: compact,
|
|
28
|
+
sorted?: sorted,
|
|
29
|
+
getters?: string,
|
|
30
|
+
numericSeparator?: bool,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@module("util") external inspect: ('a, inspectOptions) => string = "inspect"
|
|
34
|
+
|
|
35
|
+
let inspectObj = a => inspect(a, {showHidden: false, depth: Null, colors: true})
|
|
36
|
+
}
|
|
37
|
+
|
|
7
38
|
module Process = {
|
|
8
39
|
type t = {env: Js.Dict.t<string>}
|
|
9
40
|
@module external process: t = "process"
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var Util = require("util");
|
|
5
|
+
|
|
6
|
+
function inspectObj(a) {
|
|
7
|
+
return Util.inspect(a, {
|
|
8
|
+
showHidden: false,
|
|
9
|
+
depth: null,
|
|
10
|
+
colors: true
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var Util$1 = {
|
|
15
|
+
inspectObj: inspectObj
|
|
16
|
+
};
|
|
4
17
|
|
|
5
18
|
var Process = {};
|
|
6
19
|
|
|
@@ -14,8 +27,9 @@ var Fs = {
|
|
|
14
27
|
Promises: Promises
|
|
15
28
|
};
|
|
16
29
|
|
|
30
|
+
exports.Util = Util$1;
|
|
17
31
|
exports.Process = Process;
|
|
18
32
|
exports.ChildProcess = ChildProcess;
|
|
19
33
|
exports.Path = Path;
|
|
20
34
|
exports.Fs = Fs;
|
|
21
|
-
/*
|
|
35
|
+
/* util Not a pure module */
|
package/src/bindings/Promise.res
CHANGED
|
@@ -53,6 +53,8 @@ external race: array<t<'a>> => t<'a> = "race"
|
|
|
53
53
|
|
|
54
54
|
external done: promise<'a> => unit = "%ignore"
|
|
55
55
|
|
|
56
|
+
external ignoreValue: promise<'a> => promise<unit> = "%identity"
|
|
57
|
+
|
|
56
58
|
external unsafe_async: 'a => promise<'a> = "%identity"
|
|
57
59
|
external unsafe_await: promise<'a> => 'a = "?await"
|
|
58
60
|
|