@proto-kit/common 0.1.1-develop.1086

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 (96) hide show
  1. package/LICENSE.md +201 -0
  2. package/dist/config/ChildContainerCreatable.d.ts +5 -0
  3. package/dist/config/ChildContainerCreatable.d.ts.map +1 -0
  4. package/dist/config/ChildContainerCreatable.js +1 -0
  5. package/dist/config/ChildContainerProvider.d.ts +5 -0
  6. package/dist/config/ChildContainerProvider.d.ts.map +1 -0
  7. package/dist/config/ChildContainerProvider.js +1 -0
  8. package/dist/config/ConfigurableModule.d.ts +25 -0
  9. package/dist/config/ConfigurableModule.d.ts.map +1 -0
  10. package/dist/config/ConfigurableModule.js +23 -0
  11. package/dist/config/ModuleContainer.d.ts +161 -0
  12. package/dist/config/ModuleContainer.d.ts.map +1 -0
  13. package/dist/config/ModuleContainer.js +278 -0
  14. package/dist/dependencyFactory/DependencyFactory.d.ts +29 -0
  15. package/dist/dependencyFactory/DependencyFactory.d.ts.map +1 -0
  16. package/dist/dependencyFactory/DependencyFactory.js +1 -0
  17. package/dist/dependencyFactory/injectOptional.d.ts +16 -0
  18. package/dist/dependencyFactory/injectOptional.d.ts.map +1 -0
  19. package/dist/dependencyFactory/injectOptional.js +39 -0
  20. package/dist/events/EventEmitter.d.ts +19 -0
  21. package/dist/events/EventEmitter.d.ts.map +1 -0
  22. package/dist/events/EventEmitter.js +34 -0
  23. package/dist/events/EventEmitterProxy.d.ts +17 -0
  24. package/dist/events/EventEmitterProxy.d.ts.map +1 -0
  25. package/dist/events/EventEmitterProxy.js +23 -0
  26. package/dist/events/EventEmittingComponent.d.ts +6 -0
  27. package/dist/events/EventEmittingComponent.d.ts.map +1 -0
  28. package/dist/events/EventEmittingComponent.js +1 -0
  29. package/dist/index.d.ts +20 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +19 -0
  32. package/dist/log.d.ts +20 -0
  33. package/dist/log.d.ts.map +1 -0
  34. package/dist/log.js +75 -0
  35. package/dist/test/equalProvable.d.ts +20 -0
  36. package/dist/test/equalProvable.d.ts.map +1 -0
  37. package/dist/test/equalProvable.js +13 -0
  38. package/dist/trees/InMemoryMerkleTreeStorage.d.ts +11 -0
  39. package/dist/trees/InMemoryMerkleTreeStorage.d.ts.map +1 -0
  40. package/dist/trees/InMemoryMerkleTreeStorage.js +12 -0
  41. package/dist/trees/MerkleTreeStore.d.ts +5 -0
  42. package/dist/trees/MerkleTreeStore.d.ts.map +1 -0
  43. package/dist/trees/MerkleTreeStore.js +1 -0
  44. package/dist/trees/MockAsyncMerkleStore.d.ts +9 -0
  45. package/dist/trees/MockAsyncMerkleStore.d.ts.map +1 -0
  46. package/dist/trees/MockAsyncMerkleStore.js +19 -0
  47. package/dist/trees/RollupMerkleTree.d.ts +147 -0
  48. package/dist/trees/RollupMerkleTree.d.ts.map +1 -0
  49. package/dist/trees/RollupMerkleTree.js +217 -0
  50. package/dist/trees/VirtualMerkleTreeStore.d.ts +13 -0
  51. package/dist/trees/VirtualMerkleTreeStore.d.ts.map +1 -0
  52. package/dist/trees/VirtualMerkleTreeStore.js +17 -0
  53. package/dist/types.d.ts +26 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +11 -0
  56. package/dist/utils.d.ts +35 -0
  57. package/dist/utils.d.ts.map +1 -0
  58. package/dist/utils.js +73 -0
  59. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts +54 -0
  60. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts.map +1 -0
  61. package/dist/zkProgrammable/ProvableMethodExecutionContext.js +96 -0
  62. package/dist/zkProgrammable/ZkProgrammable.d.ts +39 -0
  63. package/dist/zkProgrammable/ZkProgrammable.d.ts.map +1 -0
  64. package/dist/zkProgrammable/ZkProgrammable.js +67 -0
  65. package/dist/zkProgrammable/provableMethod.d.ts +19 -0
  66. package/dist/zkProgrammable/provableMethod.d.ts.map +1 -0
  67. package/dist/zkProgrammable/provableMethod.js +73 -0
  68. package/jest.config.cjs +1 -0
  69. package/package.json +34 -0
  70. package/src/config/ChildContainerCreatable.ts +5 -0
  71. package/src/config/ChildContainerProvider.ts +5 -0
  72. package/src/config/ConfigurableModule.ts +57 -0
  73. package/src/config/ModuleContainer.ts +472 -0
  74. package/src/dependencyFactory/DependencyFactory.ts +57 -0
  75. package/src/dependencyFactory/injectOptional.ts +41 -0
  76. package/src/events/EventEmitter.ts +61 -0
  77. package/src/events/EventEmitterProxy.ts +59 -0
  78. package/src/events/EventEmittingComponent.ts +7 -0
  79. package/src/index.ts +19 -0
  80. package/src/log.ts +97 -0
  81. package/src/trees/InMemoryMerkleTreeStorage.ts +17 -0
  82. package/src/trees/MerkleTreeStore.ts +5 -0
  83. package/src/trees/MockAsyncMerkleStore.ts +30 -0
  84. package/src/trees/RollupMerkleTree.ts +356 -0
  85. package/src/trees/VirtualMerkleTreeStore.ts +20 -0
  86. package/src/types.ts +49 -0
  87. package/src/utils.ts +149 -0
  88. package/src/zkProgrammable/ProvableMethodExecutionContext.ts +122 -0
  89. package/src/zkProgrammable/ZkProgrammable.ts +131 -0
  90. package/src/zkProgrammable/provableMethod.ts +123 -0
  91. package/test/config/ContainerEvents.test.ts +67 -0
  92. package/test/config/ModuleContainer.test.ts +172 -0
  93. package/test/trees/MerkleTree.test.ts +106 -0
  94. package/test/tsconfig.json +7 -0
  95. package/test/zkProgrammable/ZkProgrammable.test.ts +304 -0
  96. package/tsconfig.json +8 -0
