envio 3.0.0-alpha.0 → 3.0.0-alpha.10
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 +2 -2
- package/evm.schema.json +53 -57
- package/fuel.schema.json +35 -31
- package/index.d.ts +446 -1
- package/index.js +4 -0
- package/package.json +23 -11
- package/rescript.json +4 -1
- package/src/Batch.res.mjs +1 -1
- package/src/Benchmark.res +394 -0
- package/src/Benchmark.res.mjs +398 -0
- package/src/ChainFetcher.res +526 -0
- package/src/ChainFetcher.res.mjs +343 -0
- package/src/ChainManager.res +182 -0
- package/src/ChainManager.res.mjs +150 -0
- package/src/Config.res +367 -27
- package/src/Config.res.mjs +338 -28
- package/src/{Indexer.res → Ctx.res} +1 -1
- package/src/Ecosystem.res +25 -0
- package/src/Ecosystem.res.mjs +29 -0
- package/src/Env.res +252 -0
- package/src/Env.res.mjs +271 -0
- package/src/Envio.gen.ts +9 -1
- package/src/Envio.res +12 -9
- package/src/EventProcessing.res +476 -0
- package/src/EventProcessing.res.mjs +341 -0
- package/src/EventRegister.res +4 -15
- package/src/EventRegister.res.mjs +3 -9
- package/src/EventRegister.resi +2 -8
- package/src/FetchState.res +54 -29
- package/src/FetchState.res.mjs +62 -35
- package/src/GlobalState.res +1163 -0
- package/src/GlobalState.res.mjs +1196 -0
- package/src/GlobalStateManager.res +68 -0
- package/src/GlobalStateManager.res.mjs +75 -0
- package/src/GlobalStateManager.resi +7 -0
- package/src/HandlerLoader.res +89 -0
- package/src/HandlerLoader.res.mjs +79 -0
- package/src/Internal.gen.ts +3 -14
- package/src/Internal.res +45 -13
- package/src/LoadLayer.res +444 -0
- package/src/LoadLayer.res.mjs +296 -0
- package/src/LoadLayer.resi +32 -0
- package/src/LogSelection.res +33 -27
- package/src/LogSelection.res.mjs +6 -0
- package/src/Logging.res +11 -4
- package/src/Logging.res.mjs +14 -6
- package/src/Main.res +351 -0
- package/src/Main.res.mjs +312 -0
- package/src/Persistence.res +1 -2
- package/src/PgStorage.gen.ts +10 -0
- package/src/PgStorage.res +28 -34
- package/src/PgStorage.res.d.mts +5 -0
- package/src/PgStorage.res.mjs +27 -27
- package/src/Prometheus.res +8 -8
- package/src/Prometheus.res.mjs +10 -10
- package/src/ReorgDetection.res +6 -10
- package/src/ReorgDetection.res.mjs +6 -6
- package/src/TestIndexer.res +536 -0
- package/src/TestIndexer.res.mjs +412 -0
- package/src/TestIndexerProxyStorage.res +210 -0
- package/src/TestIndexerProxyStorage.res.mjs +157 -0
- package/src/Types.ts +1 -1
- package/src/UserContext.res +355 -0
- package/src/UserContext.res.mjs +236 -0
- package/src/Utils.res +28 -0
- package/src/Utils.res.mjs +18 -0
- package/src/bindings/ClickHouse.res +31 -1
- package/src/bindings/ClickHouse.res.mjs +27 -1
- package/src/bindings/DateFns.res +71 -0
- package/src/bindings/DateFns.res.mjs +22 -0
- package/src/bindings/Ethers.res +27 -67
- package/src/bindings/Ethers.res.mjs +18 -70
- package/src/bindings/EventSource.res +13 -0
- package/src/bindings/EventSource.res.mjs +2 -0
- package/src/bindings/NodeJs.res +44 -3
- package/src/bindings/NodeJs.res.mjs +11 -3
- package/src/bindings/Pino.res +21 -7
- package/src/bindings/Pino.res.mjs +11 -5
- package/src/bindings/Postgres.gen.ts +8 -0
- package/src/bindings/Postgres.res +3 -0
- package/src/bindings/Postgres.res.d.mts +5 -0
- package/src/bindings/RescriptMocha.res +123 -0
- package/src/bindings/RescriptMocha.res.mjs +18 -0
- package/src/bindings/Vitest.res +134 -0
- package/src/bindings/Vitest.res.mjs +9 -0
- package/src/bindings/Yargs.res +8 -0
- package/src/bindings/Yargs.res.mjs +2 -0
- package/src/db/InternalTable.res +2 -0
- package/src/db/InternalTable.res.mjs +1 -1
- package/src/sources/Evm.res +87 -0
- package/src/sources/Evm.res.mjs +105 -0
- package/src/sources/EvmChain.res +90 -0
- package/src/sources/EvmChain.res.mjs +57 -0
- package/src/sources/Fuel.res +19 -34
- package/src/sources/Fuel.res.mjs +34 -16
- package/src/sources/FuelSDK.res +38 -0
- package/src/sources/FuelSDK.res.mjs +29 -0
- package/src/sources/HyperFuel.res +2 -2
- package/src/sources/HyperFuel.resi +1 -1
- package/src/sources/HyperFuelClient.res +2 -2
- package/src/sources/HyperFuelSource.res +8 -8
- package/src/sources/HyperFuelSource.res.mjs +5 -5
- package/src/sources/HyperSyncHeightStream.res +97 -0
- package/src/sources/HyperSyncHeightStream.res.mjs +94 -0
- package/src/sources/HyperSyncSource.res +64 -172
- package/src/sources/HyperSyncSource.res.mjs +73 -155
- package/src/sources/Rpc.res +43 -0
- package/src/sources/Rpc.res.mjs +31 -0
- package/src/sources/RpcSource.res +32 -130
- package/src/sources/RpcSource.res.mjs +47 -121
- package/src/sources/Source.res +3 -2
- package/src/sources/SourceManager.res +183 -108
- package/src/sources/SourceManager.res.mjs +162 -99
- package/src/sources/SourceManager.resi +4 -5
- package/src/sources/Svm.res +59 -0
- package/src/sources/Svm.res.mjs +79 -0
- package/src/tui/Tui.res +266 -0
- package/src/tui/Tui.res.mjs +342 -0
- package/src/tui/bindings/Ink.res +376 -0
- package/src/tui/bindings/Ink.res.mjs +75 -0
- package/src/tui/bindings/Style.res +123 -0
- package/src/tui/bindings/Style.res.mjs +2 -0
- package/src/tui/components/BufferedProgressBar.res +40 -0
- package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
- package/src/tui/components/CustomHooks.res +122 -0
- package/src/tui/components/CustomHooks.res.mjs +179 -0
- package/src/tui/components/Messages.res +41 -0
- package/src/tui/components/Messages.res.mjs +75 -0
- package/src/tui/components/SyncETA.res +193 -0
- package/src/tui/components/SyncETA.res.mjs +269 -0
- package/src/tui/components/TuiData.res +46 -0
- package/src/tui/components/TuiData.res.mjs +29 -0
- package/src/Platform.res +0 -140
- package/src/Platform.res.mjs +0 -170
- package/src/bindings/Ethers.gen.ts +0 -14
- /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Js_exn from "rescript/lib/es6/js_exn.js";
|
|
4
|
+
import * as Js_dict from "rescript/lib/es6/js_dict.js";
|
|
5
|
+
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
6
|
+
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
7
|
+
|
|
8
|
+
function make(parentPort, initialState) {
|
|
9
|
+
var proxy = {
|
|
10
|
+
parentPort: parentPort,
|
|
11
|
+
initialState: initialState,
|
|
12
|
+
pendingRequests: {},
|
|
13
|
+
requestCounter: 0
|
|
14
|
+
};
|
|
15
|
+
parentPort.on("message", (function (msg) {
|
|
16
|
+
var idStr = String(msg.id);
|
|
17
|
+
var pending = proxy.pendingRequests[idStr];
|
|
18
|
+
var match = pending !== undefined ? pending : Js_exn.raiseError("TestIndexer: No pending request found for id " + idStr);
|
|
19
|
+
Js_dict.unsafeDeleteKey(proxy.pendingRequests, idStr);
|
|
20
|
+
var match$1 = msg.payload;
|
|
21
|
+
if (match$1.type === "response") {
|
|
22
|
+
return match.resolve(match$1.data);
|
|
23
|
+
} else {
|
|
24
|
+
return match.reject(new Error(match$1.message));
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
return proxy;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function nextRequestId(proxy) {
|
|
31
|
+
proxy.requestCounter = proxy.requestCounter + 1 | 0;
|
|
32
|
+
return proxy.requestCounter;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sendRequest(proxy, payload) {
|
|
36
|
+
return new Promise((function (resolve, reject) {
|
|
37
|
+
var id = nextRequestId(proxy);
|
|
38
|
+
proxy.pendingRequests[String(id)] = {
|
|
39
|
+
resolve: resolve,
|
|
40
|
+
reject: reject
|
|
41
|
+
};
|
|
42
|
+
proxy.parentPort.postMessage({
|
|
43
|
+
id: id,
|
|
44
|
+
payload: payload
|
|
45
|
+
});
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function makeStorage(proxy) {
|
|
50
|
+
return {
|
|
51
|
+
isInitialized: (async function () {
|
|
52
|
+
return true;
|
|
53
|
+
}),
|
|
54
|
+
initialize: (async function (param, param$1, param$2) {
|
|
55
|
+
return Js_exn.raiseError("TestIndexer: initialize should not be called. Use resumeInitialState instead.");
|
|
56
|
+
}),
|
|
57
|
+
resumeInitialState: (async function () {
|
|
58
|
+
return proxy.initialState;
|
|
59
|
+
}),
|
|
60
|
+
loadByIdsOrThrow: (async function (ids, table, rowsSchema) {
|
|
61
|
+
var response = await sendRequest(proxy, {
|
|
62
|
+
type: "loadByIds",
|
|
63
|
+
tableName: table.tableName,
|
|
64
|
+
ids: ids
|
|
65
|
+
});
|
|
66
|
+
return S$RescriptSchema.parseOrThrow(response, rowsSchema);
|
|
67
|
+
}),
|
|
68
|
+
loadByFieldOrThrow: (async function (fieldName, fieldSchema, fieldValue, operator, table, rowsSchema) {
|
|
69
|
+
var response = await sendRequest(proxy, {
|
|
70
|
+
type: "loadByField",
|
|
71
|
+
tableName: table.tableName,
|
|
72
|
+
fieldName: fieldName,
|
|
73
|
+
fieldValue: S$RescriptSchema.reverseConvertToJsonOrThrow(fieldValue, fieldSchema),
|
|
74
|
+
operator: operator
|
|
75
|
+
});
|
|
76
|
+
return S$RescriptSchema.parseOrThrow(response, rowsSchema);
|
|
77
|
+
}),
|
|
78
|
+
setOrThrow: (async function (param, param$1, param$2) {
|
|
79
|
+
|
|
80
|
+
}),
|
|
81
|
+
setEffectCacheOrThrow: (async function (param, param$1, param$2) {
|
|
82
|
+
|
|
83
|
+
}),
|
|
84
|
+
dumpEffectCache: (async function () {
|
|
85
|
+
|
|
86
|
+
}),
|
|
87
|
+
executeUnsafe: (async function (param) {
|
|
88
|
+
|
|
89
|
+
}),
|
|
90
|
+
setChainMeta: (async function (param) {
|
|
91
|
+
|
|
92
|
+
}),
|
|
93
|
+
pruneStaleCheckpoints: (async function (param) {
|
|
94
|
+
|
|
95
|
+
}),
|
|
96
|
+
pruneStaleEntityHistory: (async function (param, param$1, param$2) {
|
|
97
|
+
|
|
98
|
+
}),
|
|
99
|
+
getRollbackTargetCheckpoint: (async function (param, param$1) {
|
|
100
|
+
return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
|
|
101
|
+
}),
|
|
102
|
+
getRollbackProgressDiff: (async function (param) {
|
|
103
|
+
return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
|
|
104
|
+
}),
|
|
105
|
+
getRollbackData: (async function (param, param$1) {
|
|
106
|
+
return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
|
|
107
|
+
}),
|
|
108
|
+
writeBatch: (async function (batch, param, param$1, param$2, param$3, param$4, param$5, updatedEntities) {
|
|
109
|
+
var serializableEntities = Belt_Array.map(updatedEntities, (function (param) {
|
|
110
|
+
var entityConfig = param.entityConfig;
|
|
111
|
+
var encodeChange = function (change) {
|
|
112
|
+
if (change.type === "SET") {
|
|
113
|
+
return {
|
|
114
|
+
type: "SET",
|
|
115
|
+
entityId: change.entityId,
|
|
116
|
+
entity: S$RescriptSchema.reverseConvertToJsonOrThrow(change.entity, entityConfig.schema),
|
|
117
|
+
checkpointId: change.checkpointId
|
|
118
|
+
};
|
|
119
|
+
} else {
|
|
120
|
+
return {
|
|
121
|
+
type: "DELETE",
|
|
122
|
+
entityId: change.entityId,
|
|
123
|
+
checkpointId: change.checkpointId
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
entityName: entityConfig.name,
|
|
129
|
+
updates: Belt_Array.map(param.updates, (function (update) {
|
|
130
|
+
return {
|
|
131
|
+
latestChange: encodeChange(update.latestChange),
|
|
132
|
+
history: Belt_Array.map(update.history, encodeChange),
|
|
133
|
+
containsRollbackDiffChange: update.containsRollbackDiffChange
|
|
134
|
+
};
|
|
135
|
+
}))
|
|
136
|
+
};
|
|
137
|
+
}));
|
|
138
|
+
await sendRequest(proxy, {
|
|
139
|
+
type: "writeBatch",
|
|
140
|
+
updatedEntities: serializableEntities,
|
|
141
|
+
checkpointIds: batch.checkpointIds,
|
|
142
|
+
checkpointChainIds: batch.checkpointChainIds,
|
|
143
|
+
checkpointBlockNumbers: batch.checkpointBlockNumbers,
|
|
144
|
+
checkpointBlockHashes: batch.checkpointBlockHashes,
|
|
145
|
+
checkpointEventsProcessed: batch.checkpointEventsProcessed
|
|
146
|
+
});
|
|
147
|
+
})
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export {
|
|
152
|
+
make ,
|
|
153
|
+
nextRequestId ,
|
|
154
|
+
sendRequest ,
|
|
155
|
+
makeStorage ,
|
|
156
|
+
}
|
|
157
|
+
/* S-RescriptSchema Not a pure module */
|
package/src/Types.ts
CHANGED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
let codegenHelpMessage = `Rerun 'pnpm dev' to update generated code after schema.graphql changes.`
|
|
2
|
+
|
|
3
|
+
type contextParams = {
|
|
4
|
+
item: Internal.item,
|
|
5
|
+
checkpointId: float,
|
|
6
|
+
inMemoryStore: InMemoryStore.t,
|
|
7
|
+
loadManager: LoadManager.t,
|
|
8
|
+
persistence: Persistence.t,
|
|
9
|
+
isPreload: bool,
|
|
10
|
+
shouldSaveHistory: bool,
|
|
11
|
+
chains: Internal.chains,
|
|
12
|
+
config: Config.t,
|
|
13
|
+
mutable isResolved: bool,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// We don't want to expose the params to the user
|
|
17
|
+
// so instead of storing _params on the context object,
|
|
18
|
+
// we use an external WeakMap
|
|
19
|
+
let paramsByThis: Utils.WeakMap.t<unknown, contextParams> = Utils.WeakMap.make()
|
|
20
|
+
|
|
21
|
+
let effectContextPrototype = %raw(`Object.create(null)`)
|
|
22
|
+
Utils.Object.defineProperty(
|
|
23
|
+
effectContextPrototype,
|
|
24
|
+
"log",
|
|
25
|
+
{
|
|
26
|
+
get: () => {
|
|
27
|
+
(paramsByThis->Utils.WeakMap.unsafeGet(%raw(`this`))).item->Logging.getUserLogger
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
)
|
|
31
|
+
%%raw(`
|
|
32
|
+
var EffectContext = function(params, defaultShouldCache, callEffect) {
|
|
33
|
+
paramsByThis.set(this, params);
|
|
34
|
+
this.effect = callEffect;
|
|
35
|
+
this.cache = defaultShouldCache;
|
|
36
|
+
};
|
|
37
|
+
EffectContext.prototype = effectContextPrototype;
|
|
38
|
+
`)
|
|
39
|
+
|
|
40
|
+
@new
|
|
41
|
+
external makeEffectContext: (
|
|
42
|
+
contextParams,
|
|
43
|
+
~defaultShouldCache: bool,
|
|
44
|
+
~callEffect: (Internal.effect, Internal.effectInput) => promise<Internal.effectOutput>,
|
|
45
|
+
) => Internal.effectContext = "EffectContext"
|
|
46
|
+
|
|
47
|
+
let initEffect = (params: contextParams) => {
|
|
48
|
+
let rec callEffect = (effect: Internal.effect, input: Internal.effectInput) => {
|
|
49
|
+
let effectContext = makeEffectContext(
|
|
50
|
+
params,
|
|
51
|
+
~defaultShouldCache=effect.defaultShouldCache,
|
|
52
|
+
~callEffect,
|
|
53
|
+
)
|
|
54
|
+
let effectArgs: Internal.effectArgs = {
|
|
55
|
+
input,
|
|
56
|
+
context: effectContext,
|
|
57
|
+
cacheKey: input->S.reverseConvertOrThrow(effect.input)->Utils.Hash.makeOrThrow,
|
|
58
|
+
}
|
|
59
|
+
LoadLayer.loadEffect(
|
|
60
|
+
~loadManager=params.loadManager,
|
|
61
|
+
~persistence=params.persistence,
|
|
62
|
+
~effect,
|
|
63
|
+
~effectArgs,
|
|
64
|
+
~inMemoryStore=params.inMemoryStore,
|
|
65
|
+
~shouldGroup=params.isPreload,
|
|
66
|
+
~item=params.item,
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
callEffect
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
type entityContextParams = {
|
|
73
|
+
...contextParams,
|
|
74
|
+
entityConfig: Internal.entityConfig,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let getWhereTraps: Utils.Proxy.traps<entityContextParams> = {
|
|
78
|
+
get: (~target as params, ~prop: unknown) => {
|
|
79
|
+
let entityConfig = params.entityConfig
|
|
80
|
+
if prop->Js.typeof !== "string" {
|
|
81
|
+
Js.Exn.raiseError(
|
|
82
|
+
`Invalid context.${entityConfig.name}.getWhere access by a non-string property.`,
|
|
83
|
+
)
|
|
84
|
+
} else {
|
|
85
|
+
let dbFieldName = prop->(Utils.magic: unknown => string)
|
|
86
|
+
switch entityConfig.table->Table.getFieldByDbName(dbFieldName) {
|
|
87
|
+
| None =>
|
|
88
|
+
Js.Exn.raiseError(
|
|
89
|
+
`Invalid context.${entityConfig.name}.getWhere.${dbFieldName} - the field doesn't exist. ${codegenHelpMessage}`,
|
|
90
|
+
)
|
|
91
|
+
| Some(field) =>
|
|
92
|
+
let fieldValueSchema = switch field {
|
|
93
|
+
| Field({fieldSchema}) => fieldSchema
|
|
94
|
+
| DerivedFrom(_) => S.string->S.toUnknown
|
|
95
|
+
}
|
|
96
|
+
{
|
|
97
|
+
Envio.eq: fieldValue =>
|
|
98
|
+
LoadLayer.loadByField(
|
|
99
|
+
~loadManager=params.loadManager,
|
|
100
|
+
~persistence=params.persistence,
|
|
101
|
+
~operator=Eq,
|
|
102
|
+
~entityConfig,
|
|
103
|
+
~fieldName=dbFieldName,
|
|
104
|
+
~fieldValueSchema,
|
|
105
|
+
~inMemoryStore=params.inMemoryStore,
|
|
106
|
+
~shouldGroup=params.isPreload,
|
|
107
|
+
~item=params.item,
|
|
108
|
+
~fieldValue,
|
|
109
|
+
),
|
|
110
|
+
gt: fieldValue =>
|
|
111
|
+
LoadLayer.loadByField(
|
|
112
|
+
~loadManager=params.loadManager,
|
|
113
|
+
~persistence=params.persistence,
|
|
114
|
+
~operator=Gt,
|
|
115
|
+
~entityConfig,
|
|
116
|
+
~fieldName=dbFieldName,
|
|
117
|
+
~fieldValueSchema,
|
|
118
|
+
~inMemoryStore=params.inMemoryStore,
|
|
119
|
+
~shouldGroup=params.isPreload,
|
|
120
|
+
~item=params.item,
|
|
121
|
+
~fieldValue,
|
|
122
|
+
),
|
|
123
|
+
lt: fieldValue =>
|
|
124
|
+
LoadLayer.loadByField(
|
|
125
|
+
~loadManager=params.loadManager,
|
|
126
|
+
~persistence=params.persistence,
|
|
127
|
+
~operator=Lt,
|
|
128
|
+
~entityConfig,
|
|
129
|
+
~fieldName=dbFieldName,
|
|
130
|
+
~fieldValueSchema,
|
|
131
|
+
~inMemoryStore=params.inMemoryStore,
|
|
132
|
+
~shouldGroup=params.isPreload,
|
|
133
|
+
~item=params.item,
|
|
134
|
+
~fieldValue,
|
|
135
|
+
),
|
|
136
|
+
}->Utils.magic
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let noopSet = (_entity: Internal.entity) => ()
|
|
143
|
+
let noopDeleteUnsafe = (_entityId: string) => ()
|
|
144
|
+
|
|
145
|
+
let entityTraps: Utils.Proxy.traps<entityContextParams> = {
|
|
146
|
+
get: (~target as params, ~prop: unknown) => {
|
|
147
|
+
let prop = prop->(Utils.magic: unknown => string)
|
|
148
|
+
|
|
149
|
+
let set = params.isPreload
|
|
150
|
+
? noopSet
|
|
151
|
+
: (entity: Internal.entity) => {
|
|
152
|
+
params.inMemoryStore
|
|
153
|
+
->InMemoryStore.getInMemTable(~entityConfig=params.entityConfig)
|
|
154
|
+
->InMemoryTable.Entity.set(
|
|
155
|
+
Set({
|
|
156
|
+
entityId: entity.id,
|
|
157
|
+
checkpointId: params.checkpointId,
|
|
158
|
+
entity,
|
|
159
|
+
}),
|
|
160
|
+
~shouldSaveHistory=params.shouldSaveHistory,
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
switch prop {
|
|
165
|
+
| "get" =>
|
|
166
|
+
(
|
|
167
|
+
entityId =>
|
|
168
|
+
LoadLayer.loadById(
|
|
169
|
+
~loadManager=params.loadManager,
|
|
170
|
+
~persistence=params.persistence,
|
|
171
|
+
~entityConfig=params.entityConfig,
|
|
172
|
+
~inMemoryStore=params.inMemoryStore,
|
|
173
|
+
~shouldGroup=params.isPreload,
|
|
174
|
+
~item=params.item,
|
|
175
|
+
~entityId,
|
|
176
|
+
)
|
|
177
|
+
)->Utils.magic
|
|
178
|
+
| "getWhere" => params->Utils.Proxy.make(getWhereTraps)->Utils.magic
|
|
179
|
+
| "getOrThrow" =>
|
|
180
|
+
(
|
|
181
|
+
(entityId, ~message=?) =>
|
|
182
|
+
LoadLayer.loadById(
|
|
183
|
+
~loadManager=params.loadManager,
|
|
184
|
+
~persistence=params.persistence,
|
|
185
|
+
~entityConfig=params.entityConfig,
|
|
186
|
+
~inMemoryStore=params.inMemoryStore,
|
|
187
|
+
~shouldGroup=params.isPreload,
|
|
188
|
+
~item=params.item,
|
|
189
|
+
~entityId,
|
|
190
|
+
)->Promise.thenResolve(entity => {
|
|
191
|
+
switch entity {
|
|
192
|
+
| Some(entity) => entity
|
|
193
|
+
| None =>
|
|
194
|
+
Js.Exn.raiseError(
|
|
195
|
+
message->Belt.Option.getWithDefault(
|
|
196
|
+
`Entity '${params.entityConfig.name}' with ID '${entityId}' is expected to exist.`,
|
|
197
|
+
),
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
)->Utils.magic
|
|
202
|
+
| "getOrCreate" =>
|
|
203
|
+
(
|
|
204
|
+
(entity: Internal.entity) =>
|
|
205
|
+
LoadLayer.loadById(
|
|
206
|
+
~loadManager=params.loadManager,
|
|
207
|
+
~persistence=params.persistence,
|
|
208
|
+
~entityConfig=params.entityConfig,
|
|
209
|
+
~inMemoryStore=params.inMemoryStore,
|
|
210
|
+
~shouldGroup=params.isPreload,
|
|
211
|
+
~item=params.item,
|
|
212
|
+
~entityId=entity.id,
|
|
213
|
+
)->Promise.thenResolve(storageEntity => {
|
|
214
|
+
switch storageEntity {
|
|
215
|
+
| Some(entity) => entity
|
|
216
|
+
| None => {
|
|
217
|
+
set(entity)
|
|
218
|
+
entity
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
)->Utils.magic
|
|
223
|
+
| "set" => set->Utils.magic
|
|
224
|
+
| "deleteUnsafe" =>
|
|
225
|
+
if params.isPreload {
|
|
226
|
+
noopDeleteUnsafe
|
|
227
|
+
} else {
|
|
228
|
+
entityId => {
|
|
229
|
+
params.inMemoryStore
|
|
230
|
+
->InMemoryStore.getInMemTable(~entityConfig=params.entityConfig)
|
|
231
|
+
->InMemoryTable.Entity.set(
|
|
232
|
+
Delete({
|
|
233
|
+
entityId,
|
|
234
|
+
checkpointId: params.checkpointId,
|
|
235
|
+
}),
|
|
236
|
+
~shouldSaveHistory=params.shouldSaveHistory,
|
|
237
|
+
)
|
|
238
|
+
}
|
|
239
|
+
}->Utils.magic
|
|
240
|
+
| _ => Js.Exn.raiseError(`Invalid context.${params.entityConfig.name}.${prop} operation.`)
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
let handlerTraps: Utils.Proxy.traps<contextParams> = {
|
|
246
|
+
get: (~target as params, ~prop: unknown) => {
|
|
247
|
+
let prop = prop->(Utils.magic: unknown => string)
|
|
248
|
+
if params.isResolved {
|
|
249
|
+
Utils.Error.make(
|
|
250
|
+
`Impossible to access context.${prop} after the handler is resolved. Make sure you didn't miss an await in the handler.`,
|
|
251
|
+
)->ErrorHandling.mkLogAndRaise(~logger=params.item->Logging.getItemLogger)
|
|
252
|
+
}
|
|
253
|
+
switch prop {
|
|
254
|
+
| "log" =>
|
|
255
|
+
(params.isPreload ? Logging.noopLogger : params.item->Logging.getUserLogger)->Utils.magic
|
|
256
|
+
| "effect" =>
|
|
257
|
+
initEffect((params :> contextParams))->(
|
|
258
|
+
Utils.magic: (
|
|
259
|
+
(Internal.effect, Internal.effectInput) => promise<Internal.effectOutput>
|
|
260
|
+
) => unknown
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
| "isPreload" => params.isPreload->Utils.magic
|
|
264
|
+
| "chain" =>
|
|
265
|
+
let chainId = params.item->Internal.getItemChainId
|
|
266
|
+
params.chains->Utils.Dict.dangerouslyGetByIntNonOption(chainId)->Utils.magic
|
|
267
|
+
| _ =>
|
|
268
|
+
switch params.config.userEntitiesByName->Utils.Dict.dangerouslyGetNonOption(prop) {
|
|
269
|
+
| Some(entityConfig) =>
|
|
270
|
+
{
|
|
271
|
+
item: params.item,
|
|
272
|
+
isPreload: params.isPreload,
|
|
273
|
+
inMemoryStore: params.inMemoryStore,
|
|
274
|
+
loadManager: params.loadManager,
|
|
275
|
+
persistence: params.persistence,
|
|
276
|
+
shouldSaveHistory: params.shouldSaveHistory,
|
|
277
|
+
checkpointId: params.checkpointId,
|
|
278
|
+
chains: params.chains,
|
|
279
|
+
isResolved: params.isResolved,
|
|
280
|
+
config: params.config,
|
|
281
|
+
entityConfig,
|
|
282
|
+
}
|
|
283
|
+
->Utils.Proxy.make(entityTraps)
|
|
284
|
+
->Utils.magic
|
|
285
|
+
| None =>
|
|
286
|
+
Js.Exn.raiseError(`Invalid context access by '${prop}' property. ${codegenHelpMessage}`)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
let getHandlerContext = (params: contextParams): Internal.handlerContext => {
|
|
293
|
+
params->Utils.Proxy.make(handlerTraps)->Utils.magic
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Contract register context creation
|
|
297
|
+
type contractRegisterParams = {
|
|
298
|
+
item: Internal.item,
|
|
299
|
+
onRegister: (~item: Internal.item, ~contractAddress: Address.t, ~contractName: string) => unit,
|
|
300
|
+
config: Config.t,
|
|
301
|
+
mutable isResolved: bool,
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
let contractRegisterTraps: Utils.Proxy.traps<contractRegisterParams> = {
|
|
305
|
+
get: (~target as params, ~prop: unknown) => {
|
|
306
|
+
let prop = prop->(Utils.magic: unknown => string)
|
|
307
|
+
if params.isResolved {
|
|
308
|
+
Utils.Error.make(
|
|
309
|
+
`Impossible to access context.${prop} after the contract register is resolved. Make sure you didn't miss an await in the handler.`,
|
|
310
|
+
)->ErrorHandling.mkLogAndRaise(~logger=params.item->Logging.getItemLogger)
|
|
311
|
+
}
|
|
312
|
+
switch prop {
|
|
313
|
+
| "log" => params.item->Logging.getUserLogger->Utils.magic
|
|
314
|
+
| _ =>
|
|
315
|
+
// Use the pre-built mapping for efficient lookup
|
|
316
|
+
switch params.config.addContractNameToContractNameMapping->Utils.Dict.dangerouslyGetNonOption(
|
|
317
|
+
prop,
|
|
318
|
+
) {
|
|
319
|
+
| Some(contractName) => {
|
|
320
|
+
let addFunction = (contractAddress: Address.t) => {
|
|
321
|
+
let validatedAddress = if params.config.ecosystem.name === Evm {
|
|
322
|
+
// The value is passed from the user-land,
|
|
323
|
+
// so we need to validate and checksum/lowercase the address.
|
|
324
|
+
if params.config.lowercaseAddresses {
|
|
325
|
+
contractAddress->Address.Evm.fromAddressLowercaseOrThrow
|
|
326
|
+
} else {
|
|
327
|
+
contractAddress->Address.Evm.fromAddressOrThrow
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
// TODO: Ideally we should do the same for other ecosystems
|
|
331
|
+
contractAddress
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
params.onRegister(~item=params.item, ~contractAddress=validatedAddress, ~contractName)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
addFunction->Utils.magic
|
|
338
|
+
}
|
|
339
|
+
| None =>
|
|
340
|
+
Js.Exn.raiseError(`Invalid context access by '${prop}' property. ${codegenHelpMessage}`)
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
let getContractRegisterContext = (params: contractRegisterParams) => {
|
|
347
|
+
params
|
|
348
|
+
->Utils.Proxy.make(contractRegisterTraps)
|
|
349
|
+
->Utils.magic
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let getContractRegisterArgs = (params: contractRegisterParams): Internal.contractRegisterArgs => {
|
|
353
|
+
event: (params.item->Internal.castUnsafeEventItem).event,
|
|
354
|
+
context: getContractRegisterContext(params),
|
|
355
|
+
}
|