@livequery/react 2.0.30 → 2.0.92

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.
@@ -0,0 +1,23 @@
1
+ import { LivequeryCollection, LivequeryCore, type Doc, type LivequeryCollectionOptions } from "@livequery/core";
2
+ /**
3
+ * Returns the `LivequeryCore` instance from the nearest provider.
4
+ */
5
+ export declare const useLivequeryCore: () => LivequeryCore;
6
+ /**
7
+ * Provides a `LivequeryCore` instance to all descendants that use this package's hooks.
8
+ */
9
+ export declare const LivequeryCoreProvider: import("react").FC<import("react").PropsWithChildren<{
10
+ core: LivequeryCore;
11
+ }>>;
12
+ /**
13
+ * Creates and initializes a `LivequeryCollection` for the supplied collection path.
14
+ *
15
+ * The collection instance is stable for the lifetime of the component. Initialization is
16
+ * skipped when `ref` is falsy.
17
+ *
18
+ * @param ref Collection path understood by `@livequery/core`.
19
+ * @param options Collection options forwarded to `LivequeryCollection`.
20
+ * @returns A stable `LivequeryCollection` instance.
21
+ */
22
+ export declare const useCollection: <T extends Doc>(ref: string | undefined | "" | null | false, options?: Partial<LivequeryCollectionOptions<T>>) => LivequeryCollection<T>;
23
+ //# sourceMappingURL=useCollection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollection.d.ts","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,KAAK,GAAG,EAAE,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AAQ/G;;GAEG;AACH,eAAO,MAAM,gBAAgB,qBAA0B,CAAA;AAEvD;;GAEG;AACH,eAAO,MAAM,qBAAqB;UAXd,aAAa;GAW2B,CAAA;AAE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,GAAG,EAAE,KAAK,MAAM,GAAG,SAAS,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,UAAS,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAM,2BAY7I,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { type Doc } from "@livequery/core";
2
+ /**
3
+ * Subscribes to a single document path and returns the first emitted item with loading state.
4
+ *
5
+ * Internally this hook creates a `LivequeryCollection`, initializes it with the document ref,
6
+ * then reads the first item from the collection stream.
7
+ *
8
+ * @param ref Document path understood by `@livequery/core`.
9
+ * @param options Collection options used when creating the backing collection.
10
+ * @returns A tuple of `[document, loading]`.
11
+ */
12
+ export declare const useDocument: <T extends Doc>(ref: string | undefined | "" | null | false, options?: {
13
+ lazy?: boolean;
14
+ }) => readonly [import("@livequery/core").LivequeryDocument<import("@livequery/core").DocState<T>> | undefined, import("@livequery/core").LivequeryLoadingState];
15
+ //# sourceMappingURL=useDocument.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDocument.d.ts","sourceRoot":"","sources":["../src/useDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAK/D;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,GAAG,EAAE,KAAK,MAAM,GAAG,SAAS,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,UAAS;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,+JAqBvH,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolves a process-wide singleton value stored on `globalThis`.
3
+ *
4
+ * The resolver runs only the first time a given key is requested in the current runtime.
5
+ * Later calls with the same key return the cached value.
6
+ *
7
+ * @param key Unique key within the package global registry.
8
+ * @param resolver Lazy factory used when the value does not exist yet.
9
+ * @returns The cached or newly created value.
10
+ */
11
+ export declare const useGlobalValue: <T>(key: string, resolver: () => T) => T;
12
+ //# sourceMappingURL=useGlobalValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGlobalValue.d.ts","sourceRoot":"","sources":["../src/useGlobalValue.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,KAAK,MAAM,EAAE,UAAU,MAAM,CAAC,KAIzB,CACtC,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { Observable, BehaviorSubject } from "rxjs";
2
+ /**
3
+ * Accepts either a value or a lazy factory returning that value.
4
+ */
5
+ export type MaybeFunction<T> = T | (() => T);
6
+ /**
7
+ * Subscribes to an RxJS observable and mirrors its latest value into React state.
8
+ *
9
+ * When a `BehaviorSubject` is provided, the hook uses `getValue()` for the initial render.
10
+ * When a factory is provided, the observable is resolved lazily inside the effect.
11
+ *
12
+ * @param o Observable source or factory returning the source.
13
+ * @param default_value Fallback value used before the first emission when the source is not a `BehaviorSubject`.
14
+ * @returns The latest value emitted by the source.
15
+ */
16
+ export declare const useObservable: <T extends any>(o: MaybeFunction<BehaviorSubject<T> | Observable<T>>, default_value?: T) => T;
17
+ //# sourceMappingURL=useObservable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useObservable.d.ts","sourceRoot":"","sources":["../src/useObservable.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAc,MAAM,MAAM,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AAE5C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,GAAG,EAAE,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,MAgBnH,CAAA"}
package/package.json CHANGED
@@ -4,38 +4,38 @@
4
4
  "url": "https://github.com/livequery/react"
