grainjs 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +23 -71
  2. package/dist/cjs/index.js +5 -1
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/lib/PriorityQueue.d.ts +1 -1
  5. package/dist/cjs/lib/_computed_queue.js +3 -3
  6. package/dist/cjs/lib/_computed_queue.js.map +1 -1
  7. package/dist/cjs/lib/binding.d.ts +11 -4
  8. package/dist/cjs/lib/binding.js +5 -5
  9. package/dist/cjs/lib/binding.js.map +1 -1
  10. package/dist/cjs/lib/computed.d.ts +49 -28
  11. package/dist/cjs/lib/computed.js +38 -52
  12. package/dist/cjs/lib/computed.js.map +1 -1
  13. package/dist/cjs/lib/dispose.d.ts +109 -96
  14. package/dist/cjs/lib/dispose.js +106 -80
  15. package/dist/cjs/lib/dispose.js.map +1 -1
  16. package/dist/cjs/lib/dom.d.ts +38 -18
  17. package/dist/cjs/lib/dom.js +44 -20
  18. package/dist/cjs/lib/dom.js.map +1 -1
  19. package/dist/cjs/lib/domComponent.d.ts +56 -48
  20. package/dist/cjs/lib/domComponent.js +66 -1
  21. package/dist/cjs/lib/domComponent.js.map +1 -1
  22. package/dist/cjs/lib/domComputed.d.ts +31 -21
  23. package/dist/cjs/lib/domComputed.js +14 -11
  24. package/dist/cjs/lib/domComputed.js.map +1 -1
  25. package/dist/cjs/lib/domDispose.d.ts +27 -12
  26. package/dist/cjs/lib/domDispose.js +26 -11
  27. package/dist/cjs/lib/domDispose.js.map +1 -1
  28. package/dist/cjs/lib/domForEach.d.ts +4 -3
  29. package/dist/cjs/lib/domForEach.js +10 -9
  30. package/dist/cjs/lib/domForEach.js.map +1 -1
  31. package/dist/cjs/lib/domImpl.d.ts +33 -10
  32. package/dist/cjs/lib/domImpl.js +28 -9
  33. package/dist/cjs/lib/domImpl.js.map +1 -1
  34. package/dist/cjs/lib/domMethods.d.ts +93 -47
  35. package/dist/cjs/lib/domMethods.js +88 -46
  36. package/dist/cjs/lib/domMethods.js.map +1 -1
  37. package/dist/cjs/lib/domevent.d.ts +87 -62
  38. package/dist/cjs/lib/domevent.js +84 -59
  39. package/dist/cjs/lib/domevent.js.map +1 -1
  40. package/dist/cjs/lib/emit.d.ts +62 -32
  41. package/dist/cjs/lib/emit.js +67 -53
  42. package/dist/cjs/lib/emit.js.map +1 -1
  43. package/dist/cjs/lib/kowrap.d.ts +6 -3
  44. package/dist/cjs/lib/kowrap.js +6 -3
  45. package/dist/cjs/lib/kowrap.js.map +1 -1
  46. package/dist/cjs/lib/obsArray.d.ts +91 -53
  47. package/dist/cjs/lib/obsArray.js +87 -55
  48. package/dist/cjs/lib/obsArray.js.map +1 -1
  49. package/dist/cjs/lib/observable.d.ts +25 -15
  50. package/dist/cjs/lib/observable.js +29 -18
  51. package/dist/cjs/lib/observable.js.map +1 -1
  52. package/dist/cjs/lib/pureComputed.d.ts +12 -15
  53. package/dist/cjs/lib/pureComputed.js +15 -18
  54. package/dist/cjs/lib/pureComputed.js.map +1 -1
  55. package/dist/cjs/lib/styled.d.ts +78 -61
  56. package/dist/cjs/lib/styled.js +26 -79
  57. package/dist/cjs/lib/styled.js.map +1 -1
  58. package/dist/cjs/lib/subscribe.d.ts +41 -37
  59. package/dist/cjs/lib/subscribe.js +31 -40
  60. package/dist/cjs/lib/subscribe.js.map +1 -1
  61. package/dist/cjs/lib/util.js +1 -0
  62. package/dist/cjs/lib/util.js.map +1 -1
  63. package/dist/cjs/lib/widgets/input.d.ts +3 -1
  64. package/dist/cjs/lib/widgets/input.js +6 -4
  65. package/dist/cjs/lib/widgets/input.js.map +1 -1
  66. package/dist/cjs/lib/widgets/select.d.ts +4 -2
  67. package/dist/cjs/lib/widgets/select.js +7 -5
  68. package/dist/cjs/lib/widgets/select.js.map +1 -1
  69. package/dist/esm/lib/_computed_queue.js +3 -3
  70. package/dist/esm/lib/_computed_queue.js.map +1 -1
  71. package/dist/esm/lib/binding.js +2 -2
  72. package/dist/esm/lib/binding.js.map +1 -1
  73. package/dist/esm/lib/computed.js +36 -50
  74. package/dist/esm/lib/computed.js.map +1 -1
  75. package/dist/esm/lib/dispose.js +104 -78
  76. package/dist/esm/lib/dispose.js.map +1 -1
  77. package/dist/esm/lib/dom.js +38 -18
  78. package/dist/esm/lib/dom.js.map +1 -1
  79. package/dist/esm/lib/domComponent.js +65 -0
  80. package/dist/esm/lib/domComponent.js.map +1 -1
  81. package/dist/esm/lib/domComputed.js +10 -7
  82. package/dist/esm/lib/domComputed.js.map +1 -1
  83. package/dist/esm/lib/domDispose.js +26 -11
  84. package/dist/esm/lib/domDispose.js.map +1 -1
  85. package/dist/esm/lib/domForEach.js +3 -2
  86. package/dist/esm/lib/domForEach.js.map +1 -1
  87. package/dist/esm/lib/domImpl.js +26 -7
  88. package/dist/esm/lib/domImpl.js.map +1 -1
  89. package/dist/esm/lib/domMethods.js +77 -35
  90. package/dist/esm/lib/domMethods.js.map +1 -1
  91. package/dist/esm/lib/domevent.js +84 -59
  92. package/dist/esm/lib/domevent.js.map +1 -1
  93. package/dist/esm/lib/emit.js +67 -53
  94. package/dist/esm/lib/emit.js.map +1 -1
  95. package/dist/esm/lib/kowrap.js +5 -2
  96. package/dist/esm/lib/kowrap.js.map +1 -1
  97. package/dist/esm/lib/obsArray.js +82 -50
  98. package/dist/esm/lib/obsArray.js.map +1 -1
  99. package/dist/esm/lib/observable.js +26 -15
  100. package/dist/esm/lib/observable.js.map +1 -1
  101. package/dist/esm/lib/pureComputed.js +15 -18
  102. package/dist/esm/lib/pureComputed.js.map +1 -1
  103. package/dist/esm/lib/styled.js +24 -77
  104. package/dist/esm/lib/styled.js.map +1 -1
  105. package/dist/esm/lib/subscribe.js +27 -36
  106. package/dist/esm/lib/subscribe.js.map +1 -1
  107. package/dist/esm/lib/util.js +1 -0
  108. package/dist/esm/lib/util.js.map +1 -1
  109. package/dist/esm/lib/widgets/input.js +3 -1
  110. package/dist/esm/lib/widgets/input.js.map +1 -1
  111. package/dist/esm/lib/widgets/select.js +3 -1
  112. package/dist/esm/lib/widgets/select.js.map +1 -1
  113. package/dist/grain-full.debug.js +2146 -3062
  114. package/dist/grain-full.debug.js.map +7 -0
  115. package/dist/grain-full.min.js +6 -2
  116. package/dist/grain-full.min.js.map +7 -1
  117. package/lib/binding.ts +9 -2
  118. package/lib/computed.ts +56 -56
  119. package/lib/dispose.ts +110 -85
  120. package/lib/dom.ts +39 -20
  121. package/lib/domComponent.ts +66 -57
  122. package/lib/domComputed.ts +29 -19
  123. package/lib/domDispose.ts +28 -11
  124. package/lib/domForEach.ts +7 -3
  125. package/lib/domImpl.ts +30 -7
  126. package/lib/domMethods.ts +101 -46
  127. package/lib/domevent.ts +85 -60
  128. package/lib/emit.ts +64 -50
  129. package/lib/kowrap.ts +5 -2
  130. package/lib/obsArray.ts +89 -54
  131. package/lib/observable.ts +26 -15
  132. package/lib/pureComputed.ts +16 -22
  133. package/lib/styled.ts +85 -71
  134. package/lib/subscribe.ts +41 -45
  135. package/lib/util.ts +1 -0
  136. package/lib/widgets/input.ts +3 -1
  137. package/lib/widgets/select.ts +3 -1
  138. package/package.json +38 -27
