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.
Files changed (67) hide show
  1. package/api/cache/APICache.d.ts +1 -0
  2. package/api/cache/APICache.js +8 -6
  3. package/api/cache/EndpointCache.d.ts +5 -6
  4. package/api/cache/EndpointCache.js +7 -13
  5. package/api/endpoint/Endpoint.d.ts +1 -1
  6. package/api/index.d.ts +0 -1
  7. package/api/index.js +0 -1
  8. package/api/provider/APIProvider.d.ts +39 -4
  9. package/api/provider/APIProvider.js +76 -0
  10. package/api/provider/MockAPIProvider.d.ts +5 -5
  11. package/api/provider/MockAPIProvider.js +2 -2
  12. package/api/provider/ThroughAPIProvider.d.ts +6 -0
  13. package/api/provider/ThroughAPIProvider.js +15 -0
  14. package/bun/BunPostgreSQLProvider.d.ts +3 -2
  15. package/cloudflare/CloudflareD1Provider.d.ts +3 -2
  16. package/cloudflare/CloudflareKVProvider.d.ts +16 -18
  17. package/cloudflare/CloudflareKVProvider.js +11 -13
  18. package/db/cache/CollectionCache.d.ts +37 -0
  19. package/db/cache/CollectionCache.js +62 -0
  20. package/db/cache/DBCache.d.ts +38 -0
  21. package/db/cache/DBCache.js +59 -0
  22. package/db/collection/Collection.d.ts +12 -10
  23. package/db/index.d.ts +2 -0
  24. package/db/index.js +2 -0
  25. package/db/provider/CacheDBProvider.d.ts +18 -18
  26. package/db/provider/ChangesDBProvider.d.ts +11 -11
  27. package/db/provider/DBProvider.d.ts +17 -17
  28. package/db/provider/DBProvider.js +2 -2
  29. package/db/provider/DebugDBProvider.d.ts +15 -15
  30. package/db/provider/MemoryDBProvider.d.ts +28 -26
  31. package/db/provider/MemoryDBProvider.js +10 -5
  32. package/db/provider/MockDBProvider.d.ts +17 -17
  33. package/db/provider/PostgreSQLProvider.d.ts +4 -2
  34. package/db/provider/PostgreSQLProvider.js +1 -1
  35. package/db/provider/SQLProvider.d.ts +23 -23
  36. package/db/provider/SQLProvider.js +24 -23
  37. package/db/provider/SQLiteProvider.d.ts +6 -2
  38. package/db/provider/SQLiteProvider.js +14 -1
  39. package/db/provider/ThroughDBProvider.d.ts +19 -19
  40. package/db/provider/ValidationDBProvider.d.ts +14 -14
  41. package/db/provider/ValidationDBProvider.js +4 -8
  42. package/db/store/QueryStore.d.ts +3 -3
  43. package/firestore/client/FirestoreClientProvider.d.ts +21 -15
  44. package/firestore/client/FirestoreClientProvider.js +40 -37
  45. package/firestore/lite/FirestoreLiteProvider.d.ts +21 -15
  46. package/firestore/lite/FirestoreLiteProvider.js +38 -29
  47. package/firestore/server/FirestoreServerProvider.d.ts +21 -15
  48. package/firestore/server/FirestoreServerProvider.js +67 -71
  49. package/package.json +1 -1
  50. package/react/createAPIContext.d.ts +4 -2
  51. package/react/createAPIContext.js +22 -15
  52. package/react/createDBContext.d.ts +31 -0
  53. package/react/createDBContext.js +35 -0
  54. package/react/index.d.ts +1 -2
  55. package/react/index.js +1 -2
  56. package/util/http.d.ts +3 -2
  57. package/util/http.js +6 -6
  58. package/util/item.d.ts +4 -4
  59. package/util/query.d.ts +1 -4
  60. package/util/uri.d.ts +9 -4
  61. package/util/uri.js +4 -0
  62. package/api/provider/ClientAPIProvider.d.ts +0 -37
  63. package/api/provider/ClientAPIProvider.js +0 -51
  64. package/react/createCacheContext.d.ts +0 -13
  65. package/react/createCacheContext.js +0 -22
  66. package/react/createDataContext.d.ts +0 -26
  67. 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
- * - Param with `undefined` value will be ignored.
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, caller?: AnyCaller): URL;
90
- export declare function withURIParams(url: PossibleURI, params: PossibleURIParams, caller?: AnyCaller): URI;
91
- /** Return a URI without one or more params (or same URI if no changes were made). */
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
- }