envio 3.9.0 → 3.10.0-subgraph

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.
Files changed (143) hide show
  1. package/evm.schema.json +26 -0
  2. package/fuel.schema.json +26 -0
  3. package/index.d.ts +41 -8
  4. package/package.json +6 -7
  5. package/src/Batch.res +9 -0
  6. package/src/ChainState.res +35 -39
  7. package/src/ChainState.res.mjs +14 -11
  8. package/src/ChainState.resi +15 -7
  9. package/src/Config.res +61 -44
  10. package/src/Config.res.mjs +56 -19
  11. package/src/Core.res +19 -0
  12. package/src/Core.res.mjs +11 -0
  13. package/src/CrossChainState.res +15 -23
  14. package/src/CrossChainState.res.mjs +10 -18
  15. package/src/CrossChainState.resi +4 -1
  16. package/src/Ecosystem.res +7 -2
  17. package/src/Envio.res +6 -4
  18. package/src/EventConfigBuilder.res +169 -26
  19. package/src/EventConfigBuilder.res.mjs +124 -15
  20. package/src/EventProcessing.res +6 -6
  21. package/src/EventProcessing.res.mjs +8 -6
  22. package/src/HandlerLoader.res +20 -8
  23. package/src/HandlerLoader.res.mjs +11 -2
  24. package/src/HandlerRegister.res +21 -4
  25. package/src/HandlerRegister.res.mjs +24 -5
  26. package/src/InMemoryStore.res +9 -7
  27. package/src/InMemoryStore.res.mjs +3 -3
  28. package/src/IndexerState.res +43 -6
  29. package/src/IndexerState.res.mjs +36 -7
  30. package/src/IndexerState.resi +4 -4
  31. package/src/Internal.res +16 -17
  32. package/src/Metrics.res +72 -6
  33. package/src/Metrics.res.mjs +30 -2
  34. package/src/Persistence.res +36 -30
  35. package/src/Persistence.res.mjs +1 -20
  36. package/src/PgStorage.res +104 -56
  37. package/src/PgStorage.res.mjs +57 -35
  38. package/src/PruneStaleHistory.res +85 -52
  39. package/src/PruneStaleHistory.res.mjs +63 -37
  40. package/src/Rollback.res +68 -45
  41. package/src/Rollback.res.mjs +38 -19
  42. package/src/RollbackCommit.res +7 -9
  43. package/src/RollbackCommit.res.mjs +5 -6
  44. package/src/SafeCheckpointTracking.res +11 -11
  45. package/src/SafeCheckpointTracking.res.mjs +7 -6
  46. package/src/SimulateItems.res +33 -18
  47. package/src/SimulateItems.res.mjs +26 -22
  48. package/src/Sink.res +38 -26
  49. package/src/Sink.res.mjs +21 -16
  50. package/src/TestIndexer.res +5 -5
  51. package/src/TestIndexer.res.mjs +1 -1
  52. package/src/UserContext.res +358 -51
  53. package/src/UserContext.res.mjs +271 -35
  54. package/src/Utils.res +170 -0
  55. package/src/Utils.res.mjs +153 -0
  56. package/src/Writing.res +2 -2
  57. package/src/Writing.res.mjs +1 -1
  58. package/src/bindings/ClickHouse.res +366 -698
  59. package/src/bindings/ClickHouse.res.mjs +371 -421
  60. package/src/bindings/ClickHouseSink.res +337 -0
  61. package/src/bindings/ClickHouseSink.res.mjs +246 -0
  62. package/src/bindings/EventSource.res +8 -2
  63. package/src/bindings/NodeJs.res +6 -0
  64. package/src/bindings/Vitest.res +23 -0
  65. package/src/bindings/Vitest.res.mjs +3 -0
  66. package/src/bindings/WebSocket.res +9 -10
  67. package/src/db/CheckpointBounds.res +53 -0
  68. package/src/db/CheckpointBounds.res.mjs +44 -0
  69. package/src/db/EntityFilter.res +36 -17
  70. package/src/db/EntityFilter.res.mjs +25 -14
  71. package/src/db/EntityHistory.res +47 -22
  72. package/src/db/EntityHistory.res.mjs +19 -12
  73. package/src/db/InternalTable.res +84 -35
  74. package/src/db/InternalTable.res.mjs +56 -23
  75. package/src/db/RollbackFloors.res +55 -0
  76. package/src/db/RollbackFloors.res.mjs +92 -0
  77. package/src/db/Table.res +22 -4
  78. package/src/db/Table.res.mjs +30 -9
  79. package/src/sources/Evm.res +2 -0
  80. package/src/sources/Evm.res.mjs +2 -0
  81. package/src/sources/EvmHyperSyncSource.res +3 -3
  82. package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
  83. package/src/sources/EvmRpcWs.res +124 -0
  84. package/src/sources/EvmRpcWs.res.mjs +117 -0
  85. package/src/sources/Fuel.res +2 -0
  86. package/src/sources/Fuel.res.mjs +2 -0
  87. package/src/sources/FuelHyperSyncSource.res +1 -1
  88. package/src/sources/FuelHyperSyncSource.res.mjs +2 -1
  89. package/src/sources/HeightFeed.res +568 -0
  90. package/src/sources/HeightFeed.res.mjs +452 -0
  91. package/src/sources/HeightStream.res +257 -0
  92. package/src/sources/HeightStream.res.mjs +194 -0
  93. package/src/sources/HyperSync.res +5 -0
  94. package/src/sources/HyperSync.res.mjs +3 -0
  95. package/src/sources/HyperSync.resi +4 -0
  96. package/src/sources/HyperSyncSSE.res +49 -0
  97. package/src/sources/HyperSyncSSE.res.mjs +79 -0
  98. package/src/sources/RpcSource.res +1 -1
  99. package/src/sources/RpcSource.res.mjs +2 -2
  100. package/src/sources/Source.res +54 -1
  101. package/src/sources/Source.res.mjs +25 -0
  102. package/src/sources/SourceManager.res +220 -227
  103. package/src/sources/SourceManager.res.mjs +139 -164
  104. package/src/sources/SourceManager.resi +8 -0
  105. package/src/sources/Svm.res +2 -0
  106. package/src/sources/Svm.res.mjs +2 -0
  107. package/src/sources/SvmHyperSyncClient.res +70 -127
  108. package/src/sources/SvmHyperSyncClient.res.mjs +51 -25
  109. package/src/sources/SvmHyperSyncSource.res +18 -15
  110. package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
  111. package/src/subgraph/blocks.ts +176 -0
  112. package/src/subgraph/calls.ts +217 -0
  113. package/src/subgraph/conformance.ts +102 -0
  114. package/src/subgraph/division.ts +133 -0
  115. package/src/subgraph/errors.ts +90 -0
  116. package/src/subgraph/graph-ts-types/VERSION +2 -0
  117. package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
  118. package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
  119. package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
  120. package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
  121. package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
  122. package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
  123. package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
  124. package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
  125. package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
  126. package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
  127. package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
  128. package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
  129. package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
  130. package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
  131. package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
  132. package/src/subgraph/graph-ts-types/index.d.ts +102 -0
  133. package/src/subgraph/graph-ts.ts +1948 -0
  134. package/src/subgraph/hosts.ts +148 -0
  135. package/src/subgraph/runtime.ts +863 -0
  136. package/src/subgraph/scope.ts +66 -0
  137. package/svm.schema.json +6 -81
  138. package/src/MemoryStorage.res +0 -729
  139. package/src/MemoryStorage.res.mjs +0 -586
  140. package/src/sources/HyperSyncHeightStream.res +0 -129
  141. package/src/sources/HyperSyncHeightStream.res.mjs +0 -110
  142. package/src/sources/RpcWebSocketHeightStream.res +0 -175
  143. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -180
