Skip to content

Commit 6e8381f

Browse files
committed
add api.cleanup for solid.js, sinuous,etc
1 parent 8d99948 commit 6e8381f

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ Defines how to check if a value is a signal or observable. This is where you ide
149149

150150
Specifies how to retrieve the current value from a signal or observable. This function is where you define how to extract the current value from your reactive signal (e.g., v?.value or v?.()).
151151

152+
- **api.cleanup()**
153+
154+
Provides a function to handle cleanup logic. This can be used to define any custom cleanup behavior required when a subscription is no longer needed.
155+
152156
### Example API Customization
153157

154158
### Any source
@@ -163,7 +167,7 @@ export let v =
163167
? cb.splice.bind(cb, cb.push(c) - 1, 1, 0)
164168
: cb.map((f) => f && f((v = c)));
165169

166-
api.any = (target) => (next, error, complete) => target?.(v => next(v));
170+
api.any = (target) => (next, error, complete) => target?.((v) => next(v));
167171

168172
const num = v(42);
169173
let off = sub(num)(console.log);
@@ -176,11 +180,12 @@ num(30);
176180
### Solidjs
177181
178182
```js
179-
const { createSignal, createEffect } = require("solid-js");
183+
const { createSignal, createEffect, cleanup } = require("solid-js");
180184

181185
api.effect = createEffect;
182186
api.is = (v) => v?.name?.includes("readSignal");
183187
api.get = (v) => v?.();
188+
api.cleanup = cleanup; //optional
184189

185190
const [val, setVal] = createSignal(0);
186191

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "usub",
33
"description": "Subscribe to any reactive sources",
4-
"version": "0.2.1",
4+
"version": "0.2.2",
55
"type": "module",
66
"source": "./src/index.js",
77
"main": "./dist/index.js",

src/index.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ Symbol.observable ||= Symbol('observable');
55
const
66
registry = new FinalizationRegistry((unsub) => {
77
if (!unsub?._) {
8-
unsub.call?.();
8+
unsub?.call?.();
99
}
1010
}),
1111
// Utility function to handle unsubscription and complete callback
12-
unsubr = (unsub, complete, out) => (
13-
unsub && (out = () => (unsub?.call ? unsub() : unsub?.unsubscribe?.(), out._ = true, complete?.()))
12+
unsubr = (unsub, cleanup, out) => (
13+
unsub && (out = () => (unsub?.call ? unsub() : unsub?.unsubscribe?.(), out._ = true, cleanup?.()))
1414
),
1515

1616
// API object providing basic functions for handling effects and values
1717
api = {
18+
// Handle any reactive subscription
1819
any: undefined,
20+
// If any cleanup is requested
21+
cleanup: undefined,
1922
// Executes the provided function
2023
effect: (f) => f(),
2124
// Returns false for any value (placeholder implementation)
@@ -32,33 +35,32 @@ const
3235
arg[Symbol.observable] || // Observable symbol
3336
arg[Symbol.asyncIterator] || // Async iterator
3437
arg.then || // Promise
35-
arg.call || // Function
38+
(target?.call && !api?.any) || // Function
3639
arg.subscribe || // Observable with subscribe method
3740
api.is(arg) // Custom observable check
3841
),
39-
40-
sub = (target, stop, unsub) => (next, error, complete) => target && (
41-
unsub = unsubr((target[Symbol.observable]?.() || target).subscribe?.((v) => next(get(v)), error, complete), complete) ||
42-
((target.call || api.is(target)) && api.effect(() => next(get(target)))) ||
42+
sub = (target, stop, unsub) => (next, error, cleanup) => target && (
43+
unsub = unsubr((target[Symbol.observable]?.() || target).subscribe?.((v) => next(get(v)), error, cleanup), cleanup) ||
44+
(((target?.call && !api?.any) || api.is(target)) && api.effect(() => (next(get(target)), api?.cleanup?.(cleanup) || cleanup))) ||
4345
(
44-
target.then?.(v => (!stop && next(get(v)), complete?.()), error) ||
46+
target.then?.(v => (!stop && next(get(v)), cleanup?.()), error) ||
4547
target[Symbol.asyncIterator] && (async v => {
4648
try {
4749
// FIXME: possible drawback: it will catch error happened in next, not only in iterator
4850
for await (v of target) { if (stop) return; next(get(v)) }
49-
complete?.()
51+
cleanup?.()
5052
} catch (err) { error?.(err) }
5153
})()
5254
) && (_ => stop = 1) ||
53-
(api?.any?.(target)?.(next, error, complete)),
55+
(api?.any?.(target)?.(next, error, cleanup)),
5456
// register autocleanup
5557
registry.register(target, unsub),
5658
unsub
5759
);
5860

5961
export {
60-
is,
6162
api,
63+
is,
6264
sub,
6365
get
6466
}

0 commit comments

Comments
 (0)