Skip to content

Commit

Permalink
Implement a helper function to destroy an array of resources
Browse files Browse the repository at this point in the history
  • Loading branch information
mbeckem committed Aug 15, 2024
1 parent 6cc7fcd commit 50550d3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/plenty-pots-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/core": minor
---

Add `destroyResources(resources)` to destroy an array of resources.
2 changes: 1 addition & 1 deletion src/packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export {
rethrowAbortError
} from "./error";
export { EventEmitter, type EventSource, type EventNames } from "./events";
export { destroyResource, type Resource } from "./resources";
export { destroyResource, destroyResources, type Resource } from "./resources";
export { createLogger, type Logger, type LogLevel, type LogMethod } from "./Logger";
export { createManualPromise, type ManualPromise } from "./utils";
43 changes: 43 additions & 0 deletions src/packages/core/resources.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)
// SPDX-License-Identifier: Apache-2.0
import { expect, it } from "vitest";
import { destroyResources, Resource } from "./resources";

it("destroys all resources in the array", () => {
const events: string[] = [];
const resources: Resource[] = [
{
destroy() {
events.push("destroyed 1");
}
},
{
destroy() {
events.push("destroyed 2");
}
}
];

destroyResources(resources);
expect(events).toEqual(["destroyed 2", "destroyed 1"]); // reverse order
});

it("handles cycles correctly", () => {
const events: string[] = [];
const resources: Resource[] = [
{
destroy() {
events.push("destroyed 1");
destroyResources(resources); // still only destroys each resource only once
}
},
{
destroy() {
events.push("destroyed 2");
}
}
];

destroyResources(resources);
expect(events).toEqual(["destroyed 2", "destroyed 1"]);
});
16 changes: 16 additions & 0 deletions src/packages/core/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,19 @@ export function destroyResource<R extends Resource>(resource: R | undefined): un
resource?.destroy();
return undefined;
}

/**
* A helper function that invokes `destroy()` on each resource in the given array.
*
* This function destroys the resources in reverse order (starting from the last element).
* This is done to reverse the order of construction.
*
* The array will be cleared by this function.
*/
export function destroyResources<R extends Resource>(resources: R[]): void {
// `destroy()` might call us in a cycle, so we modify the array in place.
let resource: Resource | undefined;
while ((resource = resources.pop())) {
resource.destroy();
}
}

0 comments on commit 50550d3

Please sign in to comment.