5
5
  },
6
6
  "type": "module",
7
- "version": "2.0.30",
7
+ "version": "2.0.92",
8
8
  "description": "",
9
- "main": "build/index.js",
10
- "types": "build/index.d.ts",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
11
18
  "files": [
12
- "build/**/*"
19
+ "dist/**/*"
13
20
  ],
14
21
  "dependencies": {
15
- "@livequery/client": "^2.0.30",
16
- "rxjs": "^7.8.1"
22
+ "@livequery/core": "^2.0.92",
23
+ "rxjs": "^7.8.2"
17
24
  },
18
25
  "devDependencies": {
19
- "@livequery/types": "^2.0.22",
20
- "@types/react": "^17.0.11",
21
- "typescript": "5.6.3"
26
+ "@types/react": "^19.2.14"
22
27
  },
23
28
  "peerDependencies": {
24
- "react": "^18.3.1"
29
+ "react": "^19.2.5"
25
30
  },
26
31
  "scripts": {
27
- "test": "echo \"Error: no test specified\" && exit 1",
28
- "build": "rm -rf build; tsc -b .",
29
- "deploy": "yarn build; git add .; git commit -m \"Update\"; git push origin master; npm publish --access public"
32
+ "clean": "rm -rf dist",
33
+ "build:js": "bun build ./src/index.ts --outdir ./dist --target browser --format esm --sourcemap",
34
+ "build:types": "bunx tsc -p tsconfig.build.json",
35
+ "build": "bun run clean && bun run build:js && bun run build:types",
36
+ "build:watch": "bun build ./src/index.ts --outdir ./dist --target browser --format esm --watch",
37
+ "prepublishOnly": "bun run build"
30
38
  },
31
39
  "author": "",
32
- "license": "ISC",
33
- "exports": {
34
- ".": {
35
- "import": {
36
- "types": "./build/index.d.ts",
37
- "default": "./build/index.js"
38
- }
39
- }
40
- }
40
+ "license": "ISC"
41
41
  }