@@ -1,6 +1,5 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as ChainId from "./ChainId.res.mjs";
4
3
  import * as EnvioGlobal from "./EnvioGlobal.res.mjs";
5
4
 
6
5
  let callbacks = EnvioGlobal.value.rollbackCommitCallbacks;
@@ -16,10 +15,10 @@ function register(callback) {
16
15
  };
17
16
  }
18
17
 
19
- async function fire(progressBlockNumberByChainId) {
20
- await Promise.all(Object.entries(progressBlockNumberByChainId).flatMap(param => {
21
- let args_chainId = ChainId.normalizeOrThrow(param[0]);
22
- let args_rollbackToBlock = param[1];
18
+ async function fire(progressedChains) {
19
+ await Promise.all(progressedChains.flatMap(param => {
20
+ let args_chainId = param.chainId;
21
+ let args_rollbackToBlock = param.progressBlockNumber;
23
22
  let args = {
24
23
  chainId: args_chainId,
25
24
  rollbackToBlock: args_rollbackToBlock
@@ -33,4 +32,4 @@ export {
33
32
  register,
34
33
  fire,
35
34
  }
36
- /* ChainId Not a pure module */
35
+ /* EnvioGlobal Not a pure module */
@@ -33,15 +33,15 @@ let make = (
33
33
  }
34
34
  }
35
35
 
36
- let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int) => {
36
+ let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int): option<
37
+ Internal.checkpointId,
38
+ > => {
37
39
  let safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth
38
40
 
39
41
  switch safeCheckpointTracking.checkpointIds {
40
- | [] => 0n
41
- | _
42
- if safeCheckpointTracking.checkpointBlockNumbers->Array.getUnsafe(0) >
43
- safeBlockNumber => 0n
44
- | [checkpointId] => checkpointId
42
+ | [] => None
43
+ | _ if safeCheckpointTracking.checkpointBlockNumbers->Array.getUnsafe(0) > safeBlockNumber => None
44
+ | [checkpointId] => Some(checkpointId)
45
45
  | _ => {
46
46
  let trackingCheckpointsCount = safeCheckpointTracking.checkpointIds->Array.length
47
47
  let result = ref(None)
@@ -52,16 +52,15 @@ let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int) =
52
52
  safeCheckpointTracking.checkpointBlockNumbers->Array.getUnsafe(idx.contents) >
53
53
  safeBlockNumber
54
54
  ) {
55
- result :=
56
- Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(idx.contents - 1))
55
+ result := Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(idx.contents - 1))
57
56
  }
58
57
  idx := idx.contents + 1
59
58
  }
60
59
 
61
60
  switch result.contents {
62
- | Some(checkpointId) => checkpointId
61
+ | Some(_) => result.contents
63
62
  | None =>
64
- safeCheckpointTracking.checkpointIds->Array.getUnsafe(trackingCheckpointsCount - 1)
63
+ Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(trackingCheckpointsCount - 1))
65
64
  }
66
65
  }
67
66
  }
@@ -75,7 +74,8 @@ let updateOnNewBatch = (
75
74
  ~batchCheckpointBlockNumbers: array<int>,
76
75
  ~batchCheckpointChainIds: array<ChainId.t>,
77
76
  ) => {
78
- let safeCheckpointId = getSafeCheckpointId(safeCheckpointTracking, ~sourceBlockNumber)
77
+ let safeCheckpointId =
78
+ getSafeCheckpointId(safeCheckpointTracking, ~sourceBlockNumber)->Option.getOr(0n)
79
79
 
80
80
  let mutCheckpointIds = []
81
81
  let mutCheckpointBlockNumbers = []
@@ -1,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
3
4
 
4
5
  function make(maxReorgDepth, shouldRollbackOnReorg, chainReorgCheckpoints) {
5
6
  if (!(maxReorgDepth > 0 && shouldRollbackOnReorg)) {
@@ -22,10 +23,10 @@ function getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber) {
22
23
  let safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth | 0;
23
24
  let match = safeCheckpointTracking.checkpointIds;
24
25
  if (match.length === 0) {
25
- return 0n;
26
+ return;
26
27
  }
27
28
  if (safeCheckpointTracking.checkpointBlockNumbers[0] > safeBlockNumber) {
28
- return 0n;
29
+ return;
29
30
  }
30
31
  if (match.length === 1) {
31
32
  return match[0];
@@ -39,16 +40,16 @@ function getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber) {
39
40
  }
40
41
  idx = idx + 1 | 0;
41
42
  };
42
- let checkpointId = result;
43
- if (checkpointId !== undefined) {
44
- return checkpointId;
43
+ let match$1 = result;
44
+ if (match$1 !== undefined) {
45
+ return result;
45
46
  } else {
46
47
  return safeCheckpointTracking.checkpointIds[trackingCheckpointsCount - 1 | 0];
47
48
  }
48
49
  }
49
50
 
50
51
  function updateOnNewBatch(safeCheckpointTracking, sourceBlockNumber, chainId, batchCheckpointIds, batchCheckpointBlockNumbers, batchCheckpointChainIds) {
51
- let safeCheckpointId = getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber);
52
+ let safeCheckpointId = Stdlib_Option.getOr(getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber), 0n);
52
53
  let mutCheckpointIds = [];
53
54
  let mutCheckpointBlockNumbers = [];
54
55
  for (let idx = 0, idx_finish = safeCheckpointTracking.checkpointIds.length; idx < idx_finish; ++idx) {
@@ -338,11 +338,12 @@ let parse = (
338
338
  | None =>
339
339
  switch blockJson {
340
340
  | Some(bj) =>
341
- switch (bj->(Utils.magic: JSON.t => dict<JSON.t>))->Dict.get("slot") {
341
+ switch bj->(Utils.magic: JSON.t => dict<JSON.t>)->Dict.get("slot") {
342
342
  | Some(v) =>
343
- v->(Utils.magic: JSON.t => Nullable.t<int>)->Nullable.toOption->Option.getOr(
344
- currentBlock.contents,
345
- )
343
+ v
344
+ ->(Utils.magic: JSON.t => Nullable.t<int>)
345
+ ->Nullable.toOption
346
+ ->Option.getOr(currentBlock.contents)
346
347
  | None => currentBlock.contents
347
348
  }
348
349
  | None => currentBlock.contents
@@ -371,13 +372,23 @@ let parse = (
371
372
  | None => []
372
373
  }
373
374
  }
374
- let data = item.data->Option.getOr(svmEventConfig.discriminator->Option.getOr("0x"))
375
- let argsJson = item.args->Option.mapOr("{}", args => args->JSON.stringify)
375
+ let data = switch (item.data, svmEventConfig.discriminator) {
376
+ | (Some(data), _) => data
377
+ | (None, Some(discriminator)) =>
378
+ discriminator
379
+ ->String.replace("0x", "")
380
+ ->NodeJs.Buffer.fromHex
381
+ ->Uint8Array.fromArrayLikeOrIterable
382
+ | (None, None) => Uint8Array.fromLength(0)
383
+ }
384
+ let args = item.args->Option.getOr(Dict.make()->(Utils.magic: dict<unknown> => unknown))
376
385
  let logs = item.logs->Option.map(logs =>
377
- logs->Array.map((log): SvmHyperSyncClient.EventItems.log => {
378
- kind: log.kind->Null.fromOption,
379
- message: log.message->Null.fromOption,
380
- })
386
+ logs->Array.map(
387
+ (log): SvmHyperSyncClient.EventItems.log => {
388
+ kind: log.kind->Null.fromOption,
389
+ message: log.message->Null.fromOption,
390
+ },
391
+ )
381
392
  )
382
393
 
383
394
  let liveRegistrations = liveRegistrationsFor(~config, ~chainId, ~eventConfig)
@@ -414,13 +425,13 @@ let parse = (
414
425
  accountIndex: ?activity.transactionAccountIndex,
415
426
  isSigner: ?activity.isSigner,
416
427
  isWritable: ?activity.isWritable,
417
- preBalance: ?activity.lamports->Option.flatMap(l => l.pre),
418
- postBalance: ?activity.lamports->Option.flatMap(l => l.post),
419
- mint: ?activity.token->Option.flatMap(t => t.mint),
420
- owner: ?activity.token->Option.flatMap(t => t.owner),
421
- decimals: ?activity.token->Option.flatMap(t => t.decimals),
422
- preAmount: ?activity.token->Option.flatMap(t => t.preAmount),
423
- postAmount: ?activity.token->Option.flatMap(t => t.postAmount),
428
+ preBalance: ?(activity.lamports->Option.flatMap(l => l.pre)),
429
+ postBalance: ?(activity.lamports->Option.flatMap(l => l.post)),
430
+ mint: ?(activity.token->Option.flatMap(t => t.mint)),
431
+ owner: ?(activity.token->Option.flatMap(t => t.owner)),
432
+ decimals: ?(activity.token->Option.flatMap(t => t.decimals)),
433
+ preAmount: ?(activity.token->Option.flatMap(t => t.preAmount)),
434
+ postAmount: ?(activity.token->Option.flatMap(t => t.postAmount)),
424
435
  })
425
436
  ->ignore
426
437
  )
@@ -456,7 +467,11 @@ let parse = (
456
467
  accounts: accountArguments,
457
468
  data,
458
469
  isInner: item.isInner->Option.getOr(false),
459
- argsJson,
470
+ // As the Rust client does: present exactly when this registration
471
+ // selected `args`.
472
+ args: onEventRegistration.fieldSelection.instructionFields->Utils.Set.has("args")
473
+ ? Null.make(args)
474
+ : Null.null,
460
475
  logs: logs->Null.fromOption,
461
476
  },
462
477
  ~programName,
@@ -245,8 +245,12 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
245
245
  }
246
246
  }) : [];
247
247
  }