@@ -1,75 +1,3 @@
1
- /**
2
- * dispose.js provides tools to objects that needs to dispose resources, such as destroy DOM, and
3
- * unsubscribe from events. The motivation with examples is presented here:
4
- *
5
- * https://phab.getgrist.com/w/disposal/
6
- *
7
- * Disposable is a class for components that need cleanup (e.g. maintain DOM, listen to events,
8
- * subscribe to anything). It provides a .dispose() method that should be called to destroy the
9
- * component, and .onDispose()/.autoDispose() methods that the component should use to take
10
- * responsibility for other pieces that require cleanup.
11
- *
12
- * To define a disposable class:
13
- * class Foo extends Disposable { ... }
14
- *
15
- * To create Foo:
16
- * const foo = Foo.create(owner, ...args);
17
- * This is better than `new Foo` for two reasons:
18
- * 1. If Foo's constructor throws an exception, any disposals registered in that constructor
19
- * before the exception are honored.
20
- * 2. It ensures you specify the owner of the new instance (but you can use null to skip it).
21
- *
22
- * In Foo's constructor (or rarely methods), take ownership of other Disposable objects:
23
- * this.bar = Bar.create(this, ...);
24
- *
25
- * For objects that are not instances of Disposable but have a .dispose() methods, use:
26
- * this.bar = this.autoDispose(createSomethingDisposable());
27
- *
28
- * To call a function on disposal (e.g. to add custom disposal logic):
29
- * this.onDispose(() => this.myUnsubscribeAllMethod());
30
- * this.onDispose(this.myUnsubscribeAllMethod, this); // slightly more efficient
31
- *
32
- * To mark this object to be wiped out on disposal (i.e. set all properties to null):
33
- * this.wipeOnDispose();
34
- * See the documentation of that method for more info.
35
- *
36
- * To dispose Foo directly:
37
- * foo.dispose();
38
- * To determine if an object has already been disposed:
39
- * foo.isDisposed()
40
- *
41
- * If you need to replace an owned object, or release, or dispose it early, use a Holder:
42
- * this._holder = Holder.create(this);
43
- * Bar.create(this._holder, 1); // creates new Bar(1)
44
- * Bar.create(this._holder, 2); // creates new Bar(2) and disposes previous object
45
- * this._holder.clear(); // disposes contained object
46
- * this._holder.release(); // releases contained object
47
- *
48
- * If you need a container for multiple objects and dispose them all together, use a MultiHolder:
49
- * this._mholder = MultiHolder.create(null);
50
- * Bar.create(this._mholder, 1); // create new Bar(1)
51
- * Bar.create(this._mholder, 2); // create new Bar(2)
52
- * this._mholder.dispose(); // disposes both objects
53
- *
54
- * If creating your own class with a dispose() method, do NOT throw exceptions from dispose().
55
- * These cannot be handled properly in all cases. Read here about the same issue in C++:
56
- * http://bin-login.name/ftp/pub/docs/programming_languages/cpp/cffective_cpp/MAGAZINE/SU_FRAME.HTM#destruct
57
- *
58
- * Using a parametrized (generic) class as a Disposable is tricky. E.g.
59
- * class Bar<T> extends Disposable { ... }
60
- * // Bar<T>.create(...) <-- doesn't work
61
- * // Bar.create<T>(...) <-- doesn't work
62
- * // Bar.create(...) <-- works, but with {} for Bar's type parameters
63
- *
64
- * The solution is to expose the constructor type using a helper method:
65
- * class Bar<T> extends Disposable {
66
- * // Note the tuple below which must match the constructor parameters of Bar<U>.
67
- * public static ctor<U>(): IDisposableCtor<Bar<U>, [U, boolean]> { return this; }
68
- * constructor(a: T, b: boolean) { ... }
69
- * }
70
- * Bar.ctor<T>().create(...) // <-- works, creates Bar<T>, and does type-checking!
71
- */
72
- import { LLink } from './emit';
73
1
  /**
74
2
  * Anything with a .dispose() method is a disposable object, and implements the IDisposable interface.
75
3
  */
