(key: string, data: Metadata)
| 452 | } |
| 453 | |
| 454 | async storeMetadata(key: string, data: Metadata) { |
| 455 | // semaphore ensures metadata updates are always ordered, even if |
| 456 | // calls to storeMetadata are not. concurrent metadata updates |
| 457 | // will result in the metadata branch being unable to update. |
| 458 | if (!this._metadataSemaphore) { |
| 459 | this._metadataSemaphore = semaphore(1); |
| 460 | } |
| 461 | return new Promise<void>((resolve, reject) => |
| 462 | this._metadataSemaphore?.take(async () => { |
| 463 | try { |
| 464 | const branchData = await this.checkMetadataRef(); |
| 465 | const file = { path: `${key}.json`, raw: JSON.stringify(data) }; |
| 466 | |
| 467 | await this.uploadBlob(file); |
| 468 | const changeTree = await this.updateTree(branchData.sha, [file as TreeFile]); |
| 469 | const { sha } = await this.commit(`Updating “${key}” metadata`, changeTree); |
| 470 | await this.patchRef('meta', '_decap_cms', sha); |
| 471 | await localForage.setItem(`gh.meta.${key}`, { |
| 472 | expires: Date.now() + 300000, // In 5 minutes |
| 473 | data, |
| 474 | }); |
| 475 | this._metadataSemaphore?.leave(); |
| 476 | resolve(); |
| 477 | } catch (err) { |
| 478 | reject(err); |
| 479 | } |
| 480 | }), |
| 481 | ); |
| 482 | } |
| 483 | |
| 484 | deleteMetadata(key: string) { |
| 485 | if (!this._metadataSemaphore) { |
no test coverage detected