248
- let data = Stdlib_Option.getOr(rawJson.data, Stdlib_Option.getOr(eventConfig.discriminator, "0x"));
249
- let argsJson = Stdlib_Option.mapOr(rawJson.args, "{}", args => JSON.stringify(args));
248
+ let match$3 = rawJson.data;
249
+ let match$4 = eventConfig.discriminator;
250
+ let data = match$3 !== undefined ? match$3 : (
251
+ match$4 !== undefined ? Uint8Array.from(Buffer.from(match$4.replace("0x", ""), "hex")) : new Uint8Array(0)
252
+ );
253
+ let args$1 = Stdlib_Option.getOr(rawJson.args, {});
250
254
  let logs = Stdlib_Option.map(rawJson.logs, logs => logs.map(log => ({
251
255
  kind: Stdlib_Null.fromOption(log.kind),
252
256
  message: Stdlib_Null.fromOption(log.message)
@@ -312,7 +316,7 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
312
316
  accounts: accountArguments,
313
317
  data: data,
314
318
  isInner: Stdlib_Option.getOr(rawJson.isInner, false),
315
- argsJson: argsJson,
319
+ args: newrecord.fieldSelection.instructionFields.has("args") ? args$1 : null,
316
320
  logs: Stdlib_Null.fromOption(logs)
317
321
  }, match$1, match$2, eventConfig, newrecord.fieldSelection);
318
322
  payload["srcAddress"] = programId;
@@ -329,14 +333,14 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
329
333
  });
