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,72 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Performance from "./bindings/Performance.res.mjs";
|
|
4
|
+
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
5
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
|
+
|
|
7
|
+
let refuseReal = {
|
|
8
|
+
contents: false
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function refused(what) {
|
|
12
|
+
return Stdlib_JsError.throwWithMessage(`Clock.real ` + what + ` on virtual time. Use the clock the code was given, so advanceTime can see and move it.`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function real_now() {
|
|
16
|
+
if (refuseReal.contents) {
|
|
17
|
+
return refused("read the time");
|
|
18
|
+
} else {
|
|
19
|
+
return Performance.now();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function real_setTimeout(label, callback, millis) {
|
|
24
|
+
if (refuseReal.contents && millis > 0) {
|
|
25
|
+
return refused(`armed "` + label + `"`);
|
|
26
|
+
} else {
|
|
27
|
+
return setTimeout(callback, millis);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function real_clearTimeout(timer) {
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function real_random(prim) {
|
|
36
|
+
return Math.random();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let real = {
|
|
40
|
+
now: real_now,
|
|
41
|
+
setTimeout: real_setTimeout,
|
|
42
|
+
clearTimeout: real_clearTimeout,
|
|
43
|
+
random: real_random
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
function delay(clock, label, millis) {
|
|
47
|
+
return new Promise((resolve, _reject) => {
|
|
48
|
+
clock.setTimeout(label, () => resolve(), millis);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function jitter(clock, delay) {
|
|
53
|
+
return (delay / 2 | 0) + (clock.random() * (delay / 2 | 0) | 0) | 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function clearRef(clock, timer) {
|
|
57
|
+
let timer$1 = timer.contents;
|
|
58
|
+
if (timer$1 !== undefined) {
|
|
59
|
+
clock.clearTimeout(Primitive_option.valFromOption(timer$1));
|
|
60
|
+
}
|
|
61
|
+
timer.contents = undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
refuseReal,
|
|
66
|
+
refused,
|
|
67
|
+
real,
|
|
68
|
+
delay,
|
|
69
|
+
jitter,
|
|
70
|
+
clearRef,
|
|
71
|
+
}
|
|
72
|
+
/* No side effect */
|
package/src/Config.res
CHANGED
|
@@ -65,6 +65,7 @@ type chain = {
|
|
|
65
65
|
endBlock?: int,
|
|
66
66
|
maxReorgDepth: int,
|
|
67
67
|
blockLag: int,
|
|
68
|
+
blockThrottle: int,
|
|
68
69
|
contracts: array<contract>,
|
|
69
70
|
sourceConfig: sourceConfig,
|
|
70
71
|
}
|
|
@@ -217,6 +218,7 @@ let publicConfigChainSchema = S.schema(s =>
|
|
|
217
218
|
"endBlock": s.matches(S.option(S.int)),
|
|
218
219
|
"maxReorgDepth": s.matches(S.option(S.int)),
|
|
219
220
|
"blockLag": s.matches(S.option(S.int)),
|
|
221
|
+
"blockThrottle": s.matches(S.option(S.int)),
|
|
220
222
|
// EVM/Fuel source config (hypersync for EVM, hyperfuel for Fuel)
|
|
221
223
|
"hypersync": s.matches(S.option(S.string)),
|
|
222
224
|
"rpcs": s.matches(S.option(S.array(rpcConfigSchema))),
|
|
@@ -1069,18 +1071,23 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
1069
1071
|
startBlock: publicChainConfig["startBlock"],
|
|
1070
1072
|
endBlock: ?publicChainConfig["endBlock"],
|
|
1071
1073
|
maxReorgDepth: switch ecosystemName {
|
|
1072
|
-
|
|
1074
|
+
// One less than the 200 blocks behind the head a source checks for a
|
|
1075
|
+
// lagging node, so the backfill, which stops one block below the window,
|
|
1076
|
+
// ends exactly where those checks begin.
|
|
1077
|
+
| Ecosystem.Evm => publicChainConfig["maxReorgDepth"]->Option.getOr(199)
|
|
1073
1078
|
// Tower BFT roots a block once 32 votes lock it in (MAX_LOCKOUT_HISTORY
|
|
1074
1079
|
// is 31, plus the slot itself), which is what `finalized` waits for — so
|
|
1075
1080
|
// 32 is the protocol's own bound on how far a fork can be replaced. That
|
|
1076
1081
|
// bound counts *blocks* while the threshold here is measured in slot
|
|
1077
1082
|
// numbers, and skipped slots make the slot distance the larger of the
|
|
1078
1083
|
// two, so the default keeps a wide margin over it. Slots are ~0.4s, so
|
|
1079
|
-
// even this spans well under two minutes of chain.
|
|
1080
|
-
|
|
1084
|
+
// even this spans well under two minutes of chain. One less than 200
|
|
1085
|
+
// for the same reason as EVM: the backfill stops one slot below it.
|
|
1086
|
+
| Ecosystem.Svm => publicChainConfig["maxReorgDepth"]->Option.getOr(199)
|
|
1081
1087
|
| Ecosystem.Fuel => 0
|
|
1082
1088
|
},
|
|
1083
1089
|
blockLag: publicChainConfig["blockLag"]->Option.getOr(0),
|
|
1090
|
+
blockThrottle: publicChainConfig["blockThrottle"]->Option.getOr(0),
|
|
1084
1091
|
contracts,
|
|
1085
1092
|
sourceConfig,
|
|
1086
1093
|
}
|
package/src/Config.res.mjs
CHANGED
|
@@ -88,6 +88,7 @@ let publicConfigChainSchema = S$RescriptSchema.schema(s => ({
|
|
|
88
88
|
endBlock: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
89
89
|
maxReorgDepth: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
90
90
|
blockLag: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
91
|
+
blockThrottle: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
91
92
|
hypersync: s.m(S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
92
93
|
rpcs: s.m(S$RescriptSchema.option(S$RescriptSchema.array(rpcConfigSchema))),
|
|
93
94
|
contracts: s.m(S$RescriptSchema.option(S$RescriptSchema.dict(chainContractSchema)))
|
|
@@ -762,7 +763,7 @@ function fromPublic(publicConfigJson) {
|
|
|
762
763
|
break;
|
|
763
764
|
case "evm" :
|
|
764
765
|
case "svm" :
|
|
765
|
-
tmp = Stdlib_Option.getOr(publicChainConfig.maxReorgDepth,
|
|
766
|
+
tmp = Stdlib_Option.getOr(publicChainConfig.maxReorgDepth, 199);
|
|
766
767
|
break;
|
|
767
768
|
}
|
|
768
769
|
return {
|
|
@@ -773,6 +774,7 @@ function fromPublic(publicConfigJson) {
|
|
|
773
774
|
endBlock: publicChainConfig.endBlock,
|
|
774
775
|
maxReorgDepth: tmp,
|
|
775
776
|
blockLag: Stdlib_Option.getOr(publicChainConfig.blockLag, 0),
|
|
777
|
+
blockThrottle: Stdlib_Option.getOr(publicChainConfig.blockThrottle, 0),
|
|
776
778
|
contracts: contracts,
|
|
777
779
|
sourceConfig: sourceConfig
|
|
778
780
|
};
|
|
@@ -972,7 +974,7 @@ function diffPaths(stored, current) {
|
|
|
972
974
|
}
|
|
973
975
|
return;
|
|
974
976
|
}
|
|
975
|
-
} else {
|
|
977
|
+
} else if (s !== null) {
|
|
976
978
|
switch (typeof s) {
|
|
977
979
|
case "object" :
|
|
978
980
|
if (typeof c === "object" && c !== null && !Array.isArray(c)) {
|
package/src/Core.res
CHANGED
|
@@ -18,6 +18,8 @@ type loggerCtor
|
|
|
18
18
|
type mockHyperSyncServerCtor
|
|
19
19
|
// Test-only: the ledger behind envio-tests' MockSource.
|
|
20
20
|
type mockSourceCtor
|
|
21
|
+
// Test-only: the virtual clock a scenario's source layer runs on.
|
|
22
|
+
type virtualClockCtor
|
|
21
23
|
type fromUserApiOptions = {
|
|
22
24
|
schema?: string,
|
|
23
25
|
env?: dict<string>,
|
|
@@ -31,46 +33,6 @@ type fromUserApiResult = {
|
|
|
31
33
|
indexerCode: Null.t<string>,
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
// One column of a Postgres table, flattened for the boundary: napi carries no
|
|
35
|
-
// tagged union, so the field type arrives as its name plus whichever of the
|
|
36
|
-
// modifiers it takes.
|
|
37
|
-
type pgColumnInput = {
|
|
38
|
-
// The database column name, renames already resolved.
|
|
39
|
-
name: string,
|
|
40
|
-
fieldType: string,
|
|
41
|
-
isArray: bool,
|
|
42
|
-
isNullable: bool,
|
|
43
|
-
isPrimaryKey: bool,
|
|
44
|
-
defaultValue?: string,
|
|
45
|
-
precision?: int,
|
|
46
|
-
scale?: int,
|
|
47
|
-
enumName?: string,
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
type pgTableInput = {
|
|
51
|
-
// In the order the table declares them.
|
|
52
|
-
columns: array<pgColumnInput>,
|
|
53
|
-
// The columns a batch's rows carry, in the order they are laid out.
|
|
54
|
-
writeColumns: array<string>,
|
|
55
|
-
partitionByColumn?: string,
|
|
56
|
-
appendOnly: bool,
|
|
57
|
-
// An entity's history table, and the column its chain is in when it is
|
|
58
|
-
// per-chain.
|
|
59
|
-
historyTable?: string,
|
|
60
|
-
chainIdColumn?: string,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
type pgIndexColumnInput = {
|
|
64
|
-
name: string,
|
|
65
|
-
direction: string,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type pgIndexInput = {
|
|
69
|
-
tableName: string,
|
|
70
|
-
columns: array<pgIndexColumnInput>,
|
|
71
|
-
method: string,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
36
|
type addon = {
|
|
75
37
|
getConfigJson: (~configPath: Null.t<string>, ~directory: Null.t<string>) => string,
|
|
76
38
|
encodeIndexedTopic: (~abiType: string, ~value: unknown) => EvmTypes.Hex.t,
|
|
@@ -107,6 +69,8 @@ type addon = {
|
|
|
107
69
|
mockHyperSyncServer: mockHyperSyncServerCtor,
|
|
108
70
|
@as("MockSource")
|
|
109
71
|
mockSource: mockSourceCtor,
|
|
72
|
+
@as("VirtualClock")
|
|
73
|
+
virtualClock: virtualClockCtor,
|
|
110
74
|
encodeAddresses: (~ecosystem: string, ~addresses: array<Address.t>) => array<NodeJs.Buffer.t>,
|
|
111
75
|
normalizeEvmAddress: (~address: string, ~shouldChecksum: bool) => Null.t<Address.t>,
|
|
112
76
|
renderAddresses: (
|
package/src/EffectState.res
CHANGED
|
@@ -11,6 +11,8 @@ type effectRateLimitState = {
|
|
|
11
11
|
mutable availableCalls: int,
|
|
12
12
|
mutable windowStartTime: float,
|
|
13
13
|
mutable nextWindowPromise: option<promise<unit>>,
|
|
14
|
+
// The run's clock: a test on virtual time opens the next window by advancing.
|
|
15
|
+
clock: Clock.t,
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
// Per-(effect, scope) counters rendered into the envio_effect_* metrics. Live
|
|
@@ -80,9 +82,14 @@ type t = {
|
|
|
80
82
|
// rollback; stats and the rate-limit window survive because the table does.
|
|
81
83
|
tables: dict<effectCacheInMemTable>,
|
|
82
84
|
unregisteredCacheCounts: dict<unregisteredCacheCount>,
|
|
85
|
+
clock: Clock.t,
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
let make = (): t => {
|
|
88
|
+
let make = (~clock=Clock.real, ()): t => {
|
|
89
|
+
tables: Dict.make(),
|
|
90
|
+
unregisteredCacheCounts: Dict.make(),
|
|
91
|
+
clock,
|
|
92
|
+
}
|
|
86
93
|
|
|
87
94
|
let setUnregisteredCacheCount = (self: t, ~effectName, ~scope, ~count) => {
|
|
88
95
|
let tableName = Internal.EffectCache.toTableName(~effectName, ~scope)
|
|
@@ -214,8 +221,9 @@ let getTable = (self: t, ~effect: Internal.effect, ~scope: Internal.chainScope)
|
|
|
214
221
|
callsPerDuration,
|
|
215
222
|
durationMs,
|
|
216
223
|
availableCalls: callsPerDuration,
|
|
217
|
-
windowStartTime:
|
|
224
|
+
windowStartTime: self.clock.now(),
|
|
218
225
|
nextWindowPromise: None,
|
|
226
|
+
clock: self.clock,
|
|
219
227
|
})
|
|
220
228
|
}
|
|
221
229
|
let inMemTable: effectCacheInMemTable = {
|
package/src/EffectState.res.mjs
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Clock from "./Clock.res.mjs";
|
|
3
4
|
import * as Utils from "./Utils.res.mjs";
|
|
4
5
|
import * as Internal from "./Internal.res.mjs";
|
|
5
6
|
import * as Performance from "./bindings/Performance.res.mjs";
|
|
6
7
|
|
|
7
|
-
function make() {
|
|
8
|
+
function make(clockOpt, param) {
|
|
9
|
+
let clock = clockOpt !== undefined ? clockOpt : Clock.real;
|
|
8
10
|
return {
|
|
9
11
|
tables: {},
|
|
10
|
-
unregisteredCacheCounts: {}
|
|
12
|
+
unregisteredCacheCounts: {},
|
|
13
|
+
clock: clock
|
|
11
14
|
};
|
|
12
15
|
}
|
|
13
16
|
|
|
@@ -130,8 +133,9 @@ function getTable(self, effect, scope) {
|
|
|
130
133
|
callsPerDuration: callsPerDuration,
|
|
131
134
|
durationMs: match$1.durationMs,
|
|
132
135
|
availableCalls: callsPerDuration,
|
|
133
|
-
windowStartTime:
|
|
134
|
-
nextWindowPromise: undefined
|
|
136
|
+
windowStartTime: self.clock.now(),
|
|
137
|
+
nextWindowPromise: undefined,
|
|
138
|
+
clock: self.clock
|
|
135
139
|
};
|
|
136
140
|
} else {
|
|
137
141
|
rateLimitState = undefined;
|
package/src/EffectState.resi
CHANGED
|
@@ -4,6 +4,8 @@ type effectRateLimitState = {
|
|
|
4
4
|
mutable availableCalls: int,
|
|
5
5
|
mutable windowStartTime: float,
|
|
6
6
|
mutable nextWindowPromise: option<promise<unit>>,
|
|
7
|
+
// The run's clock: a test on virtual time opens the next window by advancing.
|
|
8
|
+
clock: Clock.t,
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
// Per-(effect, scope) metric counters. Survive rollback so they stay monotonic.
|
|
@@ -32,7 +34,7 @@ type effectCacheInMemTable = {
|
|
|
32
34
|
// Opaque store of all per-(effect, scope) runtime state.
|
|
33
35
|
type t
|
|
34
36
|
|
|
35
|
-
let make: unit => t
|
|
37
|
+
let make: (~clock: Clock.t=?, unit) => t
|
|
36
38
|
// Get, or lazily create, the in-mem table for an (effect, scope). Reuses the
|
|
37
39
|
// surviving rate-limit window when the table is recreated after a rollback.
|
|
38
40
|
let getTable: (t, ~effect: Internal.effect, ~scope: Internal.chainScope) => effectCacheInMemTable
|
package/src/EntityId.res
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
// Opaque representation of an entity id. The generated per-entity types expose
|
|
2
|
-
// the real scalar (string / int / bigint); the generic storage and in-memory
|
|
2
|
+
// the real scalar (string / int / bigint / Uint8Array); the generic storage and in-memory
|
|
3
3
|
// layers work with any entity's id through this type without knowing which
|
|
4
4
|
// scalar backs it. The runtime value is always the real id, never a stringified
|
|
5
|
-
// form — `
|
|
5
|
+
// form — a table's `entityIdToKey` derives the string only where a dict or Set key is needed.
|
|
6
6
|
type t
|
|
7
7
|
|
|
8
8
|
external unsafeOfAny: 'a => t = "%identity"
|
|
9
9
|
external unsafeToAny: t => 'a = "%identity"
|
|
10
10
|
external unsafeOfString: string => t = "%identity"
|
|
11
|
-
|
|
12
|
-
// Stringified id used as a JS object/dict key. `String` matches how JS coerces
|
|
13
|
-
// a value used as an object key, so an id indexes the same whether the raw
|
|
14
|
-
// value or its key form is used for lookup, across string/int/bigint.
|
|
15
|
-
let toKey: t => string = %raw(`String`)
|
package/src/EntityId.res.mjs
CHANGED
package/src/EntityTables.res
CHANGED
|
@@ -6,7 +6,10 @@ type t = dict<InMemoryTable.Entity.t>
|
|
|
6
6
|
let make = (entities: array<Internal.entityConfig>): t => {
|
|
7
7
|
let init = Dict.make()
|
|
8
8
|
entities->Array.forEach(entityConfig => {
|
|
9
|
-
init->Dict.set(
|
|
9
|
+
init->Dict.set(
|
|
10
|
+
(entityConfig.name :> string),
|
|
11
|
+
InMemoryTable.Entity.make(~entityIdToKey=entityConfig.table.entityIdToKey),
|
|
12
|
+
)
|
|
10
13
|
})
|
|
11
14
|
init
|
|
12
15
|
}
|
package/src/EntityTables.res.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
|
6
6
|
function make(entities) {
|
|
7
7
|
let init = {};
|
|
8
8
|
entities.forEach(entityConfig => {
|
|
9
|
-
init[entityConfig.name] = InMemoryTable.Entity.make();
|
|
9
|
+
init[entityConfig.name] = InMemoryTable.Entity.make(entityConfig.table.entityIdToKey);
|
|
10
10
|
});
|
|
11
11
|
return init;
|
|
12
12
|
}
|