diff --git a/yarn-project/accounts/package.json b/yarn-project/accounts/package.json index d4d3d8ab9168..0817971899bb 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 4afb656f15c5..ff0dd170380f 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 54eb3313a3d9..6d8ccc7a0220 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 f2bbd2972dec..30d19cff4e9a 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 40ff9add3382..98f57facfd73 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 bcc6c9196c55..9e85f69d16a4 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 7adf7f8a7eb0..efdeb93cc5c8 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 6e187ffd065b..ac515b882187 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 acde8d5092b1..597b83807a11 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 6e874e8b1297..b06d89e907c1 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 82ea912b59f5..5a83df9826bd 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 ea37249686db..e8fe9b83dfb5 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 c0f4af797327..b6a9891babd8 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 98d1e156cd4c..bf630f4e0475 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 48c6c5535a49..6a278c79364b 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 b7518c9547fe..2e49f7f23244 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 2af937f8c183..b63a267cbfe3 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 000000000000..4ed809e11dfc --- /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 000000000000..badd35e86645 --- /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 000000000000..ad4ee8377cf4 --- /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 ed6eabfd7d04..a666ef9d1f1b 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 0bf868d644d2..c66a9bd63a99 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 2ca6477b1498..ae05345eeaad 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 0446f9a9d02c..15447b9c794c 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 be2ad23370e2..eff346f3fe9c 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 7e1e56e654f4..909ce8f37bfc 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 9e9d564c9aee..57225e75e381 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 5a4260dc2579..14e66ce63efd 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 7ef660b828e2..f3d2aca61c5b 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 1a6c5f42afd7..56db1a57b3f5 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 c7bff393480f..0bae20accc83 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 9a99cddb3d81..986f559d49cd 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 21c4d635e3e5..b7130d53215e 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 1f0e9c1aaf45..b36c544458df 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 0f5849a2ab2e..99dc133984f4 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 835dd9bbea1e..9b7e9212da44 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 8356b976f28b..33694b0aea72 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 6647847ff448..ecbc5444c34d 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 ca291a0e2dbd..f9c6c329220e 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 4fe9e6e145b8..ac680f836866 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 23ca3b591068..a3cb3cf04faf 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 8c7a1f793e7f..f1d6e33fd609 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" } } }