From 68cb4db560f3902cb83c463e24e0a05668f21c19 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Wed, 29 Jan 2025 17:35:26 +0100 Subject: [PATCH 01/23] Renamed SimpleAsyncStateService file --- packages/protocol/src/index.ts | 2 +- packages/protocol/src/protocol/Protocol.ts | 2 +- packages/protocol/src/protocol/ProtocolEnvironment.ts | 2 +- .../src/state/{StateService.ts => SimpleAsyncStateService.ts} | 0 packages/protocol/src/state/StateServiceProvider.ts | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename packages/protocol/src/state/{StateService.ts => SimpleAsyncStateService.ts} (100%) diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index e4419af3a..52cb8af4b 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -39,7 +39,7 @@ export * from "./state/context/RuntimeMethodExecutionContext"; export * from "./state/protocol/ProtocolState"; export * from "./state/State"; export * from "./state/StateMap"; -export * from "./state/StateService"; +export * from "./state/SimpleAsyncStateService"; export * from "./state/StateServiceProvider"; export * from "./state/assert/assert"; export * from "./settlement/contracts/authorizations/ContractAuthorization"; diff --git a/packages/protocol/src/protocol/Protocol.ts b/packages/protocol/src/protocol/Protocol.ts index f9ebb6fdc..79d086e8d 100644 --- a/packages/protocol/src/protocol/Protocol.ts +++ b/packages/protocol/src/protocol/Protocol.ts @@ -13,7 +13,7 @@ import { DependencyContainer, Lifecycle } from "tsyringe"; import { BlockProvable } from "../prover/block/BlockProvable"; import { StateTransitionProvable } from "../prover/statetransition/StateTransitionProvable"; import { StateServiceProvider } from "../state/StateServiceProvider"; -import { SimpleAsyncStateService } from "../state/StateService"; +import { SimpleAsyncStateService } from "../state/SimpleAsyncStateService"; import { NoopBlockHook } from "../hooks/NoopBlockHook"; import { BlockHeightHook } from "../hooks/BlockHeightHook"; import { LastStateRootBlockHook } from "../hooks/LastStateRootBlockHook"; diff --git a/packages/protocol/src/protocol/ProtocolEnvironment.ts b/packages/protocol/src/protocol/ProtocolEnvironment.ts index f6a291de7..5203694b1 100644 --- a/packages/protocol/src/protocol/ProtocolEnvironment.ts +++ b/packages/protocol/src/protocol/ProtocolEnvironment.ts @@ -1,6 +1,6 @@ import { AreProofsEnabled } from "@proto-kit/common"; -import { SimpleAsyncStateService } from "../state/StateService"; +import { SimpleAsyncStateService } from "../state/SimpleAsyncStateService"; import { StateServiceProvider } from "../state/StateServiceProvider"; export interface ProtocolEnvironment { diff --git a/packages/protocol/src/state/StateService.ts b/packages/protocol/src/state/SimpleAsyncStateService.ts similarity index 100% rename from packages/protocol/src/state/StateService.ts rename to packages/protocol/src/state/SimpleAsyncStateService.ts diff --git a/packages/protocol/src/state/StateServiceProvider.ts b/packages/protocol/src/state/StateServiceProvider.ts index d39fea612..40d54717b 100644 --- a/packages/protocol/src/state/StateServiceProvider.ts +++ b/packages/protocol/src/state/StateServiceProvider.ts @@ -1,7 +1,7 @@ import { injectable } from "tsyringe"; import { log } from "@proto-kit/common"; -import { SimpleAsyncStateService } from "./StateService"; +import { SimpleAsyncStateService } from "./SimpleAsyncStateService"; const errors = { stateServiceNotSet: () => From c5052dcb1d62c3c6c216d794df444b419600e9a6 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 30 Jan 2025 18:42:39 +0100 Subject: [PATCH 02/23] Added masking methods to AsyncStateService interface --- .../src/state/async/AsyncStateService.ts | 16 +++++++++++----- .../src/state/state/CachedStateService.ts | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/sequencer/src/state/async/AsyncStateService.ts b/packages/sequencer/src/state/async/AsyncStateService.ts index b5420abc3..b5e7a1be0 100644 --- a/packages/sequencer/src/state/async/AsyncStateService.ts +++ b/packages/sequencer/src/state/async/AsyncStateService.ts @@ -11,13 +11,19 @@ export interface StateEntry { * CachedStateService to preload keys for In-Circuit usage. */ export interface AsyncStateService { - openTransaction: () => Promise; + openTransaction(): Promise; - commit: () => Promise; + commit(): Promise; - writeStates: (entries: StateEntry[]) => void; + writeStates(entries: StateEntry[]): void; - getMany: (keys: Field[]) => Promise; + getMany(keys: Field[]): Promise; - get: (key: Field) => Promise; + get(key: Field): Promise; + + createMask(name: string): Promise; + + mergeIntoParent(): Promise; + + drop(): Promise; } diff --git a/packages/sequencer/src/state/state/CachedStateService.ts b/packages/sequencer/src/state/state/CachedStateService.ts index 2824ba418..5af85e235 100644 --- a/packages/sequencer/src/state/state/CachedStateService.ts +++ b/packages/sequencer/src/state/state/CachedStateService.ts @@ -15,10 +15,22 @@ export class CachedStateService { private writes: StateEntry[] = []; - public constructor(private readonly parent: AsyncStateService | undefined) { + public constructor( + private readonly parent: AsyncStateService | undefined, + public readonly name?: string + ) { super(); } + public async createMask(name: string): Promise { + return new CachedStateService(this, name); + } + + public async drop(): Promise { + this.writes = []; + this.values = {}; + } + /** * Works like get(), but if a value is in this store, * but is known to be empty, this will return null @@ -43,6 +55,7 @@ export class CachedStateService await mapSequential(this.writes, async ({ key, value }) => { await this.set(key, value); }); + this.writes = []; } public async openTransaction(): Promise { From 875419406fa5ae64b0b096e452bf264ba3252a7c Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 30 Jan 2025 18:53:03 +0100 Subject: [PATCH 03/23] Implemented DB-native masking for PrismaStateService --- packages/persistance/package.json | 6 +- .../migration.sql | 29 ++++ packages/persistance/prisma/schema.prisma | 20 ++- .../sql/deleteCollisionsFromParentMask.sql | 18 +++ .../prisma/sql/mergeIntoParent.sql | 10 ++ packages/persistance/prisma/sql/readState.sql | 10 ++ .../src/PrismaDatabaseConnection.ts | 4 +- .../src/services/prisma/PrismaStateService.ts | 131 +++++++++++++++--- .../persistance/test-integration/utils.ts | 11 +- 9 files changed, 200 insertions(+), 39 deletions(-) create mode 100644 packages/persistance/prisma/migrations/20250129151707_state_masking/migration.sql create mode 100644 packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql create mode 100644 packages/persistance/prisma/sql/mergeIntoParent.sql create mode 100644 packages/persistance/prisma/sql/readState.sql diff --git a/packages/persistance/package.json b/packages/persistance/package.json index a58550706..1ae13a6c1 100644 --- a/packages/persistance/package.json +++ b/packages/persistance/package.json @@ -6,7 +6,7 @@ "version": "0.1.1-develop.833+397881ed", "scripts": { "build": "npm run prisma-generate && tsc -p tsconfig.json", - "prisma-generate": "npx prisma generate", + "prisma-generate": "npx prisma generate --sql", "prisma-migrate": "npx prisma migrate deploy", "dev": "tsc -p tsconfig.json --watch", "lint": "eslint ./src ./test ./test-integration", @@ -20,9 +20,9 @@ "access": "public" }, "dependencies": { - "@prisma/client": "^5.18.0", + "@prisma/client": "^5.22.0", "lodash": "^4.17.21", - "prisma": "^5.18.0", + "prisma": "^5.22.0", "redis": "^4.6.12", "reflect-metadata": "^0.1.13" }, diff --git a/packages/persistance/prisma/migrations/20250129151707_state_masking/migration.sql b/packages/persistance/prisma/migrations/20250129151707_state_masking/migration.sql new file mode 100644 index 000000000..bb4f4821c --- /dev/null +++ b/packages/persistance/prisma/migrations/20250129151707_state_masking/migration.sql @@ -0,0 +1,29 @@ +/* + Warnings: + + - The primary key for the `State` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `mask` on the `State` table. All the data in the column will be lost. + - Added the required column `maskId` to the `State` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +TRUNCATE TABLE "State"; +ALTER TABLE "State" DROP CONSTRAINT "State_pkey", +DROP COLUMN "mask", +ADD COLUMN "maskId" INTEGER NOT NULL, +ADD CONSTRAINT "State_pkey" PRIMARY KEY ("path", "maskId"); + +-- CreateTable +CREATE TABLE "Mask" ( + "id" SERIAL NOT NULL, + "name" VARCHAR(256) NOT NULL, + "parent" INTEGER, + + CONSTRAINT "Mask_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "State" ADD CONSTRAINT "State_maskId_fkey" FOREIGN KEY ("maskId") REFERENCES "Mask"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Mask" ADD CONSTRAINT "Mask_parent_fkey" FOREIGN KEY ("parent") REFERENCES "Mask"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/persistance/prisma/schema.prisma b/packages/persistance/prisma/schema.prisma index 58c214477..19f4899ca 100644 --- a/packages/persistance/prisma/schema.prisma +++ b/packages/persistance/prisma/schema.prisma @@ -2,10 +2,10 @@ // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" // output = "./../node_modules/.prisma/client" // Enable after upgrade to 5.9.0 - // previewFeatures = ["relationJoins"] + previewFeatures = ["typedSql"] } datasource db { @@ -16,9 +16,21 @@ datasource db { model State { path Decimal @db.Decimal(78, 0) values Decimal[] @db.Decimal(78, 0) - mask String @db.VarChar(256) - @@id([path, mask]) + maskId Int + mask Mask @relation(fields: [maskId], references: [id]) + + @@id([path, maskId]) +} + +model Mask { + id Int @id @default(autoincrement()) + name String @db.VarChar(256) + + parent Int? + parentMask Mask? @relation("ParentMasks", fields: [parent], references: [id]) + children Mask[] @relation("ParentMasks") + State State[] } model Transaction { diff --git a/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql b/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql new file mode 100644 index 000000000..7f38962b6 --- /dev/null +++ b/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql @@ -0,0 +1,18 @@ +/* + DELETE PATHS FROM PARENT MASK + + Strategy on this query: + 1. Find the mask we are interested in, as a record with the id and it's parent id + 2. Select all paths that exist on that mask + 3. Delete all records whose mask is the parent of (1), and whose path is contained in (2) + */ + +WITH mask AS ( + SELECT id, parent FROM "Mask" m WHERE m.id = $1), +paths AS ( + SELECT path FROM "State" s + JOIN mask m on s."maskId" = m.id + ) +DELETE FROM "State" s + WHERE s."maskId" IN (SELECT parent FROM mask) + AND s.path IN (SELECT path FROM paths) \ No newline at end of file diff --git a/packages/persistance/prisma/sql/mergeIntoParent.sql b/packages/persistance/prisma/sql/mergeIntoParent.sql new file mode 100644 index 000000000..2f2e3f754 --- /dev/null +++ b/packages/persistance/prisma/sql/mergeIntoParent.sql @@ -0,0 +1,10 @@ +/* +Strategy: + 1. Find the mask we are interested in, as a record with the id and it's parent id + 2. Update the maskId to the masks parent for all the entries of that particular mask +*/ + +WITH mask AS ( + SELECT id, parent FROM "Mask" m WHERE m.id = $1) +UPDATE "State" SET "maskId" = (SELECT parent FROM mask) +WHERE "maskId" = (SELECT id FROM mask) \ No newline at end of file diff --git a/packages/persistance/prisma/sql/readState.sql b/packages/persistance/prisma/sql/readState.sql new file mode 100644 index 000000000..a19b7229d --- /dev/null +++ b/packages/persistance/prisma/sql/readState.sql @@ -0,0 +1,10 @@ +WITH RECURSIVE find_masks(id, parent) AS ( + SELECT m.id, m.parent FROM "Mask" m WHERE m.id = $1 + UNION ALL + SELECT s.id, s.parent FROM "Mask" s, find_masks f + WHERE f.parent = s.id +) +SELECT distinct on (state.path) state.path, state.values FROM find_masks + JOIN "State" state ON state."maskId" = find_masks.id +WHERE state.path = ANY($2) +ORDER BY state.path, state."maskId" DESC; \ No newline at end of file diff --git a/packages/persistance/src/PrismaDatabaseConnection.ts b/packages/persistance/src/PrismaDatabaseConnection.ts index 54f5cfb30..f70d06516 100644 --- a/packages/persistance/src/PrismaDatabaseConnection.ts +++ b/packages/persistance/src/PrismaDatabaseConnection.ts @@ -64,9 +64,6 @@ export class PrismaDatabaseConnection blockStorage: { useClass: PrismaBlockStorage, }, - unprovenStateService: { - useFactory: () => new PrismaStateService(this, "block"), - }, settlementStorage: { useClass: PrismaSettlementStorage, }, @@ -90,6 +87,7 @@ export class PrismaDatabaseConnection "Settlement", "IncomingMessageBatch", "IncomingMessageBatchTransaction", + "Mask", ]; await this.prismaClient.$transaction( diff --git a/packages/persistance/src/services/prisma/PrismaStateService.ts b/packages/persistance/src/services/prisma/PrismaStateService.ts index 8e34fd22c..6e0ec964c 100644 --- a/packages/persistance/src/services/prisma/PrismaStateService.ts +++ b/packages/persistance/src/services/prisma/PrismaStateService.ts @@ -1,6 +1,11 @@ import { AsyncStateService, StateEntry } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { Prisma } from "@prisma/client"; +import { + readState, + deleteCollisionsFromParentMask, + mergeIntoParent, +} from "@prisma/client/sql"; import { noop } from "@proto-kit/common"; import { injectable } from "tsyringe"; @@ -16,24 +21,60 @@ const Decimal = Prisma.Decimal.clone({ export class PrismaStateService implements AsyncStateService { private cache: StateEntry[] = []; + private maskId?: number; + /** * @param connection - * @param mask A indicator to which masking level the values belong + * @param mask A indicator to which masking level the values belong. + * This name has to be unique + * @param parent */ public constructor( private readonly connection: PrismaConnection, - private readonly mask: string + private readonly mask: string, + private readonly parent?: number ) {} + private async getMaskId(): Promise { + if (this.maskId === undefined) { + this.maskId = await this.initializeMask(this.mask, this.parent); + } + return this.maskId; + } + + private async initializeMask(mask: string, parent?: number): Promise { + const { prismaClient } = this.connection; + + const found = await prismaClient.mask.findFirst({ + where: { + name: mask, + parent, + }, + }); + + if (found === null) { + const createdMask = await prismaClient.mask.create({ + data: { + parent, + name: mask, + }, + }); + return createdMask.id; + } + return found.id; + } + public async commit(): Promise { const { prismaClient } = this.connection; + const maskId = await this.getMaskId(); + const data = this.cache .filter((entry) => entry.value !== undefined) .map((entry) => ({ path: new Decimal(entry.key.toString()), values: entry.value!.map((field) => new Decimal(field.toString())), - mask: this.mask, + maskId, })); await prismaClient.state.deleteMany({ @@ -41,7 +82,7 @@ export class PrismaStateService implements AsyncStateService { path: { in: this.cache.map((x) => new Decimal(x.key.toString())), }, - mask: this.mask, + maskId, }, }); await prismaClient.state.createMany({ @@ -52,23 +93,17 @@ export class PrismaStateService implements AsyncStateService { } public async getMany(keys: Field[]): Promise { - const records = await this.connection.prismaClient.state.findMany({ - where: { - AND: [ - { - path: { - in: keys.map((key) => new Decimal(key.toString())), - }, - }, - { - mask: this.mask, - }, - ], - }, - }); + const maskId = await this.getMaskId(); + const paths = keys.map((key) => new Decimal(key.toString())); + + const records = await this.connection.prismaClient.$queryRawTyped( + readState(maskId, paths) + ); + return records.map((record) => ({ key: Field(record.path.toFixed()), - value: record.values.map((x) => Field(x.toFixed())), + // TODO Figure out why that is nullable + value: record.values?.map((x) => Field(x.toFixed())) ?? [], })); } @@ -84,4 +119,62 @@ export class PrismaStateService implements AsyncStateService { public writeStates(entries: StateEntry[]): void { this.cache.push(...entries); } + + public async createMask(name: string): Promise { + const maskId = await this.getMaskId(); + return new PrismaStateService(this.connection, name, maskId); + } + + public async mergeIntoParent(): Promise { + const maskId = await this.getMaskId(); + + const client = this.connection.prismaClient; + + if (this.parent !== undefined) { + // Rough strategy here: + // 1. Delete all entries that are bound to be overwritten from the parent mask + // 2. Update this mask's entries to parent mask id + // 3. Re-link all children of this mask to this mask's parent + // 4. Delete mask + + await client.$transaction([ + client.$queryRawTyped(deleteCollisionsFromParentMask(maskId)), + // MergeIntoParent could be a prisma query, but it isn't, because eventually, + // this Service should be stateless, therefore the parentId wouldn't be on hand + // anymore, so we need to inline it's retrieval into the query + client.$queryRawTyped(mergeIntoParent(maskId)), + client.mask.updateMany({ + where: { + parent: maskId, + }, + data: { + parent: this.parent, + }, + }), + client.mask.delete({ + where: { + id: maskId, + }, + }), + ]); + } else { + throw new Error("Can't merge into parent without a parent"); + } + } + + public async drop(): Promise { + const maskId = await this.getMaskId(); + + await this.connection.prismaClient.state.deleteMany({ + where: { + maskId, + }, + }); + + await this.connection.prismaClient.mask.delete({ + where: { + id: maskId, + }, + }); + } } diff --git a/packages/persistance/test-integration/utils.ts b/packages/persistance/test-integration/utils.ts index c0476478e..e42b336e8 100644 --- a/packages/persistance/test-integration/utils.ts +++ b/packages/persistance/test-integration/utils.ts @@ -146,16 +146,7 @@ export function createPrismaAppchain( BlockTrigger: {}, Mempool: {}, BatchProducerModule: {}, - LocalTaskWorkerModule: { - StateTransitionTask: {}, - RuntimeProvingTask: {}, - StateTransitionReductionTask: {}, - BlockReductionTask: {}, - BlockProvingTask: {}, - BlockBuildingTask: {}, - CircuitCompilerTask: {}, - WorkerRegistrationTask: {}, - }, + LocalTaskWorkerModule: VanillaTaskWorkerModules.defaultConfig(), BaseLayer: {}, BlockProducerModule: {}, TaskQueue: { From 8ab675e0e72c31862c86b1373ee7b511a8c2ff7f Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 18 Feb 2025 11:35:41 +0100 Subject: [PATCH 04/23] Removed dependency on typedSQL --- nx.json | 1 + package-lock.json | 951 +++++++++--------- packages/indexer/package.json | 2 +- packages/persistance/package.json | 2 +- packages/persistance/prisma/schema.prisma | 5 +- .../sql/deleteCollisionsFromParentMask.sql | 18 - .../prisma/sql/mergeIntoParent.sql | 10 - packages/persistance/prisma/sql/readState.sql | 10 - .../src/services/prisma/PrismaStateService.ts | 18 +- .../sql/deleteCollisionsFromParentMask.ts | 24 + .../services/prisma/sql/mergeIntoParent.ts | 16 + .../src/services/prisma/sql/readState.ts | 16 + packages/processor/package.json | 2 +- 13 files changed, 528 insertions(+), 547 deletions(-) delete mode 100644 packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql delete mode 100644 packages/persistance/prisma/sql/mergeIntoParent.sql delete mode 100644 packages/persistance/prisma/sql/readState.sql create mode 100644 packages/persistance/src/services/prisma/sql/deleteCollisionsFromParentMask.ts create mode 100644 packages/persistance/src/services/prisma/sql/mergeIntoParent.ts create mode 100644 packages/persistance/src/services/prisma/sql/readState.ts diff --git a/nx.json b/nx.json index 816559d48..3729decc9 100644 --- a/nx.json +++ b/nx.json @@ -17,6 +17,7 @@ "prisma:generate": { "inputs": [ "{projectRoot}/package.json", + "{projectRoot}/prisma/*", "{projectRoot}/prisma/**/*" ] }, diff --git a/package-lock.json b/package-lock.json index d311f8a4e..6c39628ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,6 +85,7 @@ }, "node_modules/@ampproject/remapping": { "version": "2.3.0", + "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -96,6 +97,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/highlight": "^7.24.7", @@ -107,6 +109,7 @@ }, "node_modules/@babel/compat-data": { "version": "7.24.7", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -114,6 +117,7 @@ }, "node_modules/@babel/core": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -142,6 +146,7 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -149,6 +154,7 @@ }, "node_modules/@babel/generator": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7", @@ -162,6 +168,7 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.24.7", @@ -176,6 +183,7 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -183,6 +191,7 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -193,6 +202,7 @@ }, "node_modules/@babel/helper-function-name": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", @@ -204,6 +214,7 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -214,6 +225,7 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", @@ -225,6 +237,7 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", @@ -242,6 +255,7 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.24.7", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -249,6 +263,7 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", @@ -260,6 +275,7 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -270,6 +286,7 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.24.7", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -277,6 +294,7 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.24.7", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -284,6 +302,7 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.24.7", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -291,6 +310,7 @@ }, "node_modules/@babel/helpers": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", @@ -302,6 +322,7 @@ }, "node_modules/@babel/highlight": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", @@ -315,6 +336,7 @@ }, "node_modules/@babel/parser": { "version": "7.24.7", + "dev": true, "license": "MIT", "bin": { "parser": "bin/babel-parser.js" @@ -325,6 +347,7 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -335,6 +358,7 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -345,6 +369,7 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -355,6 +380,7 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -365,6 +391,7 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -375,6 +402,7 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -388,6 +416,7 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -398,6 +427,7 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -408,6 +438,7 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -418,6 +449,7 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -428,6 +460,7 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -438,6 +471,7 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -448,6 +482,7 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -461,6 +496,7 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -474,6 +510,7 @@ }, "node_modules/@babel/template": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", @@ -486,6 +523,7 @@ }, "node_modules/@babel/traverse": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", @@ -505,6 +543,7 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -512,6 +551,7 @@ }, "node_modules/@babel/types": { "version": "7.24.7", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.24.7", @@ -524,6 +564,7 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", + "dev": true, "license": "MIT" }, "node_modules/@commitlint/config-validator": { @@ -1085,11 +1126,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ioredis/commands": { - "version": "1.2.0", - "license": "MIT", - "peer": true - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -1186,6 +1222,7 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -1200,6 +1237,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", + "dev": true, "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" @@ -1207,6 +1245,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -1218,6 +1257,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", + "dev": true, "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -1229,6 +1269,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -1239,6 +1280,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -1252,6 +1294,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -1262,10 +1305,12 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { "version": "1.0.3", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1273,6 +1318,7 @@ }, "node_modules/@jest/console": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -1288,6 +1334,7 @@ }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1301,6 +1348,7 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1315,6 +1363,7 @@ }, "node_modules/@jest/console/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1325,10 +1374,12 @@ }, "node_modules/@jest/console/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/console/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1336,6 +1387,7 @@ }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1346,6 +1398,7 @@ }, "node_modules/@jest/core": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -1391,6 +1444,7 @@ }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1404,6 +1458,7 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1418,6 +1473,7 @@ }, "node_modules/@jest/core/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1428,10 +1484,12 @@ }, "node_modules/@jest/core/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1439,6 +1497,7 @@ }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1449,6 +1508,7 @@ }, "node_modules/@jest/environment": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", @@ -1462,6 +1522,7 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -1473,6 +1534,7 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -1483,6 +1545,7 @@ }, "node_modules/@jest/fake-timers": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -1498,6 +1561,7 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -1511,6 +1575,7 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -1552,6 +1617,7 @@ }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1565,6 +1631,7 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1579,6 +1646,7 @@ }, "node_modules/@jest/reporters/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1589,10 +1657,12 @@ }, "node_modules/@jest/reporters/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1600,6 +1670,7 @@ }, "node_modules/@jest/reporters/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1610,6 +1681,7 @@ }, "node_modules/@jest/schemas": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -1620,6 +1692,7 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -1632,6 +1705,7 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -1645,6 +1719,7 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -1658,6 +1733,7 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -1682,6 +1758,7 @@ }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1695,6 +1772,7 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1709,6 +1787,7 @@ }, "node_modules/@jest/transform/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1719,10 +1798,12 @@ }, "node_modules/@jest/transform/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1730,6 +1811,7 @@ }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1740,6 +1822,7 @@ }, "node_modules/@jest/types": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -1755,6 +1838,7 @@ }, "node_modules/@jest/types/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1768,6 +1852,7 @@ }, "node_modules/@jest/types/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1782,6 +1867,7 @@ }, "node_modules/@jest/types/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1792,10 +1878,12 @@ }, "node_modules/@jest/types/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1803,6 +1891,7 @@ }, "node_modules/@jest/types/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1813,6 +1902,7 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -1825,6 +1915,7 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1832,6 +1923,7 @@ }, "node_modules/@jridgewell/set-array": { "version": "1.2.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1839,10 +1931,12 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2465,20 +2559,9 @@ "node": ">=10" } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -2490,6 +2573,7 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -2497,6 +2581,7 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -3258,10 +3343,11 @@ } }, "node_modules/@prisma/client": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.21.1.tgz", - "integrity": "sha512-3n+GgbAZYjaS/k0M03yQsQfR1APbr411r74foknnsGpmhNKBG49VuUkxIU6jORgvJPChoD4WC4PqoHImN1FP0w==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz", + "integrity": "sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==", "hasInstallScript": true, + "license": "Apache-2.0", "engines": { "node": ">=16.13" }, @@ -3274,102 +3360,6 @@ } } }, - "node_modules/@prisma/debug": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.21.1.tgz", - "integrity": "sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA==" - }, - "node_modules/@prisma/engines": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.21.1.tgz", - "integrity": "sha512-hGVTldUkIkTwoV8//hmnAAiAchi4oMEKD3aW5H2RrnI50tTdwza7VQbTTAyN3OIHWlK5DVg6xV7X8N/9dtOydA==", - "hasInstallScript": true, - "dependencies": { - "@prisma/debug": "5.21.1", - "@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "@prisma/fetch-engine": "5.21.1", - "@prisma/get-platform": "5.21.1" - } - }, - "node_modules/@prisma/engines-version": { - "version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36.tgz", - "integrity": "sha512-qvnEflL0//lh44S/T9NcvTMxfyowNeUxTunPcDfKPjyJNrCNf2F1zQLcUv5UHAruECpX+zz21CzsC7V2xAeM7Q==" - }, - "node_modules/@prisma/fetch-engine": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.21.1.tgz", - "integrity": "sha512-70S31vgpCGcp9J+mh/wHtLCkVezLUqe/fGWk3J3JWZIN7prdYSlr1C0niaWUyNK2VflLXYi8kMjAmSxUVq6WGQ==", - "dependencies": { - "@prisma/debug": "5.21.1", - "@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "@prisma/get-platform": "5.21.1" - } - }, - "node_modules/@prisma/generator-helper": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.21.1.tgz", - "integrity": "sha512-56+FLaNGO7uKIEjN5asV7L0cAWqTc+IoyFbtafYnzfvBS3HURgT+l9UGHrHfPO5EWFiot3my3UOJ/hGZfhNPbA==", - "peer": true, - "dependencies": { - "@prisma/debug": "5.21.1" - } - }, - "node_modules/@prisma/get-platform": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.21.1.tgz", - "integrity": "sha512-sRxjL3Igst3ct+e8ya/x//cDXmpLbZQ5vfps2N4tWl4VGKQAmym77C/IG/psSMsQKszc8uFC/q1dgmKFLUgXZQ==", - "dependencies": { - "@prisma/debug": "5.21.1" - } - }, - "node_modules/@prisma/internals": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/internals/-/internals-5.21.1.tgz", - "integrity": "sha512-XCjJUUDBwT0ioLrTfUKA/YsVs5gtWtMisxRssGS5tgqVaVzc8XEY01avtYIzyhz8RDLn7QlecTQGHW+5J9+w6Q==", - "peer": true, - "dependencies": { - "@prisma/debug": "5.21.1", - "@prisma/engines": "5.21.1", - "@prisma/fetch-engine": "5.21.1", - "@prisma/generator-helper": "5.21.1", - "@prisma/get-platform": "5.21.1", - "@prisma/prisma-schema-wasm": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "@prisma/schema-files-loader": "5.21.1", - "arg": "5.0.2", - "prompts": "2.4.2" - } - }, - "node_modules/@prisma/prisma-schema-wasm": { - "version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "resolved": "https://registry.npmjs.org/@prisma/prisma-schema-wasm/-/prisma-schema-wasm-5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36.tgz", - "integrity": "sha512-JJnZ7A0CSW4SNFSWe2/GexJ/Z5s69+3UqbsBuGxJe7EQyVgw/hmskmhFmM4gccihh9PA2hlDip5kmraAfO7vSA==", - "peer": true - }, - "node_modules/@prisma/schema-files-loader": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/@prisma/schema-files-loader/-/schema-files-loader-5.21.1.tgz", - "integrity": "sha512-rcZgI4rSq5tlieWQ5e+AfyjquwQ+d2vCecvbf9qvfcvs/Nw5FbjAPTLEx9l4g/iW4qgc0CTPLr19azD3npwHQw==", - "peer": true, - "dependencies": { - "@prisma/prisma-schema-wasm": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", - "fs-extra": "11.1.1" - } - }, - "node_modules/@prisma/schema-files-loader/node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/@proto-kit/api": { "resolved": "packages/api", "link": true @@ -3679,10 +3669,12 @@ }, "node_modules/@sinclair/typebox": { "version": "0.27.8", + "dev": true, "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -3690,6 +3682,7 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -3703,33 +3696,6 @@ "node": ">= 10" } }, - "node_modules/@ts-morph/common": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz", - "integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==", - "peer": true, - "dependencies": { - "fast-glob": "^3.3.2", - "minimatch": "^9.0.4", - "mkdirp": "^3.0.1", - "path-browserify": "^1.0.1" - } - }, - "node_modules/@ts-morph/common/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "peer": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", "dev": true, @@ -3760,6 +3726,7 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -3771,6 +3738,7 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.8", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -3778,6 +3746,7 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -3786,6 +3755,7 @@ }, "node_modules/@types/babel__traverse": { "version": "7.20.6", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" @@ -3868,20 +3838,12 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.9", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" } }, - "node_modules/@types/graphql-fields": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/@types/graphql-fields/-/graphql-fields-1.3.9.tgz", - "integrity": "sha512-HynTnp1HrE58uYcFcAK5UOfdrHSOIHDLCjvMU4yCmQLMj21uo7ZiZqnDGrD27pgCgHH5a1e8GYNK98Ndmma7ig==", - "peer": true, - "dependencies": { - "graphql": "*" - } - }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", @@ -3918,10 +3880,12 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", + "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", + "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -3929,6 +3893,7 @@ }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" @@ -4032,7 +3997,7 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "devOptional": true + "dev": true }, "node_modules/@types/qs": { "version": "6.9.15", @@ -4048,7 +4013,7 @@ "version": "18.3.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", - "devOptional": true, + "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4079,6 +4044,7 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.3", + "dev": true, "license": "MIT" }, "node_modules/@types/unist": { @@ -4668,6 +4634,7 @@ }, "node_modules/ansi-styles": { "version": "3.2.1", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -4678,6 +4645,7 @@ }, "node_modules/anymatch": { "version": "3.1.3", + "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -4724,12 +4692,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "peer": true - }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -4934,6 +4896,7 @@ }, "node_modules/babel-jest": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -4953,6 +4916,7 @@ }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4966,6 +4930,7 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4980,6 +4945,7 @@ }, "node_modules/babel-jest/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4990,10 +4956,12 @@ }, "node_modules/babel-jest/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5001,6 +4969,7 @@ }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -5011,6 +4980,7 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -5025,6 +4995,7 @@ }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -5039,6 +5010,7 @@ }, "node_modules/babel-plugin-istanbul/node_modules/semver": { "version": "6.3.1", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -5046,6 +5018,7 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -5059,6 +5032,7 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -5080,6 +5054,7 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -5094,6 +5069,7 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -5187,13 +5163,9 @@ "readable-stream": "^3.4.0" } }, - "node_modules/blakejs": { - "version": "1.2.1", - "license": "MIT", - "peer": true - }, "node_modules/brace-expansion": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -5201,6 +5173,7 @@ }, "node_modules/braces": { "version": "3.0.3", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -5211,6 +5184,7 @@ }, "node_modules/browserslist": { "version": "4.23.1", + "dev": true, "funding": [ { "type": "opencollective", @@ -5252,6 +5226,7 @@ }, "node_modules/bser": { "version": "2.1.1", + "dev": true, "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" @@ -5282,6 +5257,7 @@ }, "node_modules/buffer-from": { "version": "1.1.2", + "dev": true, "license": "MIT" }, "node_modules/builtins": { @@ -5292,62 +5268,6 @@ "semver": "^7.0.0" } }, - "node_modules/bullmq": { - "version": "3.15.8", - "license": "MIT", - "peer": true, - "dependencies": { - "cron-parser": "^4.6.0", - "glob": "^8.0.3", - "ioredis": "^5.3.2", - "lodash": "^4.17.21", - "msgpackr": "^1.6.2", - "semver": "^7.3.7", - "tslib": "^2.0.0", - "uuid": "^9.0.0" - } - }, - "node_modules/bullmq/node_modules/glob": { - "version": "8.1.0", - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/bullmq/node_modules/minimatch": { - "version": "5.1.6", - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/bullmq/node_modules/uuid": { - "version": "9.0.1", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/busboy": { "version": "1.6.0", "dependencies": { @@ -5522,6 +5442,7 @@ }, "node_modules/callsites": { "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5529,6 +5450,7 @@ }, "node_modules/camelcase": { "version": "5.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5552,6 +5474,7 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001639", + "dev": true, "funding": [ { "type": "opencollective", @@ -5581,6 +5504,7 @@ }, "node_modules/chalk": { "version": "2.4.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -5593,6 +5517,7 @@ }, "node_modules/char-regex": { "version": "1.0.2", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5648,6 +5573,7 @@ }, "node_modules/cjs-module-lexer": { "version": "1.3.1", + "dev": true, "license": "MIT" }, "node_modules/class-validator": { @@ -5831,12 +5757,6 @@ "node": ">= 0.12.0" } }, - "node_modules/code-block-writer": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", - "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", - "peer": true - }, "node_modules/code-excerpt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", @@ -5850,10 +5770,12 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.2", + "dev": true, "license": "MIT" }, "node_modules/color-convert": { "version": "1.9.3", + "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -5861,6 +5783,7 @@ }, "node_modules/color-name": { "version": "1.1.3", + "dev": true, "license": "MIT" }, "node_modules/color-support": { @@ -5993,6 +5916,7 @@ }, "node_modules/concat-map": { "version": "0.0.1", + "dev": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -6223,6 +6147,7 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", + "dev": true, "license": "MIT" }, "node_modules/convert-to-spaces": { @@ -6294,6 +6219,7 @@ }, "node_modules/create-jest": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -6313,6 +6239,7 @@ }, "node_modules/create-jest/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6326,6 +6253,7 @@ }, "node_modules/create-jest/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6340,6 +6268,7 @@ }, "node_modules/create-jest/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6350,10 +6279,12 @@ }, "node_modules/create-jest/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/create-jest/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6361,6 +6292,7 @@ }, "node_modules/create-jest/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6369,17 +6301,6 @@ "node": ">=8" } }, - "node_modules/cron-parser": { - "version": "4.9.0", - "license": "MIT", - "peer": true, - "dependencies": { - "luxon": "^3.2.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/cross-inspect": { "version": "1.0.0", "license": "MIT", @@ -6392,6 +6313,7 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6425,7 +6347,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "dev": true }, "node_modules/cz-conventional-changelog": { "version": "3.3.0", @@ -6681,14 +6603,6 @@ "version": "1.0.0", "license": "MIT" }, - "node_modules/denque": { - "version": "2.1.0", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/depd": { "version": "2.0.0", "license": "MIT", @@ -6735,17 +6649,9 @@ "node": ">=8" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6767,6 +6673,7 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6852,10 +6759,12 @@ }, "node_modules/electron-to-chromium": { "version": "1.4.815", + "dev": true, "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -6884,6 +6793,7 @@ }, "node_modules/encoding": { "version": "0.1.13", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -6892,6 +6802,7 @@ }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -6959,6 +6870,7 @@ }, "node_modules/error-ex": { "version": "1.3.2", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -7110,6 +7022,7 @@ }, "node_modules/escape-string-regexp": { "version": "1.0.5", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -7586,6 +7499,7 @@ }, "node_modules/esprima": { "version": "4.0.1", + "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -7640,6 +7554,7 @@ }, "node_modules/execa": { "version": "5.1.1", + "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -7661,6 +7576,7 @@ }, "node_modules/exit": { "version": "0.1.2", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -7678,6 +7594,7 @@ }, "node_modules/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -7724,6 +7641,7 @@ }, "node_modules/fast-glob": { "version": "3.3.2", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -7738,6 +7656,7 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -7748,6 +7667,7 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -7764,6 +7684,7 @@ }, "node_modules/fastq": { "version": "1.17.1", + "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7771,6 +7692,7 @@ }, "node_modules/fb-watchman": { "version": "2.0.2", + "dev": true, "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" @@ -7841,6 +7763,7 @@ }, "node_modules/fill-range": { "version": "7.1.1", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -8090,6 +8013,7 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -8105,6 +8029,7 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8162,6 +8087,7 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -8194,6 +8120,7 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -8314,6 +8241,7 @@ }, "node_modules/get-stream": { "version": "6.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -8431,6 +8359,7 @@ }, "node_modules/glob": { "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -8460,6 +8389,7 @@ }, "node_modules/glob/node_modules/brace-expansion": { "version": "1.1.11", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -8468,6 +8398,7 @@ }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -8596,6 +8527,7 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", + "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -8611,12 +8543,6 @@ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, - "node_modules/graphql-fields": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/graphql-fields/-/graphql-fields-2.0.3.tgz", - "integrity": "sha512-x3VE5lUcR4XCOxPIqaO4CE+bTK8u6gVouOdpQX9+EKHr+scqtK5Pp/l8nIGqIpN1TUlkKE6jDCCycm/WtLRAwA==", - "peer": true - }, "node_modules/graphql-query-complexity": { "version": "0.12.0", "license": "MIT", @@ -8708,6 +8634,7 @@ }, "node_modules/has-flag": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -8792,6 +8719,7 @@ }, "node_modules/hasown": { "version": "2.0.2", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8870,6 +8798,7 @@ }, "node_modules/html-escaper": { "version": "2.0.2", + "dev": true, "license": "MIT" }, "node_modules/html-void-elements": { @@ -8947,6 +8876,7 @@ }, "node_modules/human-signals": { "version": "2.1.0", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -9063,6 +8993,7 @@ }, "node_modules/import-local": { "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -9090,6 +9021,7 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -9110,6 +9042,7 @@ }, "node_modules/inflight": { "version": "1.0.6", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -9918,29 +9851,6 @@ "node": ">= 0.4" } }, - "node_modules/ioredis": { - "version": "5.4.1", - "license": "MIT", - "peer": true, - "dependencies": { - "@ioredis/commands": "^1.1.1", - "cluster-key-slot": "^1.1.0", - "debug": "^4.3.4", - "denque": "^2.1.0", - "lodash.defaults": "^4.2.0", - "lodash.isarguments": "^3.1.0", - "redis-errors": "^1.2.0", - "redis-parser": "^3.0.0", - "standard-as-callback": "^2.1.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ioredis" - } - }, "node_modules/ip-address": { "version": "9.0.5", "dev": true, @@ -9970,6 +9880,7 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", + "dev": true, "license": "MIT" }, "node_modules/is-bigint": { @@ -10025,6 +9936,7 @@ }, "node_modules/is-core-module": { "version": "2.14.0", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -10080,6 +9992,7 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10097,6 +10010,7 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10117,6 +10031,7 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -10159,6 +10074,7 @@ }, "node_modules/is-number": { "version": "7.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10257,6 +10173,7 @@ }, "node_modules/is-stream": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10386,6 +10303,7 @@ }, "node_modules/isexe": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -10396,17 +10314,9 @@ "node": ">=0.10.0" } }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "license": "MIT", - "peer": true, - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -10427,6 +10337,7 @@ }, "node_modules/istanbul-lib-instrument": { "version": "6.0.3", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -10472,6 +10383,7 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -10484,6 +10396,7 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10491,6 +10404,7 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10501,6 +10415,7 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -10725,6 +10640,7 @@ }, "node_modules/istanbul-reports": { "version": "3.1.7", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -10854,6 +10770,7 @@ }, "node_modules/jest": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -10878,6 +10795,7 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -10890,6 +10808,7 @@ }, "node_modules/jest-circus": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -10919,6 +10838,7 @@ }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -10932,6 +10852,7 @@ }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -10946,6 +10867,7 @@ }, "node_modules/jest-circus/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -10956,10 +10878,12 @@ }, "node_modules/jest-circus/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-circus/node_modules/dedent": { "version": "1.5.3", + "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -10972,6 +10896,7 @@ }, "node_modules/jest-circus/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10979,6 +10904,7 @@ }, "node_modules/jest-circus/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10989,6 +10915,7 @@ }, "node_modules/jest-cli": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -11020,6 +10947,7 @@ }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11033,6 +10961,7 @@ }, "node_modules/jest-cli/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11047,6 +10976,7 @@ }, "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11057,10 +10987,12 @@ }, "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11068,6 +11000,7 @@ }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11078,6 +11011,7 @@ }, "node_modules/jest-config": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -11121,6 +11055,7 @@ }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11134,6 +11069,7 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11148,6 +11084,7 @@ }, "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11158,10 +11095,12 @@ }, "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11169,6 +11108,7 @@ }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11179,6 +11119,7 @@ }, "node_modules/jest-diff": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11192,6 +11133,7 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11205,6 +11147,7 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11219,6 +11162,7 @@ }, "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11229,10 +11173,12 @@ }, "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11240,6 +11186,7 @@ }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11250,6 +11197,7 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -11260,6 +11208,7 @@ }, "node_modules/jest-each": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11274,6 +11223,7 @@ }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11287,6 +11237,7 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11301,6 +11252,7 @@ }, "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11311,10 +11263,12 @@ }, "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11322,6 +11276,7 @@ }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11332,6 +11287,7 @@ }, "node_modules/jest-environment-node": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -11347,6 +11303,7 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11354,6 +11311,7 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11377,6 +11335,7 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -11388,6 +11347,7 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11401,6 +11361,7 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11414,6 +11375,7 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11428,6 +11390,7 @@ }, "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11438,10 +11401,12 @@ }, "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11449,6 +11414,7 @@ }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11459,6 +11425,7 @@ }, "node_modules/jest-message-util": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -11477,6 +11444,7 @@ }, "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11490,6 +11458,7 @@ }, "node_modules/jest-message-util/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11504,6 +11473,7 @@ }, "node_modules/jest-message-util/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11514,10 +11484,12 @@ }, "node_modules/jest-message-util/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11525,6 +11497,7 @@ }, "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11535,6 +11508,7 @@ }, "node_modules/jest-mock": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11560,6 +11534,7 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11575,6 +11550,7 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11582,6 +11558,7 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11600,6 +11577,7 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -11611,6 +11589,7 @@ }, "node_modules/jest-resolve/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11624,6 +11603,7 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11638,6 +11618,7 @@ }, "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11648,10 +11629,12 @@ }, "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11659,6 +11642,7 @@ }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11669,6 +11653,7 @@ }, "node_modules/jest-runner": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -11699,6 +11684,7 @@ }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11712,6 +11698,7 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11726,6 +11713,7 @@ }, "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11736,10 +11724,12 @@ }, "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11747,6 +11737,7 @@ }, "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11757,6 +11748,7 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -11788,6 +11780,7 @@ }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11801,6 +11794,7 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11815,6 +11809,7 @@ }, "node_modules/jest-runtime/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11825,10 +11820,12 @@ }, "node_modules/jest-runtime/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11836,6 +11833,7 @@ }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11846,6 +11844,7 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -11875,6 +11874,7 @@ }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11888,6 +11888,7 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11902,6 +11903,7 @@ }, "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11912,10 +11914,12 @@ }, "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11923,6 +11927,7 @@ }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11933,6 +11938,7 @@ }, "node_modules/jest-util": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11948,6 +11954,7 @@ }, "node_modules/jest-util/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11961,6 +11968,7 @@ }, "node_modules/jest-util/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11975,6 +11983,7 @@ }, "node_modules/jest-util/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11985,10 +11994,12 @@ }, "node_modules/jest-util/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11996,6 +12007,7 @@ }, "node_modules/jest-util/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12006,6 +12018,7 @@ }, "node_modules/jest-validate": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -12021,6 +12034,7 @@ }, "node_modules/jest-validate/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12034,6 +12048,7 @@ }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -12044,6 +12059,7 @@ }, "node_modules/jest-validate/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -12058,6 +12074,7 @@ }, "node_modules/jest-validate/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -12068,10 +12085,12 @@ }, "node_modules/jest-validate/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-validate/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12079,6 +12098,7 @@ }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12089,6 +12109,7 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -12106,6 +12127,7 @@ }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12119,6 +12141,7 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -12133,6 +12156,7 @@ }, "node_modules/jest-watcher/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -12143,10 +12167,12 @@ }, "node_modules/jest-watcher/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12154,6 +12180,7 @@ }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12164,6 +12191,7 @@ }, "node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -12177,6 +12205,7 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12184,6 +12213,7 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12204,11 +12234,6 @@ "jiti": "bin/jiti.js" } }, - "node_modules/js-sha256": { - "version": "0.9.0", - "license": "MIT", - "peer": true - }, "node_modules/js-tokens": { "version": "4.0.0", "license": "MIT" @@ -12231,6 +12256,7 @@ }, "node_modules/jsesc": { "version": "2.5.2", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -12283,6 +12309,7 @@ }, "node_modules/json5": { "version": "2.2.3", + "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -12298,6 +12325,7 @@ }, "node_modules/jsonfile": { "version": "6.1.0", + "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -12367,6 +12395,7 @@ }, "node_modules/kleur": { "version": "3.0.3", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -12801,6 +12830,7 @@ }, "node_modules/leven": { "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -13266,11 +13296,6 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "license": "MIT", - "peer": true - }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", @@ -13282,11 +13307,6 @@ "version": "4.4.2", "license": "MIT" }, - "node_modules/lodash.isarguments": { - "version": "3.1.0", - "license": "MIT", - "peer": true - }, "node_modules/lodash.ismatch": { "version": "4.4.0", "dev": true, @@ -13525,6 +13545,7 @@ }, "node_modules/lru-cache": { "version": "5.1.1", + "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -13537,16 +13558,9 @@ "dev": true, "license": "MIT" }, - "node_modules/luxon": { - "version": "3.4.4", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/make-dir": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -13717,6 +13731,7 @@ }, "node_modules/makeerror": { "version": "1.0.12", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -13988,10 +14003,12 @@ }, "node_modules/merge-stream": { "version": "2.0.0", + "dev": true, "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -14093,6 +14110,7 @@ }, "node_modules/micromatch": { "version": "4.0.7", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -14143,6 +14161,7 @@ }, "node_modules/minimatch": { "version": "9.0.5", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -14412,35 +14431,6 @@ "version": "2.1.2", "license": "MIT" }, - "node_modules/msgpackr": { - "version": "1.10.2", - "license": "MIT", - "peer": true, - "optionalDependencies": { - "msgpackr-extract": "^3.0.2" - } - }, - "node_modules/msgpackr-extract": { - "version": "3.0.3", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.2.2" - }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" - } - }, "node_modules/multimatch": { "version": "5.0.0", "dev": true, @@ -14494,6 +14484,7 @@ }, "node_modules/natural-compare": { "version": "1.4.0", + "dev": true, "license": "MIT" }, "node_modules/negotiator": { @@ -14515,6 +14506,7 @@ }, "node_modules/node-fetch": { "version": "2.6.7", + "dev": true, "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -14565,20 +14557,6 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.2.2", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, "node_modules/node-gyp/node_modules/abbrev": { "version": "1.1.1", "dev": true, @@ -14600,6 +14578,7 @@ }, "node_modules/node-int64": { "version": "0.4.0", + "dev": true, "license": "MIT" }, "node_modules/node-machine-id": { @@ -14622,6 +14601,7 @@ }, "node_modules/node-releases": { "version": "2.0.14", + "dev": true, "license": "MIT" }, "node_modules/nopt": { @@ -14654,6 +14634,7 @@ }, "node_modules/normalize-path": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14962,6 +14943,7 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -15663,33 +15645,6 @@ "node": ">=6" } }, - "node_modules/o1js": { - "version": "1.7.0", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "blakejs": "1.2.1", - "cachedir": "^2.4.0", - "isomorphic-fetch": "^3.0.0", - "js-sha256": "^0.9.0", - "reflect-metadata": "^0.1.13", - "tslib": "^2.3.0" - }, - "bin": { - "snarky-run": "src/build/run.js" - }, - "engines": { - "node": ">=18.14.0" - } - }, - "node_modules/o1js/node_modules/cachedir": { - "version": "2.4.0", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -15805,6 +15760,7 @@ }, "node_modules/once": { "version": "1.4.0", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -15974,6 +15930,7 @@ }, "node_modules/p-limit": { "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -16068,6 +16025,7 @@ }, "node_modules/p-try": { "version": "2.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16309,6 +16267,7 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -16325,10 +16284,12 @@ }, "node_modules/parse-json/node_modules/json-parse-even-better-errors": { "version": "2.3.1", + "dev": true, "license": "MIT" }, "node_modules/parse-json/node_modules/lines-and-columns": { "version": "1.2.4", + "dev": true, "license": "MIT" }, "node_modules/parse-passwd": { @@ -16370,14 +16331,9 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "peer": true - }, "node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16385,6 +16341,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16392,6 +16349,7 @@ }, "node_modules/path-key": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16399,6 +16357,7 @@ }, "node_modules/path-parse": { "version": "1.0.7", + "dev": true, "license": "MIT" }, "node_modules/path-scurry": { @@ -16434,10 +16393,12 @@ }, "node_modules/picocolors": { "version": "1.0.1", + "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -16470,6 +16431,7 @@ }, "node_modules/pirates": { "version": "4.0.6", + "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -16477,6 +16439,7 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", + "dev": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -16487,6 +16450,7 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -16498,6 +16462,7 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -16508,6 +16473,7 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -16521,6 +16487,7 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -16529,15 +16496,6 @@ "node": ">=8" } }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "dev": true, @@ -16593,6 +16551,7 @@ }, "node_modules/pretty-format": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -16605,6 +16564,7 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -16614,12 +16574,13 @@ } }, "node_modules/prisma": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.21.1.tgz", - "integrity": "sha512-PB+Iqzld/uQBPaaw2UVIk84kb0ITsLajzsxzsadxxl54eaU5Gyl2/L02ysivHxK89t7YrfQJm+Ggk37uvM70oQ==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", + "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@prisma/engines": "5.21.1" + "@prisma/engines": "5.22.0" }, "bin": { "prisma": "build/index.js" @@ -16654,6 +16615,51 @@ "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, + "node_modules/prisma/node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "license": "Apache-2.0" + }, + "node_modules/prisma/node_modules/@prisma/engines": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", + "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/fetch-engine": "5.22.0", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/prisma/node_modules/@prisma/engines-version": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", + "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "license": "Apache-2.0" + }, + "node_modules/prisma/node_modules/@prisma/fetch-engine": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", + "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/prisma/node_modules/@prisma/get-platform": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", + "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, "node_modules/proc-log": { "version": "3.0.0", "dev": true, @@ -16715,6 +16721,7 @@ }, "node_modules/prompts": { "version": "2.4.2", + "dev": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -16793,6 +16800,7 @@ }, "node_modules/pure-rand": { "version": "6.1.0", + "dev": true, "funding": [ { "type": "individual", @@ -16816,6 +16824,7 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", + "dev": true, "funding": [ { "type": "github", @@ -16853,6 +16862,7 @@ }, "node_modules/react-is": { "version": "18.3.1", + "dev": true, "license": "MIT" }, "node_modules/react-json-view-lite": { @@ -17201,25 +17211,6 @@ "@redis/time-series": "1.0.5" } }, - "node_modules/redis-errors": { - "version": "1.2.0", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "license": "MIT", - "peer": true, - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/reflect-metadata": { "version": "0.1.14", "license": "Apache-2.0" @@ -17315,6 +17306,7 @@ }, "node_modules/resolve": { "version": "1.22.8", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -17330,6 +17322,7 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -17352,6 +17345,7 @@ }, "node_modules/resolve-from": { "version": "5.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17359,6 +17353,7 @@ }, "node_modules/resolve.exports": { "version": "2.0.2", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -17385,6 +17380,7 @@ }, "node_modules/reusify": { "version": "1.0.4", + "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -17420,6 +17416,7 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "dev": true, "funding": [ { "type": "github", @@ -17500,7 +17497,7 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/scheduler": { @@ -17574,6 +17571,7 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -17584,6 +17582,7 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17731,10 +17730,12 @@ }, "node_modules/sisteransi": { "version": "1.0.5", + "dev": true, "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17812,6 +17813,7 @@ }, "node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -17819,6 +17821,7 @@ }, "node_modules/source-map-support": { "version": "0.5.13", + "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -17990,11 +17993,6 @@ "node": ">=8" } }, - "node_modules/standard-as-callback": { - "version": "2.1.0", - "license": "MIT", - "peer": true - }, "node_modules/statuses": { "version": "1.5.0", "license": "MIT", @@ -18026,6 +18024,7 @@ }, "node_modules/string-length": { "version": "4.0.2", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -18161,6 +18160,7 @@ }, "node_modules/strip-bom": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18168,6 +18168,7 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -18186,6 +18187,7 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18212,6 +18214,7 @@ }, "node_modules/supports-color": { "version": "5.5.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -18222,6 +18225,7 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -18350,6 +18354,7 @@ }, "node_modules/test-exclude": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -18362,6 +18367,7 @@ }, "node_modules/test-exclude/node_modules/brace-expansion": { "version": "1.1.11", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -18370,6 +18376,7 @@ }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -18417,10 +18424,12 @@ }, "node_modules/tmpl": { "version": "1.0.5", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18428,6 +18437,7 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -18445,6 +18455,7 @@ }, "node_modules/tr46": { "version": "0.0.3", + "dev": true, "license": "MIT" }, "node_modules/treeverse": { @@ -18556,16 +18567,6 @@ "version": "6.0.4", "license": "MIT" }, - "node_modules/ts-morph": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz", - "integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==", - "peer": true, - "dependencies": { - "@ts-morph/common": "~0.24.0", - "code-block-writer": "^13.0.1" - } - }, "node_modules/ts-pattern": { "version": "4.3.0", "license": "MIT" @@ -18647,22 +18648,6 @@ "dev": true, "license": "0BSD" }, - "node_modules/tsyringe": { - "version": "4.8.0", - "license": "MIT", - "peer": true, - "dependencies": { - "tslib": "^1.9.3" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/tsyringe/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD", - "peer": true - }, "node_modules/tuf-js": { "version": "1.1.7", "dev": true, @@ -18773,6 +18758,7 @@ }, "node_modules/type-detect": { "version": "4.0.8", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18979,38 +18965,9 @@ "typedoc": "0.26.x" } }, - "node_modules/typegraphql-prisma": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/typegraphql-prisma/-/typegraphql-prisma-0.28.0.tgz", - "integrity": "sha512-LMTsYEAteeXhnJRmH2sBWarR8Jc9Um13mtSpi8Vh6G8QUTlp5tRfqMjd+Fw06HS6SBshU6NilZJlsPaz26SQCw==", - "peer": true, - "dependencies": { - "@prisma/generator-helper": "^5.18.0", - "@prisma/internals": "^5.18.0", - "pluralize": "^8.0.0", - "semver": "^7.6.3", - "ts-morph": "^23.0.0", - "tslib": "^2.6.3" - }, - "bin": { - "typegraphql-prisma": "lib/generator.js" - }, - "engines": { - "node": ">=20.11.1" - }, - "peerDependencies": { - "@prisma/client": "^5.18.0", - "@types/graphql-fields": "^1.3.9", - "@types/node": "*", - "graphql-fields": "^2.0.3", - "graphql-scalars": "^1.23.0", - "prisma": "^5.18.0", - "tslib": "^2.6.3", - "type-graphql": "^1.1.1 || >=1.2.0-rc || >=2.0.0-beta || >=2.0.0-rc" - } - }, "node_modules/typescript": { "version": "5.1.6", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -19174,6 +19131,7 @@ }, "node_modules/universalify": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -19190,6 +19148,7 @@ }, "node_modules/update-browserslist-db": { "version": "1.0.16", + "dev": true, "funding": [ { "type": "opencollective", @@ -19248,6 +19207,7 @@ }, "node_modules/v8-to-istanbul": { "version": "9.3.0", + "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -19359,6 +19319,7 @@ }, "node_modules/walker": { "version": "1.0.8", + "dev": true, "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" @@ -19374,15 +19335,12 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", + "dev": true, "license": "BSD-2-Clause" }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "license": "MIT", - "peer": true - }, "node_modules/whatwg-url": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -19391,6 +19349,7 @@ }, "node_modules/which": { "version": "2.0.2", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -19618,10 +19577,12 @@ }, "node_modules/wrappy": { "version": "1.0.2", + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", + "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -19751,6 +19712,7 @@ }, "node_modules/yallist": { "version": "3.1.1", + "dev": true, "license": "ISC" }, "node_modules/yaml": { @@ -19818,6 +19780,7 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -20024,9 +19987,9 @@ "version": "0.1.1-develop.833+397881ed", "license": "MIT", "dependencies": { - "@prisma/client": "^5.18.0", + "@prisma/client": "^5.22.0", "lodash": "^4.17.21", - "prisma": "^5.18.0", + "prisma": "^5.22.0", "redis": "^4.6.12", "reflect-metadata": "^0.1.13" }, diff --git a/packages/indexer/package.json b/packages/indexer/package.json index 76d942113..fe42eeef9 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -22,7 +22,7 @@ "dependencies": { "@envelop/extended-validation": "^4.1.0", "@inkjs/ui": "^1.0.0", - "@prisma/client": "^5.18.0", + "@prisma/client": "^5.22.0", "@types/yargs": "^17.0.29", "figlet": "^1.7.0", "ink": "^4.4.1", diff --git a/packages/persistance/package.json b/packages/persistance/package.json index 0a38a54fc..235f08cb5 100644 --- a/packages/persistance/package.json +++ b/packages/persistance/package.json @@ -6,7 +6,7 @@ "version": "0.1.1-develop.833+397881ed", "scripts": { "build": "npm run prisma:generate && tsc -p tsconfig.json", - "prisma:generate": "npx prisma generate --sql", + "prisma:generate": "npx prisma generate", "prisma:migrate": "npx prisma migrate deploy", "dev": "tsc -p tsconfig.json --watch", "lint": "eslint ./src ./test ./test-integration", diff --git a/packages/persistance/prisma/schema.prisma b/packages/persistance/prisma/schema.prisma index 19f4899ca..24ce7059a 100644 --- a/packages/persistance/prisma/schema.prisma +++ b/packages/persistance/prisma/schema.prisma @@ -2,10 +2,7 @@ // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { - provider = "prisma-client-js" - // output = "./../node_modules/.prisma/client" - // Enable after upgrade to 5.9.0 - previewFeatures = ["typedSql"] + provider = "prisma-client-js" } datasource db { diff --git a/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql b/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql deleted file mode 100644 index 7f38962b6..000000000 --- a/packages/persistance/prisma/sql/deleteCollisionsFromParentMask.sql +++ /dev/null @@ -1,18 +0,0 @@ -/* - DELETE PATHS FROM PARENT MASK - - Strategy on this query: - 1. Find the mask we are interested in, as a record with the id and it's parent id - 2. Select all paths that exist on that mask - 3. Delete all records whose mask is the parent of (1), and whose path is contained in (2) - */ - -WITH mask AS ( - SELECT id, parent FROM "Mask" m WHERE m.id = $1), -paths AS ( - SELECT path FROM "State" s - JOIN mask m on s."maskId" = m.id - ) -DELETE FROM "State" s - WHERE s."maskId" IN (SELECT parent FROM mask) - AND s.path IN (SELECT path FROM paths) \ No newline at end of file diff --git a/packages/persistance/prisma/sql/mergeIntoParent.sql b/packages/persistance/prisma/sql/mergeIntoParent.sql deleted file mode 100644 index 2f2e3f754..000000000 --- a/packages/persistance/prisma/sql/mergeIntoParent.sql +++ /dev/null @@ -1,10 +0,0 @@ -/* -Strategy: - 1. Find the mask we are interested in, as a record with the id and it's parent id - 2. Update the maskId to the masks parent for all the entries of that particular mask -*/ - -WITH mask AS ( - SELECT id, parent FROM "Mask" m WHERE m.id = $1) -UPDATE "State" SET "maskId" = (SELECT parent FROM mask) -WHERE "maskId" = (SELECT id FROM mask) \ No newline at end of file diff --git a/packages/persistance/prisma/sql/readState.sql b/packages/persistance/prisma/sql/readState.sql deleted file mode 100644 index a19b7229d..000000000 --- a/packages/persistance/prisma/sql/readState.sql +++ /dev/null @@ -1,10 +0,0 @@ -WITH RECURSIVE find_masks(id, parent) AS ( - SELECT m.id, m.parent FROM "Mask" m WHERE m.id = $1 - UNION ALL - SELECT s.id, s.parent FROM "Mask" s, find_masks f - WHERE f.parent = s.id -) -SELECT distinct on (state.path) state.path, state.values FROM find_masks - JOIN "State" state ON state."maskId" = find_masks.id -WHERE state.path = ANY($2) -ORDER BY state.path, state."maskId" DESC; \ No newline at end of file diff --git a/packages/persistance/src/services/prisma/PrismaStateService.ts b/packages/persistance/src/services/prisma/PrismaStateService.ts index 6e0ec964c..3f5c3a215 100644 --- a/packages/persistance/src/services/prisma/PrismaStateService.ts +++ b/packages/persistance/src/services/prisma/PrismaStateService.ts @@ -1,16 +1,15 @@ import { AsyncStateService, StateEntry } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { Prisma } from "@prisma/client"; -import { - readState, - deleteCollisionsFromParentMask, - mergeIntoParent, -} from "@prisma/client/sql"; import { noop } from "@proto-kit/common"; import { injectable } from "tsyringe"; import type { PrismaConnection } from "../../PrismaDatabaseConnection"; +import { readState } from "./sql/readState"; +import { deleteCollisionsFromParentMask } from "./sql/deleteCollisionsFromParentMask"; +import { mergeIntoParent } from "./sql/mergeIntoParent"; + // We need to create a correctly configured Decimal constructor // with our parameters const Decimal = Prisma.Decimal.clone({ @@ -96,7 +95,10 @@ export class PrismaStateService implements AsyncStateService { const maskId = await this.getMaskId(); const paths = keys.map((key) => new Decimal(key.toString())); - const records = await this.connection.prismaClient.$queryRawTyped( + const records: { + path: Prisma.Decimal; + values: Prisma.Decimal[] | null; + }[] = await this.connection.prismaClient.$queryRaw( readState(maskId, paths) ); @@ -138,11 +140,11 @@ export class PrismaStateService implements AsyncStateService { // 4. Delete mask await client.$transaction([ - client.$queryRawTyped(deleteCollisionsFromParentMask(maskId)), + client.$queryRaw(deleteCollisionsFromParentMask(maskId)), // MergeIntoParent could be a prisma query, but it isn't, because eventually, // this Service should be stateless, therefore the parentId wouldn't be on hand // anymore, so we need to inline it's retrieval into the query - client.$queryRawTyped(mergeIntoParent(maskId)), + client.$queryRaw(mergeIntoParent(maskId)), client.mask.updateMany({ where: { parent: maskId, diff --git a/packages/persistance/src/services/prisma/sql/deleteCollisionsFromParentMask.ts b/packages/persistance/src/services/prisma/sql/deleteCollisionsFromParentMask.ts new file mode 100644 index 000000000..c711180f5 --- /dev/null +++ b/packages/persistance/src/services/prisma/sql/deleteCollisionsFromParentMask.ts @@ -0,0 +1,24 @@ +import { Prisma } from "@prisma/client"; + +/* + DELETE PATHS FROM PARENT MASK + + Strategy on this query: + 1. Find the mask we are interested in, as a record with the id and it's parent id + 2. Select all paths that exist on that mask + 3. Delete all records whose mask is the parent of (1), and whose path is contained in (2) + */ + +export function deleteCollisionsFromParentMask(maskId: number) { + return Prisma.sql` + WITH mask AS ( + SELECT id, parent FROM "Mask" m WHERE m.id = ${maskId}), + paths AS ( + SELECT path FROM "State" s + JOIN mask m on s."maskId" = m.id + ) + DELETE FROM "State" s + WHERE s."maskId" IN (SELECT parent FROM mask) + AND s.path IN (SELECT path FROM paths) + `; +} diff --git a/packages/persistance/src/services/prisma/sql/mergeIntoParent.ts b/packages/persistance/src/services/prisma/sql/mergeIntoParent.ts new file mode 100644 index 000000000..17e752d7e --- /dev/null +++ b/packages/persistance/src/services/prisma/sql/mergeIntoParent.ts @@ -0,0 +1,16 @@ +import { Prisma } from "@prisma/client"; + +/* +Strategy: + 1. Find the mask we are interested in, as a record with the id and it's parent id + 2. Update the maskId to the masks parent for all the entries of that particular mask +*/ + +export function mergeIntoParent(maskId: number) { + return Prisma.sql` + WITH mask AS ( + SELECT id, parent FROM "Mask" m WHERE m.id = ${maskId}) + UPDATE "State" SET "maskId" = (SELECT parent FROM mask) + WHERE "maskId" = (SELECT id FROM mask) + `; +} diff --git a/packages/persistance/src/services/prisma/sql/readState.ts b/packages/persistance/src/services/prisma/sql/readState.ts new file mode 100644 index 000000000..f39306d85 --- /dev/null +++ b/packages/persistance/src/services/prisma/sql/readState.ts @@ -0,0 +1,16 @@ +import { Prisma } from "@prisma/client"; + +export function readState(maskId: number, paths: Prisma.Decimal[]) { + return Prisma.sql` + WITH RECURSIVE find_masks(id, parent) AS ( + SELECT m.id, m.parent FROM "Mask" m WHERE m.id = ${maskId} + UNION ALL + SELECT s.id, s.parent FROM "Mask" s, find_masks f + WHERE f.parent = s.id + ) + SELECT distinct on (state.path) state.path, state.values FROM find_masks + JOIN "State" state ON state."maskId" = find_masks.id + WHERE state.path = ANY(${paths}) + ORDER BY state.path, state."maskId" DESC; + `; +} diff --git a/packages/processor/package.json b/packages/processor/package.json index 63a5a9848..2be7e77bf 100644 --- a/packages/processor/package.json +++ b/packages/processor/package.json @@ -24,7 +24,7 @@ "main": "dist/index.js", "dependencies": { "@inkjs/ui": "^1.0.0", - "@prisma/client": "^5.19.1", + "@prisma/client": "^5.22.0", "@types/yargs": "^17.0.29", "figlet": "^1.7.0", "ink": "^4.4.1", From 84c0707bc01816687be914e8d7213ec39dcb9c72 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 18 Feb 2025 11:47:43 +0100 Subject: [PATCH 05/23] Re-added UnprovenStateService --- packages/persistance/src/PrismaDatabaseConnection.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/persistance/src/PrismaDatabaseConnection.ts b/packages/persistance/src/PrismaDatabaseConnection.ts index f70d06516..15c31d8f4 100644 --- a/packages/persistance/src/PrismaDatabaseConnection.ts +++ b/packages/persistance/src/PrismaDatabaseConnection.ts @@ -73,6 +73,9 @@ export class PrismaDatabaseConnection transactionStorage: { useClass: PrismaTransactionStorage, }, + unprovenStateService: { + useFactory: () => new PrismaStateService(this, "block"), + }, }; } From c2c713b40e1a51263172190cf964bbf8738c30e9 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 18 Feb 2025 12:31:01 +0100 Subject: [PATCH 06/23] Fixed package-lock --- package-lock.json | 1078 ++++++++++++++++++++++++++------------------- 1 file changed, 630 insertions(+), 448 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c39628ca..64fcd3f4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,7 +85,6 @@ }, "node_modules/@ampproject/remapping": { "version": "2.3.0", - "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -97,7 +96,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/highlight": "^7.24.7", @@ -109,7 +107,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.24.7", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -117,7 +114,6 @@ }, "node_modules/@babel/core": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -146,7 +142,6 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -154,7 +149,6 @@ }, "node_modules/@babel/generator": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7", @@ -168,7 +162,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.24.7", @@ -183,7 +176,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -191,7 +183,6 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -202,7 +193,6 @@ }, "node_modules/@babel/helper-function-name": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", @@ -214,7 +204,6 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -225,7 +214,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", @@ -237,7 +225,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", @@ -255,7 +242,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.24.7", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -263,7 +249,6 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.24.7", @@ -275,7 +260,6 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" @@ -286,7 +270,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.24.7", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -294,7 +277,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.24.7", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -302,7 +284,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.24.7", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -310,7 +291,6 @@ }, "node_modules/@babel/helpers": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.24.7", @@ -322,7 +302,6 @@ }, "node_modules/@babel/highlight": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", @@ -336,7 +315,6 @@ }, "node_modules/@babel/parser": { "version": "7.24.7", - "dev": true, "license": "MIT", "bin": { "parser": "bin/babel-parser.js" @@ -347,7 +325,6 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -358,7 +335,6 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -369,7 +345,6 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -380,7 +355,6 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -391,7 +365,6 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -402,7 +375,6 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -416,7 +388,6 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -427,7 +398,6 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -438,7 +408,6 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -449,7 +418,6 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -460,7 +428,6 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -471,7 +438,6 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -482,7 +448,6 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -496,7 +461,6 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" @@ -510,7 +474,6 @@ }, "node_modules/@babel/template": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", @@ -523,7 +486,6 @@ }, "node_modules/@babel/traverse": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", @@ -543,7 +505,6 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -551,7 +512,6 @@ }, "node_modules/@babel/types": { "version": "7.24.7", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.24.7", @@ -564,7 +524,6 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "dev": true, "license": "MIT" }, "node_modules/@commitlint/config-validator": { @@ -1126,6 +1085,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "license": "MIT", + "peer": true + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -1222,7 +1188,6 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -1237,7 +1202,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", - "dev": true, "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" @@ -1245,7 +1209,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -1257,7 +1220,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -1269,7 +1231,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -1280,7 +1241,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -1294,7 +1254,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -1305,12 +1264,10 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { "version": "1.0.3", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1318,7 +1275,6 @@ }, "node_modules/@jest/console": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -1334,7 +1290,6 @@ }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1348,7 +1303,6 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1363,7 +1317,6 @@ }, "node_modules/@jest/console/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1374,12 +1327,10 @@ }, "node_modules/@jest/console/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/@jest/console/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1387,7 +1338,6 @@ }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1398,7 +1348,6 @@ }, "node_modules/@jest/core": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -1444,7 +1393,6 @@ }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1458,7 +1406,6 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1473,7 +1420,6 @@ }, "node_modules/@jest/core/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1484,12 +1430,10 @@ }, "node_modules/@jest/core/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1497,7 +1441,6 @@ }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1508,7 +1451,6 @@ }, "node_modules/@jest/environment": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", @@ -1522,7 +1464,6 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -1534,7 +1475,6 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -1545,7 +1485,6 @@ }, "node_modules/@jest/fake-timers": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -1561,7 +1500,6 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -1575,7 +1513,6 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -1617,7 +1554,6 @@ }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1631,7 +1567,6 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1646,7 +1581,6 @@ }, "node_modules/@jest/reporters/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1657,12 +1591,10 @@ }, "node_modules/@jest/reporters/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1670,7 +1602,6 @@ }, "node_modules/@jest/reporters/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1681,7 +1612,6 @@ }, "node_modules/@jest/schemas": { "version": "29.6.3", - "dev": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -1692,7 +1622,6 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -1705,7 +1634,6 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -1719,7 +1647,6 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -1733,7 +1660,6 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -1758,7 +1684,6 @@ }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1772,7 +1697,6 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1787,7 +1711,6 @@ }, "node_modules/@jest/transform/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1798,12 +1721,10 @@ }, "node_modules/@jest/transform/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1811,7 +1732,6 @@ }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1822,7 +1742,6 @@ }, "node_modules/@jest/types": { "version": "29.6.3", - "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -1838,7 +1757,6 @@ }, "node_modules/@jest/types/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1852,7 +1770,6 @@ }, "node_modules/@jest/types/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1867,7 +1784,6 @@ }, "node_modules/@jest/types/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1878,12 +1794,10 @@ }, "node_modules/@jest/types/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1891,7 +1805,6 @@ }, "node_modules/@jest/types/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -1902,7 +1815,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -1915,7 +1827,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1923,7 +1834,6 @@ }, "node_modules/@jridgewell/set-array": { "version": "1.2.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1931,12 +1841,10 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -2559,9 +2467,92 @@ "node": ">=10" } }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -2573,7 +2564,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -2581,7 +2571,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -3360,6 +3349,112 @@ } } }, + "node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", + "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/fetch-engine": "5.22.0", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", + "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", + "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/generator-helper": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.22.0.tgz", + "integrity": "sha512-LwqcBQ5/QsuAaLNQZAIVIAJDJBMjHwMwn16e06IYx/3Okj/xEEfw9IvrqB2cJCl3b2mCBlh3eVH0w9WGmi4aHg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", + "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, + "node_modules/@prisma/internals": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/internals/-/internals-5.22.0.tgz", + "integrity": "sha512-Rsjw2ARB9VQzDczzEimUriSBdXmYG/Z5tNRer2IEwof/O8Q6A9cqV3oNVUpJ52TgWfQqMAq5K/KEf8LvvYLLOw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines": "5.22.0", + "@prisma/fetch-engine": "5.22.0", + "@prisma/generator-helper": "5.22.0", + "@prisma/get-platform": "5.22.0", + "@prisma/prisma-schema-wasm": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/schema-files-loader": "5.22.0", + "arg": "5.0.2", + "prompts": "2.4.2" + } + }, + "node_modules/@prisma/prisma-schema-wasm": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "resolved": "https://registry.npmjs.org/@prisma/prisma-schema-wasm/-/prisma-schema-wasm-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", + "integrity": "sha512-WPNB7SgTxF/rSHMa5o5/9AIINy4oVnRhvUkRzqR4Nfp8Hu9Q2IyUptxuiDuzRVJdjJBRi/U82sHTxyiD3oBBhQ==", + "license": "Apache-2.0", + "peer": true + }, + "node_modules/@prisma/schema-files-loader": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/schema-files-loader/-/schema-files-loader-5.22.0.tgz", + "integrity": "sha512-/TNAJXvMSk6mCgZa+gIBM6sp5OUQBnb7rbjiSQm88gvcSibxEuKkVV/2pT3RmQpEAn1yiabvS4+dOvIotYe3ww==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@prisma/prisma-schema-wasm": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "fs-extra": "11.1.1" + } + }, + "node_modules/@prisma/schema-files-loader/node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/@proto-kit/api": { "resolved": "packages/api", "link": true @@ -3669,12 +3764,10 @@ }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "dev": true, "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -3682,7 +3775,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -3696,6 +3788,35 @@ "node": ">= 10" } }, + "node_modules/@ts-morph/common": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz", + "integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-glob": "^3.3.2", + "minimatch": "^9.0.4", + "mkdirp": "^3.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "peer": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", "dev": true, @@ -3726,7 +3847,6 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -3738,7 +3858,6 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.8", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -3746,7 +3865,6 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -3755,7 +3873,6 @@ }, "node_modules/@types/babel__traverse": { "version": "7.20.6", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" @@ -3838,12 +3955,21 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.9", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/graphql-fields": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@types/graphql-fields/-/graphql-fields-1.3.9.tgz", + "integrity": "sha512-HynTnp1HrE58uYcFcAK5UOfdrHSOIHDLCjvMU4yCmQLMj21uo7ZiZqnDGrD27pgCgHH5a1e8GYNK98Ndmma7ig==", + "license": "MIT", + "peer": true, + "dependencies": { + "graphql": "*" + } + }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", @@ -3880,12 +4006,10 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", - "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", - "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -3893,7 +4017,6 @@ }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", - "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" @@ -3997,7 +4120,7 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true + "devOptional": true }, "node_modules/@types/qs": { "version": "6.9.15", @@ -4013,7 +4136,7 @@ "version": "18.3.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4044,7 +4167,6 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.3", - "dev": true, "license": "MIT" }, "node_modules/@types/unist": { @@ -4634,7 +4756,6 @@ }, "node_modules/ansi-styles": { "version": "3.2.1", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -4645,7 +4766,6 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -4692,6 +4812,13 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT", + "peer": true + }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -4896,7 +5023,6 @@ }, "node_modules/babel-jest": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -4916,7 +5042,6 @@ }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4930,7 +5055,6 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4945,7 +5069,6 @@ }, "node_modules/babel-jest/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4956,12 +5079,10 @@ }, "node_modules/babel-jest/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4969,7 +5090,6 @@ }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -4980,7 +5100,6 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -4995,7 +5114,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -5010,7 +5128,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/semver": { "version": "6.3.1", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -5018,7 +5135,6 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -5032,7 +5148,6 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", - "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -5054,7 +5169,6 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", - "dev": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -5069,7 +5183,6 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -5163,9 +5276,15 @@ "readable-stream": "^3.4.0" } }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "license": "MIT", + "peer": true + }, "node_modules/brace-expansion": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -5173,7 +5292,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -5184,7 +5302,6 @@ }, "node_modules/browserslist": { "version": "4.23.1", - "dev": true, "funding": [ { "type": "opencollective", @@ -5226,7 +5343,6 @@ }, "node_modules/bser": { "version": "2.1.1", - "dev": true, "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" @@ -5257,7 +5373,6 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, "license": "MIT" }, "node_modules/builtins": { @@ -5268,6 +5383,71 @@ "semver": "^7.0.0" } }, + "node_modules/bullmq": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-3.16.2.tgz", + "integrity": "sha512-wZIsCdI2H6lza6GdePquCWbrslhYHS7GnDPpP0hzoHkvKiBOt/5jHcsHcHhJi/fob+dfo8dazWKTSLlGLFFqUw==", + "license": "MIT", + "peer": true, + "dependencies": { + "cron-parser": "^4.6.0", + "glob": "^8.0.3", + "ioredis": "^5.3.2", + "lodash": "^4.17.21", + "msgpackr": "^1.6.2", + "semver": "^7.3.7", + "tslib": "^2.0.0", + "uuid": "^9.0.0" + } + }, + "node_modules/bullmq/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/bullmq/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bullmq/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/busboy": { "version": "1.6.0", "dependencies": { @@ -5442,7 +5622,6 @@ }, "node_modules/callsites": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5450,7 +5629,6 @@ }, "node_modules/camelcase": { "version": "5.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5474,7 +5652,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001639", - "dev": true, "funding": [ { "type": "opencollective", @@ -5504,7 +5681,6 @@ }, "node_modules/chalk": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -5517,7 +5693,6 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5573,7 +5748,6 @@ }, "node_modules/cjs-module-lexer": { "version": "1.3.1", - "dev": true, "license": "MIT" }, "node_modules/class-validator": { @@ -5757,6 +5931,13 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT", + "peer": true + }, "node_modules/code-excerpt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", @@ -5770,12 +5951,10 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/color-convert": { "version": "1.9.3", - "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -5783,7 +5962,6 @@ }, "node_modules/color-name": { "version": "1.1.3", - "dev": true, "license": "MIT" }, "node_modules/color-support": { @@ -5916,7 +6094,6 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -6147,7 +6324,6 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/convert-to-spaces": { @@ -6219,7 +6395,6 @@ }, "node_modules/create-jest": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -6239,7 +6414,6 @@ }, "node_modules/create-jest/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6253,7 +6427,6 @@ }, "node_modules/create-jest/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6268,7 +6441,6 @@ }, "node_modules/create-jest/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6279,12 +6451,10 @@ }, "node_modules/create-jest/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/create-jest/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6292,7 +6462,6 @@ }, "node_modules/create-jest/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6301,6 +6470,19 @@ "node": ">=8" } }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/cross-inspect": { "version": "1.0.0", "license": "MIT", @@ -6313,7 +6495,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6347,7 +6528,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "devOptional": true }, "node_modules/cz-conventional-changelog": { "version": "3.3.0", @@ -6603,6 +6784,16 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "license": "MIT", @@ -6649,9 +6840,19 @@ "node": ">=8" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6673,7 +6874,6 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", - "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6759,12 +6959,10 @@ }, "node_modules/electron-to-chromium": { "version": "1.4.815", - "dev": true, "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -6793,7 +6991,6 @@ }, "node_modules/encoding": { "version": "0.1.13", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -6802,7 +6999,6 @@ }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -6870,7 +7066,6 @@ }, "node_modules/error-ex": { "version": "1.3.2", - "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -7022,7 +7217,6 @@ }, "node_modules/escape-string-regexp": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -7499,7 +7693,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -7554,7 +7747,6 @@ }, "node_modules/execa": { "version": "5.1.1", - "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -7576,7 +7768,6 @@ }, "node_modules/exit": { "version": "0.1.2", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -7594,7 +7785,6 @@ }, "node_modules/expect": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -7641,7 +7831,6 @@ }, "node_modules/fast-glob": { "version": "3.3.2", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -7656,7 +7845,6 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -7667,7 +7855,6 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -7684,7 +7871,6 @@ }, "node_modules/fastq": { "version": "1.17.1", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7692,7 +7878,6 @@ }, "node_modules/fb-watchman": { "version": "2.0.2", - "dev": true, "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" @@ -7763,7 +7948,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -8013,7 +8197,6 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -8029,7 +8212,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8087,7 +8269,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -8120,7 +8301,6 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -8241,7 +8421,6 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -8359,7 +8538,6 @@ }, "node_modules/glob": { "version": "7.2.3", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -8389,7 +8567,6 @@ }, "node_modules/glob/node_modules/brace-expansion": { "version": "1.1.11", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -8398,7 +8575,6 @@ }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -8527,7 +8703,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -8543,6 +8718,13 @@ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, + "node_modules/graphql-fields": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/graphql-fields/-/graphql-fields-2.0.3.tgz", + "integrity": "sha512-x3VE5lUcR4XCOxPIqaO4CE+bTK8u6gVouOdpQX9+EKHr+scqtK5Pp/l8nIGqIpN1TUlkKE6jDCCycm/WtLRAwA==", + "license": "MIT", + "peer": true + }, "node_modules/graphql-query-complexity": { "version": "0.12.0", "license": "MIT", @@ -8634,7 +8816,6 @@ }, "node_modules/has-flag": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -8719,7 +8900,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8798,7 +8978,6 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "dev": true, "license": "MIT" }, "node_modules/html-void-elements": { @@ -8876,7 +9055,6 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -8993,7 +9171,6 @@ }, "node_modules/import-local": { "version": "3.1.0", - "dev": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -9021,7 +9198,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -9042,7 +9218,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -9851,6 +10026,31 @@ "node": ">= 0.4" } }, + "node_modules/ioredis": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.5.0.tgz", + "integrity": "sha512-7CutT89g23FfSa8MDoIFs2GYYa0PaNiW/OrT+nRyjRXHDZd17HmIgy+reOQ/yhh72NznNjGuS8kbCAcA4Ro4mw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, "node_modules/ip-address": { "version": "9.0.5", "dev": true, @@ -9880,7 +10080,6 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "dev": true, "license": "MIT" }, "node_modules/is-bigint": { @@ -9936,7 +10135,6 @@ }, "node_modules/is-core-module": { "version": "2.14.0", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -9992,7 +10190,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10010,7 +10207,6 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10031,7 +10227,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -10074,7 +10269,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10173,7 +10367,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10303,7 +10496,6 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -10314,9 +10506,19 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "license": "MIT", + "peer": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -10337,7 +10539,6 @@ }, "node_modules/istanbul-lib-instrument": { "version": "6.0.3", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -10383,7 +10584,6 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -10396,7 +10596,6 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10404,7 +10603,6 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10415,7 +10613,6 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -10640,7 +10837,6 @@ }, "node_modules/istanbul-reports": { "version": "3.1.7", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -10770,7 +10966,6 @@ }, "node_modules/jest": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -10795,7 +10990,6 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -10808,7 +11002,6 @@ }, "node_modules/jest-circus": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -10838,7 +11031,6 @@ }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -10852,7 +11044,6 @@ }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -10867,7 +11058,6 @@ }, "node_modules/jest-circus/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -10878,12 +11068,10 @@ }, "node_modules/jest-circus/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-circus/node_modules/dedent": { "version": "1.5.3", - "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -10896,7 +11084,6 @@ }, "node_modules/jest-circus/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10904,7 +11091,6 @@ }, "node_modules/jest-circus/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10915,7 +11101,6 @@ }, "node_modules/jest-cli": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", @@ -10947,7 +11132,6 @@ }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -10961,7 +11145,6 @@ }, "node_modules/jest-cli/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -10976,7 +11159,6 @@ }, "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -10987,12 +11169,10 @@ }, "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11000,7 +11180,6 @@ }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11011,7 +11190,6 @@ }, "node_modules/jest-config": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -11055,7 +11233,6 @@ }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11069,7 +11246,6 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11084,7 +11260,6 @@ }, "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11095,12 +11270,10 @@ }, "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11108,7 +11281,6 @@ }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11119,7 +11291,6 @@ }, "node_modules/jest-diff": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11133,7 +11304,6 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11147,7 +11317,6 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11162,7 +11331,6 @@ }, "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11173,12 +11341,10 @@ }, "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11186,7 +11352,6 @@ }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11197,7 +11362,6 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -11208,7 +11372,6 @@ }, "node_modules/jest-each": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11223,7 +11386,6 @@ }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11237,7 +11399,6 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11252,7 +11413,6 @@ }, "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11263,12 +11423,10 @@ }, "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11276,7 +11434,6 @@ }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11287,7 +11444,6 @@ }, "node_modules/jest-environment-node": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -11303,7 +11459,6 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", - "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11311,7 +11466,6 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11335,7 +11489,6 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -11347,7 +11500,6 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11361,7 +11513,6 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11375,7 +11526,6 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11390,7 +11540,6 @@ }, "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11401,12 +11550,10 @@ }, "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11414,7 +11561,6 @@ }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11425,7 +11571,6 @@ }, "node_modules/jest-message-util": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -11444,7 +11589,6 @@ }, "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11458,7 +11602,6 @@ }, "node_modules/jest-message-util/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11473,7 +11616,6 @@ }, "node_modules/jest-message-util/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11484,12 +11626,10 @@ }, "node_modules/jest-message-util/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11497,7 +11637,6 @@ }, "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11508,7 +11647,6 @@ }, "node_modules/jest-mock": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11534,7 +11672,6 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11550,7 +11687,6 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", - "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11558,7 +11694,6 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -11577,7 +11712,6 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -11589,7 +11723,6 @@ }, "node_modules/jest-resolve/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11603,7 +11736,6 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11618,7 +11750,6 @@ }, "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11629,12 +11760,10 @@ }, "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11642,7 +11771,6 @@ }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11653,7 +11781,6 @@ }, "node_modules/jest-runner": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -11684,7 +11811,6 @@ }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11698,7 +11824,6 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11713,7 +11838,6 @@ }, "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11724,12 +11848,10 @@ }, "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11737,7 +11859,6 @@ }, "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11748,7 +11869,6 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -11780,7 +11900,6 @@ }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11794,7 +11913,6 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11809,7 +11927,6 @@ }, "node_modules/jest-runtime/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11820,12 +11937,10 @@ }, "node_modules/jest-runtime/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11833,7 +11948,6 @@ }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11844,7 +11958,6 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -11874,7 +11987,6 @@ }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11888,7 +12000,6 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11903,7 +12014,6 @@ }, "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11914,12 +12024,10 @@ }, "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11927,7 +12035,6 @@ }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -11938,7 +12045,6 @@ }, "node_modules/jest-util": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -11954,7 +12060,6 @@ }, "node_modules/jest-util/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -11968,7 +12073,6 @@ }, "node_modules/jest-util/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11983,7 +12087,6 @@ }, "node_modules/jest-util/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11994,12 +12097,10 @@ }, "node_modules/jest-util/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12007,7 +12108,6 @@ }, "node_modules/jest-util/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12018,7 +12118,6 @@ }, "node_modules/jest-validate": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -12034,7 +12133,6 @@ }, "node_modules/jest-validate/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12048,7 +12146,6 @@ }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -12059,7 +12156,6 @@ }, "node_modules/jest-validate/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -12074,7 +12170,6 @@ }, "node_modules/jest-validate/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -12085,12 +12180,10 @@ }, "node_modules/jest-validate/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-validate/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12098,7 +12191,6 @@ }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12109,7 +12201,6 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -12127,7 +12218,6 @@ }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12141,7 +12231,6 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -12156,7 +12245,6 @@ }, "node_modules/jest-watcher/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -12167,12 +12255,10 @@ }, "node_modules/jest-watcher/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12180,7 +12266,6 @@ }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12191,7 +12276,6 @@ }, "node_modules/jest-worker": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -12205,7 +12289,6 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12213,7 +12296,6 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12234,6 +12316,13 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT", + "peer": true + }, "node_modules/js-tokens": { "version": "4.0.0", "license": "MIT" @@ -12256,7 +12345,6 @@ }, "node_modules/jsesc": { "version": "2.5.2", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -12309,7 +12397,6 @@ }, "node_modules/json5": { "version": "2.2.3", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -12325,7 +12412,6 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -12395,7 +12481,6 @@ }, "node_modules/kleur": { "version": "3.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -12830,7 +12915,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -13296,6 +13380,13 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT", + "peer": true + }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", @@ -13307,6 +13398,13 @@ "version": "4.4.2", "license": "MIT" }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT", + "peer": true + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "dev": true, @@ -13545,7 +13643,6 @@ }, "node_modules/lru-cache": { "version": "5.1.1", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -13558,9 +13655,18 @@ "dev": true, "license": "MIT" }, + "node_modules/luxon": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + } + }, "node_modules/make-dir": { "version": "4.0.0", - "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -13731,7 +13837,6 @@ }, "node_modules/makeerror": { "version": "1.0.12", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -14003,12 +14108,10 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -14110,7 +14213,6 @@ }, "node_modules/micromatch": { "version": "4.0.7", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -14161,7 +14263,6 @@ }, "node_modules/minimatch": { "version": "9.0.5", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -14431,6 +14532,39 @@ "version": "2.1.2", "license": "MIT" }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "license": "MIT", + "peer": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, "node_modules/multimatch": { "version": "5.0.0", "dev": true, @@ -14484,7 +14618,6 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, "license": "MIT" }, "node_modules/negotiator": { @@ -14506,7 +14639,6 @@ }, "node_modules/node-fetch": { "version": "2.6.7", - "dev": true, "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -14557,6 +14689,22 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/abbrev": { "version": "1.1.1", "dev": true, @@ -14578,7 +14726,6 @@ }, "node_modules/node-int64": { "version": "0.4.0", - "dev": true, "license": "MIT" }, "node_modules/node-machine-id": { @@ -14601,7 +14748,6 @@ }, "node_modules/node-releases": { "version": "2.0.14", - "dev": true, "license": "MIT" }, "node_modules/nopt": { @@ -14634,7 +14780,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14943,7 +15088,6 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -15645,6 +15789,35 @@ "node": ">=6" } }, + "node_modules/o1js": { + "version": "1.7.0", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "blakejs": "1.2.1", + "cachedir": "^2.4.0", + "isomorphic-fetch": "^3.0.0", + "js-sha256": "^0.9.0", + "reflect-metadata": "^0.1.13", + "tslib": "^2.3.0" + }, + "bin": { + "snarky-run": "src/build/run.js" + }, + "engines": { + "node": ">=18.14.0" + } + }, + "node_modules/o1js/node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -15760,7 +15933,6 @@ }, "node_modules/once": { "version": "1.4.0", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -15930,7 +16102,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -16025,7 +16196,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16267,7 +16437,6 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -16284,12 +16453,10 @@ }, "node_modules/parse-json/node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, "license": "MIT" }, "node_modules/parse-json/node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, "license": "MIT" }, "node_modules/parse-passwd": { @@ -16331,9 +16498,15 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT", + "peer": true + }, "node_modules/path-exists": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16341,7 +16514,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16349,7 +16521,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16357,7 +16528,6 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, "license": "MIT" }, "node_modules/path-scurry": { @@ -16393,12 +16563,10 @@ }, "node_modules/picocolors": { "version": "1.0.1", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -16431,7 +16599,6 @@ }, "node_modules/pirates": { "version": "4.0.6", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -16439,7 +16606,6 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "dev": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -16450,7 +16616,6 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -16462,7 +16627,6 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -16473,7 +16637,6 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -16487,7 +16650,6 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -16496,6 +16658,16 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "dev": true, @@ -16551,7 +16723,6 @@ }, "node_modules/pretty-format": { "version": "29.7.0", - "dev": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -16564,7 +16735,6 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -16615,51 +16785,6 @@ "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, - "node_modules/prisma/node_modules/@prisma/debug": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", - "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", - "license": "Apache-2.0" - }, - "node_modules/prisma/node_modules/@prisma/engines": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", - "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.22.0", - "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "@prisma/fetch-engine": "5.22.0", - "@prisma/get-platform": "5.22.0" - } - }, - "node_modules/prisma/node_modules/@prisma/engines-version": { - "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", - "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", - "license": "Apache-2.0" - }, - "node_modules/prisma/node_modules/@prisma/fetch-engine": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", - "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.22.0", - "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", - "@prisma/get-platform": "5.22.0" - } - }, - "node_modules/prisma/node_modules/@prisma/get-platform": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", - "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.22.0" - } - }, "node_modules/proc-log": { "version": "3.0.0", "dev": true, @@ -16721,7 +16846,6 @@ }, "node_modules/prompts": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -16800,7 +16924,6 @@ }, "node_modules/pure-rand": { "version": "6.1.0", - "dev": true, "funding": [ { "type": "individual", @@ -16824,7 +16947,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "dev": true, "funding": [ { "type": "github", @@ -16862,7 +16984,6 @@ }, "node_modules/react-is": { "version": "18.3.1", - "dev": true, "license": "MIT" }, "node_modules/react-json-view-lite": { @@ -17211,6 +17332,29 @@ "@redis/time-series": "1.0.5" } }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "peer": true, + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/reflect-metadata": { "version": "0.1.14", "license": "Apache-2.0" @@ -17306,7 +17450,6 @@ }, "node_modules/resolve": { "version": "1.22.8", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -17322,7 +17465,6 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "dev": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -17345,7 +17487,6 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17353,7 +17494,6 @@ }, "node_modules/resolve.exports": { "version": "2.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -17380,7 +17520,6 @@ }, "node_modules/reusify": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -17416,7 +17555,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "dev": true, "funding": [ { "type": "github", @@ -17497,7 +17635,7 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/scheduler": { @@ -17571,7 +17709,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -17582,7 +17719,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17730,12 +17866,10 @@ }, "node_modules/sisteransi": { "version": "1.0.5", - "dev": true, "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17813,7 +17947,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -17821,7 +17954,6 @@ }, "node_modules/source-map-support": { "version": "0.5.13", - "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -17993,6 +18125,13 @@ "node": ">=8" } }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT", + "peer": true + }, "node_modules/statuses": { "version": "1.5.0", "license": "MIT", @@ -18024,7 +18163,6 @@ }, "node_modules/string-length": { "version": "4.0.2", - "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -18160,7 +18298,6 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18168,7 +18305,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -18187,7 +18323,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18214,7 +18349,6 @@ }, "node_modules/supports-color": { "version": "5.5.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -18225,7 +18359,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -18354,7 +18487,6 @@ }, "node_modules/test-exclude": { "version": "6.0.0", - "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -18367,7 +18499,6 @@ }, "node_modules/test-exclude/node_modules/brace-expansion": { "version": "1.1.11", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -18376,7 +18507,6 @@ }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -18424,12 +18554,10 @@ }, "node_modules/tmpl": { "version": "1.0.5", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18437,7 +18565,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -18455,7 +18582,6 @@ }, "node_modules/tr46": { "version": "0.0.3", - "dev": true, "license": "MIT" }, "node_modules/treeverse": { @@ -18567,6 +18693,17 @@ "version": "6.0.4", "license": "MIT" }, + "node_modules/ts-morph": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz", + "integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ts-morph/common": "~0.24.0", + "code-block-writer": "^13.0.1" + } + }, "node_modules/ts-pattern": { "version": "4.3.0", "license": "MIT" @@ -18648,6 +18785,26 @@ "dev": true, "license": "0BSD" }, + "node_modules/tsyringe": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.8.0.tgz", + "integrity": "sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD", + "peer": true + }, "node_modules/tuf-js": { "version": "1.1.7", "dev": true, @@ -18758,7 +18915,6 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18965,9 +19121,39 @@ "typedoc": "0.26.x" } }, + "node_modules/typegraphql-prisma": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/typegraphql-prisma/-/typegraphql-prisma-0.28.0.tgz", + "integrity": "sha512-LMTsYEAteeXhnJRmH2sBWarR8Jc9Um13mtSpi8Vh6G8QUTlp5tRfqMjd+Fw06HS6SBshU6NilZJlsPaz26SQCw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@prisma/generator-helper": "^5.18.0", + "@prisma/internals": "^5.18.0", + "pluralize": "^8.0.0", + "semver": "^7.6.3", + "ts-morph": "^23.0.0", + "tslib": "^2.6.3" + }, + "bin": { + "typegraphql-prisma": "lib/generator.js" + }, + "engines": { + "node": ">=20.11.1" + }, + "peerDependencies": { + "@prisma/client": "^5.18.0", + "@types/graphql-fields": "^1.3.9", + "@types/node": "*", + "graphql-fields": "^2.0.3", + "graphql-scalars": "^1.23.0", + "prisma": "^5.18.0", + "tslib": "^2.6.3", + "type-graphql": "^1.1.1 || >=1.2.0-rc || >=2.0.0-beta || >=2.0.0-rc" + } + }, "node_modules/typescript": { "version": "5.1.6", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -19131,7 +19317,6 @@ }, "node_modules/universalify": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -19148,7 +19333,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.0.16", - "dev": true, "funding": [ { "type": "opencollective", @@ -19207,7 +19391,6 @@ }, "node_modules/v8-to-istanbul": { "version": "9.3.0", - "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -19319,7 +19502,6 @@ }, "node_modules/walker": { "version": "1.0.8", - "dev": true, "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" @@ -19335,12 +19517,17 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "dev": true, "license": "BSD-2-Clause" }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT", + "peer": true + }, "node_modules/whatwg-url": { "version": "5.0.0", - "dev": true, "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -19349,7 +19536,6 @@ }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -19577,12 +19763,10 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", - "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -19712,7 +19896,6 @@ }, "node_modules/yallist": { "version": "3.1.1", - "dev": true, "license": "ISC" }, "node_modules/yaml": { @@ -19780,7 +19963,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -19897,7 +20079,7 @@ "dependencies": { "@envelop/extended-validation": "^4.1.0", "@inkjs/ui": "^1.0.0", - "@prisma/client": "^5.18.0", + "@prisma/client": "^5.22.0", "@types/yargs": "^17.0.29", "figlet": "^1.7.0", "ink": "^4.4.1", @@ -20012,7 +20194,7 @@ "license": "MIT", "dependencies": { "@inkjs/ui": "^1.0.0", - "@prisma/client": "^5.19.1", + "@prisma/client": "^5.22.0", "@types/yargs": "^17.0.29", "figlet": "^1.7.0", "ink": "^4.4.1", From 432d86fa43801d1390de4e8eb5e99d430faacb76 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Wed, 19 Feb 2025 11:13:59 +0100 Subject: [PATCH 07/23] Tip tracking for BlockStorage --- .../src/mempool/private/PrivateMempool.ts | 9 ++- .../sequencing/BlockProducerModule.ts | 27 +++++-- .../src/state/StateServiceCreator.ts | 77 +++++++++++++++++++ .../src/state/state/CachedStateService.ts | 2 +- .../src/storage/StorageDependencyFactory.ts | 5 +- .../src/storage/inmemory/InMemoryDatabase.ts | 9 +-- .../test/integration/BlockProduction.test.ts | 22 +++--- .../integration/services/BlockTestService.ts | 16 ++-- 8 files changed, 126 insertions(+), 41 deletions(-) create mode 100644 packages/sequencer/src/state/StateServiceCreator.ts diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index f1c56f5af..83db843f2 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -27,8 +27,8 @@ import { SequencerModulesRecord, } from "../../sequencer/executor/Sequencer"; import { CachedStateService } from "../../state/state/CachedStateService"; -import { AsyncStateService } from "../../state/async/AsyncStateService"; import { distinctByPredicate } from "../../helpers/utils"; +import { StateServiceCreator } from "../../state/StateServiceCreator"; type MempoolTransactionPaths = { transaction: PendingTransaction; @@ -54,8 +54,8 @@ export class PrivateMempool private readonly protocol: Protocol, @inject("Sequencer") private readonly sequencer: Sequencer, - @inject("UnprovenStateService") - private readonly stateService: AsyncStateService + @inject("StateServiceCreator") + private readonly stateServiceCreator: StateServiceCreator ) { super(); this.accountStateHook = @@ -104,7 +104,8 @@ export class PrivateMempool public async getTxs(limit?: number): Promise { const txs = await this.transactionStorage.getPendingUserTransactions(); - const baseCachedStateService = new CachedStateService(this.stateService); + const stateService = await this.stateServiceCreator.getMask("latest"); + const baseCachedStateService = new CachedStateService(stateService); const networkState = (await this.getStagedNetworkState()) ?? NetworkState.empty(); diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 78e358955..452e2adf2 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -16,7 +16,6 @@ import { import { BlockQueue } from "../../../storage/repositories/BlockStorage"; import { PendingTransaction } from "../../../mempool/PendingTransaction"; import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; -import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { Block, BlockResult, @@ -24,6 +23,7 @@ import { } from "../../../storage/model/Block"; import { Database } from "../../../storage/Database"; import { IncomingMessagesService } from "../../../settlement/messages/IncomingMessagesService"; +import { StateServiceCreator } from "../../../state/StateServiceCreator"; import { BlockProductionService } from "./BlockProductionService"; import { BlockResultService } from "./BlockResultService"; @@ -40,8 +40,8 @@ export class BlockProducerModule extends SequencerModule { public constructor( @inject("Mempool") private readonly mempool: Mempool, private readonly messageService: IncomingMessagesService, - @inject("UnprovenStateService") - private readonly unprovenStateService: AsyncStateService, + @inject("StateServiceCreator") + private readonly stateServiceCreator: StateServiceCreator, @inject("UnprovenMerkleStore") private readonly unprovenMerkleStore: AsyncMerkleTreeStore, @inject("BlockQueue") @@ -106,12 +106,16 @@ export class BlockProducerModule extends SequencerModule { } public async generateMetadata(block: Block): Promise { + const stateServiceMask = `block-${block.height.toBigInt()}`; + const asyncStateService = + await this.stateServiceCreator.getMask(stateServiceMask); + const { result, blockHashTreeStore, treeStore, stateService } = await this.resultService.generateMetadataForNextBlock( block, this.unprovenMerkleStore, this.blockTreeStore, - this.unprovenStateService + asyncStateService ); await this.database.executeInTransaction(async () => { @@ -120,6 +124,8 @@ export class BlockProducerModule extends SequencerModule { await stateService.mergeIntoParent(); await this.blockQueue.pushResult(result); + + await this.stateServiceCreator.mergeIntoParent(stateServiceMask); }); return result; @@ -197,6 +203,15 @@ export class BlockProducerModule extends SequencerModule { }; } + private async createMask(previousBlock: Block) { + const isFirstBlock = previousBlock.hash.equals(0n).toBoolean(); + const height = isFirstBlock ? 0n : previousBlock.height.toBigInt() + 1n; + + // const parent = isFirstBlock ? "base" : `block-${height - 1n}`; + + return await this.stateServiceCreator.createMask(`block-${height}`, "base"); + } + private async produceBlock(): Promise { this.productionInProgress = true; @@ -207,8 +222,10 @@ export class BlockProducerModule extends SequencerModule { return undefined; } + const stateService = await this.createMask(metadata.block); + const blockResult = await this.productionService.createBlock( - this.unprovenStateService, + stateService, txs, metadata, this.allowEmptyBlock() diff --git a/packages/sequencer/src/state/StateServiceCreator.ts b/packages/sequencer/src/state/StateServiceCreator.ts new file mode 100644 index 000000000..1eb13e008 --- /dev/null +++ b/packages/sequencer/src/state/StateServiceCreator.ts @@ -0,0 +1,77 @@ +import { AsyncStateService } from "./async/AsyncStateService"; +import { CachedStateService } from "./state/CachedStateService"; + +export interface StateServiceCreator { + createMask(name: string, parent: string): Promise; + getMask(name: string): Promise; + mergeIntoParent(name: string): Promise; +} + +export class InMemoryMasker< + T extends { + createMask(name: string): Promise; + mergeIntoParent(): Promise; + name?: string; + }, +> { + public constructor(base: T) { + this.serviceStack = [base]; + } + + private serviceStack: T[]; + + private findService(name: string) { + if (name === "latest") { + return this.serviceStack.at(-1)!; + } + return this.serviceStack.find((service) => service.name === name); + } + + public async getMask(name: string) { + const candidate = this.findService(name); + if (candidate === undefined) { + throw new Error(`State service ${name} not found`); + } + return candidate; + } + + public async createMask(name: string, parentName: string): Promise { + const candidate = this.findService(name); + if (candidate !== undefined) { + return candidate; + } + const parent = this.findService(parentName); + if (parent === undefined) { + throw new Error(`State service ${parentName} not found`); + } + const mask = await parent.createMask(name); + this.serviceStack.push(mask); + return mask; + } + + public async mergeIntoParent(name: string): Promise { + const service = await this.getMask(name); + + await service.mergeIntoParent(); + + const index = this.serviceStack.indexOf(service); + if (index === -1) { + throw new Error( + "Service not found in stack although found earlier, this shouldn't happen" + ); + } + this.serviceStack.splice(index, 1); + } +} + +export class InMemoryStateServiceCreator + extends InMemoryMasker + implements StateServiceCreator +{ + public constructor() { + super(new CachedStateService(undefined, "base")); + } +} + +// export class InMemoryTreeStoreCreator +// export InMemoryMasker diff --git a/packages/sequencer/src/state/state/CachedStateService.ts b/packages/sequencer/src/state/state/CachedStateService.ts index 5af85e235..79f80b4b6 100644 --- a/packages/sequencer/src/state/state/CachedStateService.ts +++ b/packages/sequencer/src/state/state/CachedStateService.ts @@ -22,7 +22,7 @@ export class CachedStateService super(); } - public async createMask(name: string): Promise { + public async createMask(name: string): Promise { return new CachedStateService(this, name); } diff --git a/packages/sequencer/src/storage/StorageDependencyFactory.ts b/packages/sequencer/src/storage/StorageDependencyFactory.ts index ed660d8fa..153e504bd 100644 --- a/packages/sequencer/src/storage/StorageDependencyFactory.ts +++ b/packages/sequencer/src/storage/StorageDependencyFactory.ts @@ -4,8 +4,8 @@ import { DependencyRecord, } from "@proto-kit/common"; -import { AsyncStateService } from "../state/async/AsyncStateService"; import { AsyncMerkleTreeStore } from "../state/async/AsyncMerkleTreeStore"; +import { StateServiceCreator } from "../state/StateServiceCreator"; import { BatchStorage } from "./repositories/BatchStorage"; import { BlockQueue, BlockStorage } from "./repositories/BlockStorage"; @@ -14,17 +14,16 @@ import { SettlementStorage } from "./repositories/SettlementStorage"; import { TransactionStorage } from "./repositories/TransactionStorage"; export interface StorageDependencyMinimumDependencies extends DependencyRecord { - asyncStateService: DependencyDeclaration; asyncMerkleStore: DependencyDeclaration; batchStorage: DependencyDeclaration; blockQueue: DependencyDeclaration; blockStorage: DependencyDeclaration; - unprovenStateService: DependencyDeclaration; unprovenMerkleStore: DependencyDeclaration; blockTreeStore: DependencyDeclaration; messageStorage: DependencyDeclaration; settlementStorage: DependencyDeclaration; transactionStorage: DependencyDeclaration; + stateServiceCreator: DependencyDeclaration; } export interface StorageDependencyFactory extends DependencyFactory { diff --git a/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts b/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts index a8eb330ab..47ecb5f4b 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts @@ -1,6 +1,5 @@ import { noop } from "@proto-kit/common"; -import { CachedStateService } from "../../state/state/CachedStateService"; import { sequencerModule, SequencerModule, @@ -8,6 +7,7 @@ import { import { StorageDependencyMinimumDependencies } from "../StorageDependencyFactory"; import { Database } from "../Database"; import { closeable } from "../../sequencer/builder/Closeable"; +import { InMemoryStateServiceCreator } from "../../state/StateServiceCreator"; import { InMemoryBlockStorage } from "./InMemoryBlockStorage"; import { InMemoryAsyncMerkleTreeStore } from "./InMemoryAsyncMerkleTreeStore"; @@ -24,9 +24,6 @@ export class InMemoryDatabase extends SequencerModule implements Database { asyncMerkleStore: { useClass: InMemoryAsyncMerkleTreeStore, }, - asyncStateService: { - useFactory: () => new CachedStateService(undefined), - }, batchStorage: { useClass: InMemoryBatchStorage, }, @@ -36,8 +33,8 @@ export class InMemoryDatabase extends SequencerModule implements Database { blockStorage: { useToken: "BlockQueue", }, - unprovenStateService: { - useFactory: () => new CachedStateService(undefined), + stateServiceCreator: { + useClass: InMemoryStateServiceCreator, }, unprovenMerkleStore: { useClass: InMemoryAsyncMerkleTreeStore, diff --git a/packages/sequencer/test/integration/BlockProduction.test.ts b/packages/sequencer/test/integration/BlockProduction.test.ts index b24a6a732..8a18a4632 100644 --- a/packages/sequencer/test/integration/BlockProduction.test.ts +++ b/packages/sequencer/test/integration/BlockProduction.test.ts @@ -232,7 +232,7 @@ describe("block production", () => { ); // TODO // const newState = await test.getState(balancesPath, "batch"); - const newUnprovenState = await test.getState(balancesPath, "block"); + const newUnprovenState = await test.getState(balancesPath); // expect(newState).toBeDefined(); expect(newUnprovenState).toBeDefined(); @@ -248,7 +248,7 @@ describe("block production", () => { accountModule.accountState.keyType, publicKey ); - const newAccountState = await test.getState(accountStatePath, "block"); + const newAccountState = await test.getState(accountStatePath); expect(newAccountState).toBeDefined(); expect(AccountState.fromFields(newAccountState!).nonce.toBigInt()).toBe(1n); @@ -273,14 +273,14 @@ describe("block production", () => { expect(batch!.blockHashes).toHaveLength(1); expect(batch!.proof.proof).toBe(MOCK_PROOF); - const state2 = await test.getState(balancesPath, "block"); + const state2 = await test.getState(balancesPath); expect(state2).toBeDefined(); expect(UInt64.fromFields(state2!)).toStrictEqual(UInt64.from(200)); }, 60_000); it("should reject tx and not apply the state", async () => { - expect.assertions(5); + expect.assertions(4); const privateKey = PrivateKey.random(); @@ -302,12 +302,10 @@ describe("block production", () => { balanceModule.balances.keyType, PublicKey.empty() ); - const unprovenState = await test.getState(balancesPath, "block"); - const newState = await test.getState(balancesPath, "batch"); + const unprovenState = await test.getState(balancesPath); // Assert that state is not set expect(unprovenState).toBeUndefined(); - expect(newState).toBeUndefined(); }, 30_000); it("should produce txs in non-consecutive blocks", async () => { @@ -441,7 +439,7 @@ describe("block production", () => { balanceModule.balances.keyType, publicKey ); - const newState = await test.getState(balancesPath, "block"); + const newState = await test.getState(balancesPath); expect(newState).toBeDefined(); expect(UInt64.fromFields(newState!)).toStrictEqual( @@ -485,7 +483,7 @@ describe("block production", () => { balanceModule.balances.keyType, pk1.toPublicKey() ); - const newState1 = await test.getState(balancesPath1, "block"); + const newState1 = await test.getState(balancesPath1); expect(newState1).toBeUndefined(); @@ -494,7 +492,7 @@ describe("block production", () => { balanceModule.balances.keyType, pk2.toPublicKey() ); - const newState2 = await test.getState(balancesPath2, "block"); + const newState2 = await test.getState(balancesPath2); expect(newState2).toBeDefined(); expect(UInt64.fromFields(newState2!)).toStrictEqual(UInt64.from(100)); @@ -601,7 +599,7 @@ describe("block production", () => { "totalSupply", PROTOKIT_PREFIXES.STATE_RUNTIME ); - const newState = await test.getState(supplyPath, "block"); + const newState = await test.getState(supplyPath); expect(newState).toBeDefined(); expect(UInt64.fromFields(newState!)).toStrictEqual( @@ -617,7 +615,7 @@ describe("block production", () => { pk2 ); - const newBalance = await test.getState(balancesPath, "block"); + const newBalance = await test.getState(balancesPath); expect(newBalance).toBeDefined(); expect(UInt64.fromFields(newBalance!)).toStrictEqual(UInt64.from(200)); diff --git a/packages/sequencer/test/integration/services/BlockTestService.ts b/packages/sequencer/test/integration/services/BlockTestService.ts index f51c64393..b78c39364 100644 --- a/packages/sequencer/test/integration/services/BlockTestService.ts +++ b/packages/sequencer/test/integration/services/BlockTestService.ts @@ -3,12 +3,9 @@ import { Field, PrivateKey } from "o1js"; import { Runtime, RuntimeModulesRecord } from "@proto-kit/module"; import { ArgumentTypes } from "@proto-kit/common"; -import { - AsyncStateService, - ManualBlockTrigger, - PrivateMempool, -} from "../../../src"; +import { ManualBlockTrigger, PrivateMempool } from "../../../src"; import { createTransaction } from "../utils"; +import { StateServiceCreator } from "../../../src/state/StateServiceCreator"; @injectable() @scoped(Lifecycle.ContainerScoped) @@ -17,8 +14,8 @@ export class BlockTestService { @inject("BlockTrigger") private trigger: ManualBlockTrigger, @inject("Mempool") private mempool: PrivateMempool, @inject("Runtime") private runtime: Runtime, - @inject("AsyncStateService") private batchStateService: AsyncStateService, - @inject("UnprovenStateService") private blockStateService: AsyncStateService + @inject("StateServiceCreator") + private stateServiceCreator: StateServiceCreator ) {} private nonces: Record = {}; @@ -47,9 +44,8 @@ export class BlockTestService { this.nonces[privateKey.toPublicKey().toBase58()] = nonce + 1; } - public async getState(path: Field, type: "block" | "batch" = "block") { - const service = - type === "batch" ? this.batchStateService : this.blockStateService; + public async getState(path: Field) { + const service = await this.stateServiceCreator.getMask("latest"); return await service.get(path); } From c3e5dd5f092b5761f6aa5a1b53758890f7b2856d Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 20 Feb 2025 19:17:49 +0100 Subject: [PATCH 08/23] Implemented MaskGraph and Creator interfaces --- .../src/state/async/AsyncStateService.ts | 2 - .../sequencer/src/state/masking/MaskGraph.ts | 134 ++++++++++++++++++ .../sequencer/src/state/masking/MaskName.ts | 3 + .../src/state/masking/StateServiceCreator.ts | 10 ++ .../src/state/masking/TreeStoreCreator.ts | 12 ++ 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 packages/sequencer/src/state/masking/MaskGraph.ts create mode 100644 packages/sequencer/src/state/masking/MaskName.ts create mode 100644 packages/sequencer/src/state/masking/StateServiceCreator.ts create mode 100644 packages/sequencer/src/state/masking/TreeStoreCreator.ts diff --git a/packages/sequencer/src/state/async/AsyncStateService.ts b/packages/sequencer/src/state/async/AsyncStateService.ts index b5e7a1be0..1d365eb4c 100644 --- a/packages/sequencer/src/state/async/AsyncStateService.ts +++ b/packages/sequencer/src/state/async/AsyncStateService.ts @@ -21,8 +21,6 @@ export interface AsyncStateService { get(key: Field): Promise; - createMask(name: string): Promise; - mergeIntoParent(): Promise; drop(): Promise; diff --git a/packages/sequencer/src/state/masking/MaskGraph.ts b/packages/sequencer/src/state/masking/MaskGraph.ts new file mode 100644 index 000000000..fca884476 --- /dev/null +++ b/packages/sequencer/src/state/masking/MaskGraph.ts @@ -0,0 +1,134 @@ +function assertMaskFound( + service: R | undefined, + name: string +): asserts service is R { + if (service === undefined) { + throw new Error(`Mask with name ${name} not found`); + } +} + +type Node = { + mask: T; + children: Child[]; + parent: Parent; +}; + +// export type Mask = { +// createMask(name: string): Promise; +// name: string; +// mergeIntoParent(): Promise; +// updateParent(parent: Mask): void; +// }; +// +// export type MaskBase = { +// createMask(name: string): Promise; +// name: string; +// }; + +export class MaskGraph< + Base extends { + createMask(name: string): Promise; + name: string; + }, + Mask extends Base & { + mergeIntoParent(): Promise; + updateParent(parent: Mask | Base): void; + }, +> { + public constructor(base: Base) { + this.root = { + mask: base, + children: [], + parent: undefined, + }; + } + + root: Node; + + masks: Record> = {}; + + private findMaskNode(name: string) { + return this.masks[name]; + } + + private findNode( + name: string + ): Node | undefined { + if (name === "base") { + return this.root; + } + return this.findMaskNode(name); + } + + private findService(name: string): Mask | Base | undefined { + return this.findNode(name)?.mask; + } + + public async getMask(name: string) { + const candidate = this.findService(name); + + assertMaskFound(candidate, name); + + return candidate; + } + + public async createMask( + name: string, + parentName: string, + fallback?: string + ): Promise { + const candidate = this.findService(name); + if (candidate !== undefined) { + return candidate; + } + + let parent = this.findService(parentName); + + if (parent === undefined && fallback !== undefined) { + parent = this.findService(fallback); + } + + assertMaskFound(parent, `${parentName} | ${fallback}`); + + const mask = await parent.createMask(name); + + this.masks[name] = { + mask, + parent, + children: [], + }; + this.findNode(parentName)?.children.push(mask); + + return mask; + } + + private removeFromGraph(name: string) { + const node = this.findMaskNode(name); + + assertMaskFound(node, name); + + const { children, parent } = node; + + children.forEach((child) => { + child.updateParent(parent!); + this.findNode(child.name)!.parent = parent; + }); + const parentNode = this.findNode(parent!.name)!; + parentNode.children = parentNode.children.filter((c) => c !== node.mask); + parentNode.children.push(...children); + + delete this.masks[name]; + + return node.mask; + } + + public async mergeIntoParent(name: string): Promise { + const mask = this.removeFromGraph(name); + + await mask.mergeIntoParent(); + } + + public async drop(name: string) { + this.removeFromGraph(name); + } +} diff --git a/packages/sequencer/src/state/masking/MaskName.ts b/packages/sequencer/src/state/masking/MaskName.ts new file mode 100644 index 000000000..e320c9caa --- /dev/null +++ b/packages/sequencer/src/state/masking/MaskName.ts @@ -0,0 +1,3 @@ +export const MaskName = { + // TODO +}; diff --git a/packages/sequencer/src/state/masking/StateServiceCreator.ts b/packages/sequencer/src/state/masking/StateServiceCreator.ts new file mode 100644 index 000000000..cd562c480 --- /dev/null +++ b/packages/sequencer/src/state/masking/StateServiceCreator.ts @@ -0,0 +1,10 @@ +import { AsyncStateService } from "../async/AsyncStateService"; + +export interface StateServiceCreator { + createMask(name: string, parent: string): Promise; + getMask(name: string): Promise; + mergeIntoParent(name: string): Promise; + drop(name: string): Promise; +} + +// TODO Add Prefix diff --git a/packages/sequencer/src/state/masking/TreeStoreCreator.ts b/packages/sequencer/src/state/masking/TreeStoreCreator.ts new file mode 100644 index 000000000..fd419df9a --- /dev/null +++ b/packages/sequencer/src/state/masking/TreeStoreCreator.ts @@ -0,0 +1,12 @@ +import { AsyncMerkleTreeStore } from "../async/AsyncMerkleTreeStore"; + +export interface TreeStoreCreator { + createMask( + name: string, + parent: string, + fallback?: string + ): Promise; + getMask(name: string): Promise; + mergeIntoParent(name: string): Promise; + drop(name: string): Promise; +} From 49f5b08a914fe8b04ddc0f0a22c7bca436a4bb03 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 20 Feb 2025 19:18:08 +0100 Subject: [PATCH 09/23] Implemented InMemory native masking --- .../src/state/StateServiceCreator.ts | 77 ------------------- .../src/state/merkle/CachedMerkleTreeStore.ts | 6 +- .../src/state/state/CachedStateService.ts | 9 +-- .../src/storage/StorageDependencyFactory.ts | 6 +- .../src/storage/inmemory/InMemoryDatabase.ts | 14 ++-- .../masking/InMemoryMerkleTreeStoreMask.ts | 24 ++++++ .../masking/InMemoryStateServiceCreator.ts | 13 ++++ .../masking/InMemoryStateServiceMask.ts | 15 ++++ .../masking/InMemoryTreeStoreCreator.ts | 23 ++++++ 9 files changed, 92 insertions(+), 95 deletions(-) delete mode 100644 packages/sequencer/src/state/StateServiceCreator.ts create mode 100644 packages/sequencer/src/storage/inmemory/masking/InMemoryMerkleTreeStoreMask.ts create mode 100644 packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts create mode 100644 packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceMask.ts create mode 100644 packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts diff --git a/packages/sequencer/src/state/StateServiceCreator.ts b/packages/sequencer/src/state/StateServiceCreator.ts deleted file mode 100644 index 1eb13e008..000000000 --- a/packages/sequencer/src/state/StateServiceCreator.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { AsyncStateService } from "./async/AsyncStateService"; -import { CachedStateService } from "./state/CachedStateService"; - -export interface StateServiceCreator { - createMask(name: string, parent: string): Promise; - getMask(name: string): Promise; - mergeIntoParent(name: string): Promise; -} - -export class InMemoryMasker< - T extends { - createMask(name: string): Promise; - mergeIntoParent(): Promise; - name?: string; - }, -> { - public constructor(base: T) { - this.serviceStack = [base]; - } - - private serviceStack: T[]; - - private findService(name: string) { - if (name === "latest") { - return this.serviceStack.at(-1)!; - } - return this.serviceStack.find((service) => service.name === name); - } - - public async getMask(name: string) { - const candidate = this.findService(name); - if (candidate === undefined) { - throw new Error(`State service ${name} not found`); - } - return candidate; - } - - public async createMask(name: string, parentName: string): Promise { - const candidate = this.findService(name); - if (candidate !== undefined) { - return candidate; - } - const parent = this.findService(parentName); - if (parent === undefined) { - throw new Error(`State service ${parentName} not found`); - } - const mask = await parent.createMask(name); - this.serviceStack.push(mask); - return mask; - } - - public async mergeIntoParent(name: string): Promise { - const service = await this.getMask(name); - - await service.mergeIntoParent(); - - const index = this.serviceStack.indexOf(service); - if (index === -1) { - throw new Error( - "Service not found in stack although found earlier, this shouldn't happen" - ); - } - this.serviceStack.splice(index, 1); - } -} - -export class InMemoryStateServiceCreator - extends InMemoryMasker - implements StateServiceCreator -{ - public constructor() { - super(new CachedStateService(undefined, "base")); - } -} - -// export class InMemoryTreeStoreCreator -// export InMemoryMasker diff --git a/packages/sequencer/src/state/merkle/CachedMerkleTreeStore.ts b/packages/sequencer/src/state/merkle/CachedMerkleTreeStore.ts index 677668abd..eb4018e7f 100644 --- a/packages/sequencer/src/state/merkle/CachedMerkleTreeStore.ts +++ b/packages/sequencer/src/state/merkle/CachedMerkleTreeStore.ts @@ -29,10 +29,14 @@ export class CachedMerkleTreeStore noop(); } - public constructor(private readonly parent: AsyncMerkleTreeStore) { + public constructor(public parent: AsyncMerkleTreeStore) { super(); } + public updateParent(parent: AsyncMerkleTreeStore) { + this.parent = parent; + } + public getNode(key: bigint, level: number): bigint | undefined { return super.getNode(key, level); } diff --git a/packages/sequencer/src/state/state/CachedStateService.ts b/packages/sequencer/src/state/state/CachedStateService.ts index 79f80b4b6..645df5e7d 100644 --- a/packages/sequencer/src/state/state/CachedStateService.ts +++ b/packages/sequencer/src/state/state/CachedStateService.ts @@ -15,15 +15,12 @@ export class CachedStateService { private writes: StateEntry[] = []; - public constructor( - private readonly parent: AsyncStateService | undefined, - public readonly name?: string - ) { + public constructor(private parent: AsyncStateService | undefined) { super(); } - public async createMask(name: string): Promise { - return new CachedStateService(this, name); + public updateParent(parent: AsyncStateService) { + this.parent = parent; } public async drop(): Promise { diff --git a/packages/sequencer/src/storage/StorageDependencyFactory.ts b/packages/sequencer/src/storage/StorageDependencyFactory.ts index 153e504bd..135bb08ca 100644 --- a/packages/sequencer/src/storage/StorageDependencyFactory.ts +++ b/packages/sequencer/src/storage/StorageDependencyFactory.ts @@ -5,7 +5,8 @@ import { } from "@proto-kit/common"; import { AsyncMerkleTreeStore } from "../state/async/AsyncMerkleTreeStore"; -import { StateServiceCreator } from "../state/StateServiceCreator"; +import { StateServiceCreator } from "../state/masking/StateServiceCreator"; +import { TreeStoreCreator } from "../state/masking/TreeStoreCreator"; import { BatchStorage } from "./repositories/BatchStorage"; import { BlockQueue, BlockStorage } from "./repositories/BlockStorage"; @@ -14,16 +15,15 @@ import { SettlementStorage } from "./repositories/SettlementStorage"; import { TransactionStorage } from "./repositories/TransactionStorage"; export interface StorageDependencyMinimumDependencies extends DependencyRecord { - asyncMerkleStore: DependencyDeclaration; batchStorage: DependencyDeclaration; blockQueue: DependencyDeclaration; blockStorage: DependencyDeclaration; - unprovenMerkleStore: DependencyDeclaration; blockTreeStore: DependencyDeclaration; messageStorage: DependencyDeclaration; settlementStorage: DependencyDeclaration; transactionStorage: DependencyDeclaration; stateServiceCreator: DependencyDeclaration; + treeStoreCreator: DependencyDeclaration; } export interface StorageDependencyFactory extends DependencyFactory { diff --git a/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts b/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts index 47ecb5f4b..a27b06d9c 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryDatabase.ts @@ -7,23 +7,21 @@ import { import { StorageDependencyMinimumDependencies } from "../StorageDependencyFactory"; import { Database } from "../Database"; import { closeable } from "../../sequencer/builder/Closeable"; -import { InMemoryStateServiceCreator } from "../../state/StateServiceCreator"; import { InMemoryBlockStorage } from "./InMemoryBlockStorage"; -import { InMemoryAsyncMerkleTreeStore } from "./InMemoryAsyncMerkleTreeStore"; import { InMemoryBatchStorage } from "./InMemoryBatchStorage"; import { InMemoryMessageStorage } from "./InMemoryMessageStorage"; import { InMemorySettlementStorage } from "./InMemorySettlementStorage"; import { InMemoryTransactionStorage } from "./InMemoryTransactionStorage"; +import { InMemoryStateServiceCreator } from "./masking/InMemoryStateServiceCreator"; +import { InMemoryTreeStoreCreator } from "./masking/InMemoryTreeStoreCreator"; +import { InMemoryBaseMerkleTreeStore } from "./masking/InMemoryMerkleTreeStoreMask"; @sequencerModule() @closeable() export class InMemoryDatabase extends SequencerModule implements Database { public dependencies(): StorageDependencyMinimumDependencies { return { - asyncMerkleStore: { - useClass: InMemoryAsyncMerkleTreeStore, - }, batchStorage: { useClass: InMemoryBatchStorage, }, @@ -36,11 +34,11 @@ export class InMemoryDatabase extends SequencerModule implements Database { stateServiceCreator: { useClass: InMemoryStateServiceCreator, }, - unprovenMerkleStore: { - useClass: InMemoryAsyncMerkleTreeStore, + treeStoreCreator: { + useClass: InMemoryTreeStoreCreator, }, blockTreeStore: { - useClass: InMemoryAsyncMerkleTreeStore, + useClass: InMemoryBaseMerkleTreeStore, }, messageStorage: { useClass: InMemoryMessageStorage, diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryMerkleTreeStoreMask.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryMerkleTreeStoreMask.ts new file mode 100644 index 000000000..68f59177b --- /dev/null +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryMerkleTreeStoreMask.ts @@ -0,0 +1,24 @@ +import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; +import { CachedMerkleTreeStore } from "../../../state/merkle/CachedMerkleTreeStore"; +import { InMemoryAsyncMerkleTreeStore } from "../InMemoryAsyncMerkleTreeStore"; + +export class InMemoryMerkleTreeStoreMask extends CachedMerkleTreeStore { + public constructor( + parent: AsyncMerkleTreeStore, + public readonly name: string + ) { + super(parent); + } + + public async createMask(name: string): Promise { + return new InMemoryMerkleTreeStoreMask(this, name); + } +} + +export class InMemoryBaseMerkleTreeStore extends InMemoryAsyncMerkleTreeStore { + public name = "base"; + + public async createMask(name: string): Promise { + return new InMemoryMerkleTreeStoreMask(this, name); + } +} diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts new file mode 100644 index 000000000..6f8ea5f1f --- /dev/null +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts @@ -0,0 +1,13 @@ +import { StateServiceCreator } from "../../../state/masking/StateServiceCreator"; +import { MaskGraph } from "../../../state/masking/MaskGraph"; + +import { InMemoryStateServiceMask } from "./InMemoryStateServiceMask"; + +export class InMemoryStateServiceCreator + extends MaskGraph + implements StateServiceCreator +{ + public constructor() { + super(new InMemoryStateServiceMask(undefined, "base")); + } +} diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceMask.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceMask.ts new file mode 100644 index 000000000..529cb24c1 --- /dev/null +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceMask.ts @@ -0,0 +1,15 @@ +import { AsyncStateService } from "../../../state/async/AsyncStateService"; +import { CachedStateService } from "../../../state/state/CachedStateService"; + +export class InMemoryStateServiceMask extends CachedStateService { + public constructor( + parent: AsyncStateService | undefined, + public readonly name: string + ) { + super(parent); + } + + public async createMask(name: string): Promise { + return new InMemoryStateServiceMask(this, name); + } +} diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts new file mode 100644 index 000000000..7d0d136ed --- /dev/null +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts @@ -0,0 +1,23 @@ +import { MaskGraph } from "../../../state/masking/MaskGraph"; +import { AsyncMerkleTreeStore } from "../../../state/async/AsyncMerkleTreeStore"; +import { TreeStoreCreator } from "../../../state/masking/TreeStoreCreator"; + +import { + InMemoryBaseMerkleTreeStore, + InMemoryMerkleTreeStoreMask, +} from "./InMemoryMerkleTreeStoreMask"; + +export class InMemoryTreeStoreCreator + extends MaskGraph< + AsyncMerkleTreeStore & { + createMask: (name: string) => Promise; + name: string; + }, + InMemoryMerkleTreeStoreMask + > + implements TreeStoreCreator +{ + public constructor() { + super(new InMemoryBaseMerkleTreeStore()); + } +} From 1802f78df488d195f9a1f45d7eb2f1227f7317d8 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 20 Feb 2025 19:18:44 +0100 Subject: [PATCH 10/23] Integrated masking into block prod pipeline --- packages/sequencer/src/index.ts | 8 ++++++ .../src/mempool/private/PrivateMempool.ts | 4 +-- .../production/BatchProducerModule.ts | 27 ++++++++++++++----- .../sequencing/BlockProducerModule.ts | 25 +++++++++++------ .../integration/services/BlockTestService.ts | 4 +-- 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/packages/sequencer/src/index.ts b/packages/sequencer/src/index.ts index 462da091d..67cbcc71a 100644 --- a/packages/sequencer/src/index.ts +++ b/packages/sequencer/src/index.ts @@ -75,6 +75,10 @@ export * from "./storage/inmemory/InMemoryBatchStorage"; export * from "./storage/inmemory/InMemorySettlementStorage"; export * from "./storage/inmemory/InMemoryMessageStorage"; export * from "./storage/inmemory/InMemoryTransactionStorage"; +export * from "./storage/inmemory/masking/InMemoryStateServiceCreator"; +export * from "./storage/inmemory/masking/InMemoryTreeStoreCreator"; +export * from "./storage/inmemory/masking/InMemoryStateServiceMask"; +export * from "./storage/inmemory/masking/InMemoryMerkleTreeStoreMask"; export * from "./storage/StorageDependencyFactory"; export * from "./storage/Database"; export * from "./storage/DatabasePruneModule"; @@ -89,6 +93,10 @@ export * from "./state/merkle/CachedMerkleTreeStore"; export * from "./state/merkle/SyncCachedMerkleTreeStore"; export * from "./state/state/DummyStateService"; export * from "./state/state/CachedStateService"; +export * from "./state/masking/MaskGraph"; +export * from "./state/masking/MaskName"; +export * from "./state/masking/StateServiceCreator"; +export * from "./state/masking/TreeStoreCreator"; export * from "./settlement/SettlementModule"; export * from "./settlement/messages/WithdrawalQueue"; export * from "./settlement/messages/IncomingMessageAdapter"; diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 83db843f2..52bedb2b1 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -28,7 +28,7 @@ import { } from "../../sequencer/executor/Sequencer"; import { CachedStateService } from "../../state/state/CachedStateService"; import { distinctByPredicate } from "../../helpers/utils"; -import { StateServiceCreator } from "../../state/StateServiceCreator"; +import { StateServiceCreator } from "../../state/masking/StateServiceCreator"; type MempoolTransactionPaths = { transaction: PendingTransaction; @@ -104,7 +104,7 @@ export class PrivateMempool public async getTxs(limit?: number): Promise { const txs = await this.transactionStorage.getPendingUserTransactions(); - const stateService = await this.stateServiceCreator.getMask("latest"); + const stateService = await this.stateServiceCreator.getMask("base"); const baseCachedStateService = new CachedStateService(stateService); const networkState = diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 6bdb77202..d7b343b84 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -5,7 +5,7 @@ import { NetworkState, } from "@proto-kit/protocol"; import { Field, Proof } from "o1js"; -import { log, noop } from "@proto-kit/common"; +import { log, mapSequential, noop } from "@proto-kit/common"; import { sequencerModule, @@ -14,9 +14,9 @@ import { import { BatchStorage } from "../../storage/repositories/BatchStorage"; import { SettleableBatch } from "../../storage/model/Batch"; import { CachedMerkleTreeStore } from "../../state/merkle/CachedMerkleTreeStore"; -import { AsyncMerkleTreeStore } from "../../state/async/AsyncMerkleTreeStore"; import { BlockWithResult } from "../../storage/model/Block"; import type { Database } from "../../storage/Database"; +import { TreeStoreCreator } from "../../state/masking/TreeStoreCreator"; import { BlockProofSerializer } from "./tasks/serializers/BlockProofSerializer"; import { BatchTracingService } from "./tracing/BatchTracingService"; @@ -47,8 +47,8 @@ export class BatchProducerModule extends SequencerModule { private productionInProgress = false; public constructor( - @inject("AsyncMerkleStore") - private readonly merkleStore: AsyncMerkleTreeStore, + @inject("TreeStoreCreator") + private readonly treeStoreCreator: TreeStoreCreator, @inject("BatchStorage") private readonly batchStorage: BatchStorage, @inject("Database") private readonly database: Database, @@ -101,6 +101,16 @@ export class BatchProducerModule extends SequencerModule { return undefined; } + private async mergeBatchIntoStorage(blocks: BlockWithResult[]) { + // Reverse, so that we merge from latest block to oldest. This way, + // nodes that have been written in multiple masks are only written to + // the base once, therefore implicitly deduped + await mapSequential(blocks.slice().reverse(), async (block) => { + const mask = `block-${block.block.height.toBigInt()}`; + await this.treeStoreCreator.mergeIntoParent(mask); + }); + } + private async tryProduceBatch( blocks: BlockWithResult[] ): Promise { @@ -122,7 +132,9 @@ export class BatchProducerModule extends SequencerModule { // Apply state changes to current MerkleTreeStore await this.database.executeInTransaction(async () => { await this.batchStorage.pushBatch(batchWithStateDiff.batch); - await batchWithStateDiff.changes.mergeIntoParent(); + + await this.mergeBatchIntoStorage(blocks); + // await batchWithStateDiff.changes.mergeIntoParent(); }); // TODO Add transition from unproven to proven state for stateservice @@ -186,13 +198,16 @@ export class BatchProducerModule extends SequencerModule { throw errors.blockWithoutTxs(); } - const merkleTreeStore = new CachedMerkleTreeStore(this.merkleStore); + const mask = await this.treeStoreCreator.createMask("batch", "base"); + const merkleTreeStore = new CachedMerkleTreeStore(mask); const trace = await this.batchTraceService.traceBatch( blocks.map((block) => block), merkleTreeStore ); + await this.treeStoreCreator.drop("batch"); + const proof = await this.batchFlow.executeBatch(trace, blockId); const fromNetworkState = blocks[0].block.networkState.before; diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 452e2adf2..096c04c6f 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -23,7 +23,8 @@ import { } from "../../../storage/model/Block"; import { Database } from "../../../storage/Database"; import { IncomingMessagesService } from "../../../settlement/messages/IncomingMessagesService"; -import { StateServiceCreator } from "../../../state/StateServiceCreator"; +import { TreeStoreCreator } from "../../../state/masking/TreeStoreCreator"; +import { StateServiceCreator } from "../../../state/masking/StateServiceCreator"; import { BlockProductionService } from "./BlockProductionService"; import { BlockResultService } from "./BlockResultService"; @@ -42,8 +43,10 @@ export class BlockProducerModule extends SequencerModule { private readonly messageService: IncomingMessagesService, @inject("StateServiceCreator") private readonly stateServiceCreator: StateServiceCreator, - @inject("UnprovenMerkleStore") - private readonly unprovenMerkleStore: AsyncMerkleTreeStore, + @inject("TreeStoreCreator") + private readonly treeStoreCreator: TreeStoreCreator, + // @inject("UnprovenMerkleStore") + // private readonly unprovenMerkleStore: AsyncMerkleTreeStore, @inject("BlockQueue") private readonly blockQueue: BlockQueue, @inject("BlockTreeStore") @@ -106,14 +109,20 @@ export class BlockProducerModule extends SequencerModule { } public async generateMetadata(block: Block): Promise { - const stateServiceMask = `block-${block.height.toBigInt()}`; - const asyncStateService = - await this.stateServiceCreator.getMask(stateServiceMask); + const height = block.height.toBigInt(); + const maskName = `block-${height}`; + const asyncStateService = await this.stateServiceCreator.getMask(maskName); + + const asyncTreeStore = await this.treeStoreCreator.createMask( + maskName, + `block-${height - 1n}`, + "base" + ); const { result, blockHashTreeStore, treeStore, stateService } = await this.resultService.generateMetadataForNextBlock( block, - this.unprovenMerkleStore, + asyncTreeStore, this.blockTreeStore, asyncStateService ); @@ -125,7 +134,7 @@ export class BlockProducerModule extends SequencerModule { await this.blockQueue.pushResult(result); - await this.stateServiceCreator.mergeIntoParent(stateServiceMask); + await this.stateServiceCreator.mergeIntoParent(maskName); }); return result; diff --git a/packages/sequencer/test/integration/services/BlockTestService.ts b/packages/sequencer/test/integration/services/BlockTestService.ts index b78c39364..c7c0f4acb 100644 --- a/packages/sequencer/test/integration/services/BlockTestService.ts +++ b/packages/sequencer/test/integration/services/BlockTestService.ts @@ -5,7 +5,7 @@ import { ArgumentTypes } from "@proto-kit/common"; import { ManualBlockTrigger, PrivateMempool } from "../../../src"; import { createTransaction } from "../utils"; -import { StateServiceCreator } from "../../../src/state/StateServiceCreator"; +import { StateServiceCreator } from "../../../src/state/masking/StateServiceCreator"; @injectable() @scoped(Lifecycle.ContainerScoped) @@ -45,7 +45,7 @@ export class BlockTestService { } public async getState(path: Field) { - const service = await this.stateServiceCreator.getMask("latest"); + const service = await this.stateServiceCreator.getMask("base"); return await service.get(path); } From 6b9245e7b6af3d9bf5fe8fcbaabe373ac4b2c5a7 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 24 Feb 2025 15:39:35 +0100 Subject: [PATCH 11/23] Added MaskNames --- packages/sequencer/src/state/masking/MaskName.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/sequencer/src/state/masking/MaskName.ts b/packages/sequencer/src/state/masking/MaskName.ts index e320c9caa..ee994c98b 100644 --- a/packages/sequencer/src/state/masking/MaskName.ts +++ b/packages/sequencer/src/state/masking/MaskName.ts @@ -1,3 +1,10 @@ +import { Field } from "o1js"; + export const MaskName = { - // TODO + block(height: bigint | Field) { + const heightBigint = + typeof height === "bigint" ? height : height.toBigInt(); + return `block-${heightBigint}`; + }, + base: () => "base", }; From 6982dfe20634017e399b23145b4fbe0e669bd455 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 24 Feb 2025 15:40:05 +0100 Subject: [PATCH 12/23] Replaced remaining occurrences of old service references --- .../graphql/modules/MerkleWitnessResolver.ts | 17 ++++++-- .../sdk/src/query/StateServiceQueryModule.ts | 42 +++++++++++++++---- .../src/mempool/private/PrivateMempool.ts | 5 ++- .../sequencing/BlockProducerModule.ts | 14 ++++--- .../src/settlement/BridgingModule.ts | 11 +++-- .../integration/StorageIntegration.test.ts | 15 +++---- .../integration/services/BlockTestService.ts | 4 +- 7 files changed, 76 insertions(+), 32 deletions(-) diff --git a/packages/api/src/graphql/modules/MerkleWitnessResolver.ts b/packages/api/src/graphql/modules/MerkleWitnessResolver.ts index 8c59b8cc8..b499fb28e 100644 --- a/packages/api/src/graphql/modules/MerkleWitnessResolver.ts +++ b/packages/api/src/graphql/modules/MerkleWitnessResolver.ts @@ -3,8 +3,10 @@ import { Length } from "class-validator"; import { inject } from "tsyringe"; import { RollupMerkleTree, RollupMerkleTreeWitness } from "@proto-kit/common"; import { - AsyncMerkleTreeStore, + BlockStorage, CachedMerkleTreeStore, + MaskName, + TreeStoreCreator, } from "@proto-kit/sequencer"; import { GraphqlModule, graphqlModule } from "../GraphqlModule"; @@ -34,7 +36,9 @@ export class MerkleWitnessDTO { @graphqlModule() export class MerkleWitnessResolver extends GraphqlModule { public constructor( - @inject("AsyncMerkleStore") private readonly treeStore: AsyncMerkleTreeStore + @inject("TreeStoreCreator") + private readonly treeStoreCreator: TreeStoreCreator, + @inject("BlockStorage") private readonly blockStorage: BlockStorage ) { super(); } @@ -44,7 +48,14 @@ export class MerkleWitnessResolver extends GraphqlModule { "Allows retrieval of merkle witnesses corresponding to a specific path in the appchain's state tree. These proves are generally retrieved from the current 'proven' state", }) public async witness(@Arg("path") path: string) { - const syncStore = new CachedMerkleTreeStore(this.treeStore); + const latestBlock = await this.blockStorage.getLatestBlock(); + const maskName = + latestBlock !== undefined + ? MaskName.block(latestBlock.block.height) + : MaskName.base(); + const treeStore = await this.treeStoreCreator.getMask(maskName); + + const syncStore = new CachedMerkleTreeStore(treeStore); await syncStore.preloadKey(BigInt(path)); const tree = new RollupMerkleTree(syncStore); diff --git a/packages/sdk/src/query/StateServiceQueryModule.ts b/packages/sdk/src/query/StateServiceQueryModule.ts index ec78f44aa..7f07c8957 100644 --- a/packages/sdk/src/query/StateServiceQueryModule.ts +++ b/packages/sdk/src/query/StateServiceQueryModule.ts @@ -5,6 +5,10 @@ import { Sequencer, SequencerModulesRecord, AsyncMerkleTreeStore, + BlockStorage, + TreeStoreCreator, + StateServiceCreator, + MaskName, } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { inject, injectable } from "tsyringe"; @@ -23,24 +27,46 @@ export class StateServiceQueryModule super(); } - public get asyncStateService(): AsyncStateService { - return this.sequencer.dependencyContainer.resolve( - "UnprovenStateService" + private async getCurrentTreeMask() { + const block = await this.blockStorage().getLatestBlock(); + if (block !== undefined) { + return MaskName.block(block.block.height); + } + return MaskName.base(); + } + + public blockStorage() { + return this.sequencer.dependencyContainer.resolve( + "BlockStorage" ); } - public get treeStore(): AsyncMerkleTreeStore { - return this.sequencer.dependencyContainer.resolve("AsyncMerkleStore"); + public async asyncStateService(): Promise { + const stateServiceCreator = + this.sequencer.dependencyContainer.resolve( + "StateServiceCreator" + ); + return await stateServiceCreator.getMask(MaskName.base()); + } + + public async treeStore(): Promise { + const treeStoreCreator = + this.sequencer.dependencyContainer.resolve( + "TreeStoreCreator" + ); + return await treeStoreCreator.getMask(await this.getCurrentTreeMask()); } - public get(key: Field) { - return this.asyncStateService.get(key); + public async get(key: Field) { + const stateService = await this.asyncStateService(); + return await stateService.get(key); } public async merkleWitness( path: Field ): Promise { - const syncStore = new CachedMerkleTreeStore(this.treeStore); + const treeStore = await this.treeStore(); + const syncStore = new CachedMerkleTreeStore(treeStore); await syncStore.preloadKey(path.toBigInt()); const tree = new RollupMerkleTree(syncStore); diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 52bedb2b1..102e31e7e 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -29,6 +29,7 @@ import { import { CachedStateService } from "../../state/state/CachedStateService"; import { distinctByPredicate } from "../../helpers/utils"; import { StateServiceCreator } from "../../state/masking/StateServiceCreator"; +import { MaskName } from "../../state/masking/MaskName"; type MempoolTransactionPaths = { transaction: PendingTransaction; @@ -104,7 +105,9 @@ export class PrivateMempool public async getTxs(limit?: number): Promise { const txs = await this.transactionStorage.getPendingUserTransactions(); - const stateService = await this.stateServiceCreator.getMask("base"); + const stateService = await this.stateServiceCreator.getMask( + MaskName.base() + ); const baseCachedStateService = new CachedStateService(stateService); const networkState = diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index 096c04c6f..b780d8318 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -25,6 +25,7 @@ import { Database } from "../../../storage/Database"; import { IncomingMessagesService } from "../../../settlement/messages/IncomingMessagesService"; import { TreeStoreCreator } from "../../../state/masking/TreeStoreCreator"; import { StateServiceCreator } from "../../../state/masking/StateServiceCreator"; +import { MaskName } from "../../../state/masking/MaskName"; import { BlockProductionService } from "./BlockProductionService"; import { BlockResultService } from "./BlockResultService"; @@ -110,13 +111,13 @@ export class BlockProducerModule extends SequencerModule { public async generateMetadata(block: Block): Promise { const height = block.height.toBigInt(); - const maskName = `block-${height}`; + const maskName = MaskName.block(height); const asyncStateService = await this.stateServiceCreator.getMask(maskName); const asyncTreeStore = await this.treeStoreCreator.createMask( maskName, - `block-${height - 1n}`, - "base" + MaskName.block(height - 1n), + MaskName.base() ); const { result, blockHashTreeStore, treeStore, stateService } = @@ -216,9 +217,10 @@ export class BlockProducerModule extends SequencerModule { const isFirstBlock = previousBlock.hash.equals(0n).toBoolean(); const height = isFirstBlock ? 0n : previousBlock.height.toBigInt() + 1n; - // const parent = isFirstBlock ? "base" : `block-${height - 1n}`; - - return await this.stateServiceCreator.createMask(`block-${height}`, "base"); + return await this.stateServiceCreator.createMask( + MaskName.block(height), + MaskName.base() + ); } private async produceBlock(): Promise { diff --git a/packages/sequencer/src/settlement/BridgingModule.ts b/packages/sequencer/src/settlement/BridgingModule.ts index c4e407246..135e7b2b1 100644 --- a/packages/sequencer/src/settlement/BridgingModule.ts +++ b/packages/sequencer/src/settlement/BridgingModule.ts @@ -49,6 +49,8 @@ import type { OutgoingMessageAdapter } from "./messages/WithdrawalQueue"; import type { SettlementModule } from "./SettlementModule"; import { SettlementUtils } from "./utils/SettlementUtils"; import { MinaTransactionSender } from "./transactions/MinaTransactionSender"; +import { TreeStoreCreator } from "../state/masking/TreeStoreCreator"; +import { MaskName } from "../state/masking/MaskName"; /** * Sequencer module that facilitates all transaction creation and monitoring for @@ -75,8 +77,8 @@ export class BridgingModule extends SequencerModule { private readonly settlementModule: SettlementModule, @inject("OutgoingMessageQueue") private readonly outgoingMessageQueue: OutgoingMessageAdapter, - @inject("AsyncMerkleStore") - private readonly merkleTreeStore: AsyncMerkleTreeStore, + @inject("TreeStoreCreator") + private readonly treeStoreCreator: TreeStoreCreator, @inject("FeeStrategy") private readonly feeStrategy: FeeStrategy, @inject("AreProofsEnabled") areProofsEnabled: AreProofsEnabled, @@ -357,7 +359,10 @@ export class BridgingModule extends SequencerModule { const bridgeContract = this.createBridgeContract(bridgeAddress, tokenId); - const cachedStore = new CachedMerkleTreeStore(this.merkleTreeStore); + const merkleTreeStore = await this.treeStoreCreator.getMask( + MaskName.base() + ); + const cachedStore = new CachedMerkleTreeStore(merkleTreeStore); const tree = new RollupMerkleTree(cachedStore); const [withdrawalModule, withdrawalStateName] = diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 9fa4543b6..3e1579b02 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -20,6 +20,8 @@ import { StorageDependencyFactory, BlockStorage, VanillaTaskWorkerModules, + StateServiceCreator, + MaskName, } from "../../src"; import { DefaultTestingSequencerModules, @@ -63,8 +65,7 @@ describe.each([["InMemory", InMemoryDatabase]])( >; let runtime: Runtime<{ Balance: typeof Balance }>; - let unprovenState: AsyncStateService; - let provenState: AsyncStateService; + let stateMasks: StateServiceCreator; // let unprovenTreeStore: AsyncMerkleTreeStore; // let provenTreeStore: AsyncMerkleTreeStore; @@ -125,8 +126,7 @@ describe.each([["InMemory", InMemoryDatabase]])( runtime = appChain.runtime; sequencer = appChain.sequencer; - unprovenState = sequencer.resolve("UnprovenStateService"); - provenState = sequencer.resolve("AsyncStateService"); + stateMasks = sequencer.resolve("StateServiceCreator"); }); it("test unproven block prod", async () => { @@ -174,14 +174,11 @@ describe.each([["InMemory", InMemoryDatabase]])( ) ); - const state = await unprovenState.getMany( - Object.keys(stateDiff).map(Field) - ); + const mask = await stateMasks.getMask(MaskName.base()); + const state = await mask.getMany(Object.keys(stateDiff).map(Field)); expect(checkStateDiffEquality(stateDiff, state)).toBe(true); expect(state.length).toBeGreaterThanOrEqual(1); - - await expect(provenState.get(state[0].key)).resolves.toBeUndefined(); }); it("test proven block prod", async () => { diff --git a/packages/sequencer/test/integration/services/BlockTestService.ts b/packages/sequencer/test/integration/services/BlockTestService.ts index c7c0f4acb..cc44dfe01 100644 --- a/packages/sequencer/test/integration/services/BlockTestService.ts +++ b/packages/sequencer/test/integration/services/BlockTestService.ts @@ -3,7 +3,7 @@ import { Field, PrivateKey } from "o1js"; import { Runtime, RuntimeModulesRecord } from "@proto-kit/module"; import { ArgumentTypes } from "@proto-kit/common"; -import { ManualBlockTrigger, PrivateMempool } from "../../../src"; +import { ManualBlockTrigger, MaskName, PrivateMempool } from "../../../src"; import { createTransaction } from "../utils"; import { StateServiceCreator } from "../../../src/state/masking/StateServiceCreator"; @@ -45,7 +45,7 @@ export class BlockTestService { } public async getState(path: Field) { - const service = await this.stateServiceCreator.getMask("base"); + const service = await this.stateServiceCreator.getMask(MaskName.base()); return await service.get(path); } From 16685c694af75521fbe555f27f50c408a2cdb80c Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 24 Feb 2025 17:33:43 +0100 Subject: [PATCH 13/23] Fixed ST order bug in result calculation --- .../production/sequencing/BlockResultService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index dcebfef0a..3e4098d5f 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -43,8 +43,8 @@ function collectStateDiff( } function createCombinedStateDiff( - transactions: TransactionExecutionResult[], - blockHookSTs: UntypedStateTransition[] + blockHookSTs: UntypedStateTransition[], + transactions: TransactionExecutionResult[] ) { // Flatten diff list into a single diff by applying them over each other return transactions @@ -53,7 +53,7 @@ function createCombinedStateDiff( .filter(({ applied }) => applied) .flatMap(({ stateTransitions }) => stateTransitions); - transitions.push(...blockHookSTs); + transitions.splice(0, 0, ...blockHookSTs); return collectStateDiff(transitions); }) @@ -181,8 +181,8 @@ export class BlockResultService { stateService: CachedStateService; }> { const combinedDiff = createCombinedStateDiff( - block.transactions, - block.beforeBlockStateTransitions + block.beforeBlockStateTransitions, + block.transactions ); const inMemoryStore = new CachedMerkleTreeStore(merkleTreeStore); From e96b22ae528aa9fdd24c78b3fcef4b534050eea2 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 24 Feb 2025 19:27:21 +0100 Subject: [PATCH 14/23] Added Prisma and Redis Creators --- .../src/PrismaDatabaseConnection.ts | 10 ++- packages/persistance/src/RedisConnection.ts | 12 ++-- .../src/creators/PrismaStateServiceCreator.ts | 33 +++++++++ .../src/creators/RedisTreeStoreCreator.ts | 15 ++++ .../src/services/prisma/PrismaStateService.ts | 72 ++++++++++++++----- .../services/redis/RedisMerkleTreeStore.ts | 9 ++- 6 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 packages/persistance/src/creators/PrismaStateServiceCreator.ts create mode 100644 packages/persistance/src/creators/RedisTreeStoreCreator.ts diff --git a/packages/persistance/src/PrismaDatabaseConnection.ts b/packages/persistance/src/PrismaDatabaseConnection.ts index 15c31d8f4..8a824afcb 100644 --- a/packages/persistance/src/PrismaDatabaseConnection.ts +++ b/packages/persistance/src/PrismaDatabaseConnection.ts @@ -12,6 +12,7 @@ import { PrismaBlockStorage } from "./services/prisma/PrismaBlockStorage"; import { PrismaSettlementStorage } from "./services/prisma/PrismaSettlementStorage"; import { PrismaMessageStorage } from "./services/prisma/PrismaMessageStorage"; import { PrismaTransactionStorage } from "./services/prisma/PrismaTransactionStorage"; +import { PrismaStateServiceCreator } from "./creators/PrismaStateServiceCreator"; export interface PrismaDatabaseConfig { // Either object-based config or connection string @@ -49,12 +50,9 @@ export class PrismaDatabaseConnection public dependencies(): OmitKeys< StorageDependencyMinimumDependencies, - "asyncMerkleStore" | "blockTreeStore" | "unprovenMerkleStore" + "blockTreeStore" | "treeStoreCreator" > { return { - asyncStateService: { - useFactory: () => new PrismaStateService(this, "batch"), - }, batchStorage: { useClass: PrismaBatchStore, }, @@ -73,8 +71,8 @@ export class PrismaDatabaseConnection transactionStorage: { useClass: PrismaTransactionStorage, }, - unprovenStateService: { - useFactory: () => new PrismaStateService(this, "block"), + stateServiceCreator: { + useClass: PrismaStateServiceCreator, }, }; } diff --git a/packages/persistance/src/RedisConnection.ts b/packages/persistance/src/RedisConnection.ts index da10ea78e..7d6dbf6f2 100644 --- a/packages/persistance/src/RedisConnection.ts +++ b/packages/persistance/src/RedisConnection.ts @@ -7,6 +7,7 @@ import { DependencyFactory } from "@proto-kit/common"; import isArray from "lodash/isArray"; import { RedisMerkleTreeStore } from "./services/redis/RedisMerkleTreeStore"; +import { RedisTreeStoreCreator } from "./creators/RedisTreeStoreCreator"; export interface RedisConnectionConfig { host: string; @@ -39,18 +40,15 @@ export class RedisConnectionModule public dependencies(): Pick< StorageDependencyMinimumDependencies, - "asyncMerkleStore" | "blockTreeStore" | "unprovenMerkleStore" + "blockTreeStore" | "treeStoreCreator" > { return { - asyncMerkleStore: { - useFactory: () => new RedisMerkleTreeStore(this), - }, - unprovenMerkleStore: { - useFactory: () => new RedisMerkleTreeStore(this, "unproven"), - }, blockTreeStore: { useFactory: () => new RedisMerkleTreeStore(this, "blockHash"), }, + treeStoreCreator: { + useClass: RedisTreeStoreCreator, + }, }; } diff --git a/packages/persistance/src/creators/PrismaStateServiceCreator.ts b/packages/persistance/src/creators/PrismaStateServiceCreator.ts new file mode 100644 index 000000000..3b1de25b3 --- /dev/null +++ b/packages/persistance/src/creators/PrismaStateServiceCreator.ts @@ -0,0 +1,33 @@ +import { AsyncStateService, StateServiceCreator } from "@proto-kit/sequencer"; +import { inject, injectable } from "tsyringe"; + +import { PrismaStateService } from "../services/prisma/PrismaStateService"; +import type { PrismaConnection } from "../PrismaDatabaseConnection"; + +@injectable() +export class PrismaStateServiceCreator implements StateServiceCreator { + public constructor( + @inject("Database") private readonly connection: PrismaConnection + ) {} + + public async createMask( + name: string, + parent: string + ): Promise { + return new PrismaStateService(this.connection, name, parent); + } + + public getMask(name: string): AsyncStateService { + return new PrismaStateService(this.connection, name); + } + + public async mergeIntoParent(name: string): Promise { + const service = new PrismaStateService(this.connection, name); + await service.mergeIntoParent(); + } + + public async drop(name: string): Promise { + const service = new PrismaStateService(this.connection, name); + await service.drop(); + } +} diff --git a/packages/persistance/src/creators/RedisTreeStoreCreator.ts b/packages/persistance/src/creators/RedisTreeStoreCreator.ts new file mode 100644 index 000000000..c0e4a1d71 --- /dev/null +++ b/packages/persistance/src/creators/RedisTreeStoreCreator.ts @@ -0,0 +1,15 @@ +import { + AsyncMerkleTreeStore, + InMemoryMerkleTreeStoreMask, + MaskGraph, + TreeStoreCreator, +} from "@proto-kit/sequencer"; +import { RedisMerkleTreeStore } from "../services/redis/RedisMerkleTreeStore"; + +export class RedisTreeStoreCreator + extends MaskGraph< + AsyncMerkleTreeStore, + RedisMerkleTreeStore, + InMemoryMerkleTreeStoreMask + > + implements TreeStoreCreator {} diff --git a/packages/persistance/src/services/prisma/PrismaStateService.ts b/packages/persistance/src/services/prisma/PrismaStateService.ts index 3f5c3a215..edec00cc7 100644 --- a/packages/persistance/src/services/prisma/PrismaStateService.ts +++ b/packages/persistance/src/services/prisma/PrismaStateService.ts @@ -1,4 +1,4 @@ -import { AsyncStateService, StateEntry } from "@proto-kit/sequencer"; +import { AsyncStateService, MaskName, StateEntry } from "@proto-kit/sequencer"; import { Field } from "o1js"; import { Prisma } from "@prisma/client"; import { noop } from "@proto-kit/common"; @@ -20,53 +20,85 @@ const Decimal = Prisma.Decimal.clone({ export class PrismaStateService implements AsyncStateService { private cache: StateEntry[] = []; - private maskId?: number; + private maskId?: { id: number; parentId?: number }; /** * @param connection * @param mask A indicator to which masking level the values belong. * This name has to be unique - * @param parent + * @param parentName */ public constructor( private readonly connection: PrismaConnection, private readonly mask: string, - private readonly parent?: number + private readonly parentName?: string ) {} - private async getMaskId(): Promise { + private async getMaskId(): Promise<{ id: number; parentId?: number }> { if (this.maskId === undefined) { - this.maskId = await this.initializeMask(this.mask, this.parent); + this.maskId = await this.initializeMask(this.mask, this.parentName); } return this.maskId; } - private async initializeMask(mask: string, parent?: number): Promise { + private async initializeMask( + mask: string, + parentName?: string + ): Promise<{ id: number; parentId?: number }> { const { prismaClient } = this.connection; const found = await prismaClient.mask.findFirst({ where: { name: mask, - parent, + }, + include: { + parentMask: true, }, }); if (found === null) { + // Find parent id + let parentId: number | undefined = undefined; + if (parentName !== undefined) { + const parent = await prismaClient.mask.findFirst({ + where: { + name: parentName, + }, + }); + if (parent === null) { + throw new Error(`Parent mask with name ${parentName} not found`); + } + + parentId = parent.id; + } else if (mask !== MaskName.base()) { + throw new Error( + "Can't initialize mask that's not the base using a null-parent " + ); + } + + // Create mask const createdMask = await prismaClient.mask.create({ data: { - parent, + parent: parentId, name: mask, }, }); - return createdMask.id; + return { + id: createdMask.id, + parentId: parentId, + }; } - return found.id; + + return { + id: found.id, + parentId: found.parent ?? undefined, + }; } public async commit(): Promise { const { prismaClient } = this.connection; - const maskId = await this.getMaskId(); + const { id: maskId } = await this.getMaskId(); const data = this.cache .filter((entry) => entry.value !== undefined) @@ -92,7 +124,7 @@ export class PrismaStateService implements AsyncStateService { } public async getMany(keys: Field[]): Promise { - const maskId = await this.getMaskId(); + const { id: maskId } = await this.getMaskId(); const paths = keys.map((key) => new Decimal(key.toString())); const records: { @@ -123,16 +155,18 @@ export class PrismaStateService implements AsyncStateService { } public async createMask(name: string): Promise { - const maskId = await this.getMaskId(); - return new PrismaStateService(this.connection, name, maskId); + // We only call this to make sure this mask actually exists, therefore that the + // relation can be satisfied + await this.getMaskId(); + return new PrismaStateService(this.connection, name, this.mask); } public async mergeIntoParent(): Promise { - const maskId = await this.getMaskId(); + const { id: maskId, parentId } = await this.getMaskId(); const client = this.connection.prismaClient; - if (this.parent !== undefined) { + if (parentId !== undefined) { // Rough strategy here: // 1. Delete all entries that are bound to be overwritten from the parent mask // 2. Update this mask's entries to parent mask id @@ -150,7 +184,7 @@ export class PrismaStateService implements AsyncStateService { parent: maskId, }, data: { - parent: this.parent, + parent: parentId, }, }), client.mask.delete({ @@ -165,7 +199,7 @@ export class PrismaStateService implements AsyncStateService { } public async drop(): Promise { - const maskId = await this.getMaskId(); + const { id: maskId } = await this.getMaskId(); await this.connection.prismaClient.state.deleteMany({ where: { diff --git a/packages/persistance/src/services/redis/RedisMerkleTreeStore.ts b/packages/persistance/src/services/redis/RedisMerkleTreeStore.ts index 3de87a29e..af4f70e53 100644 --- a/packages/persistance/src/services/redis/RedisMerkleTreeStore.ts +++ b/packages/persistance/src/services/redis/RedisMerkleTreeStore.ts @@ -1,5 +1,6 @@ import { AsyncMerkleTreeStore, + InMemoryMerkleTreeStoreMask, MerkleTreeNode, MerkleTreeNodeQuery, } from "@proto-kit/sequencer"; @@ -10,9 +11,11 @@ import type { RedisConnection } from "../../RedisConnection"; export class RedisMerkleTreeStore implements AsyncMerkleTreeStore { private cache: MerkleTreeNode[] = []; + public readonly name = "base"; + public constructor( private readonly connection: RedisConnection, - private readonly mask: string = "base" + private readonly mask: string ) {} private getKey(node: MerkleTreeNodeQuery): string { @@ -80,4 +83,8 @@ export class RedisMerkleTreeStore implements AsyncMerkleTreeStore { // }); // console.log(`Reduced ${concat.length} to ${this.cache.length} items to write`) } + + public async createMask(name: string) { + return new InMemoryMerkleTreeStoreMask(this, name); + } } From d4c8793cc7d3d91b762a1073e82b1f3003b8453a Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Mon, 24 Feb 2025 19:27:59 +0100 Subject: [PATCH 15/23] Type cleanup --- .../sequencer/src/state/masking/MaskGraph.ts | 35 ++++++++----------- .../src/state/masking/StateServiceCreator.ts | 2 +- .../src/state/masking/TreeStoreCreator.ts | 2 +- .../masking/InMemoryStateServiceCreator.ts | 7 +++- .../masking/InMemoryTreeStoreCreator.ts | 6 ++-- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/packages/sequencer/src/state/masking/MaskGraph.ts b/packages/sequencer/src/state/masking/MaskGraph.ts index fca884476..9f87a56fd 100644 --- a/packages/sequencer/src/state/masking/MaskGraph.ts +++ b/packages/sequencer/src/state/masking/MaskGraph.ts @@ -13,27 +13,20 @@ type Node = { parent: Parent; }; -// export type Mask = { -// createMask(name: string): Promise; -// name: string; -// mergeIntoParent(): Promise; -// updateParent(parent: Mask): void; -// }; -// -// export type MaskBase = { -// createMask(name: string): Promise; -// name: string; -// }; +type BaseMaskType = Interface & { + createMask(name: string): Promise; + name: string; +}; + +type MaskType = BaseMaskType & { + mergeIntoParent(): Promise; + updateParent(parent: Interface): void; +}; export class MaskGraph< - Base extends { - createMask(name: string): Promise; - name: string; - }, - Mask extends Base & { - mergeIntoParent(): Promise; - updateParent(parent: Mask | Base): void; - }, + Interface, + Base extends BaseMaskType, + Mask extends MaskType, > { public constructor(base: Base) { this.root = { @@ -64,7 +57,7 @@ export class MaskGraph< return this.findNode(name)?.mask; } - public async getMask(name: string) { + public getMask(name: string) { const candidate = this.findService(name); assertMaskFound(candidate, name); @@ -76,7 +69,7 @@ export class MaskGraph< name: string, parentName: string, fallback?: string - ): Promise { + ): Promise { const candidate = this.findService(name); if (candidate !== undefined) { return candidate; diff --git a/packages/sequencer/src/state/masking/StateServiceCreator.ts b/packages/sequencer/src/state/masking/StateServiceCreator.ts index cd562c480..da62b8785 100644 --- a/packages/sequencer/src/state/masking/StateServiceCreator.ts +++ b/packages/sequencer/src/state/masking/StateServiceCreator.ts @@ -2,7 +2,7 @@ import { AsyncStateService } from "../async/AsyncStateService"; export interface StateServiceCreator { createMask(name: string, parent: string): Promise; - getMask(name: string): Promise; + getMask(name: string): AsyncStateService; mergeIntoParent(name: string): Promise; drop(name: string): Promise; } diff --git a/packages/sequencer/src/state/masking/TreeStoreCreator.ts b/packages/sequencer/src/state/masking/TreeStoreCreator.ts index fd419df9a..e9f186c79 100644 --- a/packages/sequencer/src/state/masking/TreeStoreCreator.ts +++ b/packages/sequencer/src/state/masking/TreeStoreCreator.ts @@ -6,7 +6,7 @@ export interface TreeStoreCreator { parent: string, fallback?: string ): Promise; - getMask(name: string): Promise; + getMask(name: string): AsyncMerkleTreeStore; mergeIntoParent(name: string): Promise; drop(name: string): Promise; } diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts index 6f8ea5f1f..5bef718ef 100644 --- a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts @@ -2,9 +2,14 @@ import { StateServiceCreator } from "../../../state/masking/StateServiceCreator" import { MaskGraph } from "../../../state/masking/MaskGraph"; import { InMemoryStateServiceMask } from "./InMemoryStateServiceMask"; +import { AsyncStateService } from "../../../state/async/AsyncStateService"; export class InMemoryStateServiceCreator - extends MaskGraph + extends MaskGraph< + AsyncStateService, + InMemoryStateServiceMask, + InMemoryStateServiceMask + > implements StateServiceCreator { public constructor() { diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts index 7d0d136ed..5a13b4585 100644 --- a/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryTreeStoreCreator.ts @@ -9,10 +9,8 @@ import { export class InMemoryTreeStoreCreator extends MaskGraph< - AsyncMerkleTreeStore & { - createMask: (name: string) => Promise; - name: string; - }, + AsyncMerkleTreeStore, + InMemoryBaseMerkleTreeStore, InMemoryMerkleTreeStoreMask > implements TreeStoreCreator From bd85c6853071e531a2e3c8b953a4be4f34de37ea Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 25 Feb 2025 11:11:19 +0100 Subject: [PATCH 16/23] Linting --- .../src/services/prisma/PrismaStateService.ts | 2 +- packages/persistance/test/connection.test.ts | 4 ++-- packages/sequencer/src/settlement/BridgingModule.ts | 9 +++------ .../inmemory/masking/InMemoryStateServiceCreator.ts | 2 +- .../test/integration/StorageIntegration.test.ts | 1 - 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/persistance/src/services/prisma/PrismaStateService.ts b/packages/persistance/src/services/prisma/PrismaStateService.ts index edec00cc7..6535fdfd2 100644 --- a/packages/persistance/src/services/prisma/PrismaStateService.ts +++ b/packages/persistance/src/services/prisma/PrismaStateService.ts @@ -129,6 +129,7 @@ export class PrismaStateService implements AsyncStateService { const records: { path: Prisma.Decimal; + // TODO This could potentially be non-null, but should be tested values: Prisma.Decimal[] | null; }[] = await this.connection.prismaClient.$queryRaw( readState(maskId, paths) @@ -136,7 +137,6 @@ export class PrismaStateService implements AsyncStateService { return records.map((record) => ({ key: Field(record.path.toFixed()), - // TODO Figure out why that is nullable value: record.values?.map((x) => Field(x.toFixed())) ?? [], })); } diff --git a/packages/persistance/test/connection.test.ts b/packages/persistance/test/connection.test.ts index ef83f454b..561d83c0f 100644 --- a/packages/persistance/test/connection.test.ts +++ b/packages/persistance/test/connection.test.ts @@ -22,7 +22,7 @@ describe.skip("prisma", () => { password: "password", }; await db.start(); - const store = new RedisMerkleTreeStore(db); + const store = new RedisMerkleTreeStore(db, "base"); const cached = new CachedMerkleTreeStore(store); const tree = new RollupMerkleTree(cached); @@ -38,7 +38,7 @@ describe.skip("prisma", () => { console.log(`Root ${tree.getRoot().toBigInt()}`); - const store2 = new RedisMerkleTreeStore(db); + const store2 = new RedisMerkleTreeStore(db, "base"); const cached2 = new CachedMerkleTreeStore(store2); const tree2 = new RollupMerkleTree(cached2); diff --git a/packages/sequencer/src/settlement/BridgingModule.ts b/packages/sequencer/src/settlement/BridgingModule.ts index 135e7b2b1..9fe8bf14c 100644 --- a/packages/sequencer/src/settlement/BridgingModule.ts +++ b/packages/sequencer/src/settlement/BridgingModule.ts @@ -41,16 +41,15 @@ import { sequencerModule, } from "../sequencer/builder/SequencerModule"; import { CachedMerkleTreeStore } from "../state/merkle/CachedMerkleTreeStore"; -import { AsyncMerkleTreeStore } from "../state/async/AsyncMerkleTreeStore"; import { FeeStrategy } from "../protocol/baselayer/fees/FeeStrategy"; import type { MinaBaseLayer } from "../protocol/baselayer/MinaBaseLayer"; +import { TreeStoreCreator } from "../state/masking/TreeStoreCreator"; +import { MaskName } from "../state/masking/MaskName"; import type { OutgoingMessageAdapter } from "./messages/WithdrawalQueue"; import type { SettlementModule } from "./SettlementModule"; import { SettlementUtils } from "./utils/SettlementUtils"; import { MinaTransactionSender } from "./transactions/MinaTransactionSender"; -import { TreeStoreCreator } from "../state/masking/TreeStoreCreator"; -import { MaskName } from "../state/masking/MaskName"; /** * Sequencer module that facilitates all transaction creation and monitoring for @@ -359,9 +358,7 @@ export class BridgingModule extends SequencerModule { const bridgeContract = this.createBridgeContract(bridgeAddress, tokenId); - const merkleTreeStore = await this.treeStoreCreator.getMask( - MaskName.base() - ); + const merkleTreeStore = this.treeStoreCreator.getMask(MaskName.base()); const cachedStore = new CachedMerkleTreeStore(merkleTreeStore); const tree = new RollupMerkleTree(cachedStore); diff --git a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts index 5bef718ef..9b21d7c61 100644 --- a/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts +++ b/packages/sequencer/src/storage/inmemory/masking/InMemoryStateServiceCreator.ts @@ -1,8 +1,8 @@ import { StateServiceCreator } from "../../../state/masking/StateServiceCreator"; import { MaskGraph } from "../../../state/masking/MaskGraph"; +import { AsyncStateService } from "../../../state/async/AsyncStateService"; import { InMemoryStateServiceMask } from "./InMemoryStateServiceMask"; -import { AsyncStateService } from "../../../state/async/AsyncStateService"; export class InMemoryStateServiceCreator extends MaskGraph< diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 3e1579b02..2316114e4 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -8,7 +8,6 @@ import { Bool, Field, PrivateKey, UInt64 } from "o1js"; import { TypedClass, expectDefined } from "@proto-kit/common"; import { - AsyncStateService, BatchStorage, HistoricalBatchStorage, HistoricalBlockStorage, From edc8d1e9f3d95d90e6901a553b51a42072a1ff90 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 25 Feb 2025 16:37:17 +0100 Subject: [PATCH 17/23] Linting 2 --- .../src/creators/RedisTreeStoreCreator.ts | 1 + .../sequencing/BlockResultService.ts | 52 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/packages/persistance/src/creators/RedisTreeStoreCreator.ts b/packages/persistance/src/creators/RedisTreeStoreCreator.ts index c0e4a1d71..a750ae283 100644 --- a/packages/persistance/src/creators/RedisTreeStoreCreator.ts +++ b/packages/persistance/src/creators/RedisTreeStoreCreator.ts @@ -4,6 +4,7 @@ import { MaskGraph, TreeStoreCreator, } from "@proto-kit/sequencer"; + import { RedisMerkleTreeStore } from "../services/redis/RedisMerkleTreeStore"; export class RedisTreeStoreCreator diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 3e4098d5f..4a415e509 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -28,7 +28,7 @@ import type { StateRecord } from "../BatchProducerModule"; import { executeWithExecutionContext } from "./TransactionExecutionService"; -function collectStateDiff( +export function collectStateDiff( stateTransitions: UntypedStateTransition[] ): StateRecord { return stateTransitions.reduce>( @@ -42,7 +42,7 @@ function collectStateDiff( ); } -function createCombinedStateDiff( +export function createCombinedStateDiff( blockHookSTs: UntypedStateTransition[], transactions: TransactionExecutionResult[] ) { @@ -63,6 +63,28 @@ function createCombinedStateDiff( }, {}); } +export async function applyStateDiff( + store: CachedMerkleTreeStore, + stateDiff: StateRecord +): Promise { + await store.preloadKeys(Object.keys(stateDiff).map(BigInt)); + + // In case the diff is empty, we preload key 0 in order to + // retrieve the root, which we need later + if (Object.keys(stateDiff).length === 0) { + await store.preloadKey(0n); + } + + const tree = new RollupMerkleTree(store); + + Object.entries(stateDiff).forEach(([key, state]) => { + const treeValue = state !== undefined ? Poseidon.hash(state) : Field(0); + tree.setLeaf(BigInt(key), treeValue); + }); + + return tree; +} + @injectable() @scoped(Lifecycle.ContainerScoped) export class BlockResultService { @@ -147,28 +169,6 @@ export class BlockResultService { }; } - public async applyStateDiff( - store: CachedMerkleTreeStore, - stateDiff: StateRecord - ): Promise { - await store.preloadKeys(Object.keys(stateDiff).map(BigInt)); - - // In case the diff is empty, we preload key 0 in order to - // retrieve the root, which we need later - if (Object.keys(stateDiff).length === 0) { - await store.preloadKey(0n); - } - - const tree = new RollupMerkleTree(store); - - Object.entries(stateDiff).forEach(([key, state]) => { - const treeValue = state !== undefined ? Poseidon.hash(state) : Field(0); - tree.setLeaf(BigInt(key), treeValue); - }); - - return tree; - } - public async generateMetadataForNextBlock( block: Block, merkleTreeStore: AsyncMerkleTreeStore, @@ -187,7 +187,7 @@ export class BlockResultService { const inMemoryStore = new CachedMerkleTreeStore(merkleTreeStore); - const tree = await this.applyStateDiff(inMemoryStore, combinedDiff); + const tree = await applyStateDiff(inMemoryStore, combinedDiff); const witnessedStateRoot = tree.getRoot(); @@ -210,7 +210,7 @@ export class BlockResultService { ); // Apply afterBlock STs to the tree - const tree2 = await this.applyStateDiff( + const tree2 = await applyStateDiff( inMemoryStore, collectStateDiff( stateTransitions.map((stateTransition) => From d1530ea7cdd27a641fa33c35dd72b88471159e1c Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Tue, 25 Feb 2025 16:51:49 +0100 Subject: [PATCH 18/23] Linting 3 --- packages/persistance/src/PrismaDatabaseConnection.ts | 1 - packages/sdk/src/query/StateServiceQueryModule.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/persistance/src/PrismaDatabaseConnection.ts b/packages/persistance/src/PrismaDatabaseConnection.ts index 8a824afcb..9a04dbae0 100644 --- a/packages/persistance/src/PrismaDatabaseConnection.ts +++ b/packages/persistance/src/PrismaDatabaseConnection.ts @@ -6,7 +6,6 @@ import { } from "@proto-kit/sequencer"; import { DependencyFactory, OmitKeys } from "@proto-kit/common"; -import { PrismaStateService } from "./services/prisma/PrismaStateService"; import { PrismaBatchStore } from "./services/prisma/PrismaBatchStore"; import { PrismaBlockStorage } from "./services/prisma/PrismaBlockStorage"; import { PrismaSettlementStorage } from "./services/prisma/PrismaSettlementStorage"; diff --git a/packages/sdk/src/query/StateServiceQueryModule.ts b/packages/sdk/src/query/StateServiceQueryModule.ts index 7f07c8957..d1a1e7770 100644 --- a/packages/sdk/src/query/StateServiceQueryModule.ts +++ b/packages/sdk/src/query/StateServiceQueryModule.ts @@ -46,7 +46,7 @@ export class StateServiceQueryModule this.sequencer.dependencyContainer.resolve( "StateServiceCreator" ); - return await stateServiceCreator.getMask(MaskName.base()); + return stateServiceCreator.getMask(MaskName.base()); } public async treeStore(): Promise { @@ -54,7 +54,7 @@ export class StateServiceQueryModule this.sequencer.dependencyContainer.resolve( "TreeStoreCreator" ); - return await treeStoreCreator.getMask(await this.getCurrentTreeMask()); + return treeStoreCreator.getMask(await this.getCurrentTreeMask()); } public async get(key: Field) { From 5ccc3a92fbdf48bb3e6d6c66ae12c2031d2997d1 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Wed, 26 Feb 2025 12:53:40 +0100 Subject: [PATCH 19/23] Fixed integration tests --- .../api/src/graphql/modules/MerkleWitnessResolver.ts | 2 +- .../persistance/src/creators/RedisTreeStoreCreator.ts | 10 +++++++++- .../sequencer/src/mempool/private/PrivateMempool.ts | 4 +--- .../src/protocol/production/BatchProducerModule.ts | 6 +++++- .../production/sequencing/BlockProducerModule.ts | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/api/src/graphql/modules/MerkleWitnessResolver.ts b/packages/api/src/graphql/modules/MerkleWitnessResolver.ts index b499fb28e..c48a734ab 100644 --- a/packages/api/src/graphql/modules/MerkleWitnessResolver.ts +++ b/packages/api/src/graphql/modules/MerkleWitnessResolver.ts @@ -53,7 +53,7 @@ export class MerkleWitnessResolver extends GraphqlModule { latestBlock !== undefined ? MaskName.block(latestBlock.block.height) : MaskName.base(); - const treeStore = await this.treeStoreCreator.getMask(maskName); + const treeStore = this.treeStoreCreator.getMask(maskName); const syncStore = new CachedMerkleTreeStore(treeStore); await syncStore.preloadKey(BigInt(path)); diff --git a/packages/persistance/src/creators/RedisTreeStoreCreator.ts b/packages/persistance/src/creators/RedisTreeStoreCreator.ts index a750ae283..79d21497a 100644 --- a/packages/persistance/src/creators/RedisTreeStoreCreator.ts +++ b/packages/persistance/src/creators/RedisTreeStoreCreator.ts @@ -4,13 +4,21 @@ import { MaskGraph, TreeStoreCreator, } from "@proto-kit/sequencer"; +import { inject, injectable } from "tsyringe"; import { RedisMerkleTreeStore } from "../services/redis/RedisMerkleTreeStore"; +import type { RedisConnection } from "../RedisConnection"; +@injectable() export class RedisTreeStoreCreator extends MaskGraph< AsyncMerkleTreeStore, RedisMerkleTreeStore, InMemoryMerkleTreeStoreMask > - implements TreeStoreCreator {} + implements TreeStoreCreator +{ + public constructor(@inject("Database") connection: RedisConnection) { + super(new RedisMerkleTreeStore(connection, "base")); + } +} diff --git a/packages/sequencer/src/mempool/private/PrivateMempool.ts b/packages/sequencer/src/mempool/private/PrivateMempool.ts index 102e31e7e..1c1a7f241 100644 --- a/packages/sequencer/src/mempool/private/PrivateMempool.ts +++ b/packages/sequencer/src/mempool/private/PrivateMempool.ts @@ -105,9 +105,7 @@ export class PrivateMempool public async getTxs(limit?: number): Promise { const txs = await this.transactionStorage.getPendingUserTransactions(); - const stateService = await this.stateServiceCreator.getMask( - MaskName.base() - ); + const stateService = this.stateServiceCreator.getMask(MaskName.base()); const baseCachedStateService = new CachedStateService(stateService); const networkState = diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index d7b343b84..99fe69ae1 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -17,6 +17,7 @@ import { CachedMerkleTreeStore } from "../../state/merkle/CachedMerkleTreeStore" import { BlockWithResult } from "../../storage/model/Block"; import type { Database } from "../../storage/Database"; import { TreeStoreCreator } from "../../state/masking/TreeStoreCreator"; +import { MaskName } from "../../state/masking/MaskName"; import { BlockProofSerializer } from "./tasks/serializers/BlockProofSerializer"; import { BatchTracingService } from "./tracing/BatchTracingService"; @@ -198,7 +199,10 @@ export class BatchProducerModule extends SequencerModule { throw errors.blockWithoutTxs(); } - const mask = await this.treeStoreCreator.createMask("batch", "base"); + const mask = await this.treeStoreCreator.createMask( + "batch", + MaskName.base() + ); const merkleTreeStore = new CachedMerkleTreeStore(mask); const trace = await this.batchTraceService.traceBatch( diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts index b780d8318..b264ec6ba 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts @@ -112,7 +112,7 @@ export class BlockProducerModule extends SequencerModule { public async generateMetadata(block: Block): Promise { const height = block.height.toBigInt(); const maskName = MaskName.block(height); - const asyncStateService = await this.stateServiceCreator.getMask(maskName); + const asyncStateService = this.stateServiceCreator.getMask(maskName); const asyncTreeStore = await this.treeStoreCreator.createMask( maskName, From 05ad7d9e199a96e3b5f37161e55434b9416d2d44 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 27 Feb 2025 17:43:43 +0100 Subject: [PATCH 20/23] Implemented Tree mask recovery --- .../persistance/src/PrismaRedisDatabase.ts | 6 +- packages/persistance/src/RedisConnection.ts | 19 +++- packages/persistance/src/TreeMaskRecovery.ts | 87 +++++++++++++++++++ .../src/services/prisma/PrismaBlockStorage.ts | 11 +-- .../sequencing/BlockResultService.ts | 2 +- .../production/trigger/BlockTrigger.ts | 18 +++- .../storage/inmemory/InMemoryBlockStorage.ts | 4 +- packages/sequencer/src/storage/model/Block.ts | 8 ++ .../src/storage/repositories/BlockStorage.ts | 2 +- 9 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 packages/persistance/src/TreeMaskRecovery.ts diff --git a/packages/persistance/src/PrismaRedisDatabase.ts b/packages/persistance/src/PrismaRedisDatabase.ts index 735703035..34f8fa639 100644 --- a/packages/persistance/src/PrismaRedisDatabase.ts +++ b/packages/persistance/src/PrismaRedisDatabase.ts @@ -4,6 +4,7 @@ import { StorageDependencyMinimumDependencies, Database, closeable, + Sequencer, } from "@proto-kit/sequencer"; import { ChildContainerProvider } from "@proto-kit/common"; import { PrismaClient } from "@prisma/client"; @@ -20,6 +21,7 @@ import { RedisConnectionModule, RedisTransaction, } from "./RedisConnection"; +import { inject } from "tsyringe"; export interface PrismaRedisCombinedConfig { prisma: PrismaDatabaseConfig; @@ -36,10 +38,10 @@ export class PrismaRedisDatabase public redis: RedisConnectionModule; - public constructor() { + public constructor(@inject("Sequencer") sequencer: Sequencer) { super(); this.prisma = new PrismaDatabaseConnection(); - this.redis = new RedisConnectionModule(); + this.redis = new RedisConnectionModule(sequencer); } public get prismaClient(): PrismaClient { diff --git a/packages/persistance/src/RedisConnection.ts b/packages/persistance/src/RedisConnection.ts index 7d6dbf6f2..553baf42d 100644 --- a/packages/persistance/src/RedisConnection.ts +++ b/packages/persistance/src/RedisConnection.ts @@ -1,13 +1,15 @@ import { createClient, RedisClientType } from "redis"; import { + Sequencer, SequencerModule, StorageDependencyMinimumDependencies, } from "@proto-kit/sequencer"; -import { DependencyFactory } from "@proto-kit/common"; +import { DependencyFactory, log } from "@proto-kit/common"; import isArray from "lodash/isArray"; import { RedisMerkleTreeStore } from "./services/redis/RedisMerkleTreeStore"; import { RedisTreeStoreCreator } from "./creators/RedisTreeStoreCreator"; +import { TreeMaskRecovery } from "./TreeMaskRecovery"; export interface RedisConnectionConfig { host: string; @@ -27,6 +29,10 @@ export class RedisConnectionModule extends SequencerModule implements DependencyFactory, RedisConnection { + public constructor(private readonly sequencer: Sequencer) { + super(); + } + private client?: RedisClientType; public get redisClient(): RedisClientType { @@ -79,8 +85,19 @@ export class RedisConnectionModule } } + private async recoverMemoryMasks() { + log.info("Starting recovery of tree masks"); + + const recovery = + this.sequencer.dependencyContainer.resolve(TreeMaskRecovery); + + await recovery.recreateMasks(); + } + public async start(): Promise { await this.init(); + + await this.recoverMemoryMasks(); } public async close() { diff --git a/packages/persistance/src/TreeMaskRecovery.ts b/packages/persistance/src/TreeMaskRecovery.ts new file mode 100644 index 000000000..aab7528aa --- /dev/null +++ b/packages/persistance/src/TreeMaskRecovery.ts @@ -0,0 +1,87 @@ +import { inject, injectable } from "tsyringe"; +import { + applyStateDiff, + assertBlockHasResult, + AsyncMerkleTreeStore, + BlockQueue, + BlockWithResult, + CachedMerkleTreeStore, + collectStateDiff, + MaskName, + TreeStoreCreator, +} from "@proto-kit/sequencer"; +import { reduceSequential } from "@proto-kit/common"; + +@injectable() +export class TreeMaskRecovery { + public constructor( + @inject("BlockQueue") + private readonly blockQueue: BlockQueue, + @inject("TreeStoreCreator") + private readonly treeStoreCreator: TreeStoreCreator + ) {} + + /** + * Strategy: + * 1. Collect all STs + * 2. Collect a distinct diff of all to-values (state diff) + * 3. Iteratively apply that to the tree + */ + private async applyBlock(mask: AsyncMerkleTreeStore, block: BlockWithResult) { + const transitions = [block.block.beforeBlockStateTransitions]; + const txTransitions = block.block.transactions.flatMap((tx) => + tx.stateTransitions + .filter((batch) => batch.applied) + .map((batch) => batch.stateTransitions) + ); + transitions.push(...txTransitions); + transitions.push(block.result.afterBlockStateTransitions); + + const stateDiff = collectStateDiff(transitions.flat()); + const cache = new CachedMerkleTreeStore(mask); + + await applyStateDiff(cache, stateDiff); + + await cache.mergeIntoParent(); + } + + /** + * This method fetches all pending (i.e. un-batched) blocks and recreates + * their in-memory tree masks. + * + * The crash might have happened between block production and result generation. + * In this case, we need to first recreate all earlier masks, then generate the result. + * The last part happens automatically in BlockProducerModule.start(). + * However, since normal block production doesn't do any tree ops, we can skip + * that potential incomplete block altogether. + */ + public async recreateMasks() { + const blocks = await this.blockQueue.getPendingBlocks(); + + await reduceSequential( + blocks, + async (previousMask, block) => { + if (previousMask === undefined) { + throw new Error( + "More than one result missing for the recent blocks, something is wrong" + ); + } + if (block.result !== undefined) { + const maskName = MaskName.block(block.block.height); + const mask = await this.treeStoreCreator.createMask( + maskName, + previousMask + ); + + assertBlockHasResult(block); + + await this.applyBlock(mask, block); + + return maskName; + } + return undefined; + }, + MaskName.base() as string | undefined + ); + } +} diff --git a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts index 51ebaed62..4ed8b1615 100644 --- a/packages/persistance/src/services/prisma/PrismaBlockStorage.ts +++ b/packages/persistance/src/services/prisma/PrismaBlockStorage.ts @@ -197,7 +197,7 @@ export class PrismaBlockStorage return result; } - public async getNewBlocks(): Promise { + public async getPendingBlocks(): Promise { const blocks = await this.connection.prismaClient.block.findMany({ where: { batch: null, @@ -226,15 +226,10 @@ export class PrismaBlockStorage const { result } = block; - if (result === null) { - throw new Error( - `No BlockResult has been set for block ${block.hash} yet` - ); - } - return { block: decodedBlock, - result: this.blockResultMapper.mapIn(result), + result: + result !== null ? this.blockResultMapper.mapIn(result) : undefined, }; }); } diff --git a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts index 4a415e509..426630490 100644 --- a/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts +++ b/packages/sequencer/src/protocol/production/sequencing/BlockResultService.ts @@ -42,7 +42,7 @@ export function collectStateDiff( ); } -export function createCombinedStateDiff( +function createCombinedStateDiff( blockHookSTs: UntypedStateTransition[], transactions: TransactionExecutionResult[] ) { diff --git a/packages/sequencer/src/protocol/production/trigger/BlockTrigger.ts b/packages/sequencer/src/protocol/production/trigger/BlockTrigger.ts index 09d47c997..abb812594 100644 --- a/packages/sequencer/src/protocol/production/trigger/BlockTrigger.ts +++ b/packages/sequencer/src/protocol/production/trigger/BlockTrigger.ts @@ -12,7 +12,11 @@ import { BlockProducerModule } from "../sequencing/BlockProducerModule"; import { BlockQueue } from "../../../storage/repositories/BlockStorage"; import { SequencerModule } from "../../../sequencer/builder/SequencerModule"; import { SettlementModule } from "../../../settlement/SettlementModule"; -import { Block, BlockWithResult } from "../../../storage/model/Block"; +import { + assertBlockHasResult, + Block, + BlockWithResult, +} from "../../../storage/model/Block"; /** * A BlockTrigger is the primary method to start the production of a block and @@ -49,9 +53,17 @@ export class BlockTriggerBase< } protected async produceBatch(): Promise { - const blocks = await this.blockQueue.getNewBlocks(); + const blocks = await this.blockQueue.getPendingBlocks(); + + // Make sure all blocks have results + const completedBlocks = blocks.map((block) => { + assertBlockHasResult(block); + return block; + }); + if (blocks.length > 0) { - const batch = await this.batchProducerModule?.createBatch(blocks); + const batch = + await this.batchProducerModule?.createBatch(completedBlocks); if (batch !== undefined) { this.events.emit("batch-produced", batch); } diff --git a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts index 9a14f7d8c..879b8cb44 100644 --- a/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts +++ b/packages/sequencer/src/storage/inmemory/InMemoryBlockStorage.ts @@ -64,7 +64,7 @@ export class InMemoryBlockStorage return result; } - public async getNewBlocks(): Promise { + public async getPendingBlocks(): Promise { const latestBatch = await this.batchStorage.getLatestBatch(); let cursor = 0; @@ -89,7 +89,7 @@ export class InMemoryBlockStorage return slice.map((block, index) => ({ block, - result: results[index + 1]!, + result: results.at(index + 1), })); } diff --git a/packages/sequencer/src/storage/model/Block.ts b/packages/sequencer/src/storage/model/Block.ts index 823b3c8c6..d099ac4d3 100644 --- a/packages/sequencer/src/storage/model/Block.ts +++ b/packages/sequencer/src/storage/model/Block.ts @@ -82,6 +82,14 @@ export interface BlockWithMaybeResult { result?: BlockResult; } +export function assertBlockHasResult( + block: BlockWithMaybeResult +): asserts block is BlockWithResult { + if (block.result === undefined) { + throw new Error("Given block has no result attached"); + } +} + // eslint-disable-next-line @typescript-eslint/no-redeclare export const BlockWithResult = { // toBlockProverState: ({ block, result }: BlockWithResult) => ({ diff --git a/packages/sequencer/src/storage/repositories/BlockStorage.ts b/packages/sequencer/src/storage/repositories/BlockStorage.ts index 4803ba5a5..9c51c0e68 100644 --- a/packages/sequencer/src/storage/repositories/BlockStorage.ts +++ b/packages/sequencer/src/storage/repositories/BlockStorage.ts @@ -8,7 +8,7 @@ import type { export interface BlockQueue { pushBlock: (block: Block) => Promise; pushResult: (result: BlockResult) => Promise; - getNewBlocks: () => Promise; + getPendingBlocks: () => Promise; getLatestBlockAndResult: () => Promise; } From 7ead8cc3263bfd5fb96cb95048c8230b31c42442 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Thu, 27 Feb 2025 17:45:57 +0100 Subject: [PATCH 21/23] Added test to test mask recovery --- .../test-integration/SequencerRestart.test.ts | 119 +++++++++++++----- 1 file changed, 87 insertions(+), 32 deletions(-) diff --git a/packages/persistance/test-integration/SequencerRestart.test.ts b/packages/persistance/test-integration/SequencerRestart.test.ts index 6619ed5ab..98b580f6d 100644 --- a/packages/persistance/test-integration/SequencerRestart.test.ts +++ b/packages/persistance/test-integration/SequencerRestart.test.ts @@ -1,6 +1,6 @@ import "reflect-metadata"; import { afterAll, beforeAll, expect } from "@jest/globals"; -import { expectDefined } from "@proto-kit/common"; +import { expectDefined, log } from "@proto-kit/common"; import { PrivateKey } from "o1js"; import { container } from "tsyringe"; @@ -39,55 +39,110 @@ describe("sequencer restart", () => { await appChain.sequencer.resolve("Database").close(); }; - beforeAll(async () => { - await setup(); - await clearDB(); - + const produce = async (num: number, type: "block" | "batch") => { const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); - console.log(sender.toPublicKey().toBase58()); - - for (let block = 0; block < 2; block++) { + for (let block = 0; block < num; block++) { await prepareBlock(appChain, sender.toPublicKey(), senderNonce); senderNonce++; - const [producedBlock] = await blockTrigger.produceBlockAndBatch(); + const producedBlock = await blockTrigger.produceBlock(); if ((producedBlock?.transactions.length ?? 0) === 0) { throw new Error(`Block not produced correctly: ${block}`); } + if (type === "batch") { + await blockTrigger.produceBatch(); + } } + }; - await teardown(); + describe("resume at latest block", () => { + beforeAll(async () => { + await setup(); + await clearDB(); - await setup(); - }, 40000); + await produce(2, "batch"); - afterAll(async () => { - await teardown(); - }); + await teardown(); + + await setup(); + }, 40000); + + afterAll(async () => { + await teardown(); + }); - it("should fetch correct nonce", async () => { - const accountState = - await appChain.query.protocol.AccountState.accountState.get( - sender.toPublicKey() - ); + it("should fetch correct nonce", async () => { + const accountState = + await appChain.query.protocol.AccountState.accountState.get( + sender.toPublicKey() + ); - expectDefined(accountState); + expectDefined(accountState); - expect(accountState.nonce.toString()).toBe("2"); + expect(accountState.nonce.toString()).toBe("2"); + }); + + it("should be able to produce a block on top", async () => { + const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); + await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + senderNonce++; + + const [block, batch] = await blockTrigger.produceBlockAndBatch(); + + expectDefined(block); + expectDefined(batch); + + expect(block.transactions).toHaveLength(1); + expect(block.transactions[0].tx.nonce.toString()).toBe("2"); + }, 15000); }); - it("should be able to produce a block on top", async () => { - const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); - await prepareBlock(appChain, sender.toPublicKey(), senderNonce); - senderNonce++; + describe("reconstruct untraced block masks", () => { + beforeEach(async () => { + log.setLevel("DEBUG"); - const [block, batch] = await blockTrigger.produceBlockAndBatch(); + await setup(); + await clearDB(); - expectDefined(block); - expectDefined(batch); + await produce(2, "block"); - expect(block.transactions).toHaveLength(1); - expect(block.transactions[0].tx.nonce.toString()).toBe("2"); - }, 15000); + await teardown(); + + await setup(); + + console.log("beforeEach"); + }, 40000); + + afterEach(async () => { + await teardown(); + }); + + it("should be able to produce a block on top", async () => { + const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); + await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + senderNonce++; + + const block = await blockTrigger.produceBlock(); + + expectDefined(block); + + expect(block.transactions).toHaveLength(1); + expect(block.transactions[0].tx.nonce.toString()).toBe("2"); + + // Should be able to trace after additional block + const batch = await blockTrigger.produceBatch(); + + expectDefined(batch); + expect(batch.blockHashes).toHaveLength(3); + }, 15000); + + it("should be able to trace", async () => { + const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); + const batch = await blockTrigger.produceBatch(); + + expectDefined(batch); + expect(batch.blockHashes).toHaveLength(2); + }); + }); }); From e3663cace57d905ab151598b6c7d54fae0074475 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Fri, 28 Feb 2025 19:10:54 +0100 Subject: [PATCH 22/23] Fixed sequencer-restart test --- .../PrismaBlockProduction.test.ts | 8 ++-- .../test-integration/SequencerRestart.test.ts | 41 ++++++++++--------- .../persistance/test-integration/utils.ts | 7 +++- .../protocol/src/prover/block/BlockProver.ts | 2 +- .../production/BatchProducerModule.ts | 30 ++++++++++---- .../test/merkle/CachedMerkleStore.test.ts | 9 +++- 6 files changed, 61 insertions(+), 36 deletions(-) diff --git a/packages/persistance/test-integration/PrismaBlockProduction.test.ts b/packages/persistance/test-integration/PrismaBlockProduction.test.ts index 61eb02d3c..015076930 100644 --- a/packages/persistance/test-integration/PrismaBlockProduction.test.ts +++ b/packages/persistance/test-integration/PrismaBlockProduction.test.ts @@ -17,7 +17,7 @@ import { import { createPrismaAppchain, IntegrationTestDBConfig, - prepareBlock, + injectTransaction, } from "./utils"; describe("prisma integration", () => { @@ -56,7 +56,7 @@ describe("prisma integration", () => { beforeAll(async () => { await setup(); - await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + await injectTransaction(appChain, sender.toPublicKey(), senderNonce); senderNonce++; [block, batch] = await appChain.sequencer @@ -179,7 +179,7 @@ describe("prisma integration", () => { signer: sender2, }, }); - await prepareBlock(appChain, sender2.toPublicKey(), 0); + await injectTransaction(appChain, sender2.toPublicKey(), 0); }); it("should produce the block", async () => { @@ -210,7 +210,7 @@ describe("prisma integration", () => { beforeAll(async () => { await setup(); - transaction = await prepareBlock( + transaction = await injectTransaction( appChain, sender.toPublicKey(), senderNonce diff --git a/packages/persistance/test-integration/SequencerRestart.test.ts b/packages/persistance/test-integration/SequencerRestart.test.ts index 98b580f6d..ee001cd95 100644 --- a/packages/persistance/test-integration/SequencerRestart.test.ts +++ b/packages/persistance/test-integration/SequencerRestart.test.ts @@ -1,13 +1,13 @@ import "reflect-metadata"; import { afterAll, beforeAll, expect } from "@jest/globals"; -import { expectDefined, log } from "@proto-kit/common"; +import { expectDefined, log, sleep } from "@proto-kit/common"; import { PrivateKey } from "o1js"; import { container } from "tsyringe"; import { createPrismaAppchain, IntegrationTestDBConfig, - prepareBlock, + injectTransaction, } from "./utils"; describe("sequencer restart", () => { @@ -16,13 +16,11 @@ describe("sequencer restart", () => { const sender = PrivateKey.random(); let senderNonce = 0; - const clearDB = async () => { - const db = appChain.sequencer.resolve("Database"); - await db.prisma.pruneDatabase(); - await db.redis.pruneDatabase(); - }; + const setup = async (pruneOnStartup: boolean) => { + if (pruneOnStartup) { + senderNonce = 0; + } - const setup = async () => { const { prismaConfig, redisConfig } = IntegrationTestDBConfig; appChain = createPrismaAppchain(prismaConfig, redisConfig); @@ -30,6 +28,11 @@ describe("sequencer restart", () => { Signer: { signer: sender, }, + Sequencer: { + DatabasePruneModule: { + pruneOnStartup: pruneOnStartup, + }, + }, }); await appChain.start(false, container.createChildContainer()); @@ -43,12 +46,12 @@ describe("sequencer restart", () => { const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); for (let block = 0; block < num; block++) { - await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + await injectTransaction(appChain, sender.toPublicKey(), senderNonce); senderNonce++; const producedBlock = await blockTrigger.produceBlock(); if ((producedBlock?.transactions.length ?? 0) === 0) { - throw new Error(`Block not produced correctly: ${block}`); + throw new Error(`Block at height ${block} not produced correctly`); } if (type === "batch") { await blockTrigger.produceBatch(); @@ -58,14 +61,13 @@ describe("sequencer restart", () => { describe("resume at latest block", () => { beforeAll(async () => { - await setup(); - await clearDB(); + await setup(true); await produce(2, "batch"); await teardown(); - await setup(); + await setup(false); }, 40000); afterAll(async () => { @@ -85,7 +87,7 @@ describe("sequencer restart", () => { it("should be able to produce a block on top", async () => { const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); - await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + await injectTransaction(appChain, sender.toPublicKey(), senderNonce); senderNonce++; const [block, batch] = await blockTrigger.produceBlockAndBatch(); @@ -100,16 +102,17 @@ describe("sequencer restart", () => { describe("reconstruct untraced block masks", () => { beforeEach(async () => { - log.setLevel("DEBUG"); + log.setLevel("TRACE"); + + await setup(true); - await setup(); - await clearDB(); + await sleep(1000); await produce(2, "block"); await teardown(); - await setup(); + await setup(false); console.log("beforeEach"); }, 40000); @@ -120,7 +123,7 @@ describe("sequencer restart", () => { it("should be able to produce a block on top", async () => { const blockTrigger = appChain.sequencer.resolve("BlockTrigger"); - await prepareBlock(appChain, sender.toPublicKey(), senderNonce); + await injectTransaction(appChain, sender.toPublicKey(), senderNonce); senderNonce++; const block = await blockTrigger.produceBlock(); diff --git a/packages/persistance/test-integration/utils.ts b/packages/persistance/test-integration/utils.ts index e42b336e8..267ab42e8 100644 --- a/packages/persistance/test-integration/utils.ts +++ b/packages/persistance/test-integration/utils.ts @@ -32,6 +32,7 @@ import { BlockProducerModule, VanillaTaskWorkerModules, SequencerStartupModule, + DatabasePruneModule, } from "@proto-kit/sequencer"; import { Bool, PrivateKey, PublicKey, Struct } from "o1js"; @@ -104,6 +105,7 @@ export function createPrismaAppchain( Sequencer: Sequencer.from({ modules: { Database: PrismaRedisDatabase, + DatabasePruneModule, Mempool: PrivateMempool, LocalTaskWorkerModule: LocalTaskWorkerModule.from( @@ -143,6 +145,9 @@ export function createPrismaAppchain( }, redis: redisConnection, }, + DatabasePruneModule: { + pruneOnStartup: false, + }, BlockTrigger: {}, Mempool: {}, BatchProducerModule: {}, @@ -165,7 +170,7 @@ export function createPrismaAppchain( return appChain; } -export async function prepareBlock( +export async function injectTransaction( appChain: ReturnType, sender: PublicKey, nonce: number diff --git a/packages/protocol/src/prover/block/BlockProver.ts b/packages/protocol/src/prover/block/BlockProver.ts index 6362e7055..03cc63fdc 100644 --- a/packages/protocol/src/prover/block/BlockProver.ts +++ b/packages/protocol/src/prover/block/BlockProver.ts @@ -531,7 +531,7 @@ export class BlockProverProgrammable extends ZkProgrammable< witnessedRootsHash, stateTransitionProof.publicOutput.witnessedRootsHash, apply, - "Root accumulator Commitment is not the same that have been executed by the ST proof" + "Root accumulator Commitment is not the same as has been executed by the ST proof" ); // update root only if we didn't defer diff --git a/packages/sequencer/src/protocol/production/BatchProducerModule.ts b/packages/sequencer/src/protocol/production/BatchProducerModule.ts index 99fe69ae1..bcc31f950 100644 --- a/packages/sequencer/src/protocol/production/BatchProducerModule.ts +++ b/packages/sequencer/src/protocol/production/BatchProducerModule.ts @@ -5,7 +5,7 @@ import { NetworkState, } from "@proto-kit/protocol"; import { Field, Proof } from "o1js"; -import { log, mapSequential, noop } from "@proto-kit/common"; +import { log, mapSequential, noop, RollupMerkleTree } from "@proto-kit/common"; import { sequencerModule, @@ -17,7 +17,6 @@ import { CachedMerkleTreeStore } from "../../state/merkle/CachedMerkleTreeStore" import { BlockWithResult } from "../../storage/model/Block"; import type { Database } from "../../storage/Database"; import { TreeStoreCreator } from "../../state/masking/TreeStoreCreator"; -import { MaskName } from "../../state/masking/MaskName"; import { BlockProofSerializer } from "./tasks/serializers/BlockProofSerializer"; import { BatchTracingService } from "./tracing/BatchTracingService"; @@ -135,7 +134,6 @@ export class BatchProducerModule extends SequencerModule { await this.batchStorage.pushBatch(batchWithStateDiff.batch); await this.mergeBatchIntoStorage(blocks); - // await batchWithStateDiff.changes.mergeIntoParent(); }); // TODO Add transition from unproven to proven state for stateservice @@ -173,6 +171,23 @@ export class BatchProducerModule extends SequencerModule { }; } + private async checkTreeConsistency( + merkleTreeStore: CachedMerkleTreeStore, + publicOutput: BlockProverPublicOutput + ) { + // Preload root + const [fetchedRoot] = await merkleTreeStore.getNodesAsync([ + { key: 0n, level: 255 }, + ]); + const root = fetchedRoot ?? RollupMerkleTree.EMPTY_ROOT; + + if (root !== publicOutput.stateRoot.toBigInt()) { + throw new Error( + `Mismatch in output state roots: ${root} != ${publicOutput.stateRoot.toBigInt()}` + ); + } + } + /** * Computes a batch based on an array of sequenced blocks. * This process is also known as tracing, as we "trace" every computational step @@ -199,10 +214,7 @@ export class BatchProducerModule extends SequencerModule { throw errors.blockWithoutTxs(); } - const mask = await this.treeStoreCreator.createMask( - "batch", - MaskName.base() - ); + const mask = this.treeStoreCreator.getMask("base"); const merkleTreeStore = new CachedMerkleTreeStore(mask); const trace = await this.batchTraceService.traceBatch( @@ -210,10 +222,10 @@ export class BatchProducerModule extends SequencerModule { merkleTreeStore ); - await this.treeStoreCreator.drop("batch"); - const proof = await this.batchFlow.executeBatch(trace, blockId); + await this.checkTreeConsistency(merkleTreeStore, proof.publicOutput); + const fromNetworkState = blocks[0].block.networkState.before; const toNetworkState = blocks.at(-1)!.result.afterNetworkState; diff --git a/packages/sequencer/test/merkle/CachedMerkleStore.test.ts b/packages/sequencer/test/merkle/CachedMerkleStore.test.ts index 4d882d7db..aa1d2004a 100644 --- a/packages/sequencer/test/merkle/CachedMerkleStore.test.ts +++ b/packages/sequencer/test/merkle/CachedMerkleStore.test.ts @@ -45,10 +45,15 @@ describe("cached merkle store", () => { it("should preload through multiple levels", async () => { const cache2 = new CachedMerkleTreeStore(cache1); + const cache3 = new CachedMerkleTreeStore(cache2); - await cache2.preloadKey(5n); + await expect( + cache3.getNodesAsync([{ key: 5n, level: 0 }]) + ).resolves.toStrictEqual([10n]); + + await cache3.preloadKey(5n); - expect(cache2.getNode(5n, 0)).toStrictEqual(10n); + expect(cache3.getNode(5n, 0)).toStrictEqual(10n); }); it("should cache correctly", async () => { From 0c455a10c8bb5f22629304858063ea12a9a04236 Mon Sep 17 00:00:00 2001 From: Raphael Panic Date: Sat, 1 Mar 2025 21:18:28 +0100 Subject: [PATCH 23/23] Fixed compile error in test --- .../sequencer/test/integration/StorageIntegration.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sequencer/test/integration/StorageIntegration.test.ts b/packages/sequencer/test/integration/StorageIntegration.test.ts index 2316114e4..fc68163fc 100644 --- a/packages/sequencer/test/integration/StorageIntegration.test.ts +++ b/packages/sequencer/test/integration/StorageIntegration.test.ts @@ -145,7 +145,7 @@ describe.each([["InMemory", InMemoryDatabase]])( expectDefined(generatedBlock); - const blocks = await sequencer.resolve("BlockQueue").getNewBlocks(); + const blocks = await sequencer.resolve("BlockQueue").getPendingBlocks(); expect(blocks).toHaveLength(1); @@ -187,7 +187,7 @@ describe.each([["InMemory", InMemoryDatabase]])( expectDefined(generatedBatch); - const blocks = await sequencer.resolve("BlockQueue").getNewBlocks(); + const blocks = await sequencer.resolve("BlockQueue").getPendingBlocks(); expect(blocks).toHaveLength(0); const batchStorage = sequencer.resolve(