Replies: 5 comments 11 replies
-
The main detail that needs to be clarified is how to make this composable? Stuff like makeAbortable needs to apply inside and outside of the It basically looks like this: type RequestContext = {
abortSignal?: AbortSignal,
}
function makeAbortable<Response>(
requestAccessor: Accessor<undefined | RequestInfo | [RequestInfo, RequestInit]>,
requestFetcher: (RequestInfo | [RequestInfo, RequestInit]) => Promise<Response>,
requestContext: RequestContext = {}
) => [
wrappedRequestAccessor: Accessor<undefined | RequestInfo | [RequestInfo, RequestInit]>,
wrappedRequestFetcher: (RequestInfo | [RequestInfo, RequestInit]) => Promise<Response>,
requestContextWithAbortSignal: RequestContext
] This means you can extend the return value into the arguments of the following wrapper, i.e. const resourceContext = {}
const [resource, actions] = createResource(...makeAbortable(...makeCached(...makeRequest(urlAccessor, resourceContext))))
resourceContext.abortSignal.abort()
// or
const [accessor, fetcher, resourceContext] = makeAbortable(...makeCached(...makeRequest(urlAccessor)))
const [resource, actions] = createResource(accessor, fetcher)
resourceContext.abortSignal.abort() Which makes it pretty easy to optionally chain the wrappers. However, chaining them will require them to be always loaded, so I would prefer to make them either optional or asynchronous, which is the next detail to be covered. |
Beta Was this translation helpful? Give feedback.
-
I'm curently considering a change of plan, but that would require a deviation from our naming scheme. A rather elegant way to ensure composition works with tree shaking is to have the functions added as part of the options, i.e. const [resource, actions] = createFetch(urlAccessor, options, [withDebounceRequest(), withAbort(), withRetry(10), withCache(rules)]); As you can see, I invented an external |
Beta Was this translation helpful? Give feedback.
-
The first draft is coming along nicely; I'm currently pondering whether I should make this a breaking change by omitting |
Beta Was this translation helpful? Give feedback.
-
OK, I now have a draft PR open: #131 - I still need to figure out the most efficient caching pattern. |
Beta Was this translation helpful? Give feedback.
-
After some deliberation on the issue, I also found that it would be simple to allow the creation of the request using other methods than fetch, e.g. XMLHttpRequest or axios. The question is how to expose the capability? There are basically two options:
Option 1 has the risk that they'll forget to add the request manually, in which case they'll receive a helpful error message. Option 2 has the drawback of being somewhat confusing with 4 arguments to the call. |
Beta Was this translation helpful? Give feedback.
-
The fetch primitive does its job, but is too tightly integrated and difficult to extend; therefore it should be broken up into smaller composable parts, which then can extend the functionality of Solid's resources:
makeRequest
- creates a resource URL fetcher from RequestInfo/-Init or Accessors thereof, unwraps the response, and also returns signal to get the response objectmakeCached
- wraps resource arguments so the resource will be cached, following certain rules (cache timeout, cache non-200 responses) and gives a setter for manual query invalidation; also allows to cache the data in localStorage or sessionStoragemakeRetry
- wraps resource arguments so requests will be retried a specified number of times with a configurable timeout in between (if the resource is abortable, it should be aborted while paused)makeAbortable
- wraps resource arguments to make the resource abortable with an AbortSignal, also provides a state (boolean or reason) and an abort callbackmakeTimeout
- wraps an abortable resource so it will be automatically aborted after a certain timeoutThis requires a breaking change: since we now useUpdate: that only applies tocreateResource
more directly, we are reliant on the first argument to return a singular value to be fed into our fetcher; so if we have both RequestInfo and RequestInit, it needs to be given as an Array.makeRequest
, not tocreateFetch
, which can still take the previous arguments, though augmented with options in order to compose the other stuff. However, I'd really like for tree shaking to work here, so I need to figure out how to make this configurable.createFetch
will continue to exist and then merely compose the whole structure from these primitives, which allows for more fine-grained tree shaking.There are still a few finer details of the new architecture that need to be specified, so I wanted to start this as a discussion.
Beta Was this translation helpful? Give feedback.
All reactions