envio 3.1.2 → 3.2.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.
Files changed (134) hide show
  1. package/evm.schema.json +83 -11
  2. package/fuel.schema.json +83 -11
  3. package/index.d.ts +184 -3
  4. package/package.json +6 -6
  5. package/src/Batch.res +2 -2
  6. package/src/ChainFetcher.res +27 -3
  7. package/src/ChainFetcher.res.mjs +17 -3
  8. package/src/ChainManager.res +163 -0
  9. package/src/ChainManager.res.mjs +136 -0
  10. package/src/Config.res +213 -30
  11. package/src/Config.res.mjs +102 -41
  12. package/src/Core.res +16 -10
  13. package/src/Ecosystem.res +0 -3
  14. package/src/Env.res +2 -2
  15. package/src/Env.res.mjs +2 -2
  16. package/src/Envio.res +101 -2
  17. package/src/Envio.res.mjs +2 -3
  18. package/src/EventConfigBuilder.res +52 -0
  19. package/src/EventConfigBuilder.res.mjs +32 -0
  20. package/src/EventUtils.res +2 -2
  21. package/src/FetchState.res +23 -14
  22. package/src/FetchState.res.mjs +21 -15
  23. package/src/GlobalState.res +219 -363
  24. package/src/GlobalState.res.mjs +314 -491
  25. package/src/GlobalStateManager.res +49 -59
  26. package/src/GlobalStateManager.res.mjs +5 -4
  27. package/src/GlobalStateManager.resi +1 -1
  28. package/src/HandlerLoader.res +12 -1
  29. package/src/HandlerLoader.res.mjs +6 -1
  30. package/src/HandlerRegister.res +9 -9
  31. package/src/HandlerRegister.res.mjs +9 -9
  32. package/src/Hasura.res +102 -32
  33. package/src/Hasura.res.mjs +88 -34
  34. package/src/InMemoryStore.res +10 -1
  35. package/src/InMemoryStore.res.mjs +4 -1
  36. package/src/InMemoryTable.res +83 -136
  37. package/src/InMemoryTable.res.mjs +57 -86
  38. package/src/Internal.res +54 -5
  39. package/src/Internal.res.mjs +2 -8
  40. package/src/LazyLoader.res +2 -2
  41. package/src/LazyLoader.res.mjs +3 -3
  42. package/src/LoadLayer.res +47 -60
  43. package/src/LoadLayer.res.mjs +28 -50
  44. package/src/LoadLayer.resi +2 -5
  45. package/src/LogSelection.res +4 -4
  46. package/src/LogSelection.res.mjs +5 -7
  47. package/src/Logging.res +1 -1
  48. package/src/Main.res +61 -2
  49. package/src/Main.res.mjs +37 -1
  50. package/src/Persistence.res +3 -16
  51. package/src/PgStorage.res +125 -114
  52. package/src/PgStorage.res.mjs +112 -95
  53. package/src/Ports.res +5 -0
  54. package/src/Ports.res.mjs +9 -0
  55. package/src/Prometheus.res +3 -3
  56. package/src/Prometheus.res.mjs +4 -4
  57. package/src/ReorgDetection.res +4 -4
  58. package/src/ReorgDetection.res.mjs +4 -5
  59. package/src/SafeCheckpointTracking.res +16 -16
  60. package/src/SafeCheckpointTracking.res.mjs +2 -2
  61. package/src/SimulateItems.res +10 -14
  62. package/src/SimulateItems.res.mjs +5 -2
  63. package/src/Sink.res +1 -1
  64. package/src/Sink.res.mjs +1 -2
  65. package/src/SvmTypes.res +9 -0
  66. package/src/SvmTypes.res.mjs +14 -0
  67. package/src/TestIndexer.res +17 -57
  68. package/src/TestIndexer.res.mjs +14 -48
  69. package/src/TestIndexerProxyStorage.res +23 -23
  70. package/src/TestIndexerProxyStorage.res.mjs +12 -15
  71. package/src/Throttler.res +2 -2
  72. package/src/Time.res +2 -2
  73. package/src/Time.res.mjs +2 -2
  74. package/src/UserContext.res +19 -118
  75. package/src/UserContext.res.mjs +10 -66
  76. package/src/Utils.res +15 -15
  77. package/src/Utils.res.mjs +7 -8
  78. package/src/adapters/MarkBatchProcessedAdapter.res +5 -0
  79. package/src/adapters/MarkBatchProcessedAdapter.res.mjs +14 -0
  80. package/src/bindings/BigDecimal.res +1 -1
  81. package/src/bindings/BigDecimal.res.mjs +2 -2
  82. package/src/bindings/ClickHouse.res +8 -6
  83. package/src/bindings/ClickHouse.res.mjs +5 -5
  84. package/src/bindings/Hrtime.res +1 -1
  85. package/src/bindings/Pino.res +2 -2
  86. package/src/bindings/Pino.res.mjs +3 -4
  87. package/src/db/EntityFilter.res +410 -0
  88. package/src/db/EntityFilter.res.mjs +424 -0
  89. package/src/db/EntityHistory.res +1 -1
  90. package/src/db/EntityHistory.res.mjs +1 -1
  91. package/src/db/InternalTable.res +10 -10
  92. package/src/db/InternalTable.res.mjs +41 -45
  93. package/src/db/Schema.res +2 -2
  94. package/src/db/Schema.res.mjs +3 -3
  95. package/src/db/Table.res +106 -22
  96. package/src/db/Table.res.mjs +84 -35
  97. package/src/sources/EventRouter.res +67 -2
  98. package/src/sources/EventRouter.res.mjs +45 -3
  99. package/src/sources/Evm.res +0 -7
  100. package/src/sources/Evm.res.mjs +0 -15
  101. package/src/sources/EvmChain.res +1 -1
  102. package/src/sources/EvmChain.res.mjs +1 -2
  103. package/src/sources/EvmRpcClient.res +42 -0
  104. package/src/sources/EvmRpcClient.res.mjs +64 -0
  105. package/src/sources/Fuel.res +0 -7
  106. package/src/sources/Fuel.res.mjs +0 -15
  107. package/src/sources/HyperFuelSource.res +5 -4
  108. package/src/sources/HyperFuelSource.res.mjs +2 -2
  109. package/src/sources/HyperSyncClient.res +9 -5
  110. package/src/sources/HyperSyncClient.res.mjs +2 -2
  111. package/src/sources/HyperSyncHeightStream.res +2 -2
  112. package/src/sources/HyperSyncHeightStream.res.mjs +2 -2
  113. package/src/sources/HyperSyncSource.res +10 -9
  114. package/src/sources/HyperSyncSource.res.mjs +4 -4
  115. package/src/sources/Rpc.res +1 -5
  116. package/src/sources/Rpc.res.mjs +1 -9
  117. package/src/sources/RpcSource.res +57 -21
  118. package/src/sources/RpcSource.res.mjs +47 -20
  119. package/src/sources/RpcWebSocketHeightStream.res +1 -1
  120. package/src/sources/SourceManager.res +3 -2
  121. package/src/sources/SourceManager.res.mjs +1 -1
  122. package/src/sources/Svm.res +3 -10
  123. package/src/sources/Svm.res.mjs +4 -18
  124. package/src/sources/SvmHyperSyncClient.res +265 -0
  125. package/src/sources/SvmHyperSyncClient.res.mjs +28 -0
  126. package/src/sources/SvmHyperSyncSource.res +638 -0
  127. package/src/sources/SvmHyperSyncSource.res.mjs +557 -0
  128. package/src/tui/Tui.res +9 -2
  129. package/src/tui/Tui.res.mjs +18 -3
  130. package/src/tui/components/BufferedProgressBar.res +2 -2
  131. package/src/tui/components/TuiData.res +3 -0
  132. package/svm.schema.json +523 -14
  133. package/src/TableIndices.res +0 -115
  134. package/src/TableIndices.res.mjs +0 -144
