shelving 1.142.0 → 1.143.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.
@@ -1,2 +1,2 @@
1
1
  /** React security symbol — see https://github.com/facebook/react/pull/4832 */
2
- export const REACT_ELEMENT_TYPE = Symbol.for("react.element");
2
+ export const REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element");
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.142.0",
14
+ "version": "1.143.0",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",
@@ -57,19 +57,19 @@
57
57
  "build:test:unit": "bun test ./dist/**/*.test.js --bail"
58
58
  },
59
59
  "devDependencies": {
60
- "@biomejs/biome": "^1.8.3",
61
- "@google-cloud/firestore": "^7.9.0",
62
- "@types/bun": "^1.1.6",
63
- "@types/react": "^18.3.3",
64
- "@types/react-dom": "^18.3.0",
65
- "firebase": "^10.12.5",
66
- "react": "^18.3.1",
67
- "react-dom": "^18.3.1",
68
- "typescript": "^5.8.2"
60
+ "@biomejs/biome": "^1.9.4",
61
+ "@google-cloud/firestore": "^7.11.3",
62
+ "@types/bun": "^1.2.18",
63
+ "@types/react": "^19.1.8",
64
+ "@types/react-dom": "^19.1.6",
65
+ "firebase": "^11.10.0",
66
+ "react": "^19.1.0",
67
+ "react-dom": "^19.1.0",
68
+ "typescript": "^5.8.3"
69
69
  },
70
70
  "peerDependencies": {
71
- "@google-cloud/firestore": ">=4.0.0",
72
- "firebase": ">=9.0.0",
73
- "react": ">=17.0.0"
71
+ "@google-cloud/firestore": ">=7.0.0",
72
+ "firebase": ">=11.0.0",
73
+ "react": ">=19.0.0"
74
74
  }
75
75
  }
@@ -1,21 +1,22 @@
1
- import { createContext, createElement, useContext, useRef } from "react";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
2
3
  import { UnexpectedError } from "../error/UnexpectedError.js";
4
+ import { useMap } from "./useMap.js";
3
5
  /**
4
6
  * Create a cache context that can be provided to React elements and allows them to call `useCache()`
5
7
  * - Cache is a `Map` indexed by strings that can be used to store any value.
6
8
  */
7
9
  export function createCacheContext() {
8
- const context = createContext(undefined);
10
+ const Context = createContext(undefined);
9
11
  const useCache = () => {
10
- const cache = useContext(context);
12
+ const cache = useContext(Context);
11
13
  if (!cache)
12
- throw new UnexpectedError("useCache() must be used inside <Cache>", { caller: useCache });
14
+ throw new UnexpectedError("useCache() must be used inside <CacheContext>", { caller: useCache });
13
15
  return cache;
14
16
  };
15
17
  const CacheContext = ({ children }) => {
16
- // biome-ignore lint/suspicious/noAssignInExpressions: This is the most efficient way to do this.
17
- const cache = (useRef().current ||= new Map());
18
- return createElement(context.Provider, { children, value: cache });
18
+ const cache = useMap();
19
+ return _jsx(Context, { value: cache, children: children });
19
20
  };
20
21
  return { useCache, CacheContext };
21
22
  }
package/react/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./createCacheContext.js";
2
2
  export * from "./createDataContext.js";
3
- export * from "./useInstance.js";
3
+ export * from "./useProps.js";
4
+ export * from "./useMap.js";
4
5
  export * from "./useLazy.js";
5
6
  export * from "./useReduce.js";
6
7
  export * from "./useSequence.js";
package/react/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from "./createCacheContext.js";
2
2
  export * from "./createDataContext.js";
3
- export * from "./useInstance.js";
3
+ export * from "./useProps.js";
4
+ export * from "./useMap.js";
4
5
  export * from "./useLazy.js";
5
6
  export * from "./useReduce.js";
6
7
  export * from "./useSequence.js";
@@ -1,17 +1,16 @@
1
1
  import { isArrayEqual } from "../util/equal.js";
2
- import { useInternals } from "./useInternals.js";
2
+ import { useProps } from "./useProps.js";
3
3
  /**
4
4
  * Use a memoised class instance.
5
5
  * - Creates a new instance of `Constructor` using `args`
6
6
  * - Returns same instance for as long as `args` is equal to previous `args`.
7
7
  */