@@ -77,7 +5,7 @@ export interface IDisposable {
77
5
  dispose(): void;
78
6
  }
79
7
  /**
80
- * Anything with .autoDispose() can be the owner of a disposable object. This is a type-specific
8
+ * Anything with `.autoDispose()` can be the owner of a disposable object. This is a type-specific
81
9
  * class that can only own a disposable object of type T.
82
10
  */
83
11
  export interface IDisposableOwnerT<T extends IDisposable> {
@@ -97,33 +25,107 @@ export interface IDisposableCtor<Derived, CtorArgs extends any[]> {
97
25
  create<T extends new (...args: any[]) => any>(this: T, owner: IDisposableOwnerT<InstanceType<T>> | null, ...args: ConstructorParameters<T>): InstanceType<T>;
98
26
  }
99
27
  /**
100
- * Base class for disposable objects that can own other objects. See the module documentation.
28
+ * Base class for disposable objects that can own other objects.
29
+ *
30
+ * For background and motivation, see [Disposables](/dispose).
31
+ *
32
+ * `Disposable` is a class for components that need cleanup (e.g. maintain DOM, listen to events,
33
+ * subscribe to anything). It provides a `.dispose()` method that should be called to destroy the
34
+ * component, and `.onDispose()` / `.autoDispose()` methods that the component should use to take
35
+ * responsibility for other pieces that require cleanup.
36
+ *
37
+ * To define a disposable class:
38
+ * ```ts
39
+ * class Foo extends Disposable { ... }
40
+ * ```
41
+ *
42
+ * To create `Foo`:
43
+ * ```ts
44
+ * const foo = Foo.create(owner, ...args);
45
+ * ```
46
+ * This is better than `new Foo` for two reasons:
47
+ * 1. If `Foo`'s constructor throws an exception, any disposals registered in that constructor
48
+ * before the exception are honored.
49
+ * 2. It ensures you specify the owner of the new instance (but you can use null to skip it).
50
+ *
51
+ * In `Foo`'s constructor (or rarely methods), take ownership of other Disposable objects:
52
+ * ```ts
53
+ * this.bar = Bar.create(this, ...);
54
+ * ```
55
+ *
56
+ * For objects that are not instances of Disposable but have a .dispose() methods, use:
57
+ * ```ts
58
+ * this.bar = this.autoDispose(createSomethingDisposable());
59
+ * ```
60
+ *
61
+ * To call a function on disposal (e.g. to add custom disposal logic):
62
+ * ```ts
63
+ * this.onDispose(() => this.myUnsubscribeAllMethod());
64
+ * this.onDispose(this.myUnsubscribeAllMethod, this);
65
+ * ```
66
+ *
67
+ * To mark this object to be wiped out on disposal (i.e. set all properties to null):
68
+ * ```ts
69
+ * this.wipeOnDispose();
70
+ * ```
71
+ * See the documentation of that method for more info.
72
+ *
73
+ * To dispose Foo directly: `foo.dispose()`.
74
+ *
75
+ * To determine if an object has already been disposed: `foo.isDisposed()`.
76
+ *
77
+ * If you need to replace an owned object, or release, or dispose it early, use a
78
+ * [`Holder`](#Holder) or [`MultiHolder`](#MultiHolder).
79
+ *
80
+ * If creating your own class with a `dispose()` method, do NOT throw exceptions from `dispose()`.
81
+ * These cannot be handled properly in all cases.
82
+ *
83
+ * Using a parametrized (generic) class as a Disposable is tricky. E.g.
84
+ * ```ts
85
+ * class Bar<T> extends Disposable { ... }
86
+ * // Bar<T>.create(...) <-- doesn't work
87
+ * // Bar.create<T>(...) <-- doesn't work
88
+ * // Bar.create(...) <-- works, but with {} for Bar's type parameters
89
+ * ```
90
+ *
91
+ * The solution is to expose the constructor type using a helper method:
92
+ * ```ts
93
+ * class Bar<T> extends Disposable {
94
+ * // Note the tuple below which must match the constructor parameters of Bar<U>.
95
+ * public static ctor<U>(): IDisposableCtor<Bar<U>, [U, boolean]> { return this; }
96
+ * constructor(a: T, b: boolean) { ... }
97
+ * }
98
+ * Bar.ctor<T>().create(...) // <-- works, creates Bar<T>, and does type-checking!
99
+ * ```
101
100
  */
102
101
  export declare abstract class Disposable implements IDisposable, IDisposableOwner {
103
102
  /**
104
103
  * Create Disposable instances using `Class.create(owner, ...)` rather than `new Class(...)`.
105
104
  *
106
105
  * This reminds you to provide an owner, and ensures that if the constructor throws an
107
- * exception, dispose() gets called to clean up the partially-constructed object.
106
+ * exception, `dispose()` gets called to clean up the partially-constructed object.
108
107
  *
109
- * Owner may be null if intend to ensure disposal some other way.
108
+ * Owner may be `null` if you intend to ensure disposal some other way.
110
109
  */
111
110
  static create<T extends new (...args: any[]) => any>(this: T, owner: IDisposableOwnerT<InstanceType<T>> | null, ...args: ConstructorParameters<T>): InstanceType<T>;
112
111
  private _disposalList;
113
112
  constructor();
114
- /** Take ownership of obj, and dispose it when this.dispose() is called. */
113
+ /** Take ownership of `obj`, and dispose it when `this.dispose()` is called. */
115
114
  autoDispose<T extends IDisposable>(obj: T): T;
116
- /** Call the given callback when this.dispose() is called. */
117
- onDispose<T>(callback: (this: T) => void, context?: T): DisposeListener;
115
+ /** Call the given callback when `this.dispose()` is called. */
116
+ onDispose<T>(callback: (this: T) => void, context?: T): IDisposable;
118
117
  /**
119
118
  * Wipe out this object when it is disposed, i.e. set all its properties to null. It is
120
119
  * recommended to call this early in the constructor.
121
120
  *
122
121
  * This makes disposal more costly, but has certain benefits:
122
+ *
123
123
  * - If anything still refers to the object and uses it, we'll get an early error, rather than
124
124
  * silently keep going, potentially doing useless work (or worse) and wasting resources.
125
+ *
125
126
  * - If anything still refers to the object (even without using it), the fields of the object
126
127
  * can still be garbage-collected.
128
+ *
127
129
  * - If there are circular references involving this object, they get broken, making the job
128
130
  * easier for the garbage collector.
129
131
  *
@@ -136,7 +138,7 @@ export declare abstract class Disposable implements IDisposable, IDisposableOwne
136
138
  */
137
139
  isDisposed(): boolean;
138
140
  /**
139
- * Clean up `this` by disposing all owned objects, and calling onDispose() callbacks, in reverse
141
+ * Clean up `this` by disposing all owned objects, and calling `onDispose()` callbacks, in reverse
140
142
  * order to that in which they were added.
141
143
  */
142
144
  dispose(): void;
@@ -148,14 +150,28 @@ export declare abstract class Disposable implements IDisposable, IDisposableOwne
148
150
  }
149
151
  /**
150
152
  * Holder keeps a single disposable object. If given responsibility for another object using
151
- * holder.autoDispose() or Foo.create(holder, ...), it automatically disposes the currently held
153
+ * `holder.autoDispose()` or `Foo.create(holder, ...)`, it automatically disposes the currently held
152
154
  * object. It also disposes it when the holder itself is disposed.
153
155
  *
154
- * If the object is an instance of Disposable, the holder will also notice when the object gets
156
+ * If the object is an instance of `Disposable`, the holder will also notice when the object gets
155
157
  * disposed from outside of it, in which case the holder will become empty again.
158
+ *
159
+ * If you need a container for multiple objects and dispose them all together, use a `MultiHolder`:
160
+ *
161
+ * :::info Example
162
+ * ```ts
163
+ * this._holder = Holder.create(this);
164
+ * Bar.create(this._holder, 1); // creates new Bar(1), assuming it's a Disposable
165
+ * Bar.create(this._holder, 2); // creates new Bar(2) and disposes previous object
166
+ * this._holder.clear(); // disposes contained object
167
+ * this._holder.release(); // releases contained object
168
+ * ```
169
+ * :::
156
170
  */
157
171
  export declare class Holder<T extends IDisposable> implements IDisposable, IDisposableOwner {
172
+ /** `Holder.create(owner)` creates a new `Holder`. */
158
173
  static create<T extends IDisposable>(owner: IDisposableOwnerT<Holder<T>> | null): Holder<T>;
174
+ /** @internal */
159
175
  protected _owned: T | null;
160
176
  private _disposalListener;
161
177
  /** Take ownership of a new object, disposing the previously held one. */
@@ -175,9 +191,18 @@ export declare class Holder<T extends IDisposable> implements IDisposable, IDisp
175
191
  private _onOutsideDispose;
176
192
  }
177
193
  /**
178
- * MultiHolder keeps multiple disposable object. It disposes all held object when the holder
179
- * itself is disposed. It's actually nothing more than the Disposable base class itself, just
194
+ * `MultiHolder` keeps multiple disposable objects. It disposes all held object when the holder
195
+ * itself is disposed. It's actually nothing more than the `Disposable` base class itself, just
180
196
  * exposed with a clearer name that describes its purpose.
197
+ *
198
+ * :::info Example
199
+ * ```ts
200
+ * this._mholder = MultiHolder.create(null);
201
+ * Bar.create(this._mholder, 1); // create new Bar(1)
202
+ * Bar.create(this._mholder, 2); // create new Bar(2)
203
+ * this._mholder.dispose(); // disposes both objects
204
+ * ```
205
+ * :::
181
206
  */
182
207
  export declare class MultiHolder extends Disposable {
183
208
  }
@@ -185,15 +210,3 @@ export declare class MultiHolder extends Disposable {
185
210
  * Sets owner of obj (i.e. calls owner.autoDispose(obj)) unless owner is null. Returns obj.
186
211
  */
187
212
  export declare function setDisposeOwner<T extends IDisposable>(owner: IDisposableOwnerT<T> | null, obj: T): T;
188
- /**
189
- * Internal class that keeps track of one item of the DisposalList. It mimicks emit.Listener, but
190
- * reports and swallows erros when it calls the callbacks in the list.
191
- */
192
- declare class DisposeListener extends LLink implements IDisposable {
193
- private callback;
194
- private context?;
195
- static callAll(begin: LLink, end: LLink, owner: Disposable): void;
196
- constructor(callback: () => void, context?: any);
197
- dispose(): void;
198
- }
199
- export {};
@@ -1,105 +1,97 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setDisposeOwner = exports.MultiHolder = exports.Holder = exports.Disposable = void 0;
4
+ const emit_1 = require("./emit");
5
+ // Internal "owner" of disposable objects which doesn't actually dispose or keep track of them. It
6
+ // is the effective owner when creating a Disposable with `new Foo()` rather than `Foo.create()`.
7
+ const _noopOwner = {
8
+ autoDispose(obj) { },
9
+ };
10
+ // Newly-created Disposable instances will have this as their owner. This is not a constant, it
11
+ // is used by create() for the safe creation of Disposables.
12
+ let _defaultDisposableOwner = _noopOwner;
2
13
  /**
3
- * dispose.js provides tools to objects that needs to dispose resources, such as destroy DOM, and
4
- * unsubscribe from events. The motivation with examples is presented here:
14
+ * Base class for disposable objects that can own other objects.
5
15
  *
6
- * https://phab.getgrist.com/w/disposal/
16
+ * For background and motivation, see [Disposables](/dispose).
7
17
  *
8
- * Disposable is a class for components that need cleanup (e.g. maintain DOM, listen to events,
9
- * subscribe to anything). It provides a .dispose() method that should be called to destroy the
10
- * component, and .onDispose()/.autoDispose() methods that the component should use to take
18
+ * `Disposable` is a class for components that need cleanup (e.g. maintain DOM, listen to events,
19
+ * subscribe to anything). It provides a `.dispose()` method that should be called to destroy the
20
+ * component, and `.onDispose()` / `.autoDispose()` methods that the component should use to take
11
21
  * responsibility for other pieces that require cleanup.
12
22
  *
13
23
  * To define a disposable class:
14
- * class Foo extends Disposable { ... }
24
+ * ```ts
25
+ * class Foo extends Disposable { ... }
26
+ * ```
15
27
  *
16
- * To create Foo:
17
- * const foo = Foo.create(owner, ...args);
28
+ * To create `Foo`:
29
+ * ```ts
30
+ * const foo = Foo.create(owner, ...args);
31
+ * ```
18
32
  * This is better than `new Foo` for two reasons:
19
- * 1. If Foo's constructor throws an exception, any disposals registered in that constructor
33
+ * 1. If `Foo`'s constructor throws an exception, any disposals registered in that constructor
20
34
  * before the exception are honored.
21
35
  * 2. It ensures you specify the owner of the new instance (but you can use null to skip it).
22
36
  *
23
- * In Foo's constructor (or rarely methods), take ownership of other Disposable objects:
24
- * this.bar = Bar.create(this, ...);
37
+ * In `Foo`'s constructor (or rarely methods), take ownership of other Disposable objects:
38
+ * ```ts
39
+ * this.bar = Bar.create(this, ...);
40
+ * ```
25
41
  *
26
42
  * For objects that are not instances of Disposable but have a .dispose() methods, use:
27
- * this.bar = this.autoDispose(createSomethingDisposable());
43
+ * ```ts
44
+ * this.bar = this.autoDispose(createSomethingDisposable());
45
+ * ```
28
46
  *
29
47
  * To call a function on disposal (e.g. to add custom disposal logic):
30
- * this.onDispose(() => this.myUnsubscribeAllMethod());
31
- * this.onDispose(this.myUnsubscribeAllMethod, this); // slightly more efficient
48
+ * ```ts
49
+ * this.onDispose(() => this.myUnsubscribeAllMethod());
50
+ * this.onDispose(this.myUnsubscribeAllMethod, this);
51
+ * ```
32
52
  *
33
53
  * To mark this object to be wiped out on disposal (i.e. set all properties to null):
34
- * this.wipeOnDispose();
54
+ * ```ts
55
+ * this.wipeOnDispose();
56
+ * ```
35
57
  * See the documentation of that method for more info.
36
58
  *
37
- * To dispose Foo directly:
38
- * foo.dispose();
39
- * To determine if an object has already been disposed:
40
- * foo.isDisposed()
59
+ * To dispose Foo directly: `foo.dispose()`.
41
60
  *
42
- * If you need to replace an owned object, or release, or dispose it early, use a Holder:
43
- * this._holder = Holder.create(this);
44
- * Bar.create(this._holder, 1); // creates new Bar(1)
45
- * Bar.create(this._holder, 2); // creates new Bar(2) and disposes previous object
46
- * this._holder.clear(); // disposes contained object
47
- * this._holder.release(); // releases contained object
61
+ * To determine if an object has already been disposed: `foo.isDisposed()`.
48
62
  *
49
- * If you need a container for multiple objects and dispose them all together, use a MultiHolder:
50
- * this._mholder = MultiHolder.create(null);
51
- * Bar.create(this._mholder, 1); // create new Bar(1)
52
- * Bar.create(this._mholder, 2); // create new Bar(2)
53
- * this._mholder.dispose(); // disposes both objects
63
+ * If you need to replace an owned object, or release, or dispose it early, use a
64
+ * [`Holder`](#Holder) or [`MultiHolder`](#MultiHolder).
54
65
  *
55
- * If creating your own class with a dispose() method, do NOT throw exceptions from dispose().
56
- * These cannot be handled properly in all cases. Read here about the same issue in C++:
57
- * http://bin-login.name/ftp/pub/docs/programming_languages/cpp/cffective_cpp/MAGAZINE/SU_FRAME.HTM#destruct
66
+ * If creating your own class with a `dispose()` method, do NOT throw exceptions from `dispose()`.
67
+ * These cannot be handled properly in all cases.
58
68
  *
59
69
  * Using a parametrized (generic) class as a Disposable is tricky. E.g.
60
- * class Bar<T> extends Disposable { ... }
61
- * // Bar<T>.create(...) <-- doesn't work
62
- * // Bar.create<T>(...) <-- doesn't work
63
- * // Bar.create(...) <-- works, but with {} for Bar's type parameters
70
+ * ```ts
71
+ * class Bar<T> extends Disposable { ... }
72
+ * // Bar<T>.create(...) <-- doesn't work
73
+ * // Bar.create<T>(...) <-- doesn't work
74
+ * // Bar.create(...) <-- works, but with {} for Bar's type parameters
75
+ * ```
64
76
  *
65
77
  * The solution is to expose the constructor type using a helper method:
66
- * class Bar<T> extends Disposable {
67
- * // Note the tuple below which must match the constructor parameters of Bar<U>.
68
- * public static ctor<U>(): IDisposableCtor<Bar<U>, [U, boolean]> { return this; }
69
- * constructor(a: T, b: boolean) { ... }
70
- * }
71
- * Bar.ctor<T>().create(...) // <-- works, creates Bar<T>, and does type-checking!
72
- */
73
- Object.defineProperty(exports, "__esModule", { value: true });
74
- exports.setDisposeOwner = exports.MultiHolder = exports.Holder = exports.Disposable = void 0;
75
- const emit_1 = require("./emit");
76
- // Internal "owner" of disposable objects which doesn't actually dispose or keep track of them. It
77
- // is the effective owner when creating a Disposable with `new Foo()` rather than `Foo.create()`.
78
- const _noopOwner = {
79
- autoDispose(obj) { },
80
- };
81
- // Newly-created Disposable instances will have this as their owner. This is not a constant, it
82
- // is used by create() for the safe creation of Disposables.
83
- let _defaultDisposableOwner = _noopOwner;
84
- /**
85
- * Base class for disposable objects that can own other objects. See the module documentation.
78
+ * ```ts
79
+ * class Bar<T> extends Disposable {
80
+ * // Note the tuple below which must match the constructor parameters of Bar<U>.
81
+ * public static ctor<U>(): IDisposableCtor<Bar<U>, [U, boolean]> { return this; }
82
+ * constructor(a: T, b: boolean) { ... }
83
+ * }
84
+ * Bar.ctor<T>().create(...) // <-- works, creates Bar<T>, and does type-checking!
85
+ * ```
86
86
  */
87
87
  class Disposable {
88
- constructor() {
89
- this._disposalList = new DisposalList();
90
- // This registers with a temp Holder when using create(), and is a no-op when using `new Foo`.
91
- _defaultDisposableOwner.autoDispose(this);
92
- // Be sure to reset to no-op, so that a (non-recommended) direct call like 'new Bar()', from
93
- // inside Foo's constructor doesn't use the same Holder that's temporarily holding Foo.
94
- _defaultDisposableOwner = _noopOwner;
95
- }
96
88
  /**
97
89
  * Create Disposable instances using `Class.create(owner, ...)` rather than `new Class(...)`.
98
90
  *
99
91
  * This reminds you to provide an owner, and ensures that if the constructor throws an
100
- * exception, dispose() gets called to clean up the partially-constructed object.
92
+ * exception, `dispose()` gets called to clean up the partially-constructed object.
101
93
  *
102
- * Owner may be null if intend to ensure disposal some other way.
94
+ * Owner may be `null` if you intend to ensure disposal some other way.
103
95
  */
104
96
  static create(owner, ...args) {
105
97
  const origDefaultOwner = _defaultDisposableOwner;
@@ -127,12 +119,20 @@ class Disposable {
127
119
  _defaultDisposableOwner = origDefaultOwner;
128
120
  }
129
121
  }
130
- /** Take ownership of obj, and dispose it when this.dispose() is called. */
122
+ constructor() {
123
+ this._disposalList = new DisposalList();
124
+ // This registers with a temp Holder when using create(), and is a no-op when using `new Foo`.
125
+ _defaultDisposableOwner.autoDispose(this);
126
+ // Be sure to reset to no-op, so that a (non-recommended) direct call like 'new Bar()', from
127
+ // inside Foo's constructor doesn't use the same Holder that's temporarily holding Foo.
128
+ _defaultDisposableOwner = _noopOwner;
129
+ }
130
+ /** Take ownership of `obj`, and dispose it when `this.dispose()` is called. */
131
131
  autoDispose(obj) {
132
132
  this.onDispose(obj.dispose, obj);
133
133
  return obj;
134
134
  }
135
- /** Call the given callback when this.dispose() is called. */
135
+ /** Call the given callback when `this.dispose()` is called. */
136
136
  onDispose(callback, context) {
137
137
  return this._disposalList.addListener(callback, context);
138
138
  }
@@ -141,10 +141,13 @@ class Disposable {
141
141
  * recommended to call this early in the constructor.
142
142
  *
143
143
  * This makes disposal more costly, but has certain benefits:
144
+ *
144
145
  * - If anything still refers to the object and uses it, we'll get an early error, rather than
145
146
  * silently keep going, potentially doing useless work (or worse) and wasting resources.
147
+ *
146
148
  * - If anything still refers to the object (even without using it), the fields of the object
147
149
  * can still be garbage-collected.
150
+ *
148
151
  * - If there are circular references involving this object, they get broken, making the job
149
152
  * easier for the garbage collector.
150
153
  *
@@ -161,7 +164,7 @@ class Disposable {
161
164
  return this._disposalList === null;
162
165
  }
163
166
  /**
164
- * Clean up `this` by disposing all owned objects, and calling onDispose() callbacks, in reverse
167
+ * Clean up `this` by disposing all owned objects, and calling `onDispose()` callbacks, in reverse
165
168
  * order to that in which they were added.
166
169
  */
167
170
  dispose() {
@@ -191,17 +194,31 @@ class Disposable {
191
194
  exports.Disposable = Disposable;
192
195
  /**
193
196
  * Holder keeps a single disposable object. If given responsibility for another object using
194
- * holder.autoDispose() or Foo.create(holder, ...), it automatically disposes the currently held
197
+ * `holder.autoDispose()` or `Foo.create(holder, ...)`, it automatically disposes the currently held
195
198
  * object. It also disposes it when the holder itself is disposed.
196
199
  *
197
- * If the object is an instance of Disposable, the holder will also notice when the object gets
200
+ * If the object is an instance of `Disposable`, the holder will also notice when the object gets
198
201
  * disposed from outside of it, in which case the holder will become empty again.
202
+ *
203
+ * If you need a container for multiple objects and dispose them all together, use a `MultiHolder`:
204
+ *
205
+ * :::info Example
206
+ * ```ts
207
+ * this._holder = Holder.create(this);
208
+ * Bar.create(this._holder, 1); // creates new Bar(1), assuming it's a Disposable
209
+ * Bar.create(this._holder, 2); // creates new Bar(2) and disposes previous object
210
+ * this._holder.clear(); // disposes contained object
211
+ * this._holder.release(); // releases contained object
212
+ * ```
213
+ * :::
199
214
  */
200
215
  class Holder {
201
216
  constructor() {
217
+ /** @internal */
202
218
  this._owned = null;
203
219
  this._disposalListener = undefined;
204
220
  }
221
+ /** `Holder.create(owner)` creates a new `Holder`. */
205
222
  static create(owner) {
206
223
  return setDisposeOwner(owner, new Holder());
207
224
  }
@@ -251,9 +268,18 @@ class Holder {
251
268
  }
252
269
  exports.Holder = Holder;
253
270
  /**
254
- * MultiHolder keeps multiple disposable object. It disposes all held object when the holder
255
- * itself is disposed. It's actually nothing more than the Disposable base class itself, just
271
+ * `MultiHolder` keeps multiple disposable objects. It disposes all held object when the holder
272
+ * itself is disposed. It's actually nothing more than the `Disposable` base class itself, just
256
273
  * exposed with a clearer name that describes its purpose.
274
+ *
275
+ * :::info Example
276
+ * ```ts
277
+ * this._mholder = MultiHolder.create(null);
278
+ * Bar.create(this._mholder, 1); // create new Bar(1)
279
+ * Bar.create(this._mholder, 2); // create new Bar(2)
280
+ * this._mholder.dispose(); // disposes both objects
281
+ * ```
282
+ * :::
257
283
  */
258
284
  class MultiHolder extends Disposable {
259
285
  }
@@ -303,11 +329,6 @@ class DisposalList extends emit_1.LLink {
303
329
  * reports and swallows erros when it calls the callbacks in the list.
304
330
  */
305
331
  class DisposeListener extends emit_1.LLink {
306
- constructor(callback, context) {
307
- super();
308
- this.callback = callback;
309
- this.context = context;
310
- }
311
332
  static callAll(begin, end, owner) {
312
333
  while (begin !== end) {
313
334
  const lis = begin;
@@ -321,6 +342,11 @@ class DisposeListener extends emit_1.LLink {
321
342
  begin = lis._next;
322
343
  }
323
344
  }
345
+ constructor(callback, context) {
346
+ super();
347
+ this.callback = callback;
348
+ this.context = context;
349
+ }
324
350
  dispose() {
325
351
  if (this.isDisposed()) {
326
352
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"dispose.js","sourceRoot":"","sources":["../../../lib/dispose.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispose.js","sourceRoot":"","sources":["../../../lib/dispose.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,3 @@
1
- /**
2
- * dom.js provides a way to build a DOM tree easily.
3
- *
4
- * E.g.
5
- * import {dom} from 'grainjs';
6
- * dom('a#link.c1.c2', {'href': url}, 'Hello ', dom('span', 'world'));
7
- * creates Node <a id="link" class="c1 c2" href={{url}}Hello <span>world</span></a>.
8
- *
9
- * dom.frag(dom('span', 'Hello'), ['blah', dom('div', 'world')])
10
- * creates document fragment with <span>Hello</span>blah<div>world</div>.
11
- *
12
- * DOM can also be created and modified inline during creation:
13
- * dom('a#id.c1',
14
- * dom.cls('c2'), dom.attr('href', url),
15
- * dom.text('Hello '), dom('span', dom.text('world')))
16
- * creates Node <a id="link" class="c1 c2" href={{url}}Hello <span>world</span></a>,
17
- * identical to the first example above.
18
- */
19
1
  export * from './domImpl';
20
2
  export * from './domComponent';
21
3
  export * from './domComputed';
@@ -31,6 +13,44 @@ import * as _domImpl from './domImpl';
31
13
  import * as _domMethods from './domMethods';
32
14
  import * as domevent from './domevent';
33
15
  import { IDomArgs, TagElem, TagName } from './domImpl';
16
+ /**
17
+ * `dom()` provides a way to build a DOM tree easily.
18
+ *
19
+ * The first argument is a string consisting of a lowercase tag name (e.g. `"div"`), with optional
20
+ * `"#foo"` suffix to add the ID `'foo'`, and zero or more `".bar"` suffixes to add a CSS class
21
+ * `'bar'`.
22
+ *
23
+ * The rest of the arguments are optional and may be any number, of these types:
24
+ *
25
+ * @param Nodes - become children of the created element
26
+ * @param strings - become text node children
27
+ * @param objects - Literal objects to set string attributes on the element.
28
+ * E.g. `{title: "foo"}`.
29
+ * @param null - The values `null` and `undefined` values are ignored completely.
30
+ * @param Arrays - flattened with each item processed recursively
31
+ * @param functions - called with the element being built as the argument, for a chance to modify
32
+ * the element as it's being created. Return values are processed recursively.
33
+ * @param functions - "dom methods" are a expressions such as `dom.attr('href', url)` or
34
+ * `dom.hide(obs)`, which are special cases of the "functions" category.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import {dom} from 'grainjs';
39
+ * dom('a', {href: url, className: 'myclass'}, 'Hello ', dom('strong', 'world'));
40
+ * ```
41
+ * creates HTML element `<a href={{url}} class="myclass">Hello <strong>world</strong></a>`.
42
+ *
43
+ * @example
44
+ * Here's an example equivalent to the one above, using dom methods `dom.cls`, `dom.attr`,
45
+ * `dom.text`. In reality, these methods are useful with observable values rather than constant
46
+ * strings.
47
+ * ```ts
48
+ * dom('a', dom.attr('href', url), dom.cls('myclass'),
49
+ * dom.text('Hello '), dom('strong', dom.text('world')));
50
+ * ```
51
+ *
52
+ * @see [DOM & Observables](/basics).
53
+ */
34
54
  export declare function dom<Tag extends TagName>(tagString: Tag, ...args: IDomArgs<TagElem<Tag>>): TagElem<Tag>;
35
55
  export declare namespace dom {
36
56
  const svg: typeof _domImpl.svg;