@@ -1,11 +0,0 @@
1
- import React, { PropsWithChildren } from 'react';
2
- import { Transporter, TransporterHook } from '@livequery/types';
3
- export type LivequeryContext = {
4
- transporter?: Transporter;
5
- hooks?: TransporterHook[];
6
- };
7
- export declare function mergeTransporterHooks(...hooks: TransporterHook[]): TransporterHook;
8
- export declare const useLivequeryContext: () => {
9
- transporter: Transporter;
10
- };
11
- export declare const LiveQueryContextProvider: (props: PropsWithChildren<LivequeryContext>) => React.JSX.Element;
@@ -1,22 +0,0 @@
1
- "use client";
2
- import React from 'react';
3
- import { createContext, useContext } from "react";
4
- import { pipe } from 'rxjs';
5
- export function mergeTransporterHooks(...hooks) {
6
- return hooks.reduce((p, c) => (next) => p(() => c(next)), (next) => pipe(next()));
7
- }
8
- const LivequeryContext = createContext({});
9
- export const useLivequeryContext = () => {
10
- const ctx = useContext(LivequeryContext);
11
- if (!ctx.transporter && typeof window != 'undefined')
12
- throw 'MISSING_LIVEQUERY_TRANSPORTER';
13
- return {
14
- transporter: ctx.transporter
15
- };
16
- };
17
- export const LiveQueryContextProvider = (props) => {
18
- const ctx = useContext(LivequeryContext);
19
- const merged = mergeTransporterHooks(...props.hooks || []);
20
- const transporter = ctx.transporter ? ctx.transporter.hook(merged) : props.transporter?.hook(merged);
21
- return (React.createElement(LivequeryContext.Provider, { value: { transporter } }, props.children));
22
- };
@@ -1,2 +0,0 @@
1
- import React, { PropsWithChildren } from 'react';
2
- export declare const createContextFromHook: <T, K>(fn: ((props: T) => K) | (() => K)) => [() => K, ({ children, ...props }: PropsWithChildren<T>) => React.JSX.Element];
@@ -1,12 +0,0 @@
1
- "use client";
2
- import React from 'react';
3
- import { createContext, useContext } from "react";
4
- export const createContextFromHook = (fn) => {
5
- const context = createContext({});
6
- const getContext = () => useContext(context);
7
- const Provider = ({ children, ...props }) => {
8
- const value = fn(props);
9
- return (React.createElement(context.Provider, { value: value }, children));
10
- };
11
- return [getContext, Provider];
12
- };
@@ -1,3 +0,0 @@
1
- export declare const createStaticContext: <T extends {}>() => [() => T, ({ children, ...props }: import("react").PropsWithChildren<{
2
- value: T;
3
- }>) => import("react").JSX.Element];
@@ -1,3 +0,0 @@
1
- "use client";
2
- import { createContextFromHook } from './createContextFromHook.js';
3
- export const createStaticContext = () => createContextFromHook((props) => props.value);
package/build/index.d.ts DELETED
@@ -1,6 +0,0 @@
1
- export * from "./useDocumentData.js";
2
- export * from './useCollectionData.js';
3
- export * from './useMonitor.js';
4
- export * from "./LiveQueryContext.js";
5
- export * from './hooks/createContextFromHook.js';
6
- export * from './hooks/createStaticContext.js';
package/build/index.js DELETED
@@ -1,6 +0,0 @@
1
- export * from "./useDocumentData.js";
2
- export * from './useCollectionData.js';
3
- export * from './useMonitor.js';
4
- export * from "./LiveQueryContext.js";
5
- export * from './hooks/createContextFromHook.js';
6
- export * from './hooks/createStaticContext.js';
@@ -1 +0,0 @@
1
- {"root":["../src/index.ts","../src/livequerycontext.tsx","../src/usecollectiondata.ts","../src/usedocumentdata.ts","../src/usemonitor.ts","../src/hooks/createcontextfromhook.tsx","../src/hooks/createstaticcontext.tsx"],"version":"5.6.3"}
@@ -1,21 +0,0 @@
1
- import { LivequeryBaseEntity, QueryOption } from "@livequery/types";
2
- import { CollectionObservable, CollectionOption, CollectionStream } from "@livequery/client";
3
- export type useCollectionDataOptions<T extends LivequeryBaseEntity = LivequeryBaseEntity> = CollectionOption<T> & {
4
- lazy?: boolean;
5
- options: Partial<QueryOption<T>>;
6
- load_all: boolean;
7
- };
8
- export type CollectionRef = string | undefined | '' | null | false;
9
- export type CollectionData<T extends LivequeryBaseEntity> = (CollectionStream<T> & Pick<CollectionObservable<T>, 'add' | 'fetch_more' | 'fetch_prev' | 'reset' | 'trigger' | 'update' | '$changes' | 'filter'> & {
10
- empty: boolean;
11
- ref: CollectionRef;
12
- filters: CollectionStream<T>['options'];
13
- });
14
- export declare const CollectionMap: Map<string, CollectionData<any>>;
15
- export declare const useCollectionData: <T extends LivequeryBaseEntity>(ref: CollectionRef, collection_options?: Partial<useCollectionDataOptions<T>>) => CollectionStream<T> & Pick<CollectionObservable<T>, "add" | "reset" | "filter" | "update" | "fetch_more" | "fetch_prev" | "trigger" | "$changes"> & {
16
- empty: boolean;
17
- ref: CollectionRef;
18
- filters: Partial<QueryOption<T>>;
19
- } & {
20
- state: number;
21
- };
@@ -1,59 +0,0 @@
1
- "use client";
2
- import { useEffect, useMemo, useState } from "react";
3
- import { useLivequeryContext } from "./LiveQueryContext.js";
4
- import { CollectionObservable } from "@livequery/client";
5
- import { Subject } from 'rxjs';
6
- function assert(fn, thiss) {
7
- return (fn || (() => { })).bind(thiss);
8
- }
9
- export const CollectionMap = new Map();
10
- export const useCollectionData = (ref, collection_options = {}) => {
11
- const { transporter } = useLivequeryContext();
12
- const client = useMemo(() => new CollectionObservable(ref, {
13
- ...collection_options,
14
- transporter
15
- }), [ref]);
16
- const [$, set_$] = useState(client.getValue());
17
- const [state, set_state] = useState(0);
18
- // Sync stream effect
19
- useEffect(() => {
20
- if (collection_options.lazy)
21
- return;
22
- client.fetch_more();
23
- const s = client.subscribe(data => {
24
- if (collection_options.load_all && data.paging.has?.next) {
25
- client.fetch_more();
26
- }
27
- else {
28
- set_$(data);
29
- set_state(Date.now());
30
- }
31
- });
32
- return () => {
33
- s.unsubscribe();
34
- };
35
- }, [client, set_$, collection_options.lazy, set_state]);
36
- const empty = !!(!$.loading && $.items.length == 0);
37
- const loading = $.n == 0 && !collection_options.lazy ? 'both' : $.loading;
38
- const result = {
39
- ...$,
40
- loading,
41
- state,
42
- empty,
43
- filters: $.options,
44
- add: assert(client?.add, client),
45
- fetch_more: assert(client?.fetch_more, client),
46
- fetch_prev: assert(client?.fetch_prev, client),
47
- filter: assert(client?.filter, client),
48
- reset: assert(client?.reset, client),
49
- trigger: assert(client?.trigger, client),
50
- update: assert(client?.update, client),
51
- $changes: client?.$changes || new Subject(),
52
- ref
53
- };
54
- useEffect(() => {
55
- ref && CollectionMap.set(ref, result);
56
- return () => { ref && CollectionMap.delete(ref); };
57
- }, [client]);
58
- return result;
59
- };
@@ -1,15 +0,0 @@
1
- import { useCollectionDataOptions } from "./useCollectionData.js";
2
- import { LivequeryBaseEntity } from "@livequery/types";
3
- import { SmartQueryItem } from "@livequery/client";
4
- export type useDocumentDataOptions<T extends LivequeryBaseEntity = LivequeryBaseEntity> = Partial<Omit<useCollectionDataOptions<T>, 'filters'>>;
5
- export declare const useDocumentData: <T extends LivequeryBaseEntity>(ref: string | undefined | "" | null | false, config?: useDocumentDataOptions<T>) => {
6
- item: SmartQueryItem<T>;
7
- error: null;
8
- loading: boolean;
9
- $changes: import("rxjs").Subject<import("@livequery/types").UpdatedData<T>>;
10
- } | {
11
- item: SmartQueryItem<T>;
12
- loading: import("@livequery/client").LoadingIndicator | undefined;
13
- error: boolean | undefined;
14
- $changes: import("rxjs").Subject<import("@livequery/types").UpdatedData<T>>;
15
- };
@@ -1,40 +0,0 @@
1
- "use client";
2
- import { useEffect, useState } from "react";
3
- import { CollectionMap, useCollectionData } from "./useCollectionData.js";
4
- import { filter, tap } from "rxjs";
5
- export const useDocumentData = (ref, config = {}) => {
6
- const [old, set_old] = useState((() => {
7
- if (!ref)
8
- return;
9
- const id = ref.split('/').pop();
10
- const collection_ref = ref.split('/').slice(0, -1).join('/');
11
- const collection = CollectionMap.get(collection_ref);
12
- if (!collection)
13
- return;
14
- const item = collection.items.find(item => item.id == id);
15
- if (!item)
16
- return;
17
- return { collection, item };
18
- })());
19
- useEffect(() => {
20
- if (!old || !old.item || !ref)
21
- return;
22
- const s = old.collection.$changes.pipe(filter(id => id.data.id == old.item.id), tap(d => set_old({ ...old, item: { ...old.item, ...d.data } }))).subscribe();
23
- return () => s.unsubscribe();
24
- }, [ref]);
25
- const { items, loading, error, $changes } = useCollectionData(old ? null : ref, config);
26
- if (old && old.item) {
27
- return {
28
- item: old.item,
29
- error: null,
30
- loading: false,
31
- $changes: old.collection.$changes
32
- };
33
- }
34
- return {
35
- item: items[0],
36
- loading,
37
- error,
38
- $changes
39
- };
40
- };
@@ -1,9 +0,0 @@
1
- type PromiseType<T> = T extends PromiseLike<infer U> ? U : T;
2
- export declare const useMonitor: <T extends (...args: any) => any>(fn: T) => {
3
- excute: T;
4
- loading: boolean | undefined;
5
- data: PromiseType<ReturnType<T>> | null | undefined;
6
- error: any;
7
- vaild: boolean;
8
- };
9
- export {};
@@ -1,16 +0,0 @@
1
- "use client";
2
- import { useState } from "react";
3
- export const useMonitor = (fn) => {
4
- const [{ error, data, loading }, update] = useState({});
5
- const excute = (async (...args) => {
6
- update({ data: null, loading: true, error: null });
7
- try {
8
- update({ data: await fn(...args), error: null, loading: false });
9
- }
10
- catch (error) {
11
- update({ data: null, error, loading: false });
12
- }
13
- });
14
- const vaild = !error && !loading;
15
- return { excute, loading, data, error, vaild };
16
- };