@aztec/foundation 0.1.0-alpha46 → 0.1.0-alpha48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tsbuildinfo +1 -1
- package/dest/abi/abi_coder.d.ts +1 -28
- package/dest/abi/abi_coder.d.ts.map +1 -1
- package/dest/abi/abi_coder.js +1 -35
- package/dest/abi/function_selector.d.ts +73 -0
- package/dest/abi/function_selector.d.ts.map +1 -0
- package/dest/abi/function_selector.js +100 -0
- package/dest/abi/index.d.ts +1 -0
- package/dest/abi/index.d.ts.map +1 -1
- package/dest/abi/index.js +2 -1
- package/dest/json-rpc/class_converter.d.ts +8 -0
- package/dest/json-rpc/class_converter.d.ts.map +1 -1
- package/dest/json-rpc/class_converter.js +20 -5
- package/dest/json-rpc/convert.d.ts.map +1 -1
- package/dest/json-rpc/convert.js +34 -3
- package/dest/json-rpc/convert.test.js +46 -1
- package/dest/json-rpc/fixtures/class_a.d.ts +11 -0
- package/dest/json-rpc/fixtures/class_a.d.ts.map +1 -0
- package/dest/json-rpc/fixtures/class_a.js +17 -0
- package/dest/json-rpc/fixtures/class_b.d.ts +11 -0
- package/dest/json-rpc/fixtures/class_b.d.ts.map +1 -0
- package/dest/json-rpc/fixtures/class_b.js +17 -0
- package/dest/log/logger.d.ts +8 -1
- package/dest/log/logger.d.ts.map +1 -1
- package/dest/log/logger.js +16 -4
- package/dest/wasm/wasm_module.d.ts.map +1 -1
- package/dest/wasm/wasm_module.js +2 -2
- package/package.json +1 -1
- package/src/abi/abi_coder.ts +1 -38
- package/src/abi/function_selector.ts +111 -0
- package/src/abi/index.ts +1 -0
- package/src/json-rpc/class_converter.ts +18 -4
- package/src/json-rpc/convert.test.ts +51 -0
- package/src/json-rpc/convert.ts +35 -3
- package/src/json-rpc/fixtures/class_a.ts +15 -0
- package/src/json-rpc/fixtures/class_b.ts +15 -0
- package/src/log/logger.ts +20 -3
- package/src/wasm/wasm_module.ts +1 -1
package/dest/wasm/wasm_module.js
CHANGED
|
@@ -18,7 +18,7 @@ export class WasmModule {
|
|
|
18
18
|
* @param importFn - Imports expected by the WASM.
|
|
19
19
|
* @param loggerName - Optional, for debug logging.
|
|
20
20
|
*/
|
|
21
|
-
constructor(module, importFn, loggerName = 'wasm') {
|
|
21
|
+
constructor(module, importFn, loggerName = 'aztec:wasm') {
|
|
22
22
|
this.module = module;
|
|
23
23
|
this.importFn = importFn;
|
|
24
24
|
this.mutexQ = new MemoryFifo();
|
|
@@ -202,4 +202,4 @@ export class WasmModule {
|
|
|
202
202
|
this.mutexQ.put(true);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
205
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FzbV9tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2FzbS93YXNtX21vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRWhDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFTLHFCQUFxQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBZ0N0RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFPckI7Ozs7O09BS0c7SUFDSCxZQUNVLE1BQW1DLEVBQ25DLFFBQXFDLEVBQzdDLFVBQVUsR0FBRyxZQUFZO1FBRmpCLFdBQU0sR0FBTixNQUFNLENBQTZCO1FBQ25DLGFBQVEsR0FBUixRQUFRLENBQTZCO1FBWHZDLFdBQU0sR0FBRyxJQUFJLFVBQVUsRUFBVyxDQUFDO1FBY3pDLElBQUksQ0FBQyxLQUFLLEdBQUcscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7T0FHRztJQUNJLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztJQUNEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFBRSxPQUFPLEdBQUcsSUFBSSxFQUFFLGFBQTRCLGFBQWE7UUFDdkYsSUFBSSxDQUFDLEtBQUssQ0FDUixnQkFBZ0IsT0FBTyxXQUFXLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENB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
|
package/package.json
CHANGED
package/src/abi/abi_coder.ts
CHANGED
|
@@ -1,41 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { keccak } from '@aztec/foundation/crypto';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generate a function signature string for a given function name and parameters.
|
|
6
|
-
* The signature is used to uniquely identify functions within noir contracts.
|
|
7
|
-
* If the function name is 'constructor', it returns just the name, otherwise it returns the name followed by the list of parameter types.
|
|
8
|
-
*
|
|
9
|
-
* @param name - The name of the function.
|
|
10
|
-
* @param parameters - An array of ABIParameter objects, each containing the type information of a function parameter.
|
|
11
|
-
* @returns A string representing the function signature.
|
|
12
|
-
*/
|
|
13
|
-
export function computeFunctionSignature(name: string, parameters: ABIParameter[]) {
|
|
14
|
-
return name === 'constructor' ? name : `${name}(${parameters.map(p => p.type.kind).join(',')})`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generate a function selector for a given function signature.
|
|
19
|
-
* @param signature - The signature of the function.
|
|
20
|
-
* @param size - Number of bytes of the return buffer.
|
|
21
|
-
* @returns A Buffer containing the n-byte function selector.
|
|
22
|
-
*/
|
|
23
|
-
export function computeFunctionSelector(signature: string, size: number) {
|
|
24
|
-
return keccak(Buffer.from(signature)).slice(0, size);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generate a function selector for a given function name and parameters.
|
|
29
|
-
* It is derived by taking the first 4 bytes of the Keccak-256 hash of the function signature.
|
|
30
|
-
*
|
|
31
|
-
* @param name - The name of the function.
|
|
32
|
-
* @param parameters - An array of ABIParameter objects, each containing the type information of a function parameter.
|
|
33
|
-
* @returns A Buffer containing the 4-byte function selector.
|
|
34
|
-
*/
|
|
35
|
-
export function generateFunctionSelector(name: string, parameters: ABIParameter[]) {
|
|
36
|
-
const signature = computeFunctionSignature(name, parameters);
|
|
37
|
-
return computeFunctionSelector(signature, 4);
|
|
38
|
-
}
|
|
1
|
+
import { ABIType } from '@aztec/foundation/abi';
|
|
39
2
|
|
|
40
3
|
/**
|
|
41
4
|
* Get the size of an ABI type in field elements.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ABIParameter } from '@aztec/foundation/abi';
|
|
2
|
+
import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer';
|
|
3
|
+
import { keccak } from '@aztec/foundation/crypto';
|
|
4
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
+
import { BufferReader } from '@aztec/foundation/serialize';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A function selector is the first 4 bytes of the hash of a function signature.
|
|
9
|
+
*/
|
|
10
|
+
export class FunctionSelector {
|
|
11
|
+
/**
|
|
12
|
+
* The size of the function selector in bytes.
|
|
13
|
+
*/
|
|
14
|
+
public static SIZE = 4;
|
|
15
|
+
|
|
16
|
+
constructor(/** number representing the function selector */ public value: number) {
|
|
17
|
+
if (value > 2 ** (FunctionSelector.SIZE * 8) - 1) {
|
|
18
|
+
throw new Error(`Function selector must fit in ${FunctionSelector.SIZE} bytes.`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the function selector is empty (all bytes are 0).
|
|
24
|
+
* @returns True if the function selector is empty (all bytes are 0).
|
|
25
|
+
*/
|
|
26
|
+
public isEmpty(): boolean {
|
|
27
|
+
return this.value === 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Serialize as a buffer.
|
|
32
|
+
* @returns The buffer.
|
|
33
|
+
*/
|
|
34
|
+
toBuffer(): Buffer {
|
|
35
|
+
return toBufferBE(BigInt(this.value), FunctionSelector.SIZE);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Serialize as a hex string.
|
|
40
|
+
* @returns The string.
|
|
41
|
+
*/
|
|
42
|
+
toString(): string {
|
|
43
|
+
return this.toBuffer().toString('hex');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Checks if this function selector is equal to another.
|
|
48
|
+
* @param other - The other function selector.
|
|
49
|
+
* @returns True if the function selectors are equal.
|
|
50
|
+
*/
|
|
51
|
+
equals(other: FunctionSelector): boolean {
|
|
52
|
+
return this.value === other.value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Deserializes from a buffer or reader, corresponding to a write in cpp.
|
|
57
|
+
* @param buffer - Buffer or BufferReader to read from.
|
|
58
|
+
* @returns The FunctionSelector.
|
|
59
|
+
*/
|
|
60
|
+
static fromBuffer(buffer: Buffer | BufferReader): FunctionSelector {
|
|
61
|
+
const reader = BufferReader.asReader(buffer);
|
|
62
|
+
const value = Number(toBigIntBE(reader.readBytes(FunctionSelector.SIZE)));
|
|
63
|
+
return new FunctionSelector(value);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns a new field with the same contents as this EthAddress.
|
|
68
|
+
*
|
|
69
|
+
* @returns An Fr instance.
|
|
70
|
+
*/
|
|
71
|
+
public toField() {
|
|
72
|
+
return new Fr(this.value);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Converts a field to function selector.
|
|
77
|
+
* @param fr - The field to convert.
|
|
78
|
+
* @returns The function selector.
|
|
79
|
+
*/
|
|
80
|
+
static fromField(fr: Fr): FunctionSelector {
|
|
81
|
+
return new FunctionSelector(Number(fr.value));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Creates a function selector from a signature.
|
|
86
|
+
* @param signature - Signature of the function to generate the selector for (e.g. "transfer(field,field)").
|
|
87
|
+
* @returns Function selector.
|
|
88
|
+
*/
|
|
89
|
+
static fromSignature(signature: string): FunctionSelector {
|
|
90
|
+
return FunctionSelector.fromBuffer(keccak(Buffer.from(signature)).subarray(0, FunctionSelector.SIZE));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Creates a function selector for a given function name and parameters.
|
|
95
|
+
* @param name - The name of the function.
|
|
96
|
+
* @param parameters - An array of ABIParameter objects, each containing the type information of a function parameter.
|
|
97
|
+
* @returns A Buffer containing the 4-byte function selector.
|
|
98
|
+
*/
|
|
99
|
+
static fromNameAndParameters(name: string, parameters: ABIParameter[]) {
|
|
100
|
+
const signature = name === 'constructor' ? name : `${name}(${parameters.map(p => p.type.kind).join(',')})`;
|
|
101
|
+
return FunctionSelector.fromSignature(signature);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Creates an empty function selector.
|
|
106
|
+
* @returns An empty function selector.
|
|
107
|
+
*/
|
|
108
|
+
static empty(): FunctionSelector {
|
|
109
|
+
return new FunctionSelector(0);
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/abi/index.ts
CHANGED
|
@@ -158,7 +158,8 @@ export class ClassConverter {
|
|
|
158
158
|
* @returns If it is a registered class.
|
|
159
159
|
*/
|
|
160
160
|
isRegisteredClass(obj: any) {
|
|
161
|
-
|
|
161
|
+
const name = obj.prototype.constructor.name;
|
|
162
|
+
return this.toName.has(obj) || this.isRegisteredClassName(name);
|
|
162
163
|
}
|
|
163
164
|
/**
|
|
164
165
|
* Convert a JSON-like object to a class object.
|
|
@@ -182,10 +183,23 @@ export class ClassConverter {
|
|
|
182
183
|
* @returns The class object.
|
|
183
184
|
*/
|
|
184
185
|
toJsonObj(classObj: any): JsonEncodedClass | StringEncodedClass {
|
|
185
|
-
const
|
|
186
|
-
assert(result, `Could not find class in lookup.`);
|
|
187
|
-
const [type, encoding] = result;
|
|
186
|
+
const { type, encoding } = this.lookupObject(classObj);
|
|
188
187
|
const data = encoding === 'string' ? classObj.toString() : classObj.toJSON();
|
|
189
188
|
return { type: type!, data };
|
|
190
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Loads the corresponding type for this class based on constructor first and constructor name if not found.
|
|
193
|
+
* Constructor match works in the event of a minifier changing function names, and constructor name match
|
|
194
|
+
* works in the event of duplicated instances of node modules being loaded (see #1826).
|
|
195
|
+
* @param classObj - Object to lookup in the registered types.
|
|
196
|
+
* @returns Registered type name and encoding.
|
|
197
|
+
*/
|
|
198
|
+
private lookupObject(classObj: any) {
|
|
199
|
+
const nameResult = this.toName.get(classObj.constructor);
|
|
200
|
+
if (nameResult) return { type: nameResult[0], encoding: nameResult[1] };
|
|
201
|
+
const classResult = this.toClass.get(classObj.constructor.name);
|
|
202
|
+
if (classResult) return { type: classObj.constructor.name, encoding: classResult[1] };
|
|
203
|
+
throw new Error(`Could not find class ${classObj.constructor.name} in lookup.`);
|
|
204
|
+
}
|
|
191
205
|
}
|
|
@@ -2,6 +2,8 @@ import { Buffer } from 'buffer';
|
|
|
2
2
|
|
|
3
3
|
import { ClassConverter } from './class_converter.js';
|
|
4
4
|
import { convertBigintsInObj, convertFromJsonObj, convertToJsonObj } from './convert.js';
|
|
5
|
+
import { ToStringClass as ToStringClassA } from './fixtures/class_a.js';
|
|
6
|
+
import { ToStringClass as ToStringClassB } from './fixtures/class_b.js';
|
|
5
7
|
import { TestNote } from './fixtures/test_state.js';
|
|
6
8
|
|
|
7
9
|
const TEST_BASE64 = 'YmFzZTY0IGRlY29kZXI=';
|
|
@@ -24,3 +26,52 @@ test('does not convert a string', () => {
|
|
|
24
26
|
expect(convertBigintsInObj('hello')).toEqual('hello');
|
|
25
27
|
expect(convertBigintsInObj({ msg: 'hello' })).toEqual({ msg: 'hello' });
|
|
26
28
|
});
|
|
29
|
+
|
|
30
|
+
test('converts a registered class', () => {
|
|
31
|
+
const cc = new ClassConverter({ ToStringClass: ToStringClassA });
|
|
32
|
+
const obj = { content: new ToStringClassA('a', 'b') };
|
|
33
|
+
const serialised = convertToJsonObj(cc, obj);
|
|
34
|
+
const deserialised = convertFromJsonObj(cc, serialised) as { content: ToStringClassA };
|
|
35
|
+
expect(deserialised.content).toBeInstanceOf(ToStringClassA);
|
|
36
|
+
expect(deserialised.content.x).toEqual('a');
|
|
37
|
+
expect(deserialised.content.y).toEqual('b');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('converts a class by name in the event of duplicate modules being loaded', () => {
|
|
41
|
+
expect(ToStringClassA.prototype.constructor.name).toEqual('ToStringClass');
|
|
42
|
+
expect(ToStringClassB.prototype.constructor.name).toEqual('ToStringClass');
|
|
43
|
+
const cc = new ClassConverter({ ToStringClass: ToStringClassA });
|
|
44
|
+
const obj = { content: new ToStringClassB('a', 'b') };
|
|
45
|
+
const serialised = convertToJsonObj(cc, obj);
|
|
46
|
+
const deserialised = convertFromJsonObj(cc, serialised) as { content: ToStringClassA };
|
|
47
|
+
expect(deserialised.content).toBeInstanceOf(ToStringClassA);
|
|
48
|
+
expect(deserialised.content.x).toEqual('a');
|
|
49
|
+
expect(deserialised.content.y).toEqual('b');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('converts a class by constructor instead of name in the event of minified bundle', () => {
|
|
53
|
+
const cc = new ClassConverter({ NotMinifiedToStringClassName: ToStringClassA });
|
|
54
|
+
const obj = { content: new ToStringClassA('a', 'b') };
|
|
55
|
+
const serialised = convertToJsonObj(cc, obj);
|
|
56
|
+
const deserialised = convertFromJsonObj(cc, serialised) as { content: ToStringClassA };
|
|
57
|
+
expect(deserialised.content).toBeInstanceOf(ToStringClassA);
|
|
58
|
+
expect(deserialised.content.x).toEqual('a');
|
|
59
|
+
expect(deserialised.content.y).toEqual('b');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('converts a plain object', () => {
|
|
63
|
+
const obj = { a: 10, b: [20, 30], c: 'foo' };
|
|
64
|
+
const cc = new ClassConverter();
|
|
65
|
+
expect(convertFromJsonObj(cc, convertToJsonObj(cc, obj))).toEqual(obj);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('refuses to convert to json an unknown class', () => {
|
|
69
|
+
const cc = new ClassConverter();
|
|
70
|
+
expect(() => convertToJsonObj(cc, { content: new ToStringClassA('a', 'b') })).toThrowError(/not registered/);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('refuses to convert from json an unknown class', () => {
|
|
74
|
+
const cc = new ClassConverter({ ToStringClass: ToStringClassA });
|
|
75
|
+
const serialised = convertToJsonObj(cc, { content: new ToStringClassA('a', 'b') });
|
|
76
|
+
expect(() => convertFromJsonObj(new ClassConverter(), serialised)).toThrowError(/not registered/);
|
|
77
|
+
});
|
package/src/json-rpc/convert.ts
CHANGED
|
@@ -3,6 +3,31 @@ import cloneDeepWith from 'lodash.clonedeepwith';
|
|
|
3
3
|
|
|
4
4
|
import { ClassConverter } from './class_converter.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Check prototype chain to determine if an object is 'plain' (not a class instance).
|
|
8
|
+
* @param obj - The object to check.
|
|
9
|
+
* @returns True if the object is 'plain'.
|
|
10
|
+
*/
|
|
11
|
+
function isPlainObject(obj: any) {
|
|
12
|
+
if (obj === null) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let proto = obj;
|
|
17
|
+
let counter = 0;
|
|
18
|
+
const MAX_PROTOTYPE_CHAIN_LENGTH = 1000; // Adjust as needed
|
|
19
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
20
|
+
if (counter >= MAX_PROTOTYPE_CHAIN_LENGTH) {
|
|
21
|
+
// This is a failsafe in case circular prototype chain has been created. It should not be hit
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
proto = Object.getPrototypeOf(proto);
|
|
25
|
+
counter++;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return Object.getPrototypeOf(obj) === proto;
|
|
29
|
+
}
|
|
30
|
+
|
|
6
31
|
/**
|
|
7
32
|
* Recursively looks through an object for bigints and converts them to object format.
|
|
8
33
|
* @param obj - The object to convert.
|
|
@@ -59,8 +84,12 @@ export function convertFromJsonObj(cc: ClassConverter, obj: any): any {
|
|
|
59
84
|
}
|
|
60
85
|
|
|
61
86
|
// Is this a convertible type?
|
|
62
|
-
if (typeof obj.type === 'string'
|
|
63
|
-
|
|
87
|
+
if (typeof obj.type === 'string') {
|
|
88
|
+
if (cc.isRegisteredClassName(obj.type)) {
|
|
89
|
+
return cc.toClassObj(obj);
|
|
90
|
+
} else {
|
|
91
|
+
throw new Error(`Object ${obj.type} not registered for serialisation`);
|
|
92
|
+
}
|
|
64
93
|
}
|
|
65
94
|
|
|
66
95
|
// Is this an array?
|
|
@@ -118,7 +147,10 @@ export function convertToJsonObj(cc: ClassConverter, obj: any): any {
|
|
|
118
147
|
}
|
|
119
148
|
return newObj;
|
|
120
149
|
}
|
|
121
|
-
|
|
150
|
+
// Throw if this is a non-primitive class that was not registered
|
|
151
|
+
if (typeof obj === 'object' && !isPlainObject(obj)) {
|
|
152
|
+
throw new Error(`Object ${obj.constructor.name} not registered for serialisation`);
|
|
153
|
+
}
|
|
122
154
|
// Leave alone, assume JSON primitive
|
|
123
155
|
return obj;
|
|
124
156
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test class for testing string converter.
|
|
3
|
+
*/
|
|
4
|
+
export class ToStringClass {
|
|
5
|
+
constructor(/** A value */ public readonly x: string, /** Another value */ public readonly y: string) {}
|
|
6
|
+
|
|
7
|
+
toString(): string {
|
|
8
|
+
return [this.x, this.y].join('-');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static fromString(value: string) {
|
|
12
|
+
const [x, y] = value.split('-');
|
|
13
|
+
return new ToStringClass(x, y);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test class for testing string converter.
|
|
3
|
+
*/
|
|
4
|
+
export class ToStringClass {
|
|
5
|
+
constructor(/** A value */ public readonly x: string, /** Another value */ public readonly y: string) {}
|
|
6
|
+
|
|
7
|
+
toString(): string {
|
|
8
|
+
return [this.x, this.y].join('-');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static fromString(value: string) {
|
|
12
|
+
const [x, y] = value.split('-');
|
|
13
|
+
return new ToStringClass(x, y);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/log/logger.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { isatty } from 'tty';
|
|
|
4
4
|
|
|
5
5
|
import { LogFn } from './index.js';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// Matches a subset of Winston log levels
|
|
8
|
+
const LogLevels = ['silent', 'error', 'warn', 'info', 'verbose', 'debug'] as const;
|
|
8
9
|
const DefaultLogLevel = 'info' as const;
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -39,13 +40,26 @@ export function createDebugLogger(name: string): DebugLogger {
|
|
|
39
40
|
|
|
40
41
|
const logger = {
|
|
41
42
|
silent: () => {},
|
|
42
|
-
fatal: (...args: any[]) => logWithDebug(debugLogger, 'fatal', args),
|
|
43
43
|
error: (...args: any[]) => logWithDebug(debugLogger, 'error', args),
|
|
44
44
|
warn: (...args: any[]) => logWithDebug(debugLogger, 'warn', args),
|
|
45
45
|
info: (...args: any[]) => logWithDebug(debugLogger, 'info', args),
|
|
46
|
+
verbose: (...args: any[]) => logWithDebug(debugLogger, 'verbose', args),
|
|
46
47
|
debug: (...args: any[]) => logWithDebug(debugLogger, 'debug', args),
|
|
47
48
|
};
|
|
48
|
-
return Object.assign(debugLogger, logger);
|
|
49
|
+
return Object.assign((...args: any[]) => logWithDebug(debugLogger, 'debug', args), logger);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A callback to capture all logs. */
|
|
53
|
+
export type LogHandler = (level: LogLevel, namespace: string, args: any[]) => void;
|
|
54
|
+
|
|
55
|
+
const logHandlers: LogHandler[] = [];
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Registers a callback for all logs, whether they are emitted in the current log level or not.
|
|
59
|
+
* @param handler - Callback to be called on every log.
|
|
60
|
+
*/
|
|
61
|
+
export function onLog(handler: LogHandler) {
|
|
62
|
+
logHandlers.push(handler);
|
|
49
63
|
}
|
|
50
64
|
|
|
51
65
|
/**
|
|
@@ -55,6 +69,9 @@ export function createDebugLogger(name: string): DebugLogger {
|
|
|
55
69
|
* @param args - Args to log.
|
|
56
70
|
*/
|
|
57
71
|
function logWithDebug(debug: debug.Debugger, level: LogLevel, args: any[]) {
|
|
72
|
+
for (const handler of logHandlers) {
|
|
73
|
+
handler(level, debug.namespace, args);
|
|
74
|
+
}
|
|
58
75
|
if (debug.enabled) {
|
|
59
76
|
debug(args[0], ...args.slice(1));
|
|
60
77
|
} else if (LogLevels.indexOf(level) <= LogLevels.indexOf(currentLevel) && process.env.NODE_ENV !== 'test') {
|
package/src/wasm/wasm_module.ts
CHANGED
|
@@ -59,7 +59,7 @@ export class WasmModule implements IWasmModule {
|
|
|
59
59
|
constructor(
|
|
60
60
|
private module: WebAssembly.Module | Buffer,
|
|
61
61
|
private importFn: (module: WasmModule) => any,
|
|
62
|
-
loggerName = 'wasm',
|
|
62
|
+
loggerName = 'aztec:wasm',
|
|
63
63
|
) {
|
|
64
64
|
this.debug = createDebugOnlyLogger(loggerName);
|
|
65
65
|
this.mutexQ.put(true);
|