package/svm.schema.json CHANGED
@@ -39,7 +39,7 @@
39
39
  "minimum": 0
40
40
  },
41
41
  "storage": {
42
- "description": "Configuration for the storage backends the indexer writes to. Defaults to `postgres: true` when omitted. ClickHouse requires Postgres to be enabled (it is not supported as a single storage yet), and at least one backend must be enabled.",
42
+ "description": "Storage backends the indexer writes data to. Defaults to Postgres when omitted. Set `clickhouse: true` to additionally sync the indexed data to ClickHouse. Mark a backend with `default: true` to store entities that don't have an @storage directive in the schema, e.g. `clickhouse: {default: true}`.",
43
43
  "anyOf": [
44
44
  {
45
45
  "$ref": "#/$defs/StorageConfig"
@@ -72,17 +72,75 @@
72
72
  "type": "object",
73
73
  "properties": {
74
74
  "postgres": {
75
- "description": "Whether to use Postgres as a storage backend (default: true).",
76
- "type": [
77
- "boolean",
78
- "null"
75
+ "description": "Whether to use Postgres as a storage backend (default: true). Accepts a boolean or an options object (the object form implies the backend is enabled).",
76
+ "anyOf": [
77
+ {
78
+ "type": [
79
+ "boolean",
80
+ "null"
81
+ ]
82
+ },
83
+ {
84
+ "type": "object",
85
+ "properties": {
86
+ "default": {
87
+ "description": "Whether entities without an @storage directive are stored in this backend (default: true when Postgres is the only enabled backend, false otherwise).",
88
+ "type": [
89
+ "boolean",
90
+ "null"
91
+ ]
92
+ },
93
+ "column_name_format": {
94
+ "description": "How entity fields are reflected in the storage column names. `original` keeps the schema.graphql field names as is, `snake_case` converts them to snake_case in the database while keeping the original casing in the exposed APIs. (default: original)",
95
+ "type": [
96
+ "string",
97
+ "null"
98
+ ],
99
+ "enum": [
100
+ "original",
101
+ "snake_case",
102
+ null
103
+ ]
104
+ }
105
+ },
106
+ "additionalProperties": false
107
+ }
79
108
  ]
80
109
  },
81
110
  "clickhouse": {
82
- "description": "Whether to additionally sync the indexed data to ClickHouse. Requires Postgres to be enabled (default: false).",
83
- "type": [
84
- "boolean",
85
- "null"
111
+ "description": "Whether to additionally sync the indexed data to ClickHouse. Requires Postgres to be enabled (default: false). Accepts a boolean or an options object (the object form implies the backend is enabled).",
112
+ "anyOf": [
113
+ {
114
+ "type": [
115
+ "boolean",
116
+ "null"
117
+ ]
118
+ },
119
+ {
120
+ "type": "object",
121
+ "properties": {
122
+ "default": {
123
+ "description": "Whether entities without an @storage directive are stored in this backend (default: false).",
124
+ "type": [
125
+ "boolean",
126
+ "null"
127
+ ]
128
+ },
129
+ "column_name_format": {
130
+ "description": "How entity fields are reflected in the storage column names. `original` keeps the schema.graphql field names as is, `snake_case` converts them to snake_case in the database while keeping the original casing in the exposed APIs. (default: original)",
131
+ "type": [
132
+ "string",
133
+ "null"
134
+ ],
135
+ "enum": [
136
+ "original",
137
+ "snake_case",
138
+ null
139
+ ]
140
+ }
141
+ },
142
+ "additionalProperties": false
143
+ }
86
144
  ]
87
145
  }
88
146
  },
@@ -104,7 +162,14 @@
104
162
  "if": {
105
163
  "properties": {
106
164
  "clickhouse": {
107
- "const": true
165
+ "anyOf": [
166
+ {
167
+ "const": true
168
+ },
169
+ {
170
+ "type": "object"
171
+ }
172
+ ]
108
173
  }
109
174
  },
110
175
  "required": [
@@ -114,7 +179,14 @@
114
179
  "then": {
115
180
  "properties": {
116
181
  "postgres": {
117
- "const": true
182
+ "anyOf": [
183
+ {
184
+ "const": true
185
+ },
186
+ {
187
+ "type": "object"
188
+ }
189
+ ]
118
190
  }
119
191
  },
120
192
  "required": [
@@ -141,8 +213,11 @@
141
213
  ]
142
214
  },
143
215
  "rpc": {
144
- "description": "RPC endpoint URL for connecting to the Svm cluster to fetch blockchain data.",
145
- "type": "string"
216
+ "description": "RPC endpoint URL for connecting to the Svm cluster to fetch blockchain data. Required unless `experimental` is set, in which case it is ignored in favour of the experimental HyperSync source.",
217
+ "type": [
218
+ "string",
219
+ "null"
220
+ ]
146
221
  },
147
222
  "start_block": {
148
223
  "description": "The slot number at which the indexer should start ingesting data",
@@ -167,13 +242,447 @@
167
242
  ],
168
243
  "format": "uint32",
169
244
  "minimum": 0
245
+ },
246
+ "experimental": {
247
+ "description": "Experimental HyperSync-backed instruction indexing. This config shape Veil change in future releases.",
248
+ "anyOf": [
249
+ {
250
+ "$ref": "#/$defs/Experimental"
251
+ },
252
+ {
253
+ "type": "null"
254
+ }
255
+ ]
170
256
  }
171
257
  },
172
258
  "additionalProperties": false,
173
259
  "required": [
174
- "rpc",
175
260
  "start_block"
176
261
  ]
262
+ },
263
+ "Experimental": {
264
+ "type": "object",
265
+ "properties": {
266
+ "hypersync_config": {
267
+ "description": "HyperSync Config for fetching historical instructions on this chain.",
268
+ "$ref": "#/$defs/HypersyncConfig"
269
+ },
270
+ "programs": {
271
+ "description": "Solana programs to index on this chain.",
272
+ "type": "array",
273
+ "items": {
274
+ "$ref": "#/$defs/Program"
275
+ }
276
+ }
277
+ },
278
+ "additionalProperties": false,
279
+ "required": [
280
+ "hypersync_config",
281
+ "programs"
282
+ ]
283
+ },
284
+ "HypersyncConfig": {
285
+ "type": "object",
286
+ "properties": {
287
+ "url": {
288
+ "description": "URL of the HyperSync endpoint (default: the public Solana HyperSync endpoint at https://solana.hypersync.xyz)",
289
+ "type": "string"
290
+ }
291
+ },
292
+ "additionalProperties": false,
293
+ "required": [
294
+ "url"
295
+ ]
296
+ },
297
+ "Program": {
298
+ "type": "object",
299
+ "properties": {
300
+ "name": {
301
+ "description": "A unique project-wide name for this program (used in generated code).",
302
+ "type": "string"
303
+ },
304
+ "program_id": {
305
+ "description": "Base58-encoded program id (32 bytes).",
306
+ "type": "string"
307
+ },
308
+ "handler": {
309
+ "description": "Optional relative path to a file where handlers are registered for the given program. If not provided, handlers can be auto-loaded from the src directory.",
310
+ "type": [
311
+ "string",
312
+ "null"
313
+ ]
314
+ },
315
+ "idl": {
316
+ "description": "Optional path (relative to config.yaml) to an Anchor IDL JSON file. When present, codegen parses the IDL and derives `accounts`/`args` for every named instruction. Mutually exclusive with per-instruction `accounts`/`args` overrides.",
317
+ "type": [
318
+ "string",
319
+ "null"
320
+ ]
321
+ },
322
+ "instructions": {
323
+ "description": "A list of instructions that should be indexed on this program.",
324
+ "type": "array",
325
+ "items": {
326
+ "$ref": "#/$defs/Instruction"
327
+ }
328
+ }
329
+ },
330
+ "additionalProperties": false,
331
+ "required": [
332
+ "name",
333
+ "program_id",
334
+ "instructions"
335
+ ]
336
+ },
337
+ "Instruction": {
338
+ "type": "object",
339
+ "properties": {
340
+ "name": {
341
+ "description": "Name of the instruction in the HyperIndex generated code. Should be unique per program.",
342
+ "type": "string"
343
+ },
344
+ "discriminator": {
345
+ "description": "Hex-encoded instruction-data prefix used as the discriminator (\"0x\" optional). Must be 1, 2, 4, or 8 bytes after decoding. An 8-byte value matches the standard Anchor discriminator.",
346
+ "type": [
347
+ "string",
348
+ "null"
349
+ ]
350
+ },
351
+ "is_inner": {
352
+ "description": "Filter on inner-vs-outer instructions. None / absent matches both.",
353
+ "type": [
354
+ "boolean",
355
+ "null"
356
+ ]
357
+ },
358
+ "account_filters": {
359
+ "description": "Optional positional account filters. Two shapes are accepted: a flat list of `{position, values}` entries (AND across positions, OR within `values`); or `{any_of: [[...]] }`, a list of AND-groups that are OR-ed together. Positions must be in 0..=5; positions 6..=9 are reserved for a future extension.",
360
+ "anyOf": [
361
+ {
362
+ "$ref": "#/$defs/AccountFilters"
363
+ },
364
+ {
365
+ "type": "null"
366
+ }
367
+ ]
368
+ },
369
+ "field_selection": {
370
+ "description": "Select which additional data to fetch for each matched instruction. Each key accepts `true` (include all fields) or a list of field names (per-field selection, not yet supported). When absent, only the instruction itself is included.",
371
+ "anyOf": [
372
+ {
373
+ "$ref": "#/$defs/SvmFieldSelection"
374
+ },
375
+ {
376
+ "type": "null"
377
+ }
378
+ ]
379
+ },
380
+ "accounts": {
381
+ "description": "Optional positional account names. The Nth entry names account slot N on the dispatched instruction; surfaces as `event.instruction.decoded.accounts.<name>`. Accounts beyond the named list become `extra_accounts`.",
382
+ "type": [
383
+ "array",
384
+ "null"
385
+ ],
386
+ "items": {
387
+ "type": "string"
388
+ }
389
+ },
390
+ "args": {
391
+ "description": "Optional Borsh argument schema. Each entry names one arg and gives its type; the decoder walks the instruction data after the discriminator in declared order. Mutually exclusive with the program-level `idl` field.",
392
+ "type": [
393
+ "array",
394
+ "null"
395
+ ],
396
+ "items": {
397
+ "$ref": "#/$defs/ArgDef"
398
+ }
399
+ }
400
+ },
401
+ "additionalProperties": false,
402
+ "required": [
403
+ "name"
404
+ ]
405
+ },
406
+ "AccountFilters": {
407
+ "anyOf": [
408
+ {
409
+ "type": "array",
410
+ "items": {
411
+ "$ref": "#/$defs/AccountFilter"
412
+ }
413
+ },
414
+ {
415
+ "$ref": "#/$defs/AnyOfAccountFilters"
416
+ }
417
+ ]
418
+ },
419
+ "AccountFilter": {
420
+ "type": "object",
421
+ "properties": {
422
+ "position": {
423
+ "description": "Account position within the instruction (0..=5).",
424
+ "type": "integer",
425
+ "format": "uint8",
426
+ "minimum": 0,
427
+ "maximum": 255
428
+ },
429
+ "values": {
430
+ "description": "Allowed base58 pubkeys for this account position.",
431
+ "type": "array",
432
+ "items": {
433
+ "type": "string"
434
+ }
435
+ }
436
+ },
437
+ "additionalProperties": false,
438
+ "required": [
439
+ "position",
440
+ "values"
441
+ ]
442
+ },
443
+ "AnyOfAccountFilters": {
444
+ "type": "object",
445
+ "properties": {
446
+ "any_of": {
447
+ "description": "A non-empty list of AND-groups. Each group is itself a non-empty list of `{position, values}` entries that must all match the same instruction. An instruction matches `any_of` when any one group matches.",
448
+ "type": "array",
449
+ "items": {
450
+ "type": "array",
451
+ "items": {
452
+ "$ref": "#/$defs/AccountFilter"
453
+ }
454
+ }
455
+ }
456
+ },
457
+ "additionalProperties": false,
458
+ "required": [
459
+ "any_of"
460
+ ]
461
+ },
462
+ "SvmFieldSelection": {
463
+ "type": "object",
464
+ "properties": {
465
+ "transaction_fields": {
466
+ "description": "Include the parent transaction for each matched instruction. Use `true` to include all fields.",
467
+ "anyOf": [
468
+ {
469
+ "$ref": "#/$defs/FieldSelectionValue"
470
+ },
471
+ {
472
+ "type": "null"
473
+ }
474
+ ]
475
+ },
476
+ "log_fields": {
477
+ "description": "Include program logs scoped to each matched instruction. Use `true` to include all fields.",
478
+ "anyOf": [
479
+ {
480
+ "$ref": "#/$defs/FieldSelectionValue"
481
+ },
482
+ {
483
+ "type": "null"
484
+ }
485
+ ]
486
+ },
487
+ "token_balance_fields": {
488
+ "description": "Include SPL Token / Token-2022 balance snapshots for the parent transaction. Implies transaction_fields: true. Use `true` to include all fields.",
489
+ "anyOf": [
490
+ {
491
+ "$ref": "#/$defs/FieldSelectionValue"
492
+ },
493
+ {
494
+ "type": "null"
495
+ }
496
+ ]
497
+ }
498
+ },
499
+ "additionalProperties": false
500
+ },
501
+ "FieldSelectionValue": {
502
+ "description": "Value for a field-selection entry. `true` includes all fields;\na list of field names enables per-field selection (not yet supported).",
503
+ "anyOf": [
504
+ {
505
+ "type": "boolean"
506
+ },
507
+ {
508
+ "type": "array",
509
+ "items": {
510
+ "type": "string"
511
+ }
512
+ }
513
+ ]
514
+ },
515
+ "ArgDef": {
516
+ "description": "One named argument of an instruction. Mirrors\n`hypersync_client_solana::decode::NamedField`.",
517
+ "type": "object",
518
+ "properties": {
519
+ "name": {
520
+ "description": "Field name as it appears on the decoded args object.",
521
+ "type": "string"
522
+ },
523
+ "type": {
524
+ "description": "Borsh type of this field.",
525
+ "$ref": "#/$defs/ArgType"
526
+ }
527
+ },
528
+ "additionalProperties": false,
529
+ "required": [
530
+ "name",
531
+ "type"
532
+ ]
533
+ },
534
+ "ArgType": {
535
+ "description": "User-facing Borsh type grammar. Mirrors\n`hypersync_client_solana::decode::FieldType`. The YAML accepts either:\n- A bare string for primitives (`\"u64\"`, `\"pubkey\"`, `\"bool\"`, ...).\n- A tagged object for composites (`{ vec: u8 }`, `{ option: pubkey }`,\n `{ array: [u8, 32] }`, `{ defined: \"DataV2\" }`).\n- An object with `kind: struct` or `kind: enum` for nominal types\n declared inline on this field. Most users will use `defined` and\n declare the nominal types under the program's `types:` block (Anchor\n IDL shape) once that lands; for now inline `struct` / `enum` is the\n only way to express nominal shapes ad-hoc.",
536
+ "anyOf": [
537
+ {
538
+ "$ref": "#/$defs/ArgPrimitive"
539
+ },
540
+ {
541
+ "$ref": "#/$defs/ArgComposite"
542
+ }
543
+ ]
544
+ },
545
+ "ArgPrimitive": {
546
+ "type": "string",
547
+ "enum": [
548
+ "bool",
549
+ "u8",
550
+ "u16",
551
+ "u32",
552
+ "u64",
553
+ "u128",
554
+ "i8",
555
+ "i16",
556
+ "i32",
557
+ "i64",
558
+ "i128",
559
+ "f32",
560
+ "f64",
561
+ "string",
562
+ "bytes",
563
+ "pubkey",
564
+ "publicKey"
565
+ ]
566
+ },
567
+ "ArgComposite": {
568
+ "oneOf": [
569
+ {
570
+ "type": "object",
571
+ "properties": {
572
+ "option": {
573
+ "$ref": "#/$defs/ArgType"
574
+ }
575
+ },
576
+ "required": [
577
+ "option"
578
+ ],
579
+ "additionalProperties": false
580
+ },
581
+ {
582
+ "type": "object",
583
+ "properties": {
584
+ "vec": {
585
+ "$ref": "#/$defs/ArgType"
586
+ }
587
+ },
588
+ "required": [
589
+ "vec"
590
+ ],
591
+ "additionalProperties": false
592
+ },
593
+ {
594
+ "description": "`[ <element type>, <length> ]` — same shape Anchor IDLs use.",
595
+ "type": "object",
596
+ "properties": {
597
+ "array": {
598
+ "type": "array",
599
+ "prefixItems": [
600
+ {
601
+ "$ref": "#/$defs/ArgType"
602
+ },
603
+ {
604
+ "type": "integer",
605
+ "format": "uint",
606
+ "minimum": 0
607
+ }
608
+ ],
609
+ "minItems": 2,
610
+ "maxItems": 2
611
+ }
612
+ },
613
+ "required": [
614
+ "array"
615
+ ],
616
+ "additionalProperties": false
617
+ },
618
+ {
619
+ "description": "Reference to a nominal type defined in the program-level\n`defined_types` registry (populated from an Anchor IDL `types:`\nblock or the bundled-Metaplex registry).",
620
+ "type": "object",
621
+ "properties": {
622
+ "defined": {
623
+ "type": "string"
624
+ }
625
+ },
626
+ "required": [
627
+ "defined"
628
+ ],
629
+ "additionalProperties": false
630
+ },
631
+ {
632
+ "description": "Inline-or-registry struct. Used as a nominal type definition in\nthe `defined_types` registry; rarely seen at the field level.",
633
+ "type": "object",
634
+ "properties": {
635
+ "struct": {
636
+ "type": "array",
637
+ "items": {
638
+ "$ref": "#/$defs/ArgDef"
639
+ }
640
+ }
641
+ },
642
+ "required": [
643
+ "struct"
644
+ ],
645
+ "additionalProperties": false
646
+ },
647
+ {
648
+ "description": "Inline-or-registry enum. Same role as `Struct`: a nominal type\ndefinition in the `defined_types` registry.",
649
+ "type": "object",
650
+ "properties": {
651
+ "enum": {
652
+ "type": "array",
653
+ "items": {
654
+ "$ref": "#/$defs/ArgEnumVariant"
655
+ }
656
+ }
657
+ },
658
+ "required": [
659
+ "enum"
660
+ ],
661
+ "additionalProperties": false
662
+ }
663
+ ]
664
+ },
665
+ "ArgEnumVariant": {
666
+ "type": "object",
667
+ "properties": {
668
+ "name": {
669
+ "type": "string"
670
+ },
671
+ "fields": {
672
+ "description": "`None` for unit variants; `Some([])` for struct variants with no\nfields. The Borsh wire format is identical in both cases (the\n1-byte tag), but the distinction is preserved for round-tripping.",
673
+ "type": [
674
+ "array",
675
+ "null"
676
+ ],
677
+ "items": {
678
+ "$ref": "#/$defs/ArgDef"
679
+ }
680
+ }
681
+ },
682
+ "additionalProperties": false,
683
+ "required": [
684
+ "name"
685
+ ]
177
686
  }
178
687
  }
179
688
  }
@@ -1,115 +0,0 @@
1
- module FieldValue = {
2
- @unboxed
3
- type rec tNonOptional =
4
- | String(string)
5
- | BigInt(bigint)
6
- | Int(int)
7
- | BigDecimal(BigDecimal.t)
8
- | Bool(bool)
9
- | Array(array<tNonOptional>)
10
-
11
- let rec toString = tNonOptional =>
12
- switch tNonOptional {
13
- | String(v) => v
14
- | BigInt(v) => v->BigInt.toString
15
- | Int(v) => v->Int.toString
16
- | BigDecimal(v) => v->BigDecimal.toString
17
- | Bool(v) => v ? "true" : "false"
18
- | Array(v) => `[${v->Belt.Array.joinWith(",", toString)}]`
19
- }
20
-
21
- //This needs to be a castable type from any type that we
22
- //support in entities so that we can create evaluations
23
- //and serialize the types without parsing/wrapping them
24
- type t = option<tNonOptional>
25
-
26
- let toString = (value: t) =>
27
- switch value {
28
- | Some(v) => v->toString
29
- | None => "undefined"
30
- }
31
-
32
- external castFrom: 'a => t = "%identity"
33
- external castTo: t => 'a = "%identity"
34
-
35
- let eq = (a, b) =>
36
- switch (a, b) {
37
- //For big decimal use custom equals operator otherwise let Caml_obj.equal do its magic
38
- | (Some(BigDecimal(bdA)), Some(BigDecimal(bdB))) => BigDecimal.equals(bdA, bdB)
39
- | (a, b) => a == b
40
- }
41
-
42
- let gt = (a, b) =>
43
- switch (a, b) {
44
- //For big decimal use custom equals operator otherwise let Caml_obj.equal do its magic
45
- | (Some(BigDecimal(bdA)), Some(BigDecimal(bdB))) => BigDecimal.gt(bdA, bdB)
46
- | (a, b) => a > b
47
- }
48
-
49
- let lt = (a, b) =>
50
- switch (a, b) {
51
- //For big decimal use custom equals operator otherwise let Caml_obj.equal do its magic
52
- | (Some(BigDecimal(bdA)), Some(BigDecimal(bdB))) => BigDecimal.lt(bdA, bdB)
53
- | (a, b) => a < b
54
- }
55
- }
56
-
57
- module Operator = {
58
- type t = Eq | Gt | Lt
59
-
60
- let values = [Eq, Gt, Lt]
61
- }
62
-
63
- module SingleIndex = {
64
- type t = {fieldName: string, fieldValue: FieldValue.t, operator: Operator.t}
65
-
66
- let make = (~fieldName, ~fieldValue: 'a, ~operator) => {
67
- fieldName,
68
- fieldValue: FieldValue.castFrom(fieldValue),
69
- operator,
70
- }
71
-
72
- // Lookups against the in-memory index table reconstruct this key from raw
73
- // (fieldName, operator, serialized value) parts, so this is the single
74
- // source of truth for the key format.
75
- let toStringByParts = (~fieldName, ~operator: Operator.t, ~fieldValueHash) =>
76
- `${fieldName}:${(operator :> string)}:${fieldValueHash}`
77
-
78
- let toString = ({fieldName, fieldValue, operator}) =>
79
- toStringByParts(~fieldName, ~operator, ~fieldValueHash=fieldValue->FieldValue.toString)
80
-
81
- let evaluate = (self: t, ~fieldName, ~fieldValue) =>
82
- self.fieldName === fieldName &&
83
- switch self.operator {
84
- | Eq => fieldValue->FieldValue.eq(self.fieldValue)
85
- | Gt => fieldValue->FieldValue.gt(self.fieldValue)
86
- | Lt => fieldValue->FieldValue.lt(self.fieldValue)
87
- }
88
- }
89
-
90
- module Index = {
91
- //Next step is to support composite indexes
92
- @unboxed
93
- type t = Single(SingleIndex.t) //| Composite(array<SingleIndex.t>)
94
-
95
- let makeSingle = (~fieldName, ~fieldValue, ~operator) => Single(
96
- SingleIndex.make(~fieldName, ~fieldValue, ~operator),
97
- )
98
-
99
- let getFieldName = index =>
100
- switch index {
101
- | Single(index) => index.fieldName
102
- }
103
-
104
- let toString = index =>
105
- switch index {
106
- | Single(index) => index->SingleIndex.toString
107
- }
108
-
109
- let toStringByParts = SingleIndex.toStringByParts
110
-
111
- let evaluate = (index: t, ~fieldName, ~fieldValue) =>
112
- switch index {
113
- | Single(index) => SingleIndex.evaluate(index, ~fieldName, ~fieldValue)
114
- }
115
- }