lifetime.d.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { MaybeAsyncBlock } from "./asyncify-helpers";
  2. import type { QuickJSHandle } from "./types";
  3. /**
  4. * An object that can be disposed.
  5. * [[Lifetime]] is the canonical implementation of Disposable.
  6. * Use [[Scope]] to manage cleaning up multiple disposables.
  7. */
  8. export interface Disposable {
  9. /**
  10. * Dispose of the underlying resources used by this object.
  11. */
  12. dispose(): void;
  13. /**
  14. * @returns true if the object is alive
  15. * @returns false after the object has been [[dispose]]d
  16. */
  17. alive: boolean;
  18. }
  19. /**
  20. * A lifetime prevents access to a value after the lifetime has been
  21. * [[dispose]]ed.
  22. *
  23. * Typically, quickjs-emscripten uses Lifetimes to protect C memory pointers.
  24. */
  25. export declare class Lifetime<T, TCopy = never, Owner = never> implements Disposable {
  26. protected readonly _value: T;
  27. protected readonly copier?: ((value: T | TCopy) => TCopy) | undefined;
  28. protected readonly disposer?: ((value: T | TCopy) => void) | undefined;
  29. protected readonly _owner?: Owner | undefined;
  30. protected _alive: boolean;
  31. protected _constructorStack: string | undefined;
  32. /**
  33. * When the Lifetime is disposed, it will call `disposer(_value)`. Use the
  34. * disposer function to implement whatever cleanup needs to happen at the end
  35. * of `value`'s lifetime.
  36. *
  37. * `_owner` is not used or controlled by the lifetime. It's just metadata for
  38. * the creator.
  39. */
  40. constructor(_value: T, copier?: ((value: T | TCopy) => TCopy) | undefined, disposer?: ((value: T | TCopy) => void) | undefined, _owner?: Owner | undefined);
  41. get alive(): boolean;
  42. /**
  43. * The value this Lifetime protects. You must never retain the value - it
  44. * may become invalid, leading to memory errors.
  45. *
  46. * @throws If the lifetime has been [[dispose]]d already.
  47. */
  48. get value(): T;
  49. get owner(): Owner | undefined;
  50. get dupable(): boolean;
  51. /**
  52. * Create a new handle pointing to the same [[value]].
  53. */
  54. dup(): Lifetime<TCopy, TCopy, Owner>;
  55. /**
  56. * Call `map` with this lifetime, then dispose the lifetime.
  57. * @return the result of `map(this)`.
  58. */
  59. consume<O>(map: (lifetime: this) => O): O;
  60. consume<O>(map: (lifetime: QuickJSHandle) => O): O;
  61. /**
  62. * Dispose of [[value]] and perform cleanup.
  63. */
  64. dispose(): void;
  65. private assertAlive;
  66. }
  67. /**
  68. * A Lifetime that lives forever. Used for constants.
  69. */
  70. export declare class StaticLifetime<T, Owner = never> extends Lifetime<T, T, Owner> {
  71. constructor(value: T, owner?: Owner);
  72. get dupable(): boolean;
  73. dup(): this;
  74. dispose(): void;
  75. }
  76. /**
  77. * A Lifetime that does not own its `value`. A WeakLifetime never calls its
  78. * `disposer` function, but can be `dup`ed to produce regular lifetimes that
  79. * do.
  80. *
  81. * Used for function arguments.
  82. */
  83. export declare class WeakLifetime<T, TCopy = never, Owner = never> extends Lifetime<T, TCopy, Owner> {
  84. constructor(value: T, copier?: (value: T | TCopy) => TCopy, disposer?: (value: TCopy) => void, owner?: Owner);
  85. dispose(): void;
  86. }
  87. /**
  88. * Scope helps reduce the burden of manually tracking and disposing of
  89. * Lifetimes. See [[withScope]]. and [[withScopeAsync]].
  90. */
  91. export declare class Scope implements Disposable {
  92. /**
  93. * Run `block` with a new Scope instance that will be disposed after the block returns.
  94. * Inside `block`, call `scope.manage` on each lifetime you create to have the lifetime
  95. * automatically disposed after the block returns.
  96. *
  97. * @warning Do not use with async functions. Instead, use [[withScopeAsync]].
  98. */
  99. static withScope<R>(block: (scope: Scope) => R): R;
  100. static withScopeMaybeAsync<Return, This, Yielded>(_this: This, block: MaybeAsyncBlock<Return, This, Yielded, [Scope]>): Return | Promise<Return>;
  101. /**
  102. * Run `block` with a new Scope instance that will be disposed after the
  103. * block's returned promise settles. Inside `block`, call `scope.manage` on each
  104. * lifetime you create to have the lifetime automatically disposed after the
  105. * block returns.
  106. */
  107. static withScopeAsync<R>(block: (scope: Scope) => Promise<R>): Promise<R>;
  108. private _disposables;
  109. /**
  110. * Track `lifetime` so that it is disposed when this scope is disposed.
  111. */
  112. manage<T extends Disposable>(lifetime: T): T;
  113. get alive(): boolean;
  114. dispose(): void;
  115. }