shelving 1.181.2 → 1.182.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/api/cache/APICache.d.ts +1 -0
- package/api/cache/APICache.js +8 -6
- package/api/cache/EndpointCache.d.ts +5 -6
- package/api/cache/EndpointCache.js +7 -13
- package/api/endpoint/Endpoint.d.ts +1 -1
- package/api/index.d.ts +0 -1
- package/api/index.js +0 -1
- package/api/provider/APIProvider.d.ts +39 -4
- package/api/provider/APIProvider.js +76 -0
- package/api/provider/MockAPIProvider.d.ts +5 -5
- package/api/provider/MockAPIProvider.js +2 -2
- package/api/provider/ThroughAPIProvider.d.ts +6 -0
- package/api/provider/ThroughAPIProvider.js +15 -0
- package/bun/BunPostgreSQLProvider.d.ts +3 -2
- package/cloudflare/CloudflareD1Provider.d.ts +3 -2
- package/cloudflare/CloudflareKVProvider.d.ts +16 -18
- package/cloudflare/CloudflareKVProvider.js +11 -13
- package/db/cache/CollectionCache.d.ts +37 -0
- package/db/cache/CollectionCache.js +62 -0
- package/db/cache/DBCache.d.ts +38 -0
- package/db/cache/DBCache.js +59 -0
- package/db/collection/Collection.d.ts +12 -10
- package/db/index.d.ts +2 -0
- package/db/index.js +2 -0
- package/db/provider/CacheDBProvider.d.ts +18 -18
- package/db/provider/ChangesDBProvider.d.ts +11 -11
- package/db/provider/DBProvider.d.ts +17 -17
- package/db/provider/DBProvider.js +2 -2
- package/db/provider/DebugDBProvider.d.ts +15 -15
- package/db/provider/MemoryDBProvider.d.ts +28 -26
- package/db/provider/MemoryDBProvider.js +10 -5
- package/db/provider/MockDBProvider.d.ts +17 -17
- package/db/provider/PostgreSQLProvider.d.ts +4 -2
- package/db/provider/PostgreSQLProvider.js +1 -1
- package/db/provider/SQLProvider.d.ts +23 -23
- package/db/provider/SQLProvider.js +24 -23
- package/db/provider/SQLiteProvider.d.ts +6 -2
- package/db/provider/SQLiteProvider.js +14 -1
- package/db/provider/ThroughDBProvider.d.ts +19 -19
- package/db/provider/ValidationDBProvider.d.ts +14 -14
- package/db/provider/ValidationDBProvider.js +4 -8
- package/db/store/QueryStore.d.ts +3 -3
- package/firestore/client/FirestoreClientProvider.d.ts +21 -15
- package/firestore/client/FirestoreClientProvider.js +40 -37
- package/firestore/lite/FirestoreLiteProvider.d.ts +21 -15
- package/firestore/lite/FirestoreLiteProvider.js +38 -29
- package/firestore/server/FirestoreServerProvider.d.ts +21 -15
- package/firestore/server/FirestoreServerProvider.js +67 -71
- package/package.json +1 -1
- package/react/createAPIContext.d.ts +4 -2
- package/react/createAPIContext.js +22 -15
- package/react/createDBContext.d.ts +31 -0
- package/react/createDBContext.js +35 -0
- package/react/index.d.ts +1 -2
- package/react/index.js +1 -2
- package/util/http.d.ts +3 -2
- package/util/http.js +6 -6
- package/util/item.d.ts +4 -4
- package/util/query.d.ts +1 -4
- package/util/uri.d.ts +9 -4
- package/util/uri.js +4 -0
- package/api/provider/ClientAPIProvider.d.ts +0 -37
- package/api/provider/ClientAPIProvider.js +0 -51
- package/react/createCacheContext.d.ts +0 -13
- package/react/createCacheContext.js +0 -22
- package/react/createDataContext.d.ts +0 -26
- package/react/createDataContext.js +0 -31
package/util/query.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ImmutableArray } from "./array.js";
|
|
2
2
|
import type { Data, DataPath, LeafData, LeafDataKey } from "./data.js";
|
|
3
|
-
import type { Identifier, Item } from "./item.js";
|
|
4
3
|
/** Query that can be applied to a list of data objects. */
|
|
5
|
-
export type Query<T extends Data> = {
|
|
4
|
+
export type Query<T extends Data = Data> = {
|
|
6
5
|
readonly [K in LeafDataKey<T> as `${K}` | `!${K}`]?: LeafData<T>[K] | ImmutableArray<LeafData<T>[K]> | undefined;
|
|
7
6
|
} & {
|
|
8
7
|
readonly [K in LeafDataKey<T> as `${K}<` | `${K}<=` | `${K}>` | `${K}>=`]?: LeafData<T>[K] | undefined;
|
|
@@ -12,8 +11,6 @@ export type Query<T extends Data> = {
|
|
|
12
11
|
readonly $order?: `${LeafDataKey<T>}` | `!${LeafDataKey<T>}` | undefined | ImmutableArray<`${LeafDataKey<T>}` | `!${LeafDataKey<T>}` | undefined>;
|
|
13
12
|
readonly $limit?: number | undefined;
|
|
14
13
|
};
|
|
15
|
-
/** A set of query constraints for item data. */
|
|
16
|
-
export type ItemQuery<I extends Identifier, T extends Data> = Query<Item<I, T>>;
|
|
17
14
|
/** A single filter that can be applied to a list of data objects. */
|
|
18
15
|
export type QueryFilter = {
|
|
19
16
|
key: DataPath;
|
package/util/uri.d.ts
CHANGED
|
@@ -82,13 +82,18 @@ export declare function withURIParam(url: URL | URLString, key: string, value: u
|
|
|
82
82
|
export declare function withURIParam(url: PossibleURI, key: string, value: unknown, caller?: AnyCaller): URI;
|
|
83
83
|
/**
|
|
84
84
|
* Return a URI with several new params set (or same URI if no changes were made).
|
|
85
|
-
* -
|
|
85
|
+
* - Any params with `undefined` value will be ignored.
|
|
86
|
+
*
|
|
87
|
+
* @param params A set of possible URI params.
|
|
88
|
+
* - If `params` is `null` or `undefined` the same input URL will be returned.
|
|
86
89
|
*
|
|
87
90
|
* @throws `ValueError` if any of the values could not be converted to strings.
|
|
88
91
|
*/
|
|
89
|
-
export declare function withURIParams(url: URL | URLString, params: PossibleURIParams
|
|
90
|
-
export declare function withURIParams(url: PossibleURI, params: PossibleURIParams
|
|
91
|
-
/**
|
|
92
|
+
export declare function withURIParams(url: URL | URLString, params: Nullish<PossibleURIParams>, caller?: AnyCaller): URL;
|
|
93
|
+
export declare function withURIParams(url: PossibleURI, params: Nullish<PossibleURIParams>, caller?: AnyCaller): URI;
|
|
94
|
+
/**
|
|
95
|
+
* Return a URI without one or more params (or same URI if no changes were made).
|
|
96
|
+
*/
|
|
92
97
|
export declare function omitURIParams(url: URL | URLString, ...keys: string[]): URL;
|
|
93
98
|
export declare function omitURIParams(url: PossibleURI, ...keys: string[]): URI;
|
|
94
99
|
/** Return a URI without a param (or same URI if no changes were made). */
|
package/util/uri.js
CHANGED
|
@@ -110,6 +110,8 @@ export function withURIParam(url, key, value, caller = withURIParam) {
|
|
|
110
110
|
}
|
|
111
111
|
export function withURIParams(url, params, caller = withURIParams) {
|
|
112
112
|
const input = requireURI(url, caller);
|
|
113
|
+
if (!params)
|
|
114
|
+
return input;
|
|
113
115
|
const output = new URI(input);
|
|
114
116
|
for (const [key, str] of getURIEntries(params, caller))
|
|
115
117
|
output.searchParams.set(key, str);
|
|
@@ -117,6 +119,8 @@ export function withURIParams(url, params, caller = withURIParams) {
|
|
|
117
119
|
}
|
|
118
120
|
export function omitURIParams(url, ...keys) {
|
|
119
121
|
const input = requireURI(url, omitURIParams);
|
|
122
|
+
if (!keys.length)
|
|
123
|
+
return input;
|
|
120
124
|
const output = new URI(input);
|
|
121
125
|
for (const key of keys)
|
|
122
126
|
output.searchParams.delete(key);
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { AnyCaller } from "../../util/function.js";
|
|
2
|
-
import { type RequestOptions } from "../../util/http.js";
|
|
3
|
-
import { type PossibleURL, type URLString } from "../../util/url.js";
|
|
4
|
-
import type { Endpoint } from "../endpoint/Endpoint.js";
|
|
5
|
-
import type { APIProvider } from "./APIProvider.js";
|
|
6
|
-
/** Options for an `APIProvider`. */
|
|
7
|
-
export interface ClientAPIProviderOptions {
|
|
8
|
-
/** The common base URL for all rendered endpoint requests. */
|
|
9
|
-
readonly url: PossibleURL;
|
|
10
|
-
/** Options used for HTTP requests created with `this.getRequest()` and `this.fetch()` */
|
|
11
|
-
readonly options?: RequestOptions;
|
|
12
|
-
}
|
|
13
|
-
/** Provider for API endpoints rooted at a common base URL. */
|
|
14
|
-
export declare class ClientAPIProvider implements APIProvider {
|
|
15
|
-
/** The common base URL for all rendered endpoint requests. */
|
|
16
|
-
readonly url: URLString;
|
|
17
|
-
/** Default options used for HTTP requests created with `this.getRequest()` and `this.fetch()` */
|
|
18
|
-
readonly options: RequestOptions;
|
|
19
|
-
constructor({ url, options }: ClientAPIProviderOptions);
|
|
20
|
-
/**
|
|
21
|
-
* Create a `Request` that targets this endpoint with a given base URL.
|
|
22
|
-
* - Path `{placeholders}` are rendered from the payload.
|
|
23
|
-
* - For `GET` and `HEAD`, remaining payload fields are appended as `?query` params.
|
|
24
|
-
* - For all other requests, payload is sent as the body.
|
|
25
|
-
*
|
|
26
|
-
* @throws {RequiredError} if this endpoint's path has `{placeholders}` but `payload` is not a data object.
|
|
27
|
-
* @throws {RequiredError} if this is a `HEAD` or `GET` request but `payload` is not a data object.
|
|
28
|
-
*/
|
|
29
|
-
getRequest<P, R>(endpoint: Endpoint<P, R>, payload: P, options?: RequestOptions, caller?: AnyCaller): Request;
|
|
30
|
-
/**
|
|
31
|
-
* Parse an HTTP `Response` for this endpoint.
|
|
32
|
-
* - Non-2xx responses become `ResponseError`.
|
|
33
|
-
* - Does not validate the result against the endpoint schema — use `ValidationAPIProvider` for that.
|
|
34
|
-
*/
|
|
35
|
-
parseResponse<P, R>(_endpoint: Endpoint<P, R>, response: Response, caller?: AnyCaller): Promise<R>;
|
|
36
|
-
fetch<P, R>(endpoint: Endpoint<P, R>, payload: P, options?: RequestOptions, caller?: AnyCaller): Promise<R>;
|
|
37
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ResponseError } from "../../error/ResponseError.js";
|
|
2
|
-
import { getMessage } from "../../util/error.js";
|
|
3
|
-
import { getRequest, getResponseContent, mergeRequestOptions } from "../../util/http.js";
|
|
4
|
-
import { omitProps } from "../../util/object.js";
|
|
5
|
-
import { requireBaseURL, requireURL } from "../../util/url.js";
|
|
6
|
-
/** Provider for API endpoints rooted at a common base URL. */
|
|
7
|
-
export class ClientAPIProvider {
|
|
8
|
-
/** The common base URL for all rendered endpoint requests. */
|
|
9
|
-
url;
|
|
10
|
-
/** Default options used for HTTP requests created with `this.getRequest()` and `this.fetch()` */
|
|
11
|
-
options;
|
|
12
|
-
constructor({ url, options = {} }) {
|
|
13
|
-
this.url = requireBaseURL(url, undefined, ClientAPIProvider);
|
|
14
|
-
this.options = options;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Create a `Request` that targets this endpoint with a given base URL.
|
|
18
|
-
* - Path `{placeholders}` are rendered from the payload.
|
|
19
|
-
* - For `GET` and `HEAD`, remaining payload fields are appended as `?query` params.
|
|
20
|
-
* - For all other requests, payload is sent as the body.
|
|
21
|
-
*
|
|
22
|
-
* @throws {RequiredError} if this endpoint's path has `{placeholders}` but `payload` is not a data object.
|
|
23
|
-
* @throws {RequiredError} if this is a `HEAD` or `GET` request but `payload` is not a data object.
|
|
24
|
-
*/
|
|
25
|
-
getRequest(endpoint, payload, options, caller = this.getRequest) {
|
|
26
|
-
// Render the path into the base URL.
|
|
27
|
-
const url = requireURL(`.${endpoint.renderPath(payload, caller)}`, requireBaseURL(this.url, undefined, caller), caller).href;
|
|
28
|
-
// Placeholders are rendered into the path so get omitted from the body payload.
|
|
29
|
-
if (endpoint.placeholders.length)
|
|
30
|
-
return getRequest(endpoint.method, url, omitProps(payload, ...endpoint.placeholders), options);
|
|
31
|
-
// No placeholders.
|
|
32
|
-
return getRequest(endpoint.method, url, payload, options);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Parse an HTTP `Response` for this endpoint.
|
|
36
|
-
* - Non-2xx responses become `ResponseError`.
|
|
37
|
-
* - Does not validate the result against the endpoint schema — use `ValidationAPIProvider` for that.
|
|
38
|
-
*/
|
|
39
|
-
async parseResponse(_endpoint, response, caller = this.parseResponse) {
|
|
40
|
-
const { ok, status } = response;
|
|
41
|
-
const content = await getResponseContent(response, caller);
|
|
42
|
-
if (!ok)
|
|
43
|
-
throw new ResponseError(getMessage(content) ?? `Error ${status}`, { code: status, cause: response, caller });
|
|
44
|
-
return content;
|
|
45
|
-
}
|
|
46
|
-
async fetch(endpoint, payload, options, caller = this.fetch) {
|
|
47
|
-
const request = this.getRequest(endpoint, payload, mergeRequestOptions(this.options, options), caller);
|
|
48
|
-
const response = await fetch(request);
|
|
49
|
-
return this.parseResponse(endpoint, response, caller);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type ReactElement, type ReactNode } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Create a cache context that can be provided to React elements and allows them to call `useCache()`
|
|
4
|
-
* - Cache is a `Map` indexed by strings that can be used to store any value.
|
|
5
|
-
*/
|
|
6
|
-
export declare function createCacheContext<T>(): {
|
|
7
|
-
/** Wrap around a set of elements to provide the cache to them. */
|
|
8
|
-
readonly CacheContext: ({ children }: {
|
|
9
|
-
children: ReactNode;
|
|
10
|
-
}) => ReactElement;
|
|
11
|
-
/** Use the current cache map in a component. */
|
|
12
|
-
readonly useCache: () => Map<string, T>;
|
|
13
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext } from "react";
|
|
3
|
-
import { UnexpectedError } from "../error/UnexpectedError.js";
|
|
4
|
-
import { useMap } from "./useMap.js";
|
|
5
|
-
/**
|
|
6
|
-
* Create a cache context that can be provided to React elements and allows them to call `useCache()`
|
|
7
|
-
* - Cache is a `Map` indexed by strings that can be used to store any value.
|
|
8
|
-
*/
|
|
9
|
-
export function createCacheContext() {
|
|
10
|
-
const Context = createContext(undefined);
|
|
11
|
-
const useCache = () => {
|
|
12
|
-
const cache = useContext(Context);
|
|
13
|
-
if (!cache)
|
|
14
|
-
throw new UnexpectedError("useCache() must be used inside <CacheContext>", { caller: useCache });
|
|
15
|
-
return cache;
|
|
16
|
-
};
|
|
17
|
-
const CacheContext = ({ children }) => {
|
|
18
|
-
const cache = useMap();
|
|
19
|
-
return _jsx(Context, { value: cache, children: children });
|
|
20
|
-
};
|
|
21
|
-
return { useCache, CacheContext };
|
|
22
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { ReactElement, ReactNode } from "react";
|
|
2
|
-
import type { Collection } from "../db/collection/Collection.js";
|
|
3
|
-
import type { DBProvider } from "../db/provider/DBProvider.js";
|
|
4
|
-
import { ItemStore } from "../db/store/ItemStore.js";
|
|
5
|
-
import { QueryStore } from "../db/store/QueryStore.js";
|
|
6
|
-
import type { Data } from "../util/data.js";
|
|
7
|
-
import type { Identifier } from "../util/item.js";
|
|
8
|
-
import type { Nullish } from "../util/null.js";
|
|
9
|
-
import type { ItemQuery } from "../util/query.js";
|
|
10
|
-
export interface DataContext<I extends Identifier = Identifier> {
|
|
11
|
-
/** Get an `ItemStore` for the specified collection item in the current `DataProvider` context and subscribe to any changes in it. */
|
|
12
|
-
useItem<T extends Data>(this: void, collection: Collection<string, I, T>, id: I): ItemStore<I, T>;
|
|
13
|
-
useItem<T extends Data>(this: void, collection: Nullish<Collection<string, I, T>>, id: Nullish<I>): ItemStore<I, T> | undefined;
|
|
14
|
-
/** Get an `QueryStore` for the specified collection query in the current `DataProvider` context and subscribe to any changes in it. */
|
|
15
|
-
useQuery<T extends Data>(this: void, collection: Collection<string, I, T>, query: ItemQuery<I, T>): QueryStore<I, T>;
|
|
16
|
-
useQuery<T extends Data>(this: void, collection: Nullish<Collection<string, I, T>>, query: Nullish<ItemQuery<I, T>>): QueryStore<I, T> | undefined;
|
|
17
|
-
readonly DataContext: ({ children }: {
|
|
18
|
-
children: ReactNode;
|
|
19
|
-
}) => ReactElement;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Create a data context
|
|
23
|
-
* - Allows React elements to call `useItem()` and `useQuery()` to access items/queries in a database provider.
|
|
24
|
-
* - If the database has a `CacheDBProvider` in its chain then in-memory data will be used in the returned stores.
|
|
25
|
-
*/
|
|
26
|
-
export declare function createDataContext<I extends Identifier = Identifier>(provider: DBProvider<I>): DataContext<I>;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { CacheDBProvider } from "../db/provider/CacheDBProvider.js";
|
|
2
|
-
import { ItemStore } from "../db/store/ItemStore.js";
|
|
3
|
-
import { QueryStore } from "../db/store/QueryStore.js";
|
|
4
|
-
import { setMapItem } from "../util/map.js";
|
|
5
|
-
import { getSource } from "../util/source.js";
|
|
6
|
-
import { createCacheContext } from "./createCacheContext.js";
|
|
7
|
-
import { useStore } from "./useStore.js";
|
|
8
|
-
/**
|
|
9
|
-
* Create a data context
|
|
10
|
-
* - Allows React elements to call `useItem()` and `useQuery()` to access items/queries in a database provider.
|
|
11
|
-
* - If the database has a `CacheDBProvider` in its chain then in-memory data will be used in the returned stores.
|
|
12
|
-
*/
|
|
13
|
-
export function createDataContext(provider) {
|
|
14
|
-
// biome-ignore lint/suspicious/noExplicitAny: The outer function enforces the type.
|
|
15
|
-
const { CacheContext, useCache } = createCacheContext();
|
|
16
|
-
// If this provider is backed by an in-memory cache, pass it to the `ItemStore` and `QueryStore` instances we create.
|
|
17
|
-
const memory = getSource(CacheDBProvider, provider)?.memory;
|
|
18
|
-
return {
|
|
19
|
-
useItem: (collection, id) => {
|
|
20
|
-
const cache = useCache();
|
|
21
|
-
const key = collection && id && `${collection.name}/${id}`;
|
|
22
|
-
return useStore(key ? cache.get(key) || setMapItem(cache, key, new ItemStore(collection, id, provider, memory)) : undefined);
|
|
23
|
-
},
|
|
24
|
-
useQuery: (collection, query) => {
|
|
25
|
-
const cache = useCache();
|
|
26
|
-
const key = collection && query && `${collection.name}?${JSON.stringify(query)}`;
|
|
27
|
-
return useStore(key ? cache.get(key) || setMapItem(cache, key, new QueryStore(collection, query, provider, memory)) : undefined);
|
|
28
|
-
},
|
|
29
|
-
DataContext: CacheContext,
|
|
30
|
-
};
|
|
31
|
-
}
|