8
8
  export function useInstance(Constructor, ...args) {
9
- const internals = useInternals();
9
+ const internals = useProps();
10
10
  // Update `internals` if `args` changes or `instance` is not set.
11
- if (!internals.args || !isArrayEqual(args, internals.args)) {
11
+ if (!internals.args || !internals.instance || !isArrayEqual(args, internals.args)) {
12
12
  internals.instance = new Constructor(...args);
13
13
  internals.args = args;
14
14
  }
15
- // biome-ignore lint/style/noNonNullAssertion: We know this is set.
16
15
  return internals.instance;
17
16
  }
package/react/useLazy.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import { isArrayEqual } from "../util/equal.js";
2
2
  import { getLazy } from "../util/lazy.js";
3
- import { useInternals } from "./useInternals.js";
3
+ import { useProps } from "./useProps.js";
4
4
  export function useLazy(value, ...args) {
5
- const internals = useInternals();
5
+ const internals = useProps();
6
6
  // Update `internals` if `args` changes.
7
- if (internals.args === undefined || !isArrayEqual(args, internals.args)) {
7
+ if (!internals.args || !isArrayEqual(args, internals.args)) {
8
8
  internals.value = getLazy(value, ...args);
9
9
  internals.args = args;
10
10
  }
11
- // biome-ignore lint/style/noNonNullAssertion: We know this is set.
12
11
  return internals.value;
13
12
  }
@@ -0,0 +1,2 @@
1
+ /** Create a mutable Map that persist for the lifetime of the component. */
2
+ export declare function useMap<K, V>(): Map<K, V>;
@@ -0,0 +1,8 @@
1
+ import { useRef } from "react";
2
+ /** Create a mutable Map that persist for the lifetime of the component. */
3
+ export function useMap() {
4
+ const ref = useRef(undefined);
5
+ if (!ref.current)
6
+ ref.current = new Map();
7
+ return ref.current;
8
+ }
@@ -0,0 +1,6 @@
1
+ type Mutable<T> = {
2
+ -readonly [K in keyof T]: T[K];
3
+ };
4
+ /** Create an object that persist for the lifetime of the component. */
5
+ export declare function useProps<T>(): Partial<Mutable<T>>;
6
+ export {};
@@ -0,0 +1,5 @@
1
+ import { useRef } from "react";
2
+ /** Create an object that persist for the lifetime of the component. */
3
+ export function useProps() {
4
+ return useRef(undefined);
5
+ }
package/react/useStore.js CHANGED
@@ -2,17 +2,16 @@ import { useSyncExternalStore } from "react";
2
2
  import { NONE } from "../util/constants.js";
3
3
  import { BLACKHOLE } from "../util/function.js";
4
4
  import { runSequence } from "../util/sequence.js";
5
- import { useInternals } from "./useInternals.js";
5
+ import { useProps } from "./useProps.js";
6
6
  export function useStore(store) {
7
7
  // Store memoized versions of `subscribe()` and `getSnapshot()` so `useSyncExternalStore()` doesn't re-subscribe on every render.
8
- const internals = useInternals();
8
+ const internals = useProps();
9
9
  // Update `internals` if `store` changes.
10
- if (store !== internals.store) {
10
+ if (store !== internals.store || !internals.subscribe || !internals.getSnapshot) {
11
11
  internals.subscribe = onStoreChange => (store ? runSequence(store, onStoreChange, onStoreChange) : BLACKHOLE);
12
12
  internals.getSnapshot = () => (!store ? undefined : store.loading ? NONE : store.value);
13
13
  internals.store = store;
14
14
  }
15
- // biome-ignore lint/style/noNonNullAssertion: We know these are set.
16
15
  useSyncExternalStore(internals.subscribe, internals.getSnapshot);
17
16
  return store;
18
17
  }
package/util/source.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { AnyCaller } from "../error/BaseError.js";
1
2
  import type { Class } from "./class.js";
2
3
  /** Something that has a source of a specified type. */
3
4
  export interface Sourceable<T> {
@@ -6,4 +7,4 @@ export interface Sourceable<T> {
6
7
  /** Recurse through `Sourceable` objects and return the first one that is an instance of `type`, or `undefined` if no source object matches. */
7
8
  export declare function getSource<T>(type: Class<T>, value: unknown): T | undefined;
8
9
  /** Recurse through `Sourceable` objects and return the first one that is an instance of `type`, or throw `RequiredError` if no source object matches. */
9
- export declare function requireSource<T>(type: Class<T>, data: unknown): T;
10
+ export declare function requireSource<T>(type: Class<T>, data: unknown, caller?: AnyCaller): T;
package/util/source.js CHANGED
@@ -10,9 +10,9 @@ export function getSource(type, value) {
10
10
  }
11
11
  }
12
12
  /** Recurse through `Sourceable` objects and return the first one that is an instance of `type`, or throw `RequiredError` if no source object matches. */
13
- export function requireSource(type, data) {
13
+ export function requireSource(type, data, caller = requireSource) {
14
14
  const source = getSource(type, data);
15
15
  if (!source)
16
- throw new RequiredError(`Source "${type.name}" not found`, { received: data, expected: type, caller: requireSource });
16
+ throw new RequiredError(`Source "${type.name}" not found`, { received: data, expected: type, caller });
17
17
  return source;
18
18
  }
@@ -1,5 +0,0 @@
1
- import type { Data } from "../util/data.js";
2
- /** Store internal implementation details for a hook that persist for the lifetime of the component. */
3
- export declare const useInternals: <T extends Data>() => T | {
4
- [K in keyof T]: undefined;
5
- };
@@ -1,3 +0,0 @@
1
- import { useRef } from "react";
2
- /** Store internal implementation details for a hook that persist for the lifetime of the component. */
3
- export const useInternals = useRef;