diff --git a/yarn-project/accounts/package.json b/yarn-project/accounts/package.json index d4d3d8ab916..0817971899b 100644 --- a/yarn-project/accounts/package.json +++ b/yarn-project/accounts/package.json @@ -52,6 +52,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/archiver/package.json b/yarn-project/archiver/package.json index 4afb656f15c..ff0dd170380 100644 --- a/yarn-project/archiver/package.json +++ b/yarn-project/archiver/package.json @@ -44,6 +44,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/aztec-faucet/package.json b/yarn-project/aztec-faucet/package.json index 54eb3313a3d..6d8ccc7a022 100644 --- a/yarn-project/aztec-faucet/package.json +++ b/yarn-project/aztec-faucet/package.json @@ -37,6 +37,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/aztec-node/package.json b/yarn-project/aztec-node/package.json index f2bbd2972de..30d19cff4e9 100644 --- a/yarn-project/aztec-node/package.json +++ b/yarn-project/aztec-node/package.json @@ -37,6 +37,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/aztec.js/package.json b/yarn-project/aztec.js/package.json index 40ff9add338..98f57facfd7 100644 --- a/yarn-project/aztec.js/package.json +++ b/yarn-project/aztec.js/package.json @@ -55,6 +55,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/aztec/package.json b/yarn-project/aztec/package.json index bcc6c9196c5..9e85f69d16a 100644 --- a/yarn-project/aztec/package.json +++ b/yarn-project/aztec/package.json @@ -94,6 +94,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/bb-prover/package.json b/yarn-project/bb-prover/package.json index 7adf7f8a7eb..efdeb93cc5c 100644 --- a/yarn-project/bb-prover/package.json +++ b/yarn-project/bb-prover/package.json @@ -41,6 +41,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/bot/package.json b/yarn-project/bot/package.json index 6e187ffd065..ac515b88218 100644 --- a/yarn-project/bot/package.json +++ b/yarn-project/bot/package.json @@ -31,6 +31,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/builder/package.json b/yarn-project/builder/package.json index acde8d5092b..597b83807a1 100644 --- a/yarn-project/builder/package.json +++ b/yarn-project/builder/package.json @@ -47,6 +47,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/circuit-types/package.json b/yarn-project/circuit-types/package.json index 6e874e8b129..b06d89e907c 100644 --- a/yarn-project/circuit-types/package.json +++ b/yarn-project/circuit-types/package.json @@ -43,6 +43,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/circuits.js/package.json b/yarn-project/circuits.js/package.json index 82ea912b59f..5a83df9826b 100644 --- a/yarn-project/circuits.js/package.json +++ b/yarn-project/circuits.js/package.json @@ -77,6 +77,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/cli-wallet/package.json b/yarn-project/cli-wallet/package.json index ea37249686d..e8fe9b83dfb 100644 --- a/yarn-project/cli-wallet/package.json +++ b/yarn-project/cli-wallet/package.json @@ -48,6 +48,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index c0f4af79732..b6a9891babd 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -48,6 +48,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index 98d1e156cd4..bf630f4e047 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -131,6 +131,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/entrypoints/package.json b/yarn-project/entrypoints/package.json index 48c6c5535a4..6a278c79364 100644 --- a/yarn-project/entrypoints/package.json +++ b/yarn-project/entrypoints/package.json @@ -41,6 +41,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/ethereum/package.json b/yarn-project/ethereum/package.json index b7518c9547f..2e49f7f2324 100644 --- a/yarn-project/ethereum/package.json +++ b/yarn-project/ethereum/package.json @@ -57,6 +57,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 2af937f8c18..b63a267cbfe 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -15,6 +15,7 @@ "./collection": "./dest/collection/index.js", "./config": "./dest/config/index.js", "./crypto": "./dest/crypto/index.js", + "./decorators": "./dest/decorators/index.js", "./error": "./dest/error/index.js", "./eth-address": "./dest/eth-address/index.js", "./eth-signature": "./dest/eth-signature/index.js", @@ -68,6 +69,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } @@ -156,4 +160,4 @@ "engines": { "node": ">=18" } -} +} \ No newline at end of file diff --git a/yarn-project/foundation/src/decorators/index.ts b/yarn-project/foundation/src/decorators/index.ts new file mode 100644 index 00000000000..4ed809e11df --- /dev/null +++ b/yarn-project/foundation/src/decorators/index.ts @@ -0,0 +1 @@ +export * from './memoize.js'; diff --git a/yarn-project/foundation/src/decorators/memoize.test.ts b/yarn-project/foundation/src/decorators/memoize.test.ts new file mode 100644 index 00000000000..badd35e8664 --- /dev/null +++ b/yarn-project/foundation/src/decorators/memoize.test.ts @@ -0,0 +1,104 @@ +import { sleep } from '../sleep/index.js'; +import { memoize } from './memoize.js'; + +class Memoized { + public readonly counters: Record = {}; + + @memoize + voidPublic() { + this.inc('voidPublic'); + } + + @memoize + synchPublic() { + this.inc('synchPublic'); + return this.counters['synchPublic'] + 10; + } + + callSyncPrivate() { + this.synchPrivate(); + this.synchPrivate(); + } + + @memoize + private synchPrivate() { + this.inc('synchPrivate'); + return this.counters['synchPrivate'] + 20; + } + + @memoize + async asyncPublic() { + this.inc('asyncPublic'); + await sleep(1); + return this.counters['asyncPublic'] + 30; + } + + async callAsyncPrivate() { + await this.asyncPrivate(); + await this.asyncPrivate(); + } + + @memoize + private async asyncPrivate() { + this.inc('asyncPrivate'); + await sleep(1); + return this.counters['asyncPrivate'] + 40; + } + + @memoize + async asyncVoid() { + this.inc('asyncVoid'); + await sleep(1); + } + + private inc(name: string) { + if (!(name in this.counters)) { + this.counters[name] = 0; + } + this.counters[name]++; + } +} + +describe('memoize', () => { + let memoized: Memoized; + + beforeEach(() => { + memoized = new Memoized(); + }); + + it('memoizes public void', () => { + memoized.voidPublic(); + memoized.voidPublic(); + expect(memoized.counters['voidPublic']).toBe(1); + }); + + it('memoizes public synchronous', () => { + expect(memoized.synchPublic()).toBe(11); + expect(memoized.synchPublic()).toBe(11); + expect(memoized.counters['synchPublic']).toBe(1); + }); + + it('memoizes private synchronous', () => { + memoized.callSyncPrivate(); + memoized.callSyncPrivate(); + expect(memoized.counters['synchPrivate']).toBe(1); + }); + + it('memoizes public asynchronous', async () => { + expect(await memoized.asyncPublic()).toBe(31); + expect(await memoized.asyncPublic()).toBe(31); + expect(memoized.counters['asyncPublic']).toBe(1); + }); + + it('memoizes private asynchronous', async () => { + await memoized.callAsyncPrivate(); + await memoized.callAsyncPrivate(); + expect(memoized.counters['asyncPrivate']).toBe(1); + }); + + it('memoizes void asynchronous', async () => { + await memoized.asyncVoid(); + await memoized.asyncVoid(); + expect(memoized.counters['asyncVoid']).toBe(1); + }); +}); diff --git a/yarn-project/foundation/src/decorators/memoize.ts b/yarn-project/foundation/src/decorators/memoize.ts new file mode 100644 index 00000000000..ad4ee8377cf --- /dev/null +++ b/yarn-project/foundation/src/decorators/memoize.ts @@ -0,0 +1,11 @@ +export function memoize(fn: () => Result, context: ClassMethodDecoratorContext) { + return function (this: This) { + const key = `__${String(context.name)}_value`; + const thisWithKey = this as { [key: string]: Result }; + if (!(key in this)) { + const result = fn.call(this); + thisWithKey[key] = result; + } + return thisWithKey[key]; + }; +} diff --git a/yarn-project/ivc-integration/package.json b/yarn-project/ivc-integration/package.json index ed6eabfd7d0..a666ef9d1f1 100644 --- a/yarn-project/ivc-integration/package.json +++ b/yarn-project/ivc-integration/package.json @@ -39,6 +39,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/key-store/package.json b/yarn-project/key-store/package.json index 0bf868d644d..c66a9bd63a9 100644 --- a/yarn-project/key-store/package.json +++ b/yarn-project/key-store/package.json @@ -35,6 +35,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/kv-store/package.json b/yarn-project/kv-store/package.json index 2ca6477b149..ae05345eeaa 100644 --- a/yarn-project/kv-store/package.json +++ b/yarn-project/kv-store/package.json @@ -34,6 +34,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/merkle-tree/package.json b/yarn-project/merkle-tree/package.json index 0446f9a9d02..15447b9c794 100644 --- a/yarn-project/merkle-tree/package.json +++ b/yarn-project/merkle-tree/package.json @@ -37,6 +37,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/noir-contracts.js/package.json b/yarn-project/noir-contracts.js/package.json index be2ad23370e..eff346f3fe9 100644 --- a/yarn-project/noir-contracts.js/package.json +++ b/yarn-project/noir-contracts.js/package.json @@ -35,6 +35,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/noir-protocol-circuits-types/package.json b/yarn-project/noir-protocol-circuits-types/package.json index 7e1e56e654f..909ce8f37bf 100644 --- a/yarn-project/noir-protocol-circuits-types/package.json +++ b/yarn-project/noir-protocol-circuits-types/package.json @@ -40,6 +40,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/p2p-bootstrap/package.json b/yarn-project/p2p-bootstrap/package.json index 9e9d564c9ae..57225e75e38 100644 --- a/yarn-project/p2p-bootstrap/package.json +++ b/yarn-project/p2p-bootstrap/package.json @@ -61,6 +61,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/p2p/package.json b/yarn-project/p2p/package.json index 5a4260dc257..14e66ce63ef 100644 --- a/yarn-project/p2p/package.json +++ b/yarn-project/p2p/package.json @@ -37,6 +37,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/package.common.json b/yarn-project/package.common.json index 7ef660b828e..f3d2aca61c5 100644 --- a/yarn-project/package.common.json +++ b/yarn-project/package.common.json @@ -28,6 +28,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/proof-verifier/package.json b/yarn-project/proof-verifier/package.json index 1a6c5f42afd..56db1a57b3f 100644 --- a/yarn-project/proof-verifier/package.json +++ b/yarn-project/proof-verifier/package.json @@ -39,6 +39,9 @@ "ts-node": "^10.9.1", "typescript": "^5.0.4" }, + "inherits": [ + "../package.common.json" + ], "jest": { "extensionsToTreatAsEsm": [ ".ts" @@ -51,6 +54,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/protocol-contracts/package.json b/yarn-project/protocol-contracts/package.json index c7bff393480..0bae20accc8 100644 --- a/yarn-project/protocol-contracts/package.json +++ b/yarn-project/protocol-contracts/package.json @@ -46,6 +46,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index 9a99cddb3d8..986f559d49c 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -42,6 +42,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/prover-node/package.json b/yarn-project/prover-node/package.json index 21c4d635e3e..b7130d53215 100644 --- a/yarn-project/prover-node/package.json +++ b/yarn-project/prover-node/package.json @@ -31,6 +31,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/pxe/package.json b/yarn-project/pxe/package.json index 1f0e9c1aaf4..b36c544458d 100644 --- a/yarn-project/pxe/package.json +++ b/yarn-project/pxe/package.json @@ -38,6 +38,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/scripts/package.json b/yarn-project/scripts/package.json index 0f5849a2ab2..99dc133984f 100644 --- a/yarn-project/scripts/package.json +++ b/yarn-project/scripts/package.json @@ -65,6 +65,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/sequencer-client/package.json b/yarn-project/sequencer-client/package.json index 835dd9bbea1..9b7e9212da4 100644 --- a/yarn-project/sequencer-client/package.json +++ b/yarn-project/sequencer-client/package.json @@ -89,6 +89,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/simulator/package.json b/yarn-project/simulator/package.json index 8356b976f28..33694b0aea7 100644 --- a/yarn-project/simulator/package.json +++ b/yarn-project/simulator/package.json @@ -38,6 +38,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/telemetry-client/package.json b/yarn-project/telemetry-client/package.json index 6647847ff44..ecbc5444c34 100644 --- a/yarn-project/telemetry-client/package.json +++ b/yarn-project/telemetry-client/package.json @@ -56,6 +56,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/txe/package.json b/yarn-project/txe/package.json index ca291a0e2db..f9c6c329220 100644 --- a/yarn-project/txe/package.json +++ b/yarn-project/txe/package.json @@ -39,6 +39,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/types/package.json b/yarn-project/types/package.json index 4fe9e6e145b..ac680f83686 100644 --- a/yarn-project/types/package.json +++ b/yarn-project/types/package.json @@ -41,6 +41,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/validator-client/package.json b/yarn-project/validator-client/package.json index 23ca3b59106..a3cb3cf04fa 100644 --- a/yarn-project/validator-client/package.json +++ b/yarn-project/validator-client/package.json @@ -38,6 +38,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } } diff --git a/yarn-project/world-state/package.json b/yarn-project/world-state/package.json index 8c7a1f793e7..f1d6e33fd60 100644 --- a/yarn-project/world-state/package.json +++ b/yarn-project/world-state/package.json @@ -39,6 +39,9 @@ "parser": { "syntax": "typescript", "decorators": true + }, + "transform": { + "decoratorVersion": "2022-03" } } }