330
334
  return;
331
335
  }
332
- let match$3 = rawJson.contract;
333
- let match$4 = rawJson.event;
334
- let match$5 = match$3 !== undefined && match$4 !== undefined ? [
335
- match$3,
336
- match$4
336
+ let match$5 = rawJson.contract;
337
+ let match$6 = rawJson.event;
338
+ let match$7 = match$5 !== undefined && match$6 !== undefined ? [
339
+ match$5,
340
+ match$6
337
341
  ] : Stdlib_JsError.throwWithMessage(`simulate: Invalid item. Each item must have "contract" and "event" fields.`);
338
- let eventName = match$5[1];
339
- let contractName = match$5[0];
342
+ let eventName = match$7[1];
343
+ let contractName = match$7[0];
340
344
  let ec$1 = findEventConfig(config, contractName, eventName);
341
345
  let eventConfig$1 = ec$1 !== undefined ? ec$1 : Stdlib_JsError.throwWithMessage(`simulate: Event "` + eventName + `" not found on contract "` + contractName + `". Check that the contract and event names match your config.yaml.`);
342
346
  let json = rawJson.params;
@@ -359,32 +363,32 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
359
363
  let blockJson$2 = (blockJson$1 == null) ? undefined : Primitive_option.some(blockJson$1);
360
364
  let transactionJson = rawJson.transaction;
361
365
  let transactionJson$1 = (transactionJson == null) ? undefined : Primitive_option.some(transactionJson);
362
- let match$6 = config.ecosystem.name;
363
- let match$7;
364
- switch (match$6) {
366
+ let match$8 = config.ecosystem.name;
367
+ let match$9;
368
+ switch (match$8) {
365
369
  case "evm" :
366
370
  let block$2 = parseEvmSimulateBlock(currentBlock.contents, blockJson$2);
367
- match$7 = [
371
+ match$9 = [
368
372
  block$2,
369
373
  block$2.number
370
374
  ];
371
375
  break;
372
376
  case "fuel" :
373
377
  let block$3 = parseFuelSimulateBlock(currentBlock.contents, blockJson$2);
374
- match$7 = [
378
+ match$9 = [
375
379
  block$3,
376
380
  block$3.height
377
381
  ];
378
382
  break;
379
383
  case "svm" :
380
- match$7 = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
384
+ match$9 = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
381
385
  break;
382
386
  }
383
- let blockNumber = match$7[1];
384
- let block$4 = match$7[0];
385
- let match$8 = config.ecosystem.name;
387
+ let blockNumber = match$9[1];
388
+ let block$4 = match$9[0];
389
+ let match$10 = config.ecosystem.name;
386
390
  let transaction$1;
387
- switch (match$8) {
391
+ switch (match$10) {
388
392
  case "evm" :
389
393
  transaction$1 = parseEvmSimulateTransaction(transactionJson$1);
390
394
  break;
@@ -411,9 +415,9 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
411
415
  }
412
416
  });
413
417
  if (Utils.$$Array.isEmpty(liveRegistrations$1)) {
414
- let match$9 = ChainMap.values(config.chainMap).length;
418
+ let match$11 = ChainMap.values(config.chainMap).length;
415
419
  Stdlib_JsError.throwWithMessage(`simulate: no handler runs for event "` + eventName + `" on contract "` + contractName + `"` + (
416
- match$9 !== 1 ? ` on chain ` + ChainId.toString(chainId) : ""
420
+ match$11 !== 1 ? ` on chain ` + ChainId.toString(chainId) : ""
417
421
  ) + `. Register a handler with indexer.onEvent (and check any \`where\` filter isn't excluding this chain) before simulating it.`);
418
422
  }
419
423
  liveRegistrations$1.forEach(reg => {
package/src/Sink.res CHANGED
@@ -1,44 +1,56 @@
1
1
  type t = {
2
2
  name: string,
3
- initialize: (
4
- ~chainConfigs: array<Config.chain>=?,
5
- ~entities: array<Internal.entityConfig>=?,
6
- ~enums: array<Table.enumConfig<Table.enum>>=?,
3
+ initialize: (~entities: array<Internal.entityConfig>) => promise<unit>,
4
+ resume: (
5
+ ~checkpointId: Internal.checkpointId,
6
+ ~chains: array<Persistence.initialChainState>,
7
+ ~entities: array<Internal.entityConfig>,
7
8
  ) => promise<unit>,
8
- resume: (~checkpointId: Internal.checkpointId) => promise<unit>,
9
9
  writeBatch: (
10
10
  ~batch: Batch.t,
11
11
  ~updatedEntities: array<Persistence.updatedEntity>,
12
12
  ) => promise<unit>,
13
13
  }
14
14
 
15
- let makeClickHouse = (~host, ~database, ~username, ~password, ~chainIdMode: ChainId.mode=Int32): t => {
16
- let client = ClickHouse.createClient({
17
- url: host,
18
- username,
19
- password,
20
- })
21
-
22
- // Don't pass database to the client; it would fail if the database doesn't
23
- // exist yet. Each query qualifies the name explicitly or runs USE first.
24
-
25
- let cache = Dict.make()
15
+ let makeClickHouse = (
16
+ ~host,
17
+ ~database,
18
+ ~username,
19
+ ~password,
20
+ ~chainIdMode: ChainId.mode=Int32,
21
+ ): t => {
22
+ let sink = ClickHouse.makeSink(~host, ~username, ~password, ~database, ~chainIdMode)
23
+ let registry = ClickHouse.makeRegistry()
24
+ let mirrored = (entities: array<Internal.entityConfig>) =>
25
+ entities->Array.filter(e => e.storage.clickhouse)
26
26
 
27
27
  {
28
28
  name: "clickhouse",
29
- initialize: (~chainConfigs as _=[], ~entities=[], ~enums=[]) => {
30
- ClickHouse.initialize(client, ~database, ~entities, ~enums, ~chainIdMode)
29
+ initialize: (~entities) => {
30
+ ClickHouse.initialize(sink, ~entities=mirrored(entities))
31
31
  },
32
- resume: (~checkpointId) => {
33
- ClickHouse.resume(client, ~database, ~checkpointId)
32
+ resume: (~checkpointId, ~chains, ~entities) => {
33
+ ClickHouse.resume(sink, ~checkpointId, ~chains, ~entities=mirrored(entities))
34
34
  },
35
35
  writeBatch: async (~batch, ~updatedEntities) => {
36
- await Promise.all(
37
- updatedEntities->Array.map(({entityConfig, scope, changes}) => {
38
- ClickHouse.setUpdatesOrThrow(client, ~cache, ~changes, ~entityConfig, ~scope, ~database)
39
- }),
40
- )->Utils.Promise.ignoreValue
41
- await ClickHouse.setCheckpointsOrThrow(client, ~batch, ~database)
36
+ // Staging reads JS values, so it holds the isolate and runs here. The
37
+ // encode and the round trips happen in Rust, which also keeps the
38
+ // checkpoints behind the rows they cover.
39
+ let entities = []
40
+ let checkpoints = try {
41
+ updatedEntities->Array.forEach(({entityConfig, scope, changes}) =>
42
+ switch ClickHouse.stageUpdatesOrThrow(sink, ~registry, ~changes, ~entityConfig, ~scope) {
43
+ | Some(handle) => entities->Array.push(handle)
44
+ | None => ()
45
+ }
46
+ )
47
+ ClickHouse.stageCheckpointsOrThrow(sink, ~registry, ~batch)
48
+ } catch {
49
+ | exn =>
50
+ sink->ClickHouseSink.discard(entities)
51
+ throw(exn)
52
+ }
53
+ await ClickHouse.writeStagedOrThrow(sink, ~entities, ~checkpoints)
42
54
  },
43
55
  }
44
56
  }
package/src/Sink.res.mjs CHANGED
@@ -1,28 +1,33 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as ClickHouse from "./bindings/ClickHouse.res.mjs";
4
- import * as Client from "@clickhouse/client";
5
4
 
6
5
  function makeClickHouse(host, database, username, password, chainIdModeOpt) {
7
6
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
8
- let client = Client.createClient({
9
- url: host,
10
- username: username,
11
- password: password
12
- });
13
- let cache = {};
7
+ let sink = ClickHouse.makeSink(host, username, password, database, chainIdMode);
8
+ let registry = ClickHouse.makeRegistry();
9
+ let mirrored = entities => entities.filter(e => e.storage.clickhouse);
14
10
  return {
15
11
  name: "clickhouse",
16
- initialize: ($staropt$star, $staropt$star$1, $staropt$star$2) => {
17
- $staropt$star !== undefined;
18
- let entities = $staropt$star$1 !== undefined ? $staropt$star$1 : [];
19
- let enums = $staropt$star$2 !== undefined ? $staropt$star$2 : [];
20
- return ClickHouse.initialize(client, database, entities, enums, chainIdMode);
21
- },
22
- resume: checkpointId => ClickHouse.resume(client, database, checkpointId),
12
+ initialize: entities => ClickHouse.initialize(sink, mirrored(entities)),
13
+ resume: (checkpointId, chains, entities) => ClickHouse.resume(sink, checkpointId, chains, mirrored(entities)),
23
14
  writeBatch: async (batch, updatedEntities) => {
24
- await Promise.all(updatedEntities.map(param => ClickHouse.setUpdatesOrThrow(client, cache, param.changes, param.entityConfig, param.scope, database)));
25
- return await ClickHouse.setCheckpointsOrThrow(client, batch, database);
15
+ let entities = [];
16
+ let checkpoints;
17
+ try {
18
+ updatedEntities.forEach(param => {
19
+ let handle = ClickHouse.stageUpdatesOrThrow(sink, registry, param.changes, param.entityConfig, param.scope);
20
+ if (handle !== undefined) {
21
+ entities.push(handle);
22
+ return;
23
+ }
24
+ });
25
+ checkpoints = ClickHouse.stageCheckpointsOrThrow(sink, registry, batch);
26
+ } catch (exn) {
27
+ sink.discard(entities);
28
+ throw exn;
29
+ }
30
+ return await ClickHouse.writeStagedOrThrow(sink, entities, checkpoints);
26
31
  }
27
32
  };
28
33
  }
@@ -589,7 +589,7 @@ let makeInMemoryStorage = (~state: testIndexerState): Persistence.storage => {
589
589
  JsError.throwWithMessage(
590
590
  "TestIndexer: initialize should not be called; the initial state is derived from config.",
591
591
  ),
592
- resumeInitialState: async () =>
592
+ resumeInitialState: async (~entities as _, ~throwIfIncompatible as _) =>
593
593
  JsError.throwWithMessage(
594
594
  "TestIndexer: resumeInitialState should not be called; the initial state is derived from config.",
595
595
  ),
@@ -625,22 +625,22 @@ let makeInMemoryStorage = (~state: testIndexerState): Persistence.storage => {
625
625
  dumpEffectCache: async () => (),
626
626
  reset: async () => (),
627
627
  setChainMeta: async _ => Obj.magic(),
628
- pruneStaleCheckpoints: async (~safeCheckpointId as _) => (),
628
+ pruneStaleCheckpoints: async (~safeCheckpoints as _) => (),
629
629
  pruneStaleEntityHistory: async (
630
630
  ~entityName as _,
631
631
  ~entityIndex as _,
632
632
  ~chainIdColumn as _,
633
- ~safeCheckpointId as _,
633
+ ~safeCheckpoints as _,
634
634
  ) => (),
635
635
  getRollbackTargetCheckpoint: async (~reorgChainId as _, ~lastKnownValidBlockNumber as _) =>
636
636
  JsError.throwWithMessage(
637
637
  "TestIndexer: Rollback is not supported. The runner forces rollbackOnReorg off, so this should be unreachable.",
638
638
  ),
639
- getRollbackProgressDiff: async (~rollbackTargetCheckpointId as _) =>
639
+ getRollbackProgressDiff: async (~floors as _) =>
640
640
  JsError.throwWithMessage(
641
641
  "TestIndexer: Rollback is not supported. The runner forces rollbackOnReorg off, so this should be unreachable.",
642
642
  ),
643
- getRollbackData: async (~entityConfig as _, ~rollbackTargetCheckpointId as _) =>
643
+ getRollbackData: async (~entityConfig as _, ~floors as _) =>
644
644
  JsError.throwWithMessage(
645
645
  "TestIndexer: Rollback is not supported. The runner forces rollbackOnReorg off, so this should be unreachable.",
646
646
  ),
@@ -385,7 +385,7 @@ function makeInMemoryStorage(state) {
385
385
  name: "test-inmemory",
386
386
  isInitialized: async () => true,
387
387
  initialize: async (param, param$1, param$2, param$3, param$4) => Stdlib_JsError.throwWithMessage("TestIndexer: initialize should not be called; the initial state is derived from config."),
388
- resumeInitialState: async () => Stdlib_JsError.throwWithMessage("TestIndexer: resumeInitialState should not be called; the initial state is derived from config."),
388
+ resumeInitialState: async (param, param$1) => Stdlib_JsError.throwWithMessage("TestIndexer: resumeInitialState should not be called; the initial state is derived from config."),
389
389
  loadOrThrow: async (filter, table) => handleLoad(state, table.tableName, filter),
390
390
  ensureQueryIndexes: async (param, param$1) => {},
391
391
  ensureSchemaIndexes: async param => {},