jrx 0.3.0-alpha.6 → 0.3.0-alpha.8
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.
- package/README.md +38 -0
- package/index.d.ts +3 -0
- package/index.js +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ npm i jrx
|
|
|
36
36
|
- [`createTransition(cb, durationMs)`](#createTransitioncb-durationms) - Progress-based animations
|
|
37
37
|
- [`computed(fn, getDeps?)`](#computedfn-getdeps) - Memoized computed values
|
|
38
38
|
- [`retry(cb, backoffSec?)`](#retrycb-backoffsec) - Retry with exponential backoff
|
|
39
|
+
- [`assignDispose(value, disposable)`](#assigndisposevalue-disposable) - Attach a `Symbol.dispose` to any value
|
|
39
40
|
|
|
40
41
|
## Naming convention
|
|
41
42
|
|
|
@@ -305,6 +306,43 @@ const data = await r // undefined
|
|
|
305
306
|
- `cb`: Callback that returns `Disposable & (T | Promise<T>)`. Receives `{ resetBackoff() }` to reset the backoff counter.
|
|
306
307
|
- `backoffSec`: Array of retry delays in seconds. Use `-1` for infinite retries with the last delay. Default: `[5, 5, 10, 10, 20, 20, 40, 40, 60, -1]`
|
|
307
308
|
|
|
309
|
+
### `assignDispose(value, disposable)`
|
|
310
|
+
|
|
311
|
+
Attaches a `Symbol.dispose` to an existing value (object, function, array, promise, etc.) that delegates to a given `Disposable`. Returns the same value, now also typed as `Disposable`.
|
|
312
|
+
|
|
313
|
+
This is useful when a function needs to return a meaningful value **and** be disposable — for example, returning a promise, a function, or a tuple from a factory while still allowing the caller to clean up the underlying resources.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
import {assignDispose} from 'jrx'
|
|
317
|
+
|
|
318
|
+
function makeThing() {
|
|
319
|
+
using stack = new DisposableStack()
|
|
320
|
+
stack.defer(() => console.log('cleanup'))
|
|
321
|
+
|
|
322
|
+
const obj = {value: 42}
|
|
323
|
+
return assignDispose(obj, stack.move())
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Async factory — wrap an in-flight promise so the caller can dispose the underlying resources mid-flight:
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
import {assignDispose} from 'jrx'
|
|
331
|
+
|
|
332
|
+
function loadThing() {
|
|
333
|
+
const stack = new DisposableStack()
|
|
334
|
+
return assignDispose(
|
|
335
|
+
(async () => {
|
|
336
|
+
const res = await fetch('/api/data', {signal: stack.adopt(new AbortController(), c => c.abort()).signal})
|
|
337
|
+
return await res.json()
|
|
338
|
+
})(),
|
|
339
|
+
stack,
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
If `value` is itself a `Disposable`, disposing the returned value disposes `value` first, then `disposable`.
|
|
345
|
+
|
|
308
346
|
## Cleanup Pattern
|
|
309
347
|
|
|
310
348
|
All effect functions return a `Disposable` object that stops the effect and runs any pending cleanup:
|
package/index.d.ts
CHANGED
|
@@ -27,3 +27,6 @@ export declare function createTimeout(cb: () => void, ms: number): {
|
|
|
27
27
|
export declare function createTransition(cb: (progress: number) => undefined | Disposable, durationMs: number): {
|
|
28
28
|
[Symbol.dispose](): void;
|
|
29
29
|
};
|
|
30
|
+
export declare function assignDispose<T extends object>(value: T, disposable: Disposable): T & {
|
|
31
|
+
[Symbol.dispose](): void;
|
|
32
|
+
};
|
package/index.js
CHANGED
|
@@ -128,3 +128,12 @@ export function createTransition(cb, durationMs) {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
export function assignDispose(value, disposable) {
|
|
132
|
+
const valueDispose = value?.[Symbol.dispose]?.bind(value);
|
|
133
|
+
return Object.assign(value, {
|
|
134
|
+
[Symbol.dispose]() {
|
|
135
|
+
valueDispose?.();
|
|
136
|
+
disposable[Symbol.dispose]();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|