{"version":3,"file":"BatchedRequester.mjs","names":[],"sources":["../../src/requester/BatchedRequester.ts"],"sourcesContent":["import { ANY_KEY, RequestBatcher } from \"../util/RequestBatcher\";\nimport type { ConnectedContext } from \"@ldo/connected\";\nimport type {\n  ContainerCreateAndOverwriteResult,\n  ContainerCreateIfAbsentResult,\n  LeafCreateAndOverwriteResult,\n  LeafCreateIfAbsentResult,\n} from \"./requests/createDataResource\";\nimport { createDataResource } from \"./requests/createDataResource\";\nimport type {\n  ReadContainerResult,\n  ReadLeafResult,\n} from \"./requests/readResource\";\nimport { readResource } from \"./requests/readResource\";\nimport type { DeleteResult } from \"./requests/deleteResource\";\nimport { deleteResource } from \"./requests/deleteResource\";\nimport { modifyQueueByMergingEventsWithTheSameKeys } from \"./util/modifyQueueFuntions\";\nimport type { SolidConnectedPlugin } from \"../SolidConnectedPlugin\";\nimport type { SolidContainer } from \"../resources/SolidContainer\";\nimport type { SolidLeaf } from \"../resources/SolidLeaf\";\n\nconst READ_KEY = \"read\";\nconst CREATE_KEY = \"createDataResource\";\nconst DELETE_KEY = \"delete\";\n\n/**\n * @internal\n *\n * A singleton for handling batched requests\n */\nexport abstract class BatchedRequester<\n  ResourceType extends SolidContainer | SolidLeaf,\n> {\n  /**\n   * @internal\n   * A request batcher to maintain state for ongoing requests\n   */\n  protected readonly requestBatcher = new RequestBatcher();\n\n  /**\n   * The uri of the resource\n   */\n  abstract readonly resource: ResourceType;\n\n  /**\n   * @internal\n   * ConnectedContext for the parent Dataset\n   */\n  protected context: ConnectedContext<SolidConnectedPlugin[]>;\n\n  /**\n   * @param context - SolidLdoDatasetContext for the parent SolidLdoDataset\n   */\n  constructor(context: ConnectedContext<SolidConnectedPlugin[]>) {\n    this.context = context;\n  }\n\n  /**\n   * Checks if the resource is currently making any request\n   * @returns true if the resource is making any requests\n   */\n  isLoading(): boolean {\n    return this.requestBatcher.isLoading(ANY_KEY);\n  }\n\n  /**\n   * Checks if the resource is currently executing a create request\n   * @returns true if the resource is currently executing a create request\n   */\n  isCreating(): boolean {\n    return this.requestBatcher.isLoading(CREATE_KEY);\n  }\n\n  /**\n   * Checks if the resource is currently executing a read request\n   * @returns true if the resource is currently executing a read request\n   */\n  isReading(): boolean {\n    return this.requestBatcher.isLoading(READ_KEY);\n  }\n\n  /**\n   * Checks if the resource is currently executing a delete request\n   * @returns true if the resource is currently executing a delete request\n   */\n  isDeletinng(): boolean {\n    return this.requestBatcher.isLoading(DELETE_KEY);\n  }\n\n  /**\n   * Read this resource.\n   * @returns A ReadLeafResult or a ReadContainerResult depending on the uri of\n   * this resource\n   */\n  async read(): Promise<ReadLeafResult | ReadContainerResult> {\n    const transaction = this.context.dataset.startTransaction();\n    const result = await this.requestBatcher.queueProcess({\n      name: READ_KEY,\n      args: [\n        this.resource,\n        { dataset: transaction, fetch: this.context.solid.fetch },\n      ],\n      perform: readResource,\n      modifyQueue: modifyQueueByMergingEventsWithTheSameKeys(READ_KEY),\n      after: (result) => {\n        if (!result.isError) {\n          transaction.commit();\n        }\n      },\n    });\n    return result;\n  }\n\n  /**\n   * Delete this resource\n   * @returns A DeleteResult\n   */\n  async delete(): Promise<DeleteResult<ResourceType>> {\n    const transaction = this.context.dataset.startTransaction();\n    const result = await this.requestBatcher.queueProcess({\n      name: DELETE_KEY,\n      args: [\n        this.resource,\n        { dataset: transaction, fetch: this.context.solid.fetch },\n      ],\n      perform: deleteResource,\n      modifyQueue: modifyQueueByMergingEventsWithTheSameKeys(DELETE_KEY),\n      after: (result) => {\n        if (!result.isError) {\n          transaction.commit();\n        }\n      },\n    });\n    return result as DeleteResult<ResourceType>;\n  }\n\n  /**\n   * Creates a Resource\n   * @param overwrite - If true, this will orverwrite the resource if it already\n   * exists\n   * @returns A ContainerCreateAndOverwriteResult or a\n   * LeafCreateAndOverwriteResult depending on this resource's URI\n   */\n  createDataResource(\n    overwrite: true,\n  ): Promise<ContainerCreateAndOverwriteResult | LeafCreateAndOverwriteResult>;\n  createDataResource(\n    overwrite?: false,\n  ): Promise<ContainerCreateIfAbsentResult | LeafCreateIfAbsentResult>;\n  createDataResource(\n    overwrite?: boolean,\n  ): Promise<\n    | ContainerCreateAndOverwriteResult\n    | LeafCreateAndOverwriteResult\n    | ContainerCreateIfAbsentResult\n    | LeafCreateIfAbsentResult\n  >;\n  async createDataResource(\n    overwrite?: boolean,\n  ): Promise<\n    | ContainerCreateAndOverwriteResult\n    | LeafCreateAndOverwriteResult\n    | ContainerCreateIfAbsentResult\n    | LeafCreateIfAbsentResult\n  > {\n    const transaction = this.context.dataset.startTransaction();\n    const result = await this.requestBatcher.queueProcess({\n      name: CREATE_KEY,\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore Apparently this is a nasty type and I can't be bothered to fix it\n      args: [\n        this.resource,\n        overwrite ?? false,\n        { dataset: transaction, fetch: this.context.solid.fetch },\n      ],\n      perform: createDataResource,\n      modifyQueue: (queue, currentlyLoading, args) => {\n        const lastElementInQueue = queue[queue.length - 1];\n        if (\n          lastElementInQueue &&\n          lastElementInQueue.name === CREATE_KEY &&\n          !!lastElementInQueue.args[1] === !!args[1]\n        ) {\n          return lastElementInQueue;\n        }\n        if (\n          currentlyLoading &&\n          currentlyLoading.name === CREATE_KEY &&\n          !!currentlyLoading.args[1] === !!args[1]\n        ) {\n          return currentlyLoading;\n        }\n        return undefined;\n      },\n      after: (result) => {\n        if (!result.isError) {\n          transaction.commit();\n        }\n      },\n    });\n    return result;\n  }\n}\n"],"mappings":";;;;;;AAqBA,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAM,aAAa;;;;;;AAOnB,IAAsB,mBAAtB,MAEE;;;;CAqBA,YAAY,SAAmD;AAhB/D,OAAmB,iBAAiB,IAAI,gBAAgB;AAiBtD,OAAK,UAAU;;;;;;CAOjB,YAAqB;AACnB,SAAO,KAAK,eAAe,UAAA,MAAkB;;;;;;CAO/C,aAAsB;AACpB,SAAO,KAAK,eAAe,UAAU,WAAW;;;;;;CAOlD,YAAqB;AACnB,SAAO,KAAK,eAAe,UAAU,SAAS;;;;;;CAOhD,cAAuB;AACrB,SAAO,KAAK,eAAe,UAAU,WAAW;;;;;;;CAQlD,MAAM,OAAsD;EAC1D,MAAM,cAAc,KAAK,QAAQ,QAAQ,kBAAkB;AAe3D,SAAO,MAdc,KAAK,eAAe,aAAa;GACpD,MAAM;GACN,MAAM,CACJ,KAAK,UACL;IAAE,SAAS;IAAa,OAAO,KAAK,QAAQ,MAAM;IAAO,CAC1D;GACD,SAAS;GACT,aAAa,0CAA0C,SAAS;GAChE,QAAQ,WAAW;AACjB,QAAI,CAAC,OAAO,QACV,aAAY,QAAQ;;GAGzB,CAAC;;;;;;CAQJ,MAAM,SAA8C;EAClD,MAAM,cAAc,KAAK,QAAQ,QAAQ,kBAAkB;AAe3D,SAAO,MAdc,KAAK,eAAe,aAAa;GACpD,MAAM;GACN,MAAM,CACJ,KAAK,UACL;IAAE,SAAS;IAAa,OAAO,KAAK,QAAQ,MAAM;IAAO,CAC1D;GACD,SAAS;GACT,aAAa,0CAA0C,WAAW;GAClE,QAAQ,WAAW;AACjB,QAAI,CAAC,OAAO,QACV,aAAY,QAAQ;;GAGzB,CAAC;;CAyBJ,MAAM,mBACJ,WAMA;EACA,MAAM,cAAc,KAAK,QAAQ,QAAQ,kBAAkB;AAmC3D,SAAO,MAlCc,KAAK,eAAe,aAAa;GACpD,MAAM;GAGN,MAAM;IACJ,KAAK;IACL,aAAa;IACb;KAAE,SAAS;KAAa,OAAO,KAAK,QAAQ,MAAM;KAAO;IAC1D;GACD,SAAS;GACT,cAAc,OAAO,kBAAkB,SAAS;IAC9C,MAAM,qBAAqB,MAAM,MAAM,SAAS;AAChD,QACE,sBACA,mBAAmB,SAAS,cAC5B,CAAC,CAAC,mBAAmB,KAAK,OAAO,CAAC,CAAC,KAAK,GAExC,QAAO;AAET,QACE,oBACA,iBAAiB,SAAS,cAC1B,CAAC,CAAC,iBAAiB,KAAK,OAAO,CAAC,CAAC,KAAK,GAEtC,QAAO;;GAIX,QAAQ,WAAW;AACjB,QAAI,CAAC,OAAO,QACV,aAAY,QAAQ;;GAGzB,CAAC"}