envio 2.27.5 → 2.28.0-alpha.1
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/rescript.json +3 -0
- package/src/ErrorHandling.res +4 -5
- package/src/ErrorHandling.res.js +7 -7
- package/src/Hasura.res +139 -16
- package/src/Hasura.res.js +99 -18
- package/src/Internal.res +7 -11
- package/src/Internal.res.js +0 -11
- package/src/InternalConfig.res +20 -0
- package/src/InternalConfig.res.js +2 -0
- package/src/Js.shim.ts +11 -0
- package/src/LoadManager.res +13 -7
- package/src/LoadManager.res.js +14 -8
- package/src/Logging.res +1 -1
- package/src/Logging.res.js +2 -2
- package/src/Persistence.res +25 -33
- package/src/Persistence.res.js +18 -20
- package/src/PgStorage.res +158 -106
- package/src/PgStorage.res.js +143 -102
- package/src/Prometheus.res +2 -2
- package/src/Prometheus.res.js +2 -3
- package/src/Time.res +1 -1
- package/src/Time.res.js +1 -2
- package/src/Utils.res +7 -0
- package/src/Utils.res.js +11 -0
- package/src/bindings/Pino.res +1 -1
- package/src/bindings/Pino.res.js +2 -1
- package/src/db/EntityHistory.res +115 -50
- package/src/db/EntityHistory.res.js +43 -26
- package/src/db/InternalTable.gen.ts +43 -0
- package/src/db/InternalTable.res +392 -0
- package/src/db/InternalTable.res.js +295 -0
- package/src/sources/SourceManager.res +3 -3
- package/src/sources/SourceManager.res.js +3 -4
- package/src/vendored/Rest.res +11 -2
- package/src/vendored/Rest.res.js +44 -35
package/src/LoadManager.res.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var Utils = require("./Utils.res.js");
|
|
5
|
-
var Internal = require("./Internal.res.js");
|
|
6
5
|
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
7
6
|
var Caml_js_exceptions = require("rescript/lib/js/caml_js_exceptions.js");
|
|
8
7
|
|
|
@@ -41,27 +40,34 @@ async function schedule(loadManager) {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
});
|
|
44
|
-
|
|
43
|
+
var isSuccess;
|
|
44
|
+
if (Utils.$$Array.isEmpty(inputsToLoad)) {
|
|
45
|
+
isSuccess = true;
|
|
46
|
+
} else {
|
|
45
47
|
try {
|
|
46
48
|
await group.load(inputsToLoad);
|
|
49
|
+
isSuccess = true;
|
|
47
50
|
}
|
|
48
51
|
catch (raw_exn){
|
|
49
52
|
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
|
|
50
|
-
var exn$1 =
|
|
53
|
+
var exn$1 = Utils.prettifyExn(exn);
|
|
51
54
|
Belt_Array.forEach(currentInputKeys, (function (inputKey) {
|
|
52
55
|
var call = calls[inputKey];
|
|
53
56
|
call.reject(exn$1);
|
|
54
57
|
}));
|
|
58
|
+
isSuccess = false;
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
if (Utils.$$Array.isEmpty(currentInputKeys)) {
|
|
58
62
|
return ;
|
|
59
63
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
if (isSuccess) {
|
|
65
|
+
currentInputKeys.forEach(function (inputKey) {
|
|
66
|
+
var call = calls[inputKey];
|
|
67
|
+
Utils.Dict.deleteInPlace(calls, inputKey);
|
|
68
|
+
call.resolve(group.getUnsafeInMemory(inputKey));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
65
71
|
var latestGroup = groups[key];
|
|
66
72
|
if (Utils.$$Array.isEmpty(Object.keys(latestGroup.calls))) {
|
|
67
73
|
return Utils.Dict.deleteInPlace(groups, key);
|
package/src/Logging.res
CHANGED
|
@@ -183,5 +183,5 @@ let getUserLogger = (eventItem): Envio.logger => {
|
|
|
183
183
|
warn: (message: string, ~params=?) => eventItem->logForItem(#uwarn, message, ~params?),
|
|
184
184
|
error: (message: string, ~params=?) => eventItem->logForItem(#uerror, message, ~params?),
|
|
185
185
|
errorWithExn: (message: string, exn) =>
|
|
186
|
-
eventItem->logForItem(#uerror, message, ~params={"err": exn->
|
|
186
|
+
eventItem->logForItem(#uerror, message, ~params={"err": exn->Utils.prettifyExn}),
|
|
187
187
|
}
|
package/src/Logging.res.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
var Pino = require("./bindings/Pino.res.js");
|
|
5
5
|
var Pino$1 = require("pino");
|
|
6
|
+
var Utils = require("./Utils.res.js");
|
|
6
7
|
var Js_exn = require("rescript/lib/js/js_exn.js");
|
|
7
8
|
var Js_dict = require("rescript/lib/js/js_dict.js");
|
|
8
9
|
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
9
|
-
var Internal = require("./Internal.res.js");
|
|
10
10
|
var Caml_option = require("rescript/lib/js/caml_option.js");
|
|
11
11
|
var EcsPinoFormat = require("@elastic/ecs-pino-format");
|
|
12
12
|
|
|
@@ -242,7 +242,7 @@ function getUserLogger(eventItem) {
|
|
|
242
242
|
}),
|
|
243
243
|
errorWithExn: (function (message, exn) {
|
|
244
244
|
var params = {
|
|
245
|
-
err:
|
|
245
|
+
err: Utils.prettifyExn(exn)
|
|
246
246
|
};
|
|
247
247
|
getEventLogger(eventItem)["uerror"](params, message);
|
|
248
248
|
})
|
package/src/Persistence.res
CHANGED
|
@@ -13,6 +13,12 @@ type effectCacheRecord = {
|
|
|
13
13
|
mutable count: int,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
type initialState = {
|
|
17
|
+
cleanRun: bool,
|
|
18
|
+
cache: dict<effectCacheRecord>,
|
|
19
|
+
chains: array<InternalTable.Chains.t>,
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
type operator = [#">" | #"="]
|
|
17
23
|
|
|
18
24
|
type storage = {
|
|
@@ -22,10 +28,11 @@ type storage = {
|
|
|
22
28
|
// Should initialize the storage so we can start interacting with it
|
|
23
29
|
// Eg create connection, schema, tables, etc.
|
|
24
30
|
initialize: (
|
|
31
|
+
~chainConfigs: array<InternalConfig.chain>=?,
|
|
25
32
|
~entities: array<Internal.entityConfig>=?,
|
|
26
|
-
~generalTables: array<Table.table>=?,
|
|
27
33
|
~enums: array<Internal.enumConfig<Internal.enum>>=?,
|
|
28
|
-
) => promise<
|
|
34
|
+
) => promise<initialState>,
|
|
35
|
+
loadInitialState: unit => promise<initialState>,
|
|
29
36
|
@raises("StorageError")
|
|
30
37
|
loadByIdsOrThrow: 'item. (
|
|
31
38
|
~ids: array<string>,
|
|
@@ -55,10 +62,6 @@ type storage = {
|
|
|
55
62
|
) => promise<unit>,
|
|
56
63
|
// This is to download cache from the database to .envio/cache
|
|
57
64
|
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
|
|
61
|
-
restoreEffectCache: (~withUpload: bool) => promise<array<effectCacheRecord>>,
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
exception StorageError({message: string, reason: exn})
|
|
@@ -66,11 +69,10 @@ exception StorageError({message: string, reason: exn})
|
|
|
66
69
|
type storageStatus =
|
|
67
70
|
| Unknown
|
|
68
71
|
| Initializing(promise<unit>)
|
|
69
|
-
| Ready(
|
|
72
|
+
| Ready(initialState)
|
|
70
73
|
|
|
71
74
|
type t = {
|
|
72
75
|
userEntities: array<Internal.entityConfig>,
|
|
73
|
-
staticTables: array<Table.table>,
|
|
74
76
|
allEntities: array<Internal.entityConfig>,
|
|
75
77
|
allEnums: array<Internal.enumConfig<Internal.enum>>,
|
|
76
78
|
mutable storageStatus: storageStatus,
|
|
@@ -86,18 +88,15 @@ let entityHistoryActionEnumConfig: Internal.enumConfig<EntityHistory.RowAction.t
|
|
|
86
88
|
|
|
87
89
|
let make = (
|
|
88
90
|
~userEntities,
|
|
89
|
-
~dcRegistryEntityConfig,
|
|
90
91
|
// TODO: Should only pass userEnums and create internal config in runtime
|
|
91
92
|
~allEnums,
|
|
92
|
-
~staticTables,
|
|
93
93
|
~storage,
|
|
94
94
|
) => {
|
|
95
|
-
let allEntities = userEntities->Js.Array2.concat([
|
|
95
|
+
let allEntities = userEntities->Js.Array2.concat([InternalTable.DynamicContractRegistry.config])
|
|
96
96
|
let allEnums =
|
|
97
97
|
allEnums->Js.Array2.concat([entityHistoryActionEnumConfig->Internal.fromGenericEnumConfig])
|
|
98
98
|
{
|
|
99
99
|
userEntities,
|
|
100
|
-
staticTables,
|
|
101
100
|
allEntities,
|
|
102
101
|
allEnums,
|
|
103
102
|
storageStatus: Unknown,
|
|
@@ -106,17 +105,7 @@ let make = (
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
let init = {
|
|
109
|
-
|
|
110
|
-
let effectCacheRecords = await persistence.storage.restoreEffectCache(~withUpload)
|
|
111
|
-
let cache = Js.Dict.empty()
|
|
112
|
-
effectCacheRecords->Js.Array2.forEach(record => {
|
|
113
|
-
Prometheus.EffectCacheCount.set(~count=record.count, ~effectName=record.effectName)
|
|
114
|
-
cache->Js.Dict.set(record.effectName, record)
|
|
115
|
-
})
|
|
116
|
-
cache
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async (persistence, ~reset=false) => {
|
|
108
|
+
async (persistence, ~chainConfigs, ~reset=false) => {
|
|
120
109
|
try {
|
|
121
110
|
let shouldRun = switch persistence.storageStatus {
|
|
122
111
|
| Unknown => true
|
|
@@ -135,17 +124,14 @@ let init = {
|
|
|
135
124
|
if reset || !(await persistence.storage.isInitialized()) {
|
|
136
125
|
Logging.info(`Initializing the indexer storage...`)
|
|
137
126
|
|
|
138
|
-
await persistence.storage.initialize(
|
|
127
|
+
let initialState = await persistence.storage.initialize(
|
|
139
128
|
~entities=persistence.allEntities,
|
|
140
|
-
~generalTables=persistence.staticTables,
|
|
141
129
|
~enums=persistence.allEnums,
|
|
130
|
+
~chainConfigs,
|
|
142
131
|
)
|
|
143
132
|
|
|
144
133
|
Logging.info(`The indexer storage is ready. Uploading cache...`)
|
|
145
|
-
persistence.storageStatus = Ready(
|
|
146
|
-
cleanRun: true,
|
|
147
|
-
cache: await loadInitialCache(persistence, ~withUpload=true),
|
|
148
|
-
})
|
|
134
|
+
persistence.storageStatus = Ready(initialState)
|
|
149
135
|
} else if (
|
|
150
136
|
// In case of a race condition,
|
|
151
137
|
// we want to set the initial status to Ready only once.
|
|
@@ -155,10 +141,7 @@ let init = {
|
|
|
155
141
|
}
|
|
156
142
|
) {
|
|
157
143
|
Logging.info(`The indexer storage is ready.`)
|
|
158
|
-
persistence.storageStatus = Ready(
|
|
159
|
-
cleanRun: false,
|
|
160
|
-
cache: await loadInitialCache(persistence, ~withUpload=false),
|
|
161
|
-
})
|
|
144
|
+
persistence.storageStatus = Ready(await persistence.storage.loadInitialState())
|
|
162
145
|
}
|
|
163
146
|
resolveRef.contents()
|
|
164
147
|
}
|
|
@@ -178,6 +161,15 @@ let getInitializedStorageOrThrow = persistence => {
|
|
|
178
161
|
}
|
|
179
162
|
}
|
|
180
163
|
|
|
164
|
+
let getInitializedState = persistence => {
|
|
165
|
+
switch persistence.storageStatus {
|
|
166
|
+
| Unknown
|
|
167
|
+
| Initializing(_) =>
|
|
168
|
+
Js.Exn.raiseError(`Failed to access the initial state. The Persistence layer is not initialized.`)
|
|
169
|
+
| Ready(initialState) => initialState
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
181
173
|
let setEffectCacheOrThrow = async (persistence, ~effect: Internal.effect, ~items) => {
|
|
182
174
|
switch persistence.storageStatus {
|
|
183
175
|
| Unknown
|
package/src/Persistence.res.js
CHANGED
|
@@ -6,6 +6,7 @@ var Logging = require("./Logging.res.js");
|
|
|
6
6
|
var Prometheus = require("./Prometheus.res.js");
|
|
7
7
|
var EntityHistory = require("./db/EntityHistory.res.js");
|
|
8
8
|
var ErrorHandling = require("./ErrorHandling.res.js");
|
|
9
|
+
var InternalTable = require("./db/InternalTable.res.js");
|
|
9
10
|
var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
|
|
10
11
|
var Caml_js_exceptions = require("rescript/lib/js/caml_js_exceptions.js");
|
|
11
12
|
|
|
@@ -24,12 +25,11 @@ var entityHistoryActionEnumConfig = {
|
|
|
24
25
|
default: "SET"
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
function make(userEntities,
|
|
28
|
-
var allEntities = userEntities.concat([
|
|
28
|
+
function make(userEntities, allEnums, storage) {
|
|
29
|
+
var allEntities = userEntities.concat([InternalTable.DynamicContractRegistry.config]);
|
|
29
30
|
var allEnums$1 = allEnums.concat([entityHistoryActionEnumConfig]);
|
|
30
31
|
return {
|
|
31
32
|
userEntities: userEntities,
|
|
32
|
-
staticTables: staticTables,
|
|
33
33
|
allEntities: allEntities,
|
|
34
34
|
allEnums: allEnums$1,
|
|
35
35
|
storageStatus: "Unknown",
|
|
@@ -37,17 +37,7 @@ function make(userEntities, dcRegistryEntityConfig, allEnums, staticTables, stor
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
async function
|
|
41
|
-
var effectCacheRecords = await persistence.storage.restoreEffectCache(withUpload);
|
|
42
|
-
var cache = {};
|
|
43
|
-
effectCacheRecords.forEach(function (record) {
|
|
44
|
-
Prometheus.EffectCacheCount.set(record.count, record.effectName);
|
|
45
|
-
cache[record.effectName] = record;
|
|
46
|
-
});
|
|
47
|
-
return cache;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function init(persistence, resetOpt) {
|
|
40
|
+
async function init(persistence, chainConfigs, resetOpt) {
|
|
51
41
|
var reset = resetOpt !== undefined ? resetOpt : false;
|
|
52
42
|
try {
|
|
53
43
|
var promise = persistence.storageStatus;
|
|
@@ -75,12 +65,11 @@ async function init(persistence, resetOpt) {
|
|
|
75
65
|
};
|
|
76
66
|
if (reset || !await persistence.storage.isInitialized()) {
|
|
77
67
|
Logging.info("Initializing the indexer storage...");
|
|
78
|
-
await persistence.storage.initialize(
|
|
68
|
+
var initialState = await persistence.storage.initialize(chainConfigs, persistence.allEntities, persistence.allEnums);
|
|
79
69
|
Logging.info("The indexer storage is ready. Uploading cache...");
|
|
80
70
|
persistence.storageStatus = {
|
|
81
71
|
TAG: "Ready",
|
|
82
|
-
|
|
83
|
-
cache: await loadInitialCache(persistence, true)
|
|
72
|
+
_0: initialState
|
|
84
73
|
};
|
|
85
74
|
} else {
|
|
86
75
|
var match = persistence.storageStatus;
|
|
@@ -90,8 +79,7 @@ async function init(persistence, resetOpt) {
|
|
|
90
79
|
Logging.info("The indexer storage is ready.");
|
|
91
80
|
persistence.storageStatus = {
|
|
92
81
|
TAG: "Ready",
|
|
93
|
-
|
|
94
|
-
cache: await loadInitialCache(persistence, false)
|
|
82
|
+
_0: await persistence.storage.loadInitialState()
|
|
95
83
|
};
|
|
96
84
|
}
|
|
97
85
|
|
|
@@ -113,6 +101,15 @@ function getInitializedStorageOrThrow(persistence) {
|
|
|
113
101
|
}
|
|
114
102
|
}
|
|
115
103
|
|
|
104
|
+
function getInitializedState(persistence) {
|
|
105
|
+
var initialState = persistence.storageStatus;
|
|
106
|
+
if (typeof initialState !== "object" || initialState.TAG === "Initializing") {
|
|
107
|
+
return Js_exn.raiseError("Failed to access the initial state. The Persistence layer is not initialized.");
|
|
108
|
+
} else {
|
|
109
|
+
return initialState._0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
116
113
|
async function setEffectCacheOrThrow(persistence, effect, items) {
|
|
117
114
|
var match = persistence.storageStatus;
|
|
118
115
|
if (typeof match !== "object") {
|
|
@@ -121,7 +118,7 @@ async function setEffectCacheOrThrow(persistence, effect, items) {
|
|
|
121
118
|
if (match.TAG === "Initializing") {
|
|
122
119
|
return Js_exn.raiseError("Failed to access the indexer storage. The Persistence layer is not initialized.");
|
|
123
120
|
}
|
|
124
|
-
var cache = match.cache;
|
|
121
|
+
var cache = match._0.cache;
|
|
125
122
|
var storage = persistence.storage;
|
|
126
123
|
var effectName = effect.name;
|
|
127
124
|
var c = cache[effectName];
|
|
@@ -147,5 +144,6 @@ exports.entityHistoryActionEnumConfig = entityHistoryActionEnumConfig;
|
|
|
147
144
|
exports.make = make;
|
|
148
145
|
exports.init = init;
|
|
149
146
|
exports.getInitializedStorageOrThrow = getInitializedStorageOrThrow;
|
|
147
|
+
exports.getInitializedState = getInitializedState;
|
|
150
148
|
exports.setEffectCacheOrThrow = setEffectCacheOrThrow;
|
|
151
149
|
/* Logging Not a pure module */
|