@proto-kit/common 0.1.1-develop.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 (150) hide show
  1. package/LICENSE.md +201 -0
  2. package/dist/compiling/AtomicCompileHelper.d.ts +13 -0
  3. package/dist/compiling/AtomicCompileHelper.d.ts.map +1 -0
  4. package/dist/compiling/AtomicCompileHelper.js +40 -0
  5. package/dist/compiling/AtomicCompileHelper.js.map +1 -0
  6. package/dist/compiling/CompilableModule.d.ts +6 -0
  7. package/dist/compiling/CompilableModule.d.ts.map +1 -0
  8. package/dist/compiling/CompilableModule.js +2 -0
  9. package/dist/compiling/CompilableModule.js.map +1 -0
  10. package/dist/compiling/CompileRegistry.d.ts +26 -0
  11. package/dist/compiling/CompileRegistry.d.ts.map +1 -0
  12. package/dist/compiling/CompileRegistry.js +68 -0
  13. package/dist/compiling/CompileRegistry.js.map +1 -0
  14. package/dist/compiling/services/ChildVerificationKeyService.d.ts +10 -0
  15. package/dist/compiling/services/ChildVerificationKeyService.d.ts.map +1 -0
  16. package/dist/compiling/services/ChildVerificationKeyService.js +27 -0
  17. package/dist/compiling/services/ChildVerificationKeyService.js.map +1 -0
  18. package/dist/config/ChildContainerCreatable.d.ts +5 -0
  19. package/dist/config/ChildContainerCreatable.d.ts.map +1 -0
  20. package/dist/config/ChildContainerCreatable.js +2 -0
  21. package/dist/config/ChildContainerCreatable.js.map +1 -0
  22. package/dist/config/ChildContainerProvider.d.ts +5 -0
  23. package/dist/config/ChildContainerProvider.d.ts.map +1 -0
  24. package/dist/config/ChildContainerProvider.js +2 -0
  25. package/dist/config/ChildContainerProvider.js.map +1 -0
  26. package/dist/config/ConfigurableModule.d.ts +25 -0
  27. package/dist/config/ConfigurableModule.d.ts.map +1 -0
  28. package/dist/config/ConfigurableModule.js +24 -0
  29. package/dist/config/ConfigurableModule.js.map +1 -0
  30. package/dist/config/ModuleContainer.d.ts +162 -0
  31. package/dist/config/ModuleContainer.d.ts.map +1 -0
  32. package/dist/config/ModuleContainer.js +289 -0
  33. package/dist/config/ModuleContainer.js.map +1 -0
  34. package/dist/config/injectAlias.d.ts +18 -0
  35. package/dist/config/injectAlias.d.ts.map +1 -0
  36. package/dist/config/injectAlias.js +47 -0
  37. package/dist/config/injectAlias.js.map +1 -0
  38. package/dist/dependencyFactory/DependencyFactory.d.ts +29 -0
  39. package/dist/dependencyFactory/DependencyFactory.d.ts.map +1 -0
  40. package/dist/dependencyFactory/DependencyFactory.js +2 -0
  41. package/dist/dependencyFactory/DependencyFactory.js.map +1 -0
  42. package/dist/dependencyFactory/injectOptional.d.ts +16 -0
  43. package/dist/dependencyFactory/injectOptional.d.ts.map +1 -0
  44. package/dist/dependencyFactory/injectOptional.js +40 -0
  45. package/dist/dependencyFactory/injectOptional.js.map +1 -0
  46. package/dist/dummyVerificationKey.d.ts +3 -0
  47. package/dist/dummyVerificationKey.d.ts.map +1 -0
  48. package/dist/dummyVerificationKey.js +8 -0
  49. package/dist/dummyVerificationKey.js.map +1 -0
  50. package/dist/events/EventEmitter.d.ts +19 -0
  51. package/dist/events/EventEmitter.d.ts.map +1 -0
  52. package/dist/events/EventEmitter.js +35 -0
  53. package/dist/events/EventEmitter.js.map +1 -0
  54. package/dist/events/EventEmitterProxy.d.ts +18 -0
  55. package/dist/events/EventEmitterProxy.d.ts.map +1 -0
  56. package/dist/events/EventEmitterProxy.js +35 -0
  57. package/dist/events/EventEmitterProxy.js.map +1 -0
  58. package/dist/events/EventEmittingComponent.d.ts +9 -0
  59. package/dist/events/EventEmittingComponent.d.ts.map +1 -0
  60. package/dist/events/EventEmittingComponent.js +2 -0
  61. package/dist/events/EventEmittingComponent.js.map +1 -0
  62. package/dist/events/ReplayingSingleUseEventEmitter.d.ts +17 -0
  63. package/dist/events/ReplayingSingleUseEventEmitter.d.ts.map +1 -0
  64. package/dist/events/ReplayingSingleUseEventEmitter.js +34 -0
  65. package/dist/events/ReplayingSingleUseEventEmitter.js.map +1 -0
  66. package/dist/index.d.ts +26 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +26 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/log.d.ts +37 -0
  71. package/dist/log.d.ts.map +1 -0
  72. package/dist/log.js +114 -0
  73. package/dist/log.js.map +1 -0
  74. package/dist/trees/InMemoryMerkleTreeStorage.d.ts +11 -0
  75. package/dist/trees/InMemoryMerkleTreeStorage.d.ts.map +1 -0
  76. package/dist/trees/InMemoryMerkleTreeStorage.js +13 -0
  77. package/dist/trees/InMemoryMerkleTreeStorage.js.map +1 -0
  78. package/dist/trees/MerkleTreeStore.d.ts +5 -0
  79. package/dist/trees/MerkleTreeStore.d.ts.map +1 -0
  80. package/dist/trees/MerkleTreeStore.js +2 -0
  81. package/dist/trees/MerkleTreeStore.js.map +1 -0
  82. package/dist/trees/MockAsyncMerkleStore.d.ts +9 -0
  83. package/dist/trees/MockAsyncMerkleStore.d.ts.map +1 -0
  84. package/dist/trees/MockAsyncMerkleStore.js +20 -0
  85. package/dist/trees/MockAsyncMerkleStore.js.map +1 -0
  86. package/dist/trees/RollupMerkleTree.d.ts +147 -0
  87. package/dist/trees/RollupMerkleTree.d.ts.map +1 -0
  88. package/dist/trees/RollupMerkleTree.js +218 -0
  89. package/dist/trees/RollupMerkleTree.js.map +1 -0
  90. package/dist/trees/VirtualMerkleTreeStore.d.ts +13 -0
  91. package/dist/trees/VirtualMerkleTreeStore.d.ts.map +1 -0
  92. package/dist/trees/VirtualMerkleTreeStore.js +18 -0
  93. package/dist/trees/VirtualMerkleTreeStore.js.map +1 -0
  94. package/dist/types.d.ts +27 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +12 -0
  97. package/dist/types.js.map +1 -0
  98. package/dist/utils.d.ts +48 -0
  99. package/dist/utils.d.ts.map +1 -0
  100. package/dist/utils.js +113 -0
  101. package/dist/utils.js.map +1 -0
  102. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts +54 -0
  103. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts.map +1 -0
  104. package/dist/zkProgrammable/ProvableMethodExecutionContext.js +97 -0
  105. package/dist/zkProgrammable/ProvableMethodExecutionContext.js.map +1 -0
  106. package/dist/zkProgrammable/ZkProgrammable.d.ts +40 -0
  107. package/dist/zkProgrammable/ZkProgrammable.d.ts.map +1 -0
  108. package/dist/zkProgrammable/ZkProgrammable.js +79 -0
  109. package/dist/zkProgrammable/ZkProgrammable.js.map +1 -0
  110. package/dist/zkProgrammable/provableMethod.d.ts +19 -0
  111. package/dist/zkProgrammable/provableMethod.d.ts.map +1 -0
  112. package/dist/zkProgrammable/provableMethod.js +71 -0
  113. package/dist/zkProgrammable/provableMethod.js.map +1 -0
  114. package/jest.config.cjs +12 -0
  115. package/package.json +34 -0
  116. package/src/compiling/AtomicCompileHelper.ts +62 -0
  117. package/src/compiling/CompilableModule.ts +6 -0
  118. package/src/compiling/CompileRegistry.ts +78 -0
  119. package/src/compiling/services/ChildVerificationKeyService.ts +26 -0
  120. package/src/config/ChildContainerCreatable.ts +5 -0
  121. package/src/config/ChildContainerProvider.ts +5 -0
  122. package/src/config/ConfigurableModule.ts +57 -0
  123. package/src/config/ModuleContainer.ts +487 -0
  124. package/src/config/injectAlias.ts +70 -0
  125. package/src/dependencyFactory/DependencyFactory.ts +57 -0
  126. package/src/dependencyFactory/injectOptional.ts +41 -0
  127. package/src/dummyVerificationKey.ts +10 -0
  128. package/src/events/EventEmitter.ts +61 -0
  129. package/src/events/EventEmitterProxy.ts +83 -0
  130. package/src/events/EventEmittingComponent.ts +11 -0
  131. package/src/events/ReplayingSingleUseEventEmitter.ts +42 -0
  132. package/src/index.ts +25 -0
  133. package/src/log.ts +143 -0
  134. package/src/trees/InMemoryMerkleTreeStorage.ts +17 -0
  135. package/src/trees/MerkleTreeStore.ts +5 -0
  136. package/src/trees/MockAsyncMerkleStore.ts +30 -0
  137. package/src/trees/RollupMerkleTree.ts +356 -0
  138. package/src/trees/VirtualMerkleTreeStore.ts +20 -0
  139. package/src/types.ts +58 -0
  140. package/src/utils.ts +200 -0
  141. package/src/zkProgrammable/ProvableMethodExecutionContext.ts +122 -0
  142. package/src/zkProgrammable/ZkProgrammable.ts +151 -0
  143. package/src/zkProgrammable/provableMethod.ts +124 -0
  144. package/test/config/ContainerEvents.test.ts +67 -0
  145. package/test/config/ModuleContainer.test.ts +215 -0
  146. package/test/config/injectAlias.test.ts +28 -0
  147. package/test/trees/MerkleTree.test.ts +106 -0
  148. package/test/tsconfig.json +7 -0
  149. package/test/zkProgrammable/ZkProgrammable.test.ts +304 -0
  150. package/tsconfig.json +8 -0
