@raf-query/core 0.11.1 → 0.13.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.
- package/CHANGELOG.md +39 -1
- package/README.md +28 -18
- package/dist/client.d.mts +163 -119
- package/dist/client.mjs +90 -162
- package/dist/entry.d.mts +73 -147
- package/dist/entry.mjs +314 -471
- package/dist/features/focus-refetch/focus-refetch.d.mts +17 -0
- package/dist/features/focus-refetch/focus-refetch.mjs +20 -0
- package/dist/features/polling/polling.d.mts +16 -0
- package/dist/features/polling/polling.mjs +39 -0
- package/dist/features/reconnect-refetch/reconnect-refetch.d.mts +17 -0
- package/dist/features/reconnect-refetch/reconnect-refetch.mjs +16 -0
- package/dist/features/shared.mjs +13 -0
- package/dist/guards.mjs +23 -0
- package/dist/hydration/hydration.d.mts +108 -0
- package/dist/hydration/hydration.mjs +142 -0
- package/dist/index.d.mts +19 -13
- package/dist/index.mjs +16 -13
- package/dist/infinite/infinite.d.mts +83 -0
- package/dist/infinite/infinite.mjs +120 -0
- package/dist/infinite/paging.d.mts +71 -0
- package/dist/infinite/paging.mjs +62 -0
- package/dist/internal.d.mts +13 -0
- package/dist/internal.mjs +7 -0
- package/dist/keys/keys.d.mts +54 -0
- package/dist/keys/keys.mjs +53 -0
- package/dist/keys/targets.d.mts +62 -0
- package/dist/keys/targets.mjs +85 -0
- package/dist/links/retry/retry.d.mts +33 -0
- package/dist/links/retry/retry.mjs +53 -0
- package/dist/links/timeout/timeout.d.mts +17 -0
- package/dist/links/timeout/timeout.mjs +35 -0
- package/dist/load.d.mts +149 -0
- package/dist/load.mjs +179 -0
- package/dist/options.d.mts +161 -332
- package/dist/options.mjs +28 -40
- package/dist/presets.d.mts +35 -0
- package/dist/presets.mjs +27 -0
- package/dist/root.d.mts +86 -0
- package/dist/structural-sharing/structural-sharing.mjs +32 -0
- package/dist/subscribe.d.mts +15 -0
- package/dist/subscribe.mjs +29 -0
- package/dist/thenable.d.mts +15 -17
- package/dist/thenable.mjs +25 -6
- package/dist/verbs.d.mts +150 -0
- package/dist/verbs.mjs +115 -0
- package/package.json +13 -9
- package/dist/_virtual/_rolldown/runtime.mjs +0 -13
- package/dist/all-keyed.d.mts +0 -18
- package/dist/all-keyed.mjs +0 -19
- package/dist/binding.d.mts +0 -92
- package/dist/binding.mjs +0 -186
- package/dist/cache.d.mts +0 -164
- package/dist/cache.mjs +0 -184
- package/dist/controls.d.mts +0 -95
- package/dist/controls.mjs +0 -70
- package/dist/hydration.d.mts +0 -84
- package/dist/hydration.mjs +0 -148
- package/dist/infinite.d.mts +0 -5
- package/dist/infinite.mjs +0 -103
- package/dist/key.d.mts +0 -18
- package/dist/key.mjs +0 -36
- package/dist/listen.mjs +0 -19
- package/dist/notify.mjs +0 -21
- package/dist/observer.d.mts +0 -110
- package/dist/observer.mjs +0 -300
- package/dist/platform.d.mts +0 -27
- package/dist/platform.mjs +0 -44
- package/dist/query.d.mts +0 -137
- package/dist/query.mjs +0 -147
- package/dist/request.mjs +0 -47
- package/dist/retry.mjs +0 -25
- package/dist/share.mjs +0 -40
package/dist/observer.d.mts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { QueryKey } from "./key.mjs";
|
|
2
|
-
import { DataOf, QueryFactory } from "./options.mjs";
|
|
3
|
-
import { Thenable } from "./thenable.mjs";
|
|
4
|
-
import { Query, query_d_exports } from "./query.mjs";
|
|
5
|
-
import { Effect, Pipeable, Stream } from "effect";
|
|
6
|
-
declare namespace observer_d_exports {
|
|
7
|
-
export { Options, QueryObserver, Result$1 as Result, ResultKey, TypeId, changes, get, getOptimisticResultUnsafe, getUnsafe, isQueryObserver, make, makeUnsafe, setOptionsUnsafe, subscribeUnsafe, trackProp, trackResult, trackThenable };
|
|
8
|
-
}
|
|
9
|
-
export declare const TypeId = "~@raf-query/core/QueryObserver";
|
|
10
|
-
export type TypeId = typeof TypeId;
|
|
11
|
-
/** How one reader observes its query. */
|
|
12
|
-
export interface Options {
|
|
13
|
-
/** Refetch on this interval (ms) while subscribed and the page is visible. */
|
|
14
|
-
readonly refetchInterval?: number;
|
|
15
|
-
/** Refetch on reconnect while stale. Default: the query's option, else `true`. */
|
|
16
|
-
readonly refetchOnReconnect?: boolean;
|
|
17
|
-
/** Refetch on window focus while stale. Default: the query's option, else `true`. */
|
|
18
|
-
readonly refetchOnWindowFocus?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* What to show while the query has no data yet:
|
|
21
|
-
* - `"suspend"` (default): the result's promise is the query's pending one.
|
|
22
|
-
* - `"previous"`: keep the last observed query's data, with `isPrevious`.
|
|
23
|
-
*/
|
|
24
|
-
readonly whilePending?: "previous" | "suspend";
|
|
25
|
-
}
|
|
26
|
-
/** What a reader sees of its query. Replaced, never mutated, on every change. */
|
|
27
|
-
interface Result$1<TData = unknown> {
|
|
28
|
-
/** Error of the last failed request. Existing data stays readable. */
|
|
29
|
-
readonly error: unknown;
|
|
30
|
-
/** The query's `fetchNextPage`. */
|
|
31
|
-
readonly fetchNextPage: Effect.Effect<void>;
|
|
32
|
-
/** The query's `fetchPreviousPage`. */
|
|
33
|
-
readonly fetchPreviousPage: Effect.Effect<void>;
|
|
34
|
-
/** Stable string form of the observed query's key. */
|
|
35
|
-
readonly hash: string;
|
|
36
|
-
readonly hasNextPage: boolean;
|
|
37
|
-
readonly hasPreviousPage: boolean;
|
|
38
|
-
/** Input of the data in `promise`; differs from the query's while `isPrevious`. */
|
|
39
|
-
readonly input: unknown;
|
|
40
|
-
/** A request is in flight: first load, new input, or background refetch. */
|
|
41
|
-
readonly isFetching: boolean;
|
|
42
|
-
readonly isFetchingNextPage: boolean;
|
|
43
|
-
readonly isFetchingPreviousPage: boolean;
|
|
44
|
-
/** No data yet for the observed query. */
|
|
45
|
-
readonly isPending: boolean;
|
|
46
|
-
/** `promise` holds a previous query's data (`whilePending: "previous"`). */
|
|
47
|
-
readonly isPrevious: boolean;
|
|
48
|
-
/** The data is older than `staleTime`, or was invalidated. */
|
|
49
|
-
readonly isStale: boolean;
|
|
50
|
-
/** Key of the data in `promise`; differs from the query's while `isPrevious`. */
|
|
51
|
-
readonly key: QueryKey;
|
|
52
|
-
/** Settles with the data to show; see `Query.State.promise`. */
|
|
53
|
-
readonly promise: Thenable<TData>;
|
|
54
|
-
/** The query's `refetch`. */
|
|
55
|
-
readonly refetch: Effect.Effect<void>;
|
|
56
|
-
/** When the data in `promise` was fetched (ms since epoch); `0` before that. */
|
|
57
|
-
readonly updatedAt: number;
|
|
58
|
-
}
|
|
59
|
-
export type ResultKey = keyof Result$1;
|
|
60
|
-
/** An observer of a factory's queries; its results hold the factory's {@link DataOf}. */
|
|
61
|
-
export interface QueryObserver<TFactory extends QueryFactory = QueryFactory> extends Pipeable.Pipeable {
|
|
62
|
-
/** The options set by the latest `make` or {@link setOptionsUnsafe}. */
|
|
63
|
-
readonly options: Options;
|
|
64
|
-
/** The observed query. */
|
|
65
|
-
readonly query: Query<TFactory>;
|
|
66
|
-
readonly [TypeId]: {
|
|
67
|
-
readonly _A: (_: never) => DataOf<TFactory>;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
export declare function isQueryObserver(value: unknown): value is QueryObserver;
|
|
71
|
-
/** Observe `query`. Doesn't subscribe to it until the observer has a listener. */
|
|
72
|
-
export declare function makeUnsafe<TFactory extends QueryFactory>(query: Query<TFactory>, options?: Options): QueryObserver<TFactory>;
|
|
73
|
-
/** {@link makeUnsafe}, as an Effect. */
|
|
74
|
-
export declare function make<TFactory extends QueryFactory>(query: Query<TFactory>, options?: Options): Effect.Effect<QueryObserver<TFactory>>;
|
|
75
|
-
/** The current result. */
|
|
76
|
-
export declare function getUnsafe<TFactory extends QueryFactory>(self: QueryObserver<TFactory>): Result$1<DataOf<TFactory>>;
|
|
77
|
-
/** {@link getUnsafe}, as an Effect. */
|
|
78
|
-
export declare function get<TFactory extends QueryFactory>(self: QueryObserver<TFactory>): Effect.Effect<Result$1<DataOf<TFactory>>>;
|
|
79
|
-
/**
|
|
80
|
-
* The result for `query` with `options` right now, without switching to
|
|
81
|
-
* them. Bindings call this during render, before `setOptionsUnsafe` commits.
|
|
82
|
-
*/
|
|
83
|
-
export declare function getOptimisticResultUnsafe<TFactory extends QueryFactory>(self: QueryObserver<TFactory>, query: Query<TFactory>, options: Options): Result$1<DataOf<TFactory>>;
|
|
84
|
-
/** Observe `query` with `options` from now on. */
|
|
85
|
-
export declare function setOptionsUnsafe<TFactory extends QueryFactory>(self: QueryObserver<TFactory>, query: Query<TFactory>, options: Options): void;
|
|
86
|
-
/** Listen for result changes. The first listener subscribes to the query. */
|
|
87
|
-
export declare function subscribeUnsafe<TFactory extends QueryFactory>(self: QueryObserver<TFactory>, listener: () => void): () => void;
|
|
88
|
-
/**
|
|
89
|
-
* The current result, then every change listeners are notified of. Counts
|
|
90
|
-
* as a listener while the stream runs, so the query counts as read.
|
|
91
|
-
*/
|
|
92
|
-
export declare function changes<TFactory extends QueryFactory>(self: QueryObserver<TFactory>): Stream.Stream<Result$1<DataOf<TFactory>>>;
|
|
93
|
-
/**
|
|
94
|
-
* Wrap `result` so that reading a property marks it tracked. Once any
|
|
95
|
-
* property is tracked, listeners are only notified when a tracked one
|
|
96
|
-
* changes.
|
|
97
|
-
*/
|
|
98
|
-
export declare function trackResult<TFactory extends QueryFactory, TResult extends Result$1<DataOf<TFactory>>>(self: QueryObserver<TFactory>, result: TResult): TResult;
|
|
99
|
-
/**
|
|
100
|
-
* Wrap `promise`, the result's or one derived from it, so that reading its
|
|
101
|
-
* `status`, `value` or `reason` marks its settling as tracked. A first load
|
|
102
|
-
* settles its promise in place, without a new promise, so only readers of
|
|
103
|
-
* those fields need to hear about it. The mark is the wrapper's, shared by
|
|
104
|
-
* the observers that hand it out.
|
|
105
|
-
*/
|
|
106
|
-
export declare function trackThenable<TFactory extends QueryFactory, TThenable extends Thenable<unknown>>(self: QueryObserver<TFactory>, promise: TThenable): TThenable;
|
|
107
|
-
/** Mark `name` as read, for bindings that track access themselves. */
|
|
108
|
-
export declare function trackProp<TFactory extends QueryFactory>(self: QueryObserver<TFactory>, name: ResultKey): void;
|
|
109
|
-
//#endregion
|
|
110
|
-
export { Result$1 as Result, observer_d_exports };
|
package/dist/observer.mjs
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
-
import { listen } from "./listen.mjs";
|
|
3
|
-
import { Platform } from "./platform.mjs";
|
|
4
|
-
import { entryOf } from "./entry.mjs";
|
|
5
|
-
import { fetchNextPage, fetchPreviousPage, getUnsafe as getUnsafe$1, hasNextPageUnsafe, hasPreviousPageUnsafe, refetch, subscribeUnsafe as subscribeUnsafe$1 } from "./query.mjs";
|
|
6
|
-
import { Effect, Exit, FiberHandle, Pipeable, Predicate, Scope } from "effect";
|
|
7
|
-
//#region src/observer.ts
|
|
8
|
-
/**
|
|
9
|
-
* One reader's view of one query at a time, as a data type, like TanStack
|
|
10
|
-
* Query's `QueryObserver`: it derives the reader's result from the query's
|
|
11
|
-
* state, keeps a previous query's data for `whilePending: "previous"`, runs
|
|
12
|
-
* `refetchInterval`, and notifies its listeners only when a result property
|
|
13
|
-
* they read changed (see {@link trackResult}), or a promise whose `status`
|
|
14
|
-
* they read settled (see {@link trackThenable}). Bindings make one per hook.
|
|
15
|
-
*
|
|
16
|
-
* The `*Unsafe` functions read and update synchronously, for renders and
|
|
17
|
-
* external stores. While it has listeners, the observer holds a `Scope` (a
|
|
18
|
-
* child of its query's) that owns the query subscription and the polling
|
|
19
|
-
* fiber; the last listener leaving, a switch to another query, or the query
|
|
20
|
-
* leaving its cache closes it.
|
|
21
|
-
*/
|
|
22
|
-
var observer_exports = /* @__PURE__ */ __exportAll({
|
|
23
|
-
TypeId: () => TypeId,
|
|
24
|
-
changes: () => changes,
|
|
25
|
-
get: () => get,
|
|
26
|
-
getOptimisticResultUnsafe: () => getOptimisticResultUnsafe,
|
|
27
|
-
getUnsafe: () => getUnsafe,
|
|
28
|
-
isQueryObserver: () => isQueryObserver,
|
|
29
|
-
make: () => make,
|
|
30
|
-
makeUnsafe: () => makeUnsafe,
|
|
31
|
-
setOptionsUnsafe: () => setOptionsUnsafe,
|
|
32
|
-
subscribeUnsafe: () => subscribeUnsafe,
|
|
33
|
-
trackProp: () => trackProp,
|
|
34
|
-
trackResult: () => trackResult,
|
|
35
|
-
trackThenable: () => trackThenable
|
|
36
|
-
});
|
|
37
|
-
const TypeId = "~@raf-query/core/QueryObserver";
|
|
38
|
-
const Proto = {
|
|
39
|
-
...Pipeable.Prototype,
|
|
40
|
-
[TypeId]: { _A: (value) => value }
|
|
41
|
-
};
|
|
42
|
-
const resultKeys = {
|
|
43
|
-
error: true,
|
|
44
|
-
fetchNextPage: true,
|
|
45
|
-
fetchPreviousPage: true,
|
|
46
|
-
hash: true,
|
|
47
|
-
hasNextPage: true,
|
|
48
|
-
hasPreviousPage: true,
|
|
49
|
-
input: true,
|
|
50
|
-
isFetching: true,
|
|
51
|
-
isFetchingNextPage: true,
|
|
52
|
-
isFetchingPreviousPage: true,
|
|
53
|
-
isPending: true,
|
|
54
|
-
isPrevious: true,
|
|
55
|
-
isStale: true,
|
|
56
|
-
key: true,
|
|
57
|
-
promise: true,
|
|
58
|
-
refetch: true,
|
|
59
|
-
updatedAt: true
|
|
60
|
-
};
|
|
61
|
-
function isQueryObserver(value) {
|
|
62
|
-
return Predicate.hasProperty(value, TypeId);
|
|
63
|
-
}
|
|
64
|
-
function implOf(self) {
|
|
65
|
-
return self;
|
|
66
|
-
}
|
|
67
|
-
function isResultKey(name) {
|
|
68
|
-
return Predicate.isString(name) && Object.hasOwn(resultKeys, name);
|
|
69
|
-
}
|
|
70
|
-
/** Whether `next.promise` has a different status than it had in the current result. */
|
|
71
|
-
function settled(self, next) {
|
|
72
|
-
return self.currentStatus !== next.promise.status;
|
|
73
|
-
}
|
|
74
|
-
function anyChanged(self, next) {
|
|
75
|
-
return settled(self, next) || Object.keys(resultKeys).some((name) => isResultKey(name) && self.current[name] !== next[name]);
|
|
76
|
-
}
|
|
77
|
-
function setCurrent(self, next) {
|
|
78
|
-
self.current = next;
|
|
79
|
-
self.currentStatus = next.promise.status;
|
|
80
|
-
}
|
|
81
|
-
/** The result for `query` with `options`, given the last query that had data. */
|
|
82
|
-
function resultOf(query, options, lastWithData) {
|
|
83
|
-
const state = getUnsafe$1(query);
|
|
84
|
-
const previous = options.whilePending === "previous" && !state.hasData && state.status !== "error" && lastWithData !== void 0 && lastWithData.hash !== query.hash ? lastWithData : void 0;
|
|
85
|
-
const shown = previous ?? query;
|
|
86
|
-
const shownState = previous ? getUnsafe$1(previous) : state;
|
|
87
|
-
return {
|
|
88
|
-
error: state.error,
|
|
89
|
-
fetchNextPage: fetchNextPage(query),
|
|
90
|
-
fetchPreviousPage: fetchPreviousPage(query),
|
|
91
|
-
hash: query.hash,
|
|
92
|
-
hasNextPage: hasNextPageUnsafe(query),
|
|
93
|
-
hasPreviousPage: hasPreviousPageUnsafe(query),
|
|
94
|
-
input: shown.handle.input,
|
|
95
|
-
isFetching: state.isFetching,
|
|
96
|
-
isFetchingNextPage: state.fetchDirection === "forward",
|
|
97
|
-
isFetchingPreviousPage: state.fetchDirection === "backward",
|
|
98
|
-
isPending: !state.hasData,
|
|
99
|
-
isPrevious: previous !== void 0,
|
|
100
|
-
isStale: state.isStale,
|
|
101
|
-
key: shown.handle.key,
|
|
102
|
-
promise: shownState.promise,
|
|
103
|
-
refetch: refetch(query),
|
|
104
|
-
updatedAt: shownState.updatedAt
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
/** Observe `query`. Doesn't subscribe to it until the observer has a listener. */
|
|
108
|
-
function makeUnsafe(query, options = {}) {
|
|
109
|
-
const current = resultOf(query, options, void 0);
|
|
110
|
-
return Object.assign(Object.create(Proto), {
|
|
111
|
-
current,
|
|
112
|
-
currentStatus: current.promise.status,
|
|
113
|
-
lastWithData: getUnsafe$1(query).hasData ? query : void 0,
|
|
114
|
-
listeners: /* @__PURE__ */ new Set(),
|
|
115
|
-
options,
|
|
116
|
-
query,
|
|
117
|
-
subscription: void 0,
|
|
118
|
-
tracked: void 0,
|
|
119
|
-
trackedProps: /* @__PURE__ */ new Set()
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/** {@link makeUnsafe}, as an Effect. */
|
|
123
|
-
function make(query, options) {
|
|
124
|
-
return Effect.sync(() => makeUnsafe(query, options));
|
|
125
|
-
}
|
|
126
|
-
/** The current result. */
|
|
127
|
-
function getUnsafe(self) {
|
|
128
|
-
return implOf(self).current;
|
|
129
|
-
}
|
|
130
|
-
/** {@link getUnsafe}, as an Effect. */
|
|
131
|
-
function get(self) {
|
|
132
|
-
return Effect.sync(() => getUnsafe(self));
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* The result for `query` with `options` right now, without switching to
|
|
136
|
-
* them. Bindings call this during render, before `setOptionsUnsafe` commits.
|
|
137
|
-
*/
|
|
138
|
-
function getOptimisticResultUnsafe(self, query, options) {
|
|
139
|
-
const impl = implOf(self);
|
|
140
|
-
const result = resultOf(query, options, impl.lastWithData);
|
|
141
|
-
if (anyChanged(impl, result)) setCurrent(impl, result);
|
|
142
|
-
return result;
|
|
143
|
-
}
|
|
144
|
-
/** Observe `query` with `options` from now on. */
|
|
145
|
-
function setOptionsUnsafe(self, query, options) {
|
|
146
|
-
const impl = implOf(self);
|
|
147
|
-
const previous = impl.query;
|
|
148
|
-
const previousInterval = impl.options.refetchInterval;
|
|
149
|
-
impl.query = query;
|
|
150
|
-
impl.options = options;
|
|
151
|
-
if (impl.listeners.size > 0) {
|
|
152
|
-
if (query !== previous) connect(impl);
|
|
153
|
-
else if (options.refetchInterval !== previousInterval) restartPolling(impl);
|
|
154
|
-
}
|
|
155
|
-
updateResult(impl);
|
|
156
|
-
}
|
|
157
|
-
/** Listen for result changes. The first listener subscribes to the query. */
|
|
158
|
-
function subscribeUnsafe(self, listener) {
|
|
159
|
-
const impl = implOf(self);
|
|
160
|
-
impl.listeners.add(listener);
|
|
161
|
-
if (!impl.subscription) {
|
|
162
|
-
connect(impl);
|
|
163
|
-
updateResult(impl);
|
|
164
|
-
}
|
|
165
|
-
return () => {
|
|
166
|
-
if (!impl.listeners.delete(listener) || impl.listeners.size > 0) return;
|
|
167
|
-
disconnect(impl);
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* The current result, then every change listeners are notified of. Counts
|
|
172
|
-
* as a listener while the stream runs, so the query counts as read.
|
|
173
|
-
*/
|
|
174
|
-
function changes(self) {
|
|
175
|
-
return listen((push) => {
|
|
176
|
-
let last;
|
|
177
|
-
const emit = () => {
|
|
178
|
-
const result = getUnsafe(self);
|
|
179
|
-
if (result !== last) {
|
|
180
|
-
last = result;
|
|
181
|
-
push(result);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
const unsubscribe = subscribeUnsafe(self, emit);
|
|
185
|
-
emit();
|
|
186
|
-
return unsubscribe;
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Wrap `result` so that reading a property marks it tracked. Once any
|
|
191
|
-
* property is tracked, listeners are only notified when a tracked one
|
|
192
|
-
* changes.
|
|
193
|
-
*/
|
|
194
|
-
function trackResult(self, result) {
|
|
195
|
-
return new Proxy(result, { get: (target, name, receiver) => {
|
|
196
|
-
if (isResultKey(name)) trackProp(self, name);
|
|
197
|
-
return Reflect.get(target, name, receiver);
|
|
198
|
-
} });
|
|
199
|
-
}
|
|
200
|
-
const settledFields = /* @__PURE__ */ new Set([
|
|
201
|
-
"reason",
|
|
202
|
-
"status",
|
|
203
|
-
"value"
|
|
204
|
-
]);
|
|
205
|
-
/**
|
|
206
|
-
* One wrapper per promise, shared by every observer, so its identity is as
|
|
207
|
-
* stable as the promise's: an observer made by a render that suspended
|
|
208
|
-
* before committing is replaced on the next attempt, and `use()` expects
|
|
209
|
-
* the same promise again.
|
|
210
|
-
*/
|
|
211
|
-
const wrappers = /* @__PURE__ */ new WeakMap();
|
|
212
|
-
/** Wrappers whose `status`, `value` or `reason` a reader has read. */
|
|
213
|
-
const settledReads = /* @__PURE__ */ new WeakSet();
|
|
214
|
-
/**
|
|
215
|
-
* Wrap `promise`, the result's or one derived from it, so that reading its
|
|
216
|
-
* `status`, `value` or `reason` marks its settling as tracked. A first load
|
|
217
|
-
* settles its promise in place, without a new promise, so only readers of
|
|
218
|
-
* those fields need to hear about it. The mark is the wrapper's, shared by
|
|
219
|
-
* the observers that hand it out.
|
|
220
|
-
*/
|
|
221
|
-
function trackThenable(self, promise) {
|
|
222
|
-
let wrapper = wrappers.get(promise);
|
|
223
|
-
if (!wrapper) {
|
|
224
|
-
const created = new Proxy(promise, { get: (target, name) => {
|
|
225
|
-
if (settledFields.has(name)) settledReads.add(created);
|
|
226
|
-
const value = Reflect.get(target, name, target);
|
|
227
|
-
return Predicate.isFunction(value) ? value.bind(target) : value;
|
|
228
|
-
} });
|
|
229
|
-
wrappers.set(promise, created);
|
|
230
|
-
wrapper = created;
|
|
231
|
-
}
|
|
232
|
-
implOf(self).tracked = wrapper;
|
|
233
|
-
return wrapper;
|
|
234
|
-
}
|
|
235
|
-
function readsSettled(self) {
|
|
236
|
-
return self.tracked !== void 0 && settledReads.has(self.tracked);
|
|
237
|
-
}
|
|
238
|
-
/** Mark `name` as read, for bindings that track access themselves. */
|
|
239
|
-
function trackProp(self, name) {
|
|
240
|
-
implOf(self).trackedProps.add(name);
|
|
241
|
-
}
|
|
242
|
-
/** Recompute the result, and notify listeners if a tracked property changed. */
|
|
243
|
-
function updateResult(self) {
|
|
244
|
-
const next = resultOf(self.query, self.options, self.lastWithData);
|
|
245
|
-
if (getUnsafe$1(self.query).hasData) self.lastWithData = self.query;
|
|
246
|
-
if (!anyChanged(self, next)) return;
|
|
247
|
-
const notify = shouldNotify(self, next);
|
|
248
|
-
setCurrent(self, next);
|
|
249
|
-
if (notify) for (const listener of self.listeners) listener();
|
|
250
|
-
}
|
|
251
|
-
/** Whether something tracked differs in `next` from the current result. */
|
|
252
|
-
function shouldNotify(self, next) {
|
|
253
|
-
if (self.trackedProps.size === 0 && !readsSettled(self)) return true;
|
|
254
|
-
if (readsSettled(self) && settled(self, next)) return true;
|
|
255
|
-
for (const name of self.trackedProps) if (self.current[name] !== next[name]) return true;
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Subscribe to the current query in a new scope under its entry's, and
|
|
260
|
-
* start polling. Replaces any previous subscription.
|
|
261
|
-
*/
|
|
262
|
-
function connect(self) {
|
|
263
|
-
disconnect(self);
|
|
264
|
-
const query = self.query;
|
|
265
|
-
const preferences = {
|
|
266
|
-
get refetchOnReconnect() {
|
|
267
|
-
return self.options.refetchOnReconnect;
|
|
268
|
-
},
|
|
269
|
-
get refetchOnWindowFocus() {
|
|
270
|
-
return self.options.refetchOnWindowFocus;
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
const scope = Scope.forkUnsafe(entryOf(query).scope);
|
|
274
|
-
self.subscription = {
|
|
275
|
-
polls: Effect.runSync(FiberHandle.make().pipe(Effect.tap(Effect.acquireRelease(Effect.sync(() => subscribeUnsafe$1(query, () => updateResult(self), preferences)), (unsubscribe) => Effect.sync(unsubscribe))), Scope.provide(scope))),
|
|
276
|
-
scope
|
|
277
|
-
};
|
|
278
|
-
restartPolling(self);
|
|
279
|
-
}
|
|
280
|
-
function disconnect(self) {
|
|
281
|
-
const subscription = self.subscription;
|
|
282
|
-
self.subscription = void 0;
|
|
283
|
-
if (subscription) Effect.runFork(Scope.close(subscription.scope, Exit.void));
|
|
284
|
-
}
|
|
285
|
-
/** Run `poll` for the current `refetchInterval`, or stop polling without one. */
|
|
286
|
-
function restartPolling(self) {
|
|
287
|
-
const subscription = self.subscription;
|
|
288
|
-
if (!subscription) return;
|
|
289
|
-
const interval = self.options.refetchInterval;
|
|
290
|
-
const polls = subscription.polls;
|
|
291
|
-
Effect.runForkWith(entryOf(self.query).cache.services)(interval !== void 0 && Number.isFinite(interval) && interval > 0 ? FiberHandle.run(polls, poll(self.query, interval)) : FiberHandle.clear(polls));
|
|
292
|
-
}
|
|
293
|
-
/** Refetch `query` every `interval` ms while the page is visible. */
|
|
294
|
-
function poll(query, interval) {
|
|
295
|
-
return Effect.gen(function* () {
|
|
296
|
-
if ((yield* Platform).isVisibleUnsafe()) yield* Effect.forkChild(refetch(query), { startImmediately: true });
|
|
297
|
-
}).pipe(Effect.delay(interval), Effect.forever);
|
|
298
|
-
}
|
|
299
|
-
//#endregion
|
|
300
|
-
export { TypeId, changes, get, getOptimisticResultUnsafe, getUnsafe, isQueryObserver, make, makeUnsafe, observer_exports, setOptionsUnsafe, subscribeUnsafe, trackProp, trackResult, trackThenable };
|
package/dist/platform.d.mts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Context, Effect } from "effect";
|
|
2
|
-
declare namespace platform_d_exports {
|
|
3
|
-
export { Platform, PlatformEvent, whenOnline };
|
|
4
|
-
}
|
|
5
|
-
/** `"focus"`: the page became visible. `"online"`: the browser reconnected. */
|
|
6
|
-
export type PlatformEvent = "focus" | "online";
|
|
7
|
-
/**
|
|
8
|
-
* The page a cache runs in: whether there is one, and its focus and network
|
|
9
|
-
* state. The default reads the global `window`, `document` and `navigator`;
|
|
10
|
-
* provide another to run a cache against a fake page.
|
|
11
|
-
*/
|
|
12
|
-
export interface Platform {
|
|
13
|
-
isOnlineUnsafe(): boolean;
|
|
14
|
-
/** No page to watch: a server render. */
|
|
15
|
-
readonly isServer: boolean;
|
|
16
|
-
isVisibleUnsafe(): boolean;
|
|
17
|
-
/** Call `listener` on every focus and reconnect until unsubscribed. */
|
|
18
|
-
subscribeUnsafe(listener: (event: PlatformEvent) => void): () => void;
|
|
19
|
-
}
|
|
20
|
-
export declare const Platform: Context.Reference<Platform>;
|
|
21
|
-
/**
|
|
22
|
-
* Succeeds now if the platform is online, else on its next `"online"` event.
|
|
23
|
-
* Interrupting it unsubscribes.
|
|
24
|
-
*/
|
|
25
|
-
export declare const whenOnline: Effect.Effect<void>;
|
|
26
|
-
//#endregion
|
|
27
|
-
export { platform_d_exports };
|
package/dist/platform.mjs
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
|
-
import { Context, Effect } from "effect";
|
|
3
|
-
//#region src/platform.ts
|
|
4
|
-
var platform_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
-
Platform: () => Platform,
|
|
6
|
-
whenOnline: () => whenOnline
|
|
7
|
-
});
|
|
8
|
-
const globalPlatform = {
|
|
9
|
-
isOnlineUnsafe: () => !("window" in globalThis) || !("navigator" in globalThis) || !("onLine" in navigator) || navigator.onLine,
|
|
10
|
-
get isServer() {
|
|
11
|
-
return !("window" in globalThis);
|
|
12
|
-
},
|
|
13
|
-
isVisibleUnsafe: () => !("document" in globalThis) || document.visibilityState !== "hidden",
|
|
14
|
-
subscribeUnsafe(listener) {
|
|
15
|
-
if (!("window" in globalThis)) return () => {};
|
|
16
|
-
const onVisibilityChange = () => {
|
|
17
|
-
if (document.visibilityState === "visible") listener("focus");
|
|
18
|
-
};
|
|
19
|
-
const onOnline = () => listener("online");
|
|
20
|
-
window.addEventListener("visibilitychange", onVisibilityChange);
|
|
21
|
-
window.addEventListener("online", onOnline);
|
|
22
|
-
return () => {
|
|
23
|
-
window.removeEventListener("visibilitychange", onVisibilityChange);
|
|
24
|
-
window.removeEventListener("online", onOnline);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const Platform = /*#__PURE__*/ Context.Reference("@raf-query/core/Platform", { defaultValue: () => globalPlatform });
|
|
29
|
-
/**
|
|
30
|
-
* Succeeds now if the platform is online, else on its next `"online"` event.
|
|
31
|
-
* Interrupting it unsubscribes.
|
|
32
|
-
*/
|
|
33
|
-
const whenOnline = /*#__PURE__*/ Effect.gen(function* () {
|
|
34
|
-
const platform = yield* Platform;
|
|
35
|
-
if (platform.isOnlineUnsafe()) return;
|
|
36
|
-
yield* Effect.callback((resume) => {
|
|
37
|
-
const unsubscribe = platform.subscribeUnsafe((event) => {
|
|
38
|
-
if (event === "online") resume(Effect.void);
|
|
39
|
-
});
|
|
40
|
-
return Effect.sync(unsubscribe);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
//#endregion
|
|
44
|
-
export { Platform, platform_exports, whenOnline };
|
package/dist/query.d.mts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { QueryKey } from "./key.mjs";
|
|
2
|
-
import { AnyQueryOptions, DataOf, ErrorOf, QueryFactory, QueryHandle, QueryMeta, ServicesOf } from "./options.mjs";
|
|
3
|
-
import { Direction } from "./infinite.mjs";
|
|
4
|
-
import { Thenable } from "./thenable.mjs";
|
|
5
|
-
import { CancelledError as CancelledError$1, DisabledError as DisabledError$1, TypeId as TypeId$1, entry_d_exports } from "./entry.mjs";
|
|
6
|
-
import { Effect, Pipeable, Stream } from "effect";
|
|
7
|
-
declare namespace query_d_exports {
|
|
8
|
-
export { CancelledError, DisabledError, FetchRequest, Query, State, SubscribeOptions, TypeId, changes, fetch, fetchNextPage, fetchPreviousPage, get, getUnsafe, hasNextPageUnsafe, hasPreviousPageUnsafe, invalidate, isQuery, isStaleUnsafe, metaUnsafe, observerCountUnsafe, readUnsafe, refetch, reset, returnsEffectUnsafe, revalidateUnsafe, subscribeUnsafe };
|
|
9
|
-
}
|
|
10
|
-
export declare const TypeId: typeof TypeId$1;
|
|
11
|
-
export type TypeId = typeof TypeId;
|
|
12
|
-
/**
|
|
13
|
-
* A cache entry, typed by the factory whose calls fill it: its data is the
|
|
14
|
-
* factory's {@link DataOf}, its error the factory's {@link ErrorOf}.
|
|
15
|
-
*/
|
|
16
|
-
export interface Query<TFactory extends QueryFactory = QueryFactory> extends Pipeable.Pipeable {
|
|
17
|
-
/** The serializable handle for this entry's factory call. */
|
|
18
|
-
readonly handle: QueryHandle<TFactory>;
|
|
19
|
-
/** Stable string form of `key`. */
|
|
20
|
-
readonly hash: string;
|
|
21
|
-
readonly key: QueryKey;
|
|
22
|
-
/** Options from the latest factory call; `undefined` for an entry only hydrated so far. */
|
|
23
|
-
readonly options: AnyQueryOptions | undefined;
|
|
24
|
-
readonly [TypeId]: {
|
|
25
|
-
readonly _A: (_: never) => DataOf<TFactory>;
|
|
26
|
-
readonly _E: (_: never) => ErrorOf<TFactory>;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/** A snapshot of one cache entry. Replaced, never mutated, on every change. */
|
|
30
|
-
export interface State<TData> {
|
|
31
|
-
/** Last successful data, kept through background errors. */
|
|
32
|
-
readonly data: TData | undefined;
|
|
33
|
-
/** Error of the last failed request, or `null`. */
|
|
34
|
-
readonly error: unknown;
|
|
35
|
-
/** Failed attempts of the current request, retries included. */
|
|
36
|
-
readonly failureCount: number;
|
|
37
|
-
/** Set while a paged query loads a page at one end of the list. */
|
|
38
|
-
readonly fetchDirection: Direction | undefined;
|
|
39
|
-
readonly hasData: boolean;
|
|
40
|
-
/** A request is in flight. */
|
|
41
|
-
readonly isFetching: boolean;
|
|
42
|
-
/** Marked stale by `invalidate`; cleared by the next successful request. */
|
|
43
|
-
readonly isInvalidated: boolean;
|
|
44
|
-
/** Older than `staleTime`, invalidated, or without data. */
|
|
45
|
-
readonly isStale: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Settles with `data`. A new promise is created per data version, already
|
|
48
|
-
* fulfilled once data exists, so it can be read synchronously.
|
|
49
|
-
*/
|
|
50
|
-
readonly promise: Thenable<TData>;
|
|
51
|
-
readonly status: "error" | "pending" | "success";
|
|
52
|
-
/** When `data` was fetched (ms since epoch); `0` without data. */
|
|
53
|
-
readonly updatedAt: number;
|
|
54
|
-
}
|
|
55
|
-
/** Per-reader preferences, registered with {@link subscribeUnsafe}. */
|
|
56
|
-
export interface SubscribeOptions {
|
|
57
|
-
readonly refetchOnReconnect?: boolean;
|
|
58
|
-
readonly refetchOnWindowFocus?: boolean;
|
|
59
|
-
}
|
|
60
|
-
export interface FetchRequest {
|
|
61
|
-
/** Load one more page at this end of a paged query. */
|
|
62
|
-
readonly direction?: Direction;
|
|
63
|
-
/** Pages to load when a paged query has none yet. */
|
|
64
|
-
readonly pages?: number;
|
|
65
|
-
/** Interrupt an in-flight request and start over (used by `invalidate`). */
|
|
66
|
-
readonly restart?: boolean;
|
|
67
|
-
}
|
|
68
|
-
export declare const CancelledError: typeof CancelledError$1;
|
|
69
|
-
export type CancelledError = CancelledError$1;
|
|
70
|
-
export declare const DisabledError: typeof DisabledError$1;
|
|
71
|
-
export type DisabledError = DisabledError$1;
|
|
72
|
-
export declare const isQuery: (value: unknown) => value is Query;
|
|
73
|
-
/**
|
|
74
|
-
* Start a request, or join the one in flight. Fails with the request's
|
|
75
|
-
* error, or a {@link CancelledError} if the entry leaves the cache first.
|
|
76
|
-
* The entry's requests run with this fiber's services from now on, as after
|
|
77
|
-
* a `QueryCache` verb.
|
|
78
|
-
*/
|
|
79
|
-
export declare const fetch: {
|
|
80
|
-
(request?: FetchRequest): <TFactory extends QueryFactory>(self: Query<TFactory>) => Effect.Effect<DataOf<TFactory>, ErrorOf<TFactory> | CancelledError, ServicesOf<TFactory>>;
|
|
81
|
-
<TFactory extends QueryFactory>(self: Query<TFactory>, request?: FetchRequest): Effect.Effect<DataOf<TFactory>, ErrorOf<TFactory> | CancelledError, ServicesOf<TFactory>>;
|
|
82
|
-
};
|
|
83
|
-
/** Refetch now; succeeds when the request settles, whatever its outcome. */
|
|
84
|
-
export declare function refetch<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<void>;
|
|
85
|
-
/** Load the page after the last one; succeeds once it settles. */
|
|
86
|
-
export declare function fetchNextPage<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<void>;
|
|
87
|
-
/** Load the page before the first one; succeeds once it settles. */
|
|
88
|
-
export declare function fetchPreviousPage<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<void>;
|
|
89
|
-
/** Mark stale, and refetch if read; succeeds once that refetch settles. */
|
|
90
|
-
export declare function invalidate<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Drop data and errors, back to the state of a new entry. Readers suspend
|
|
93
|
-
* and refetch; succeeds when that refetch settles.
|
|
94
|
-
*/
|
|
95
|
-
export declare function reset<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<void>;
|
|
96
|
-
/**
|
|
97
|
-
* The query's `meta`: the latest factory call's (the one it was hydrated
|
|
98
|
-
* with, before any), else the cache default's.
|
|
99
|
-
*/
|
|
100
|
-
export declare function metaUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): QueryMeta | undefined;
|
|
101
|
-
/**
|
|
102
|
-
* Whether the query's `queryFn` returns an Effect (`true`) or a promise or
|
|
103
|
-
* plain value (`false`), as of its last call, on this cache or the one its
|
|
104
|
-
* data was hydrated from. `undefined` until one has run. Bindings read typed
|
|
105
|
-
* errors as a `Result` only for Effects.
|
|
106
|
-
*/
|
|
107
|
-
export declare function returnsEffectUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): boolean | undefined;
|
|
108
|
-
/** The entry's current state. */
|
|
109
|
-
export declare function get<TFactory extends QueryFactory>(self: Query<TFactory>): Effect.Effect<State<DataOf<TFactory>>>;
|
|
110
|
-
/** {@link get}, synchronously. */
|
|
111
|
-
export declare function getUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): State<DataOf<TFactory>>;
|
|
112
|
-
/**
|
|
113
|
-
* The entry's current state, then every change. Counts as a reader while
|
|
114
|
-
* the stream runs, so invalidation and focus refetch it.
|
|
115
|
-
*/
|
|
116
|
-
export declare function changes<TFactory extends QueryFactory>(self: Query<TFactory>): Stream.Stream<State<DataOf<TFactory>>>;
|
|
117
|
-
/**
|
|
118
|
-
* The promise a render should unwrap. Starts the first request if nothing
|
|
119
|
-
* has, and retries a failed first load once its error has been shown.
|
|
120
|
-
*/
|
|
121
|
-
export declare function readUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): Thenable<DataOf<TFactory>>;
|
|
122
|
-
/**
|
|
123
|
-
* Refetch cached data in the background if it's stale, as `prefetch` does
|
|
124
|
-
* (on a server cache, only if invalidated). Does nothing without data or
|
|
125
|
-
* while a request is in flight.
|
|
126
|
-
*/
|
|
127
|
-
export declare function revalidateUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): void;
|
|
128
|
-
/** Listen for state changes. Subscribed entries count as read. */
|
|
129
|
-
export declare function subscribeUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>, listener: () => void, options?: SubscribeOptions): () => void;
|
|
130
|
-
/** Staleness as of now; `state.isStale` is only kept current while read. */
|
|
131
|
-
export declare function isStaleUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): boolean;
|
|
132
|
-
export declare function hasNextPageUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): boolean;
|
|
133
|
-
export declare function hasPreviousPageUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): boolean;
|
|
134
|
-
/** Readers currently subscribed. */
|
|
135
|
-
export declare function observerCountUnsafe<TFactory extends QueryFactory>(self: Query<TFactory>): number;
|
|
136
|
-
//#endregion
|
|
137
|
-
export { query_d_exports };
|