@livequery/react 2.0.151 → 2.0.153
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/README.md +38 -0
- package/dist/LivequeryClientContext.d.ts +5 -1
- package/dist/LivequeryClientContext.d.ts.map +1 -1
- package/dist/LivequeryClientContext.js +10 -1
- package/dist/LivequeryClientContext.js.map +1 -1
- package/dist/useCollection.d.ts.map +1 -1
- package/dist/useCollection.js +9 -4
- package/dist/useCollection.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ npm install @livequery/react @livequery/client react rxjs
|
|
|
20
20
|
|
|
21
21
|
- `LivequeryClientProvider`
|
|
22
22
|
- `useLivequeryClient`
|
|
23
|
+
- `useLivequeryContext`
|
|
23
24
|
- `useCollection`
|
|
24
25
|
- `useDocument`
|
|
25
26
|
- `useObservable`
|
|
@@ -74,6 +75,18 @@ Use it when:
|
|
|
74
75
|
|
|
75
76
|
The provider currently expects a `core` prop. Passing `client` will not work unless the implementation is changed.
|
|
76
77
|
|
|
78
|
+
### Provider-level `context`
|
|
79
|
+
|
|
80
|
+
The provider also accepts an optional `context` prop — an arbitrary bag forwarded with every collection operation down to the transporter's `onRequest` hook (see [`@livequery/client` → context](../client/README.md#context)). The canonical use is per-tab multi-account routing: set `{ account_id }` once at the provider and every `useCollection()` below it inherits it.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
<LivequeryClientProvider core={client} context={{ account_id: currentAccountId }}>
|
|
84
|
+
<TodoList />
|
|
85
|
+
</LivequeryClientProvider>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Changing the provider `context` (e.g. switching account) re-creates every descendant collection under the new context — old subscriptions tear down and re-subscribe. A per-call `options.context` on `useCollection` overrides the provider one (shallow merge, per-call wins).
|
|
89
|
+
|
|
77
90
|
### SharedWorker
|
|
78
91
|
|
|
79
92
|
If your app uses a SharedWorker via `@livequery/rpc`, the setup inside the worker is different — but from React's perspective nothing changes. You still construct a `LivequeryClient` and pass it to `LivequeryClientProvider` exactly as shown above. Read the `@livequery/rpc` documentation for how to expose the client from a SharedWorker; the React layer stays the same.
|
|
@@ -95,10 +108,35 @@ export function ClientStatus() {
|
|
|
95
108
|
|
|
96
109
|
The hook must be used under a matching provider. If it is called outside the provider tree, the generated context hook throws `Context provider is missing`.
|
|
97
110
|
|
|
111
|
+
## `useLivequeryContext`
|
|
112
|
+
|
|
113
|
+
`useLivequeryContext()` reads the optional `context` bag passed to `LivequeryClientProvider`. Returns `undefined` when no `context` prop was provided.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { useLivequeryContext } from '@livequery/react'
|
|
117
|
+
|
|
118
|
+
export function CurrentAccount() {
|
|
119
|
+
const context = useLivequeryContext()
|
|
120
|
+
return <span>account: {context?.account_id ?? 'none'}</span>
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Most code never calls this directly — `useCollection()` already merges this provider context into the collections it creates. Use it only when you need to read the active context for display or branching.
|
|
125
|
+
|
|
98
126
|
## `useCollection`
|
|
99
127
|
|
|
100
128
|
`useCollection<T>(ref, options)` creates a `LivequeryCollection<T>` for the current `ref`, initializes it when `ref` is truthy, and returns the collection instance. When `ref` changes, a fresh collection is created — its state is reset and reloaded for the new ref.
|
|
101
129
|
|
|
130
|
+
The collection's `context` is the provider `context` shallow-merged with `options.context` (per-call wins). `useCollection` keys the collection on both `ref` **and** the resolved context, so changing either creates a fresh instance — switching account therefore tears down the old subscription and re-subscribes under the new context.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
// inherits provider context (e.g. { account_id })
|
|
134
|
+
const todos = useCollection<Todo>('todos', { lazy: false })
|
|
135
|
+
|
|
136
|
+
// override / extend context for this collection only
|
|
137
|
+
const orders = useCollection<Order>('orders', { lazy: false, context: { account_id: otherId } })
|
|
138
|
+
```
|
|
139
|
+
|
|
102
140
|
Use it when a component needs the full collection API: reactive state plus methods such as querying or mutations.
|
|
103
141
|
|
|
104
142
|
```tsx
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { LivequeryClient } from "@livequery/client";
|
|
2
|
-
|
|
2
|
+
declare const LivequeryClientProvider: (props: import("react").PropsWithChildren<{
|
|
3
3
|
core: any;
|
|
4
|
+
context?: Record<string, any>;
|
|
4
5
|
}>) => import("react").JSX.Element;
|
|
6
|
+
export { LivequeryClientProvider };
|
|
7
|
+
export declare const useLivequeryClient: () => LivequeryClient;
|
|
8
|
+
export declare const useLivequeryContext: () => Record<string, any> | undefined;
|
|
5
9
|
//# sourceMappingURL=LivequeryClientContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LivequeryClientContext.d.ts","sourceRoot":"","sources":["../src/LivequeryClientContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"LivequeryClientContext.d.ts","sourceRoot":"","sources":["../src/LivequeryClientContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,QAAA,MAAyB,uBAAuB;UAC5B,GAAG;cAAY,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;kCAIrD,CAAA;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAClC,eAAO,MAAM,kBAAkB,uBAAgC,CAAA;AAC/D,eAAO,MAAM,mBAAmB,uCAAmC,CAAA"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import { createContextFromHook } from "./createContextFromHook.js";
|
|
2
|
-
|
|
2
|
+
// The provider now carries both the client (`core`) and an optional `context` —
|
|
3
|
+
// an arbitrary bag forwarded with every collection operation down to the
|
|
4
|
+
// transporter's onRequest hook (e.g. { account_id } for per-tab multi-account).
|
|
5
|
+
const [useLivequeryRoot, LivequeryClientProvider] = createContextFromHook((props) => ({
|
|
6
|
+
core: props.core,
|
|
7
|
+
context: props.context
|
|
8
|
+
}));
|
|
9
|
+
export { LivequeryClientProvider };
|
|
10
|
+
export const useLivequeryClient = () => useLivequeryRoot().core;
|
|
11
|
+
export const useLivequeryContext = () => useLivequeryRoot().context;
|
|
3
12
|
//# sourceMappingURL=LivequeryClientContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LivequeryClientContext.js","sourceRoot":"","sources":["../src/LivequeryClientContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,
|
|
1
|
+
{"version":3,"file":"LivequeryClientContext.js","sourceRoot":"","sources":["../src/LivequeryClientContext.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,gFAAgF;AAChF,yEAAyE;AACzE,gFAAgF;AAChF,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,GAAG,qBAAqB,CACrE,CAAC,KAAmD,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,EAAE,KAAK,CAAC,IAAuB;IACnC,OAAO,EAAE,KAAK,CAAC,OAA0C;CAC5D,CAAC,CACL,CAAA;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAClC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAA;AAC/D,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCollection.d.ts","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,GAAG,EAAE,KAAK,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAMlG,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,
|
|
1
|
+
{"version":3,"file":"useCollection.d.ts","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,GAAG,EAAE,KAAK,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAMlG,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,2BAoB7I,CAAA"}
|
package/dist/useCollection.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { LivequeryCollection } from "@livequery/client";
|
|
2
2
|
import { useMemo, useEffect } from "react";
|
|
3
|
-
import { useLivequeryClient } from "./LivequeryClientContext.js";
|
|
3
|
+
import { useLivequeryClient, useLivequeryContext } from "./LivequeryClientContext.js";
|
|
4
4
|
export const useCollection = (ref, options = {}) => {
|
|
5
5
|
const client = useLivequeryClient();
|
|
6
|
-
//
|
|
7
|
-
|
|
6
|
+
// Provider-level context (e.g. { account_id }); a per-call options.context overrides it.
|
|
7
|
+
const providerContext = useLivequeryContext();
|
|
8
|
+
const context = { ...providerContext, ...options.context };
|
|
9
|
+
const contextKey = JSON.stringify(context);
|
|
10
|
+
// Recreate the collection whenever the ref OR the context changes so each (ref, context)
|
|
11
|
+
// pair gets a fresh, fully-reset instance — switching account re-subscribes under the new
|
|
12
|
+
// context. The client is stable (provided once via context), so it is intentionally NOT a
|
|
8
13
|
// dependency — keying on it would rebuild the collection on every render if a caller ever
|
|
9
14
|
// passed an unstable client.
|
|
10
|
-
const collection = useMemo(() => new LivequeryCollection(client, options), [ref]);
|
|
15
|
+
const collection = useMemo(() => new LivequeryCollection(client, { ...options, context }), [ref, contextKey]);
|
|
11
16
|
useEffect(() => {
|
|
12
17
|
if (!client || !ref)
|
|
13
18
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCollection.js","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAA6C,MAAM,mBAAmB,CAAA;AAClG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"useCollection.js","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAA6C,MAAM,mBAAmB,CAAA;AAClG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAIrF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAgB,GAA2C,EAAE,UAAkD,EAAE,EAAE,EAAE;IAC9I,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,yFAAyF;IACzF,MAAM,eAAe,GAAG,mBAAmB,EAAE,CAAA;IAC7C,MAAM,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1C,yFAAyF;IACzF,0FAA0F;IAC1F,0FAA0F;IAC1F,0FAA0F;IAC1F,6BAA6B;IAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,mBAAmB,CAAI,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAA;IAChH,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG;YAAE,OAAM;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACzC,OAAO,GAAG,EAAE;YACR,MAAM,EAAE,WAAW,EAAE,CAAA;QACzB,CAAC,CAAA;IACL,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAChB,OAAO,UAAU,CAAA;AACrB,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"url": "https://github.com/livequery/react"
|
|
5
5
|
},
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "2.0.
|
|
7
|
+
"version": "2.0.153",
|
|
8
8
|
"description": "",
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
"dist/**/*"
|
|
50
50
|
],
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@livequery/client": "^2.0.
|
|
52
|
+
"@livequery/client": "^2.0.152",
|
|
53
53
|
"@types/bun": "^1.3.14",
|
|
54
54
|
"@types/react": "^19.2.14",
|
|
55
55
|
"@types/react-test-renderer": "^19.1.0",
|
|
56
56
|
"react-test-renderer": "^19.2.6"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@livequery/client": "^2.0.
|
|
59
|
+
"@livequery/client": "^2.0.152",
|
|
60
60
|
"react": "^19.2.5",
|
|
61
61
|
"rxjs": "^7.8.2"
|
|
62
62
|
},
|