@@ -0,0 +1,41 @@
1
+ import {
2
+ container,
3
+ injectable,
4
+ injectWithTransform,
5
+ Lifecycle,
6
+ scoped,
7
+ } from "tsyringe";
8
+
9
+ @injectable()
10
+ @scoped(Lifecycle.ResolutionScoped)
11
+ class UndefinedDisguise {}
12
+
13
+ class UndefinedTransform<Dependency> {
14
+ public transform(
15
+ incoming: Dependency | UndefinedDisguise
16
+ ): Dependency | undefined {
17
+ if (incoming instanceof UndefinedDisguise) {
18
+ return undefined;
19
+ }
20
+ return incoming;
21
+ }
22
+ }
23
+
24
+ /**
25
+ * This function injects a dependency only if it has been registered, otherwise
26
+ * injects undefined. This can be useful for having optional dependencies, where
27
+ * tsyringe would normally error out and not be able to resolve. With this
28
+ * decorator, we can now do this.
29
+ *
30
+ * The strategy we employ here is that we inject a dummy into the global
31
+ * container that is of type UndefinedDisguise. We can't inject undefined
32
+ * directly, therefore we use this object to disguise itself as undefined.
33
+ * Then a child container registers something under the same token, it by
34
+ * default resolves that new dependency. If that doesn't happen, the
35
+ * resolution hits our disguise, which we then convert into undefined
36
+ * using the Transform
37
+ */
38
+ export function injectOptional<T>(token: string) {
39
+ container.register(token, { useClass: UndefinedDisguise });
40
+ return injectWithTransform(token, UndefinedTransform<T>);
41
+ }
@@ -0,0 +1,10 @@
1
+ import { Field, VerificationKey } from "o1js";
2
+
3
+ export function dummyVerificationKey() {
4
+ return new VerificationKey({
5
+ hash: Field(
6
+ "3392518251768960475377392625298437850623664973002200885669375116181514017494"
7
+ ),
8
+ data: "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",
9
+ });
10
+ }
@@ -0,0 +1,61 @@
1
+ import { EventsRecord } from "./EventEmittingComponent";
2
+
3
+ type ListenersHolder<Events extends EventsRecord> = {
4
+ [key in keyof Events]?: ((...args: Events[key]) => void)[];
5
+ };
6
+
7
+ export class EventEmitter<Events extends EventsRecord> {
8
+ protected readonly listeners: ListenersHolder<Events> = {};
9
+
10
+ protected readonly wildcardListeners: ((
11
+ event: keyof Events,
12
+ args: Events[keyof Events]
13
+ ) => void)[] = [];
14
+
15
+ public emit<Key extends keyof Events>(
16
+ event: Key,
17
+ ...parameters: Events[Key]
18
+ ) {
19
+ const listeners = this.listeners[event];
20
+ if (listeners !== undefined) {
21
+ listeners.forEach((listener) => {
22
+ listener(...parameters);
23
+ });
24
+ }
25
+ this.wildcardListeners.forEach((wildcardListener) => {
26
+ wildcardListener(event, parameters);
27
+ });
28
+ }
29
+
30
+ public onAll(listener: (event: keyof Events, args: unknown[]) => void): void {
31
+ this.wildcardListeners.push(listener);
32
+ }
33
+
34
+ public on<Key extends keyof Events>(
35
+ event: Key,
36
+ listener: (...args: Events[Key]) => void
37
+ ) {
38
+ (this.listeners[event] ??= []).push(listener);
39
+ }
40
+
41
+ /**
42
+ * Primitive .off() with identity comparison for now.
43
+ * Could be replaced by returning an id in .on() and using that.
44
+ */
45
+ public off<Key extends keyof Events>(
46
+ event: Key,
47
+ listener: (...args: Events[Key]) => void
48
+ ) {
49
+ const events = this.listeners[event];
50
+ if (events !== undefined) {
51
+ this.listeners[event] = events.filter(
52
+ (candidate) => candidate !== listener
53
+ );
54
+ }
55
+ }
56
+ }
57
+
58
+ export type EventListenable<Events extends EventsRecord> = Pick<
59
+ EventEmitter<Events>,
60
+ "on" | "onAll" | "off"
61
+ >;
@@ -0,0 +1,83 @@
1
+ import type {
2
+ BaseModuleType,
3
+ ModuleContainer,
4
+ ModulesRecord,
5
+ } from "../config/ModuleContainer";
6
+ import { StringKeyOf, UnionToIntersection } from "../types";
7
+
8
+ import { EventEmitter } from "./EventEmitter";
9
+ import {
10
+ EventEmittingComponent,
11
+ EventEmittingContainer,
12
+ EventsRecord,
13
+ } from "./EventEmittingComponent";
14
+
15
+ export type CastToEventsRecord<Record> = Record extends EventsRecord
16
+ ? Record
17
+ : {};
18
+
19
+ export type ModuleEvents<ModuleType extends BaseModuleType> =
20
+ InstanceType<ModuleType> extends EventEmittingComponent<infer Events>
21
+ ? Events
22
+ : InstanceType<ModuleType> extends ModuleContainer<infer NestedModules>
23
+ ? CastToEventsRecord<ContainerEvents<NestedModules>>
24
+ : // &
25
+ // (InstanceType<ModuleType> extends EventEmittingContainer<
26
+ // infer ContainerEvents
27
+ // >
28
+ // ? ContainerEvents
29
+ // : {})
30
+ EventsRecord;
31
+
32
+ export type ContainerEvents<Modules extends ModulesRecord> = {
33
+ [Key in StringKeyOf<Modules>]: ModuleEvents<Modules[Key]>;
34
+ };
35
+
36
+ export type FlattenObject<Target extends Record<string, EventsRecord>> =
37
+ UnionToIntersection<Target[keyof Target]>;
38
+
39
+ export type FlattenedContainerEvents<Modules extends ModulesRecord> =
40
+ FlattenObject<ContainerEvents<Modules>>; // & FlattenObject<any>;
41
+
42
+ export class EventEmitterProxy<
43
+ Modules extends ModulesRecord,
44
+ > extends EventEmitter<CastToEventsRecord<FlattenedContainerEvents<Modules>>> {
45
+ public constructor(private readonly container: ModuleContainer<Modules>) {
46
+ super();
47
+ container.moduleNames.forEach((moduleName) => {
48
+ if (
49
+ container.isValidModuleName(container.definition.modules, moduleName)
50
+ ) {
51
+ const module = container.resolve(moduleName);
52
+ if (this.isEventEmitter(module)) {
53
+ module.events.onAll((events: any, args: any[]) => {
54
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
55
+ this.emit(events, ...args);
56
+ });
57
+ }
58
+ if (this.isEventEmittingContainer(module)) {
59
+ module.containerEvents.onAll((events: any, args: any[]) => {
60
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
61
+ this.emit(events, ...args);
62
+ });
63
+ }
64
+ }
65
+ });
66
+ }
67
+
68
+ private isEventEmittingContainer(
69
+ module: any
70
+ ): module is EventEmittingContainer<EventsRecord> {
71
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
72
+ const emitter = module.containerEvents;
73
+ return emitter !== undefined && emitter instanceof EventEmitter;
74
+ }
75
+
76
+ private isEventEmitter(
77
+ module: any
78
+ ): module is EventEmittingComponent<EventsRecord> {
79
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
80
+ const emitter = module.events;
81
+ return emitter !== undefined && emitter instanceof EventEmitter;
82
+ }
83
+ }
@@ -0,0 +1,11 @@
1
+ import type { EventEmitter } from "./EventEmitter";
2
+
3
+ export type EventsRecord = Record<string, unknown[]>;
4
+
5
+ export interface EventEmittingComponent<Events extends EventsRecord> {
6
+ events: EventEmitter<Events>;
7
+ }
8
+
9
+ export interface EventEmittingContainer<Events extends EventsRecord> {
10
+ containerEvents: EventEmitter<Events>;
11
+ }
@@ -0,0 +1,42 @@
1
+ import { EventsRecord } from "./EventEmittingComponent";
2
+ import { EventEmitter } from "./EventEmitter";
3
+
4
+ /**
5
+ * Event Emitter variant that emits a certain event only once to a registered listener.
6
+ * Additionally, if a listener registers to a event that has already been emitted, it
7
+ * re-emits it to said listener.
8
+ * This pattern is especially useful for listening for inclusions of transactions.
9
+ * Those events will only occur once, and listeners could come too late to the party,
10
+ * so we need to make sure they get notified as well in those cases.
11
+ */
12
+ export class ReplayingSingleUseEventEmitter<
13
+ Events extends EventsRecord,
14
+ > extends EventEmitter<Events> {
15
+ public emitted: Partial<Events> = {};
16
+
17
+ public emit<Key extends keyof Events>(
18
+ event: Key,
19
+ ...parameters: Events[Key]
20
+ ) {
21
+ super.emit(event, ...parameters);
22
+ this.emitted[event] = parameters;
23
+ this.listeners[event] = [];
24
+ }
25
+
26
+ public onAll(listener: (event: keyof Events, args: unknown[]) => void) {
27
+ Object.entries(this.emitted).forEach(([key, params]) => {
28
+ if (params !== undefined) listener(key, params);
29
+ });
30
+ super.onAll(listener);
31
+ }
32
+
33
+ public on<Key extends keyof Events>(
34
+ event: Key,
35
+ listener: (...args: Events[Key]) => void
36
+ ) {
37
+ if (this.emitted[event] !== undefined) {
38
+ listener(...this.emitted[event]!);
39
+ }
40
+ super.on(event, listener);
41
+ }
42
+ }
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ export * from "./config/ModuleContainer";
2
+ export * from "./config/ConfigurableModule";
3
+ export * from "./config/ChildContainerProvider";
4
+ export * from "./config/ChildContainerCreatable";
5
+ export * from "./types";
6
+ export * from "./zkProgrammable/ZkProgrammable";
7
+ export * from "./zkProgrammable/ProvableMethodExecutionContext";
8
+ export * from "./zkProgrammable/provableMethod";
9
+ export * from "./utils";
10
+ export * from "./dependencyFactory/DependencyFactory";
11
+ export * from "./dependencyFactory/injectOptional";
12
+ export * from "./log";
13
+ export * from "./events/EventEmittingComponent";
14
+ export * from "./events/EventEmitter";
15
+ export * from "./trees/MerkleTreeStore";
16
+ export * from "./trees/InMemoryMerkleTreeStorage";
17
+ export * from "./trees/RollupMerkleTree";
18
+ export * from "./events/EventEmitterProxy";
19
+ export * from "./events/ReplayingSingleUseEventEmitter";
20
+ export * from "./trees/MockAsyncMerkleStore";
21
+ export * from "./compiling/AtomicCompileHelper";
22
+ export * from "./compiling/CompileRegistry";
23
+ export * from "./compiling/CompilableModule";
24
+ export * from "./compiling/services/ChildVerificationKeyService";
25
+ export * from "./config/injectAlias";
package/src/log.ts ADDED
@@ -0,0 +1,143 @@
1
+ import loglevel, { LogLevelDesc, LogLevelNames } from "loglevel";
2
+ import { Provable } from "o1js";
3
+
4
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
5
+ function logProvable(
6
+ logFunction: (...args: unknown[]) => void,
7
+ ...args: any[]
8
+ ) {
9
+ Provable.asProver(() => {
10
+ const prettyArguments: string[] = [];
11
+
12
+ args.forEach((argument) => {
13
+ if (argument?.toPretty !== undefined) {
14
+ prettyArguments.push(argument.toPretty());
15
+ } else {
16
+ try {
17
+ prettyArguments.push(JSON.parse(JSON.stringify(argument)));
18
+ } catch {
19
+ prettyArguments.push(argument);
20
+ }
21
+ }
22
+ });
23
+ logFunction(...prettyArguments);
24
+ });
25
+ }
26
+ /* eslint-enable */
27
+
28
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
29
+ if (process.env?.IN_CI ?? false) {
30
+ loglevel.setLevel("ERROR");
31
+ }
32
+
33
+ const timeMap: Record<string, number> = {};
34
+
35
+ function time(label = "time") {
36
+ timeMap[label] = Date.now();
37
+ }
38
+
39
+ function timeLog(label = "time"): string {
40
+ const prev = timeMap[label];
41
+ if (prev === undefined) {
42
+ return "Label not found";
43
+ }
44
+ return `${label} took ${Date.now() - prev}ms`;
45
+ }
46
+
47
+ function timeEnd(label = "time"): string {
48
+ const str = timeLog(label);
49
+ delete timeMap[label];
50
+ return str;
51
+ }
52
+
53
+ export const log = {
54
+ provable: {
55
+ info: (...args: unknown[]) => {
56
+ logProvable(loglevel.info, ...args);
57
+ },
58
+
59
+ debug: (...args: unknown[]) => {
60
+ logProvable(loglevel.debug, ...args);
61
+ },
62
+
63
+ error: (...args: unknown[]) => {
64
+ logProvable(loglevel.error, ...args);
65
+ },
66
+
67
+ trace: (...args: unknown[]) => {
68
+ logProvable(log.trace, ...args);
69
+ },
70
+
71
+ warn: (...args: unknown[]) => {
72
+ logProvable(loglevel.warn, ...args);
73
+ },
74
+ },
75
+
76
+ time,
77
+
78
+ timeLog: {
79
+ info: (label?: string) => loglevel.info(timeLog(label)),
80
+ debug: (label?: string) => loglevel.debug(timeLog(label)),
81
+ error: (label?: string) => loglevel.error(timeLog(label)),
82
+ trace: (label?: string) => loglevel.trace(timeLog(label)),
83
+ warn: (label?: string) => loglevel.warn(timeLog(label)),
84
+ },
85
+
86
+ timeEnd: {
87
+ info: (label?: string) => loglevel.info(timeEnd(label)),
88
+ debug: (label?: string) => loglevel.debug(timeEnd(label)),
89
+ error: (label?: string) => loglevel.error(timeEnd(label)),
90
+ trace: (label?: string) => loglevel.trace(timeEnd(label)),
91
+ warn: (label?: string) => loglevel.warn(timeEnd(label)),
92
+ },
93
+
94
+ info: (...args: unknown[]) => {
95
+ loglevel.info(...args);
96
+ },
97
+
98
+ debug: (...args: unknown[]) => {
99
+ loglevel.debug(...args);
100
+ },
101
+
102
+ error: (...args: unknown[]) => {
103
+ loglevel.error(...args);
104
+ },
105
+
106
+ trace: (...args: unknown[]) => {
107
+ // Loglevel prints the stack trace by default. To still be able to use trace
108
+ // inside out application, we use the level, but call debug() under the hood
109
+ if (loglevel.getLevel() <= loglevel.levels.TRACE) {
110
+ loglevel.debug(...args);
111
+ }
112
+ },
113
+
114
+ warn: (...args: unknown[]) => {
115
+ loglevel.warn(...args);
116
+ },
117
+
118
+ setLevel: (level: LogLevelDesc) => {
119
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
120
+ if (!(process.env?.IN_CI ?? false)) {
121
+ loglevel.setLevel(level);
122
+ }
123
+ },
124
+
125
+ get levels() {
126
+ return loglevel.levels;
127
+ },
128
+
129
+ getLevel: () => loglevel.getLevel(),
130
+ };
131
+
132
+ const validLogLevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "SILENT"];
133
+
134
+ export function assertValidTextLogLevel(
135
+ level: string | number
136
+ ): asserts level is LogLevelNames {
137
+ if (
138
+ typeof level === "number" ||
139
+ !validLogLevels.includes(level.toUpperCase())
140
+ ) {
141
+ throw new Error(`${level} is not a valid loglevel`);
142
+ }
143
+ }
@@ -0,0 +1,17 @@
1
+ import { MerkleTreeStore } from "./MerkleTreeStore";
2
+
3
+ export class InMemoryMerkleTreeStorage implements MerkleTreeStore {
4
+ protected nodes: {
5
+ [key: number]: {
6
+ [key: string]: bigint;
7
+ };
8
+ } = {};
9
+
10
+ public getNode(key: bigint, level: number): bigint | undefined {
11
+ return this.nodes[level]?.[key.toString()];
12
+ }
13
+
14
+ public setNode(key: bigint, level: number, value: bigint): void {
15
+ (this.nodes[level] ??= {})[key.toString()] = value;
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ export interface MerkleTreeStore {
2
+ setNode: (key: bigint, level: number, value: bigint) => void;
3
+
4
+ getNode: (key: bigint, level: number) => bigint | undefined;
5
+ }
@@ -0,0 +1,30 @@
1
+ import { noop } from "../utils";
2
+
3
+ import { InMemoryMerkleTreeStorage } from "./InMemoryMerkleTreeStorage";
4
+
5
+ export class MockAsyncMerkleTreeStore {
6
+ public readonly store = new InMemoryMerkleTreeStorage();
7
+
8
+ public commit(): void {
9
+ noop();
10
+ }
11
+
12
+ public openTransaction(): void {
13
+ noop();
14
+ }
15
+
16
+ public async getNodeAsync(
17
+ key: bigint,
18
+ level: number
19
+ ): Promise<bigint | undefined> {
20
+ return this.store.getNode(key, level);
21
+ }
22
+
23
+ public async setNodeAsync(
24
+ key: bigint,
25
+ level: number,
26
+ value: bigint
27
+ ): Promise<void> {
28
+ this.store.setNode(key, level, value);
29
+ }
30
+ }