@@ -0,0 +1,278 @@
1
+ import "reflect-metadata";
2
+ import { instancePerContainerCachingFactory, isClassProvider, isFactoryProvider, isTokenProvider, isValueProvider, Lifecycle, } from "tsyringe";
3
+ import log from "loglevel";
4
+ import merge from "lodash/merge";
5
+ import { EventEmitterProxy } from "../events/EventEmitterProxy";
6
+ import { ConfigurableModule, } from "./ConfigurableModule";
7
+ const errors = {
8
+ configNotSetInContainer: (moduleName) => new Error(`Trying to get config of ${moduleName}, but it was not yet set in the module container`),
9
+ onlyValidModuleNames: (moduleName) => new Error(
10
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
11
+ `Only known module names are allowed, using unknown module name: ${moduleName}`),
12
+ unableToDecorateModule: (moduleName) =>
13
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
14
+ new Error(`Unable to decorate module ${moduleName.toString()}`),
15
+ nonModuleDependency: (runtimeModuleName) => new Error(`
16
+ Unable to register module: ${runtimeModuleName}, attempting to inject a non-module dependency`),
17
+ unknownDependency: (runtimeModuleName, name) => new Error(`Unable to register module: ${runtimeModuleName},
18
+ attempting to inject a dependency that is not registered
19
+ as a runtime module for this chain: ${name}`),
20
+ dependencyContainerNotSet: (className) => new Error(`DependencyContainer not set. Be sure to only call DI-related function in create() and not inside the constructor. (${className})`),
21
+ validModuleInstance: (moduleName, moduleTypeName) => new Error(`Incompatible module instance ("${moduleName}" not instanceof ${moduleTypeName})`),
22
+ };
23
+ export const ModuleContainerErrors = errors;
24
+ /**
25
+ * Reusable module container facilitating registration, resolution
26
+ * configuration, decoration and validation of modules
27
+ */
28
+ export class ModuleContainer extends ConfigurableModule {
29
+ constructor(definition) {
30
+ super();
31
+ this.definition = definition;
32
+ // DI container holding all the registered modules
33
+ this.providedContainer = undefined;
34
+ this.eventEmitterProxy = undefined;
35
+ }
36
+ /**
37
+ * @returns list of module names
38
+ */
39
+ get moduleNames() {
40
+ return Object.keys(this.definition.modules);
41
+ }
42
+ /**
43
+ * Check if the provided module satisfies the container requirements,
44
+ * such as only injecting other known modules.
45
+ *
46
+ * @param moduleName
47
+ * @param containedModule
48
+ */
49
+ validateModule(moduleName, containedModule) {
50
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
51
+ const dependencies = Reflect.getMetadata("design:paramtypes", containedModule);
52
+ dependencies?.forEach((dependency) => {
53
+ const name = typeof dependency === "string" ? dependency : dependency.name;
54
+ if (name === undefined) {
55
+ throw errors.nonModuleDependency(moduleName);
56
+ }
57
+ if (!this.moduleNames.includes(name)) {
58
+ throw errors.unknownDependency(moduleName, name);
59
+ }
60
+ });
61
+ }
62
+ get container() {
63
+ this.assertContainerInitialized(this.providedContainer);
64
+ return this.providedContainer;
65
+ }
66
+ /**
67
+ * Assert that the iterated `moduleName` is of ModuleName type,
68
+ * otherwise it may be just string e.g. when modules are iterated over
69
+ * using e.g. a for loop.
70
+ */
71
+ assertIsValidModuleName(moduleName) {
72
+ if (!this.isValidModuleName(this.definition.modules, moduleName)) {
73
+ throw errors.onlyValidModuleNames(moduleName);
74
+ }
75
+ }
76
+ isValidModuleName(modules, moduleName) {
77
+ return Object.prototype.hasOwnProperty.call(modules, moduleName);
78
+ }
79
+ assertContainerInitialized(container) {
80
+ if (container === undefined) {
81
+ throw errors.dependencyContainerNotSet(this.constructor.name);
82
+ }
83
+ }
84
+ /**
85
+ * Register modules into the current container, and registers
86
+ * a respective resolution hook in order to decorate the module
87
+ * upon/after resolution.
88
+ *
89
+ * @param modules
90
+ */
91
+ registerModules(modules) {
92
+ Object.keys(modules).forEach((moduleName) => {
93
+ if (Object.prototype.hasOwnProperty.call(modules, moduleName)) {
94
+ this.assertIsValidModuleName(moduleName);
95
+ log.debug(`Registering module: ${moduleName}`);
96
+ const useClass = modules[moduleName];
97
+ this.container.register(moduleName, { useClass }, { lifecycle: Lifecycle.ContainerScoped });
98
+ this.onAfterModuleResolution(moduleName);
99
+ }
100
+ });
101
+ }
102
+ get events() {
103
+ if (this.eventEmitterProxy === undefined) {
104
+ this.eventEmitterProxy = new EventEmitterProxy(this);
105
+ }
106
+ return this.eventEmitterProxy;
107
+ }
108
+ /**
109
+ * Register a non-module value into the current container
110
+ * @param modules
111
+ */
112
+ // TODO Rename to plural since object is param
113
+ registerValue(modules) {
114
+ Object.entries(modules).forEach(([moduleName, useValue]) => {
115
+ this.container.register(moduleName, { useValue });
116
+ });
117
+ }
118
+ registerClasses(modules) {
119
+ Object.entries(modules).forEach(([moduleName, useClass]) => {
120
+ this.container.register(moduleName, { useClass }, { lifecycle: Lifecycle.ContainerScoped });
121
+ });
122
+ }
123
+ /**
124
+ * Provide additional configuration after the ModuleContainer was created.
125
+ *
126
+ * Keep in mind that modules are only decorated once after they are resolved,
127
+ * therefore applying any configuration must happen
128
+ * before the first resolution.
129
+ * @param config
130
+ */
131
+ configure(config) {
132
+ this.config = config;
133
+ }
134
+ configurePartial(config) {
135
+ this.config = merge(this.currentConfig ?? {}, config);
136
+ }
137
+ get config() {
138
+ return super.config;
139
+ }
140
+ set config(config) {
141
+ super.config = merge(this.currentConfig ?? {}, config);
142
+ }
143
+ /**
144
+ * Resolves a module from the current module container
145
+ *
146
+ * We have to narrow down the `ModuleName` type here to
147
+ * `ResolvableModuleName`, otherwise the resolved value might
148
+ * be any module instance, not the one specifically requested as argument.
149
+ *
150
+ * @param moduleName
151
+ * @returns
152
+ */
153
+ resolve(moduleName) {
154
+ return this.container.resolve(moduleName);
155
+ }
156
+ resolveOrFail(moduleName, moduleType) {
157
+ const instance = this.container.resolve(moduleName);
158
+ const isValidModuleInstance = instance instanceof moduleType;
159
+ if (!isValidModuleInstance) {
160
+ throw errors.validModuleInstance(moduleName, moduleType.name);
161
+ }
162
+ return instance;
163
+ }
164
+ /**
165
+ * Override this in the child class to provide custom
166
+ * features or module checks
167
+ */
168
+ decorateModule(moduleName, containedModule) {
169
+ const config = super.config?.[moduleName];
170
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
171
+ if (!config) {
172
+ throw errors.configNotSetInContainer(moduleName.toString());
173
+ }
174
+ if (containedModule instanceof ModuleContainer) {
175
+ containedModule.configure(config);
176
+ }
177
+ else {
178
+ containedModule.config = config;
179
+ }
180
+ }
181
+ isDependencyFactory(type) {
182
+ return "dependencies" in type;
183
+ }
184
+ /**
185
+ * Inject a set of dependencies using the given list of DependencyFactories
186
+ * This method should be called during startup
187
+ */
188
+ initializeDependencyFactories(factories) {
189
+ factories.forEach((factoryName) => {
190
+ this.resolve(factoryName);
191
+ });
192
+ }
193
+ /**
194
+ * Retrieves all dependencies generated by a particular dependencyfactory
195
+ * and injects them inside this modulecontainer's DI container.
196
+ * This will be automatically called for every module, but can also be called
197
+ * explicitly to initialize an extra factory
198
+ * @param factory
199
+ * @private
200
+ */
201
+ useDependencyFactory(factory) {
202
+ const dependencies = factory.dependencies();
203
+ Object.entries(dependencies).forEach(([rawKey, declaration]) => {
204
+ const key = rawKey.charAt(0).toUpperCase() + rawKey.slice(1);
205
+ if (!this.container.isRegistered(key) ||
206
+ declaration.forceOverwrite === true) {
207
+ // Find correct provider type and call respective register
208
+ if (isValueProvider(declaration)) {
209
+ this.container.register(key, declaration);
210
+ }
211
+ else if (isFactoryProvider(declaration)) {
212
+ // this enables us to have a singletoned factory
213
+ // that returns the same instance for each resolve
214
+ this.container.register(key, {
215
+ useFactory: instancePerContainerCachingFactory(declaration.useFactory),
216
+ });
217
+ }
218
+ else if (isClassProvider(declaration)) {
219
+ this.container.register(key, declaration, {
220
+ lifecycle: Lifecycle.Singleton,
221
+ });
222
+ // eslint-disable-next-line sonarjs/no-duplicated-branches
223
+ }
224
+ else if (isTokenProvider(declaration)) {
225
+ this.container.register(key, declaration, {
226
+ lifecycle: Lifecycle.Singleton,
227
+ });
228
+ }
229
+ else {
230
+ // Can never be reached
231
+ throw new Error("Above if-statement is exhaustive");
232
+ }
233
+ }
234
+ else {
235
+ log.debug(`Dependency ${key} already registered, skipping`);
236
+ }
237
+ });
238
+ }
239
+ /**
240
+ * Handle module resolution, e.g. by decorating resolved modules
241
+ * @param moduleName
242
+ */
243
+ onAfterModuleResolution(moduleName) {
244
+ this.container.afterResolution(moduleName, (containedModuleName, containedModule) => {
245
+ // special case where tsyringe may return multiple known instances (?)
246
+ if (Array.isArray(containedModule)) {
247
+ throw errors.unableToDecorateModule(containedModuleName);
248
+ }
249
+ this.decorateModule(moduleName, containedModule);
250
+ containedModule.create(() => {
251
+ const container = this.container.createChildContainer();
252
+ container.reset();
253
+ return container;
254
+ });
255
+ if (this.isDependencyFactory(containedModule)) {
256
+ this.useDependencyFactory(containedModule);
257
+ }
258
+ }, { frequency: ModuleContainer.moduleDecorationFrequency });
259
+ }
260
+ /**
261
+ * This is a placeholder for individual modules to override.
262
+ * This method will be called whenever the underlying container fully
263
+ * initialized
264
+ */
265
+ create(childContainerProvider) {
266
+ this.providedContainer = childContainerProvider();
267
+ this.registerValue({
268
+ ChildContainerProvider: () => this.container.createChildContainer(),
269
+ });
270
+ // register all provided modules when the container is created
271
+ this.registerModules(this.definition.modules);
272
+ }
273
+ }
274
+ /**
275
+ * Determines how often are modules decorated upon resolution
276
+ * from the tsyringe DI container
277
+ */
278
+ ModuleContainer.moduleDecorationFrequency = "Once";
@@ -0,0 +1,29 @@
1
+ import { ClassProvider, FactoryProvider, TokenProvider, ValueProvider } from "tsyringe";
2
+ import { TypedClass } from "../types";
3
+ import type { BaseModuleInstanceType } from "../config/ModuleContainer";
4
+ export type DependencyDeclaration<Dependency> = ClassProvider<Dependency> | FactoryProvider<Dependency> | TokenProvider<Dependency> | ValueProvider<Dependency>;
5
+ export type DependencyRecord = Record<string, DependencyDeclaration<unknown> & {
6
+ forceOverwrite?: boolean;
7
+ }>;
8
+ /**
9
+ * This is an abstract class for creating DependencyFactories, a pattern
10
+ * to bundle multiple smaller services into one and register them into the
11
+ * injection context.
12
+ *
13
+ * This can for example be a StorageDependencyFactory that creates dependencies
14
+ * like StateService, MerkleWitnessService, etc. So in general, services that
15
+ * are not ConfigurableModules, but still are their own logical unit.
16
+ *
17
+ * DependencyFactories are designed to only be used statically for sets of
18
+ * deps that are necessary for the sequencer to work.
19
+ */
20
+ export interface DependencyFactory {
21
+ dependencies: () => DependencyRecord;
22
+ }
23
+ export type TypeFromDependencyDeclaration<Declaration extends DependencyDeclaration<unknown>> = Declaration extends DependencyDeclaration<infer Dependency> ? Dependency : never;
24
+ export type CapitalizeAny<Key extends string | number | symbol> = Key extends string ? Capitalize<Key> : Key;
25
+ export type MapDependencyRecordToTypes<Record extends DependencyRecord> = {
26
+ [Key in keyof Record as CapitalizeAny<Key>]: TypedClass<TypeFromDependencyDeclaration<Record[Key]>>;
27
+ };
28
+ export type InferDependencies<Class extends BaseModuleInstanceType> = Class extends DependencyFactory ? MapDependencyRecordToTypes<ReturnType<Class["dependencies"]>> : never;
29
+ //# sourceMappingURL=DependencyFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DependencyFactory.d.ts","sourceRoot":"","sources":["../../src/dependencyFactory/DependencyFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,eAAe,EACf,aAAa,EACb,aAAa,EACd,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAExE,MAAM,MAAM,qBAAqB,CAAC,UAAU,IACxC,aAAa,CAAC,UAAU,CAAC,GACzB,eAAe,CAAC,UAAU,CAAC,GAC3B,aAAa,CAAC,UAAU,CAAC,GACzB,aAAa,CAAC,UAAU,CAAC,CAAC;AAE9B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,MAAM,EACN,qBAAqB,CAAC,OAAO,CAAC,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9D,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,gBAAgB,CAAC;CACtC;AAED,MAAM,MAAM,6BAA6B,CACvC,WAAW,SAAS,qBAAqB,CAAC,OAAO,CAAC,IAElD,WAAW,SAAS,qBAAqB,CAAC,MAAM,UAAU,CAAC,GACvD,UAAU,GACV,KAAK,CAAC;AAEZ,MAAM,MAAM,aAAa,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,IAC5D,GAAG,SAAS,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAE7C,MAAM,MAAM,0BAA0B,CAAC,MAAM,SAAS,gBAAgB,IAAI;KACvE,GAAG,IAAI,MAAM,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,UAAU,CACrD,6BAA6B,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAC3C;CACF,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,sBAAsB,IAChE,KAAK,SAAS,iBAAiB,GAC3B,0BAA0B,CAAC,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,GAC7D,KAAK,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This function injects a dependency only if it has been registered, otherwise
3
+ * injects undefined. This can be useful for having optional dependencies, where
4
+ * tsyringe would normally error out and not be able to resolve. With this
5
+ * decorator, we can now do this.
6
+ *
7
+ * The strategy we employ here is that we inject a dummy into the global
8
+ * container that is of type UndefinedDisguise. We can't inject undefined
9
+ * directly, therefore we use this object to disguise itself as undefined.
10
+ * Then a child container registers something under the same token, it by
11
+ * default resolves that new dependency. If that doesn't happen, the
12
+ * resolution hits our disguise, which we then convert into undefined
13
+ * using the Transform
14
+ */
15
+ export declare function injectOptional<T>(token: string): (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) => any;
16
+ //# sourceMappingURL=injectOptional.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectOptional.d.ts","sourceRoot":"","sources":["../../src/dependencyFactory/injectOptional.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,0FAG9C"}
@@ -0,0 +1,39 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { container, injectable, injectWithTransform, Lifecycle, scoped, } from "tsyringe";
8
+ let UndefinedDisguise = class UndefinedDisguise {
9
+ };
10
+ UndefinedDisguise = __decorate([
11
+ injectable(),
12
+ scoped(Lifecycle.ResolutionScoped)
13
+ ], UndefinedDisguise);
14
+ class UndefinedTransform {
15
+ transform(incoming) {
16
+ if (incoming instanceof UndefinedDisguise) {
17
+ return undefined;
18
+ }
19
+ return incoming;
20
+ }
21
+ }
22
+ /**
23
+ * This function injects a dependency only if it has been registered, otherwise
24
+ * injects undefined. This can be useful for having optional dependencies, where
25
+ * tsyringe would normally error out and not be able to resolve. With this
26
+ * decorator, we can now do this.
27
+ *
28
+ * The strategy we employ here is that we inject a dummy into the global
29
+ * container that is of type UndefinedDisguise. We can't inject undefined
30
+ * directly, therefore we use this object to disguise itself as undefined.
31
+ * Then a child container registers something under the same token, it by
32
+ * default resolves that new dependency. If that doesn't happen, the
33
+ * resolution hits our disguise, which we then convert into undefined
34
+ * using the Transform
35
+ */
36
+ export function injectOptional(token) {
37
+ container.register(token, { useClass: UndefinedDisguise });
38
+ return injectWithTransform(token, (UndefinedTransform));
39
+ }
@@ -0,0 +1,19 @@
1
+ import { EventsRecord } from "./EventEmittingComponent";
2
+ type ListenersHolder<Events extends EventsRecord> = {
3
+ [key in keyof Events]?: ((...args: Events[key]) => void)[];
4
+ };
5
+ export declare class EventEmitter<Events extends EventsRecord> {
6
+ protected readonly listeners: ListenersHolder<Events>;
7
+ protected readonly wildcardListeners: ((event: keyof Events, args: Events[keyof Events]) => void)[];
8
+ emit<Key extends keyof Events>(event: Key, ...parameters: Events[Key]): void;
9
+ onAll(listener: (event: keyof Events, args: unknown[]) => void): void;
10
+ on<Key extends keyof Events>(event: Key, listener: (...args: Events[Key]) => void): void;
11
+ /**
12
+ * Primitive .off() with identity comparison for now.
13
+ * Could be replaced by returning an id in .on() and using that.
14
+ */
15
+ off<Key extends keyof Events>(event: Key, listener: (...args: Events[Key]) => void): void;
16
+ }
17
+ export type EventListenable<Events extends EventsRecord> = Pick<EventEmitter<Events>, "on" | "onAll" | "off">;
18
+ export {};
19
+ //# sourceMappingURL=EventEmitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/events/EventEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,KAAK,eAAe,CAAC,MAAM,SAAS,YAAY,IAAI;KACjD,GAAG,IAAI,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE;CAC3D,CAAC;AAEF,qBAAa,YAAY,CAAC,MAAM,SAAS,YAAY;IACnD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,CAAM;IAE3D,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CACrC,KAAK,EAAE,MAAM,MAAM,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,KACvB,IAAI,CAAC,EAAE,CAAM;IAEX,IAAI,CAAC,GAAG,SAAS,MAAM,MAAM,EAClC,KAAK,EAAE,GAAG,EACV,GAAG,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC;IAarB,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI;IAIrE,EAAE,CAAC,GAAG,SAAS,MAAM,MAAM,EAChC,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;IAK1C;;;OAGG;IACI,GAAG,CAAC,GAAG,SAAS,MAAM,MAAM,EACjC,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI;CAS3C;AAED,MAAM,MAAM,eAAe,CAAC,MAAM,SAAS,YAAY,IAAI,IAAI,CAC7D,YAAY,CAAC,MAAM,CAAC,EACpB,IAAI,GAAG,OAAO,GAAG,KAAK,CACvB,CAAC"}
@@ -0,0 +1,34 @@
1
+ export class EventEmitter {
2
+ constructor() {
3
+ this.listeners = {};
4
+ this.wildcardListeners = [];
5
+ }
6
+ emit(event, ...parameters) {
7
+ const listeners = this.listeners[event];
8
+ if (listeners !== undefined) {
9
+ listeners.forEach((listener) => {
10
+ listener(...parameters);
11
+ });
12
+ }
13
+ this.wildcardListeners.forEach((wildcardListener) => {
14
+ wildcardListener(event, parameters);
15
+ });
16
+ }
17
+ onAll(listener) {
18
+ this.wildcardListeners.push(listener);
19
+ }
20
+ on(event, listener) {
21
+ var _a;
22
+ ((_a = this.listeners)[event] ?? (_a[event] = [])).push(listener);
23
+ }
24
+ /**
25
+ * Primitive .off() with identity comparison for now.
26
+ * Could be replaced by returning an id in .on() and using that.
27
+ */
28
+ off(event, listener) {
29
+ const events = this.listeners[event];
30
+ if (events !== undefined) {
31
+ this.listeners[event] = events.filter((candidate) => candidate !== listener);
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,17 @@
1
+ import type { BaseModuleType, ModuleContainer, ModulesRecord } from "../config/ModuleContainer";
2
+ import { StringKeyOf, UnionToIntersection } from "../types";
3
+ import { EventEmitter } from "./EventEmitter";
4
+ import { EventEmittingComponent, EventsRecord } from "./EventEmittingComponent";
5
+ export type CastToEventsRecord<Record> = Record extends EventsRecord ? Record : {};
6
+ export type ModuleEvents<ModuleType extends BaseModuleType> = InstanceType<ModuleType> extends EventEmittingComponent<infer Events> ? Events : InstanceType<ModuleType> extends ModuleContainer<infer NestedModules> ? CastToEventsRecord<ContainerEvents<NestedModules>> : EventsRecord;
7
+ export type ContainerEvents<Modules extends ModulesRecord> = {
8
+ [Key in StringKeyOf<Modules>]: ModuleEvents<Modules[Key]>;
9
+ };
10
+ export type FlattenObject<Target extends Record<string, EventsRecord>> = UnionToIntersection<Target[keyof Target]>;
11
+ export type FlattenedContainerEvents<Modules extends ModulesRecord> = FlattenObject<ContainerEvents<Modules>>;
12
+ export declare class EventEmitterProxy<Modules extends ModulesRecord> extends EventEmitter<CastToEventsRecord<FlattenedContainerEvents<Modules>>> {
13
+ private readonly container;
14
+ constructor(container: ModuleContainer<Modules>);
15
+ private isEventEmitter;
16
+ }
17
+ //# sourceMappingURL=EventEmitterProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmitterProxy.d.ts","sourceRoot":"","sources":["../../src/events/EventEmitterProxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,MAAM,MAAM,kBAAkB,CAAC,MAAM,IAAI,MAAM,SAAS,YAAY,GAChE,MAAM,GACN,EAAE,CAAC;AAEP,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,cAAc,IACxD,YAAY,CAAC,UAAU,CAAC,SAAS,sBAAsB,CAAC,MAAM,MAAM,CAAC,GACjE,MAAM,GACN,YAAY,CAAC,UAAU,CAAC,SAAS,eAAe,CAAC,MAAM,aAAa,CAAC,GACnE,kBAAkB,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,GAClD,YAAY,CAAC;AAErB,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,aAAa,IAAI;KAC1D,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IACnE,mBAAmB,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;AAE5C,MAAM,MAAM,wBAAwB,CAAC,OAAO,SAAS,aAAa,IAChE,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAE1C,qBAAa,iBAAiB,CAC5B,OAAO,SAAS,aAAa,CAC7B,SAAQ,YAAY,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC;IAiBvE,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from "./EventEmitter";
2
+ export class EventEmitterProxy extends EventEmitter {
3
+ constructor(container) {
4
+ super();
5
+ this.container = container;
6
+ container.moduleNames.forEach((moduleName) => {
7
+ if (container.isValidModuleName(container.definition.modules, moduleName)) {
8
+ const module = container.resolve(moduleName);
9
+ if (this.isEventEmitter(module)) {
10
+ module.events.onAll((events, args) => {
11
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
12
+ this.emit(events, ...args);
13
+ });
14
+ }
15
+ }
16
+ });
17
+ }
18
+ isEventEmitter(module) {
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20
+ const emitter = module.events;
21
+ return emitter !== undefined && emitter instanceof EventEmitter;
22
+ }
23
+ }
@@ -0,0 +1,6 @@
1
+ import type { EventEmitter } from "./EventEmitter";
2
+ export type EventsRecord = Record<string, unknown[]>;
3
+ export interface EventEmittingComponent<Events extends EventsRecord> {
4
+ events: EventEmitter<Events>;
5
+ }
6
+ //# sourceMappingURL=EventEmittingComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventEmittingComponent.d.ts","sourceRoot":"","sources":["../../src/events/EventEmittingComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAErD,MAAM,WAAW,sBAAsB,CAAC,MAAM,SAAS,YAAY;IACjE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC9B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
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 "./trees/MockAsyncMerkleStore";
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,SAAS,CAAC;AACxB,cAAc,iCAAiC,CAAC;AAChD,cAAc,iDAAiD,CAAC;AAChE,cAAc,iCAAiC,CAAC;AAChD,cAAc,SAAS,CAAC;AACxB,cAAc,uCAAuC,CAAC;AACtD,cAAc,oCAAoC,CAAC;AACnD,cAAc,OAAO,CAAC;AACtB,cAAc,iCAAiC,CAAC;AAChD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
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 "./trees/MockAsyncMerkleStore";
package/dist/log.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import loglevel, { LogLevelDesc, LogLevelNames } from "loglevel";
2
+ export declare const log: {
3
+ provable: {
4
+ info: (...args: unknown[]) => void;
5
+ debug: (...args: unknown[]) => void;
6
+ error: (...args: unknown[]) => void;
7
+ trace: (...args: unknown[]) => void;
8
+ warn: (...args: unknown[]) => void;
9
+ };
10
+ info: (...args: unknown[]) => void;
11
+ debug: (...args: unknown[]) => void;
12
+ error: (...args: unknown[]) => void;
13
+ trace: (...args: unknown[]) => void;
14
+ warn: (...args: unknown[]) => void;
15
+ setLevel: (level: LogLevelDesc) => void;
16
+ readonly levels: loglevel.LogLevel;
17
+ getLevel: () => 0 | 2 | 3 | 1 | 4 | 5;
18
+ };
19
+ export declare function assertValidTextLogLevel(level: string | number): asserts level is LogLevelNames;
20
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA2BjE,eAAO,MAAM,GAAG;;wBAEI,OAAO,EAAE;yBAIR,OAAO,EAAE;yBAIT,OAAO,EAAE;yBAIT,OAAO,EAAE;wBAIV,OAAO,EAAE;;oBAKX,OAAO,EAAE;qBAIR,OAAO,EAAE;qBAIT,OAAO,EAAE;qBAIT,OAAO,EAAE;oBAQV,OAAO,EAAE;sBAIP,YAAY;;;CAS/B,CAAC;AAIF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GACrB,OAAO,CAAC,KAAK,IAAI,aAAa,CAOhC"}
package/dist/log.js ADDED
@@ -0,0 +1,75 @@
1
+ import loglevel from "loglevel";
2
+ import { Provable } from "o1js";
3
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
4
+ function logProvable(logFunction, ...args) {
5
+ Provable.asProver(() => {
6
+ const prettyArguments = [];
7
+ args.forEach((argument) => {
8
+ if (argument?.toPretty !== undefined) {
9
+ prettyArguments.push(argument.toPretty());
10
+ }
11
+ else {
12
+ try {
13
+ prettyArguments.push(JSON.parse(JSON.stringify(argument)));
14
+ }
15
+ catch {
16
+ prettyArguments.push(argument);
17
+ }
18
+ }
19
+ });
20
+ logFunction(...prettyArguments);
21
+ });
22
+ }
23
+ /* eslint-enable */
24
+ export const log = {
25
+ provable: {
26
+ info: (...args) => {
27
+ logProvable(loglevel.info, ...args);
28
+ },
29
+ debug: (...args) => {
30
+ logProvable(loglevel.debug, ...args);
31
+ },
32
+ error: (...args) => {
33
+ logProvable(loglevel.error, ...args);
34
+ },
35
+ trace: (...args) => {
36
+ logProvable(log.trace, ...args);
37
+ },
38
+ warn: (...args) => {
39
+ logProvable(loglevel.warn, ...args);
40
+ },
41
+ },
42
+ info: (...args) => {
43
+ loglevel.info(...args);
44
+ },
45
+ debug: (...args) => {
46
+ loglevel.debug(...args);
47
+ },
48
+ error: (...args) => {
49
+ loglevel.error(...args);
50
+ },
51
+ trace: (...args) => {
52
+ // Loglevel prints the stack trace by default. To still be able to use trace
53
+ // inside out application, we use the level, but call debug() under the hood
54
+ if (loglevel.getLevel() <= loglevel.levels.TRACE) {
55
+ loglevel.debug(...args);
56
+ }
57
+ },
58
+ warn: (...args) => {
59
+ loglevel.warn(...args);
60
+ },
61
+ setLevel: (level) => {
62
+ loglevel.setLevel(level);
63
+ },
64
+ get levels() {
65
+ return loglevel.levels;
66
+ },
67
+ getLevel: () => loglevel.getLevel(),
68
+ };
69
+ const validLogLevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "SILENT"];
70
+ export function assertValidTextLogLevel(level) {
71
+ if (typeof level === "number" ||
72
+ !validLogLevels.includes(level.toUpperCase())) {
73
+ throw new Error(`${level} is not a valid loglevel`);
74
+ }
75
+ }