mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 21:50:15 +00:00
* feat: implement Rc * feat: use Rc in sdk service * docs: add an example to `take()` * fix: clarify function doc * Add custom eslint rule package with enforced `using` rule (#13009) * feat: add custom eslint rule * feat: check for `UsingRequired` instead of hardcoding `Rc` * chore: move package to libs * wip: add tests. Tests work when run from same folder but not from root * fix: add dependencies to renovate * fix: add empty ts file to avoid typechecking throwing errors * fix: tests not running from root * chore: remove unecessary config * fix: linting * docs: add readme * chore: add platform ownership * chore: clean up comment * Add support for flat config to "Improved sdk referencing" (#13054) * WIP flat config for eslint * Add rxjs * Configure vscode to use flat config * Fix some new linting errors * Remove directory overrides of .eslintrc * Remove explicit dependencies on typescript-eslint/ and @angular-eslint/ * Add missing rules * Add rxjs recommended rules * Add storybook and enabled rxjs-angular rule * Add buildNoRestrictedImports helper * Ignore platform import restrictions * Remove unused ignores * feat: migrate rules over to .mjs and flat config * feat: implement support for .mjs tests * chore: remove old package approach * chore: update package-lock * fix: add empty TS file to stop errors * chore: clean up comments --------- Co-authored-by: Hinton <hinton@users.noreply.github.com> * fix: update CODEOWNERS to match folder name * fix: renovate.json after merge * fix: package.json, pin versions, sort order * fix: update package-lock.json --------- Co-authored-by: Hinton <hinton@users.noreply.github.com>
77 lines
1.8 KiB
TypeScript
77 lines
1.8 KiB
TypeScript
import { UsingRequired } from "../using-required";
|
|
|
|
export type Freeable = { free: () => void };
|
|
|
|
/**
|
|
* Reference counted disposable value.
|
|
* This class is used to manage the lifetime of a value that needs to be
|
|
* freed of at a specific time but might still be in-use when that happens.
|
|
*/
|
|
export class Rc<T extends Freeable> {
|
|
private markedForDisposal = false;
|
|
private refCount = 0;
|
|
private value: T;
|
|
|
|
constructor(value: T) {
|
|
this.value = value;
|
|
}
|
|
|
|
/**
|
|
* Use this function when you want to use the underlying object.
|
|
* This will guarantee that you have a reference to the object
|
|
* and that it won't be freed until your reference goes out of scope.
|
|
*
|
|
* This function must be used with the `using` keyword.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* function someFunction(rc: Rc<SomeValue>) {
|
|
* using reference = rc.take();
|
|
* reference.value.doSomething();
|
|
* // reference is automatically disposed here
|
|
* }
|
|
* ```
|
|
*
|
|
* @returns The value.
|
|
*/
|
|
take(): Ref<T> {
|
|
if (this.markedForDisposal) {
|
|
throw new Error("Cannot take a reference to a value marked for disposal");
|
|
}
|
|
|
|
this.refCount++;
|
|
return new Ref(() => this.release(), this.value);
|
|
}
|
|
|
|
/**
|
|
* Mark this Rc for disposal. When the refCount reaches 0, the value
|
|
* will be freed.
|
|
*/
|
|
markForDisposal() {
|
|
this.markedForDisposal = true;
|
|
this.freeIfPossible();
|
|
}
|
|
|
|
private release() {
|
|
this.refCount--;
|
|
this.freeIfPossible();
|
|
}
|
|
|
|
private freeIfPossible() {
|
|
if (this.refCount === 0 && this.markedForDisposal) {
|
|
this.value.free();
|
|
}
|
|
}
|
|
}
|
|
|
|
export class Ref<T extends Freeable> implements UsingRequired {
|
|
constructor(
|
|
private readonly release: () => void,
|
|
readonly value: T,
|
|
) {}
|
|
|
|
[Symbol.dispose]() {
|
|
this.release();
|
|
}
|
|
}
|