Skip to content

Commit ac5e0ff

Browse files
committed
feat: add offset and limit to live query.
1 parent a19082b commit ac5e0ff

File tree

2 files changed

+89
-18
lines changed

2 files changed

+89
-18
lines changed

packages/pglite-solid/src/hooks.ts

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ function paramsEqual(
2525
}
2626

2727
type Params = unknown[] | undefined | null
28+
type LimitAndOffset =
29+
| { offset?: never; limit?: never }
30+
| { offset: number; limit: number }
2831

2932
function useLiveQueryImpl<T = { [key: string]: unknown }>(
30-
opts: Accessor<{
31-
query: string | LiveQuery<T> | Promise<LiveQuery<T>>
32-
params?: Params
33-
key?: string
34-
}>,
33+
opts: Accessor<
34+
{
35+
query: string | LiveQuery<T> | Promise<LiveQuery<T>>
36+
params?: Params
37+
key?: string
38+
} & LimitAndOffset
39+
>,
3540
): Accessor<Omit<LiveQueryResults<T>, 'affectedRows'> | undefined> {
3641
const db = usePGlite()
3742
const liveQuery = createMemo(
@@ -67,12 +72,12 @@ function useLiveQueryImpl<T = { [key: string]: unknown }>(
6772
)
6873

6974
const params = createMemo(
70-
(prev) => {
71-
if (!paramsEqual(opts().params, prev as Params)) {
75+
(prev: Params) => {
76+
if (!paramsEqual(opts().params, prev)) {
7277
return opts().params
7378
}
7479

75-
return prev as Params
80+
return prev
7681
},
7782
opts().params,
7883
{ name: 'PGLiteLiveQueryParamsMemo' },
@@ -86,8 +91,19 @@ function useLiveQueryImpl<T = { [key: string]: unknown }>(
8691
const key = opts.key
8792
const ret =
8893
key != undefined
89-
? db.live.incrementalQuery<T>(query, params(), key, setResults)
90-
: db.live.query<T>(query, params(), setResults)
94+
? db.live.incrementalQuery<T>({
95+
query,
96+
callback: setResults,
97+
params: params(),
98+
key,
99+
})
100+
: db.live.query({
101+
query,
102+
callback: setResults,
103+
params: params(),
104+
limit: opts.limit,
105+
offset: opts.offset,
106+
})
91107

92108
const res = await ret
93109
return res
@@ -137,10 +153,12 @@ function useLiveQueryImpl<T = { [key: string]: unknown }>(
137153
}
138154

139155
export function useLiveQuery<T = { [key: string]: unknown }>(
140-
opts: Accessor<{
141-
query: string
142-
params: unknown[] | undefined | null
143-
}>,
156+
opts: Accessor<
157+
{
158+
query: string
159+
params?: unknown[] | undefined | null
160+
} & LimitAndOffset
161+
>,
144162
): Accessor<LiveQueryResults<T> | undefined>
145163

146164
export function useLiveQuery<T = { [key: string]: unknown }>(
@@ -156,10 +174,12 @@ export function useLiveQuery<T = { [key: string]: unknown }>(
156174
): Accessor<LiveQueryResults<T> | undefined>
157175

158176
export function useLiveQuery<T = { [key: string]: unknown }>(
159-
opts: Accessor<{
160-
query: string | LiveQuery<T> | Promise<LiveQuery<T>>
161-
params?: unknown[] | undefined | null
162-
}>,
177+
opts: Accessor<
178+
{
179+
query: string | LiveQuery<T> | Promise<LiveQuery<T>>
180+
params?: unknown[] | undefined | null
181+
} & LimitAndOffset
182+
>,
163183
): Accessor<LiveQueryResults<T> | undefined> {
164184
return useLiveQueryImpl<T>(opts)
165185
}

packages/pglite-solid/test/hooks.test.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,57 @@ describe('hooks', () => {
1212

1313
testLiveQuery('useLiveIncrementalQuery')
1414

15+
describe('useLiveQuery with limit and offset', () => {
16+
let db: PGliteWithLive
17+
let wrapper: (props: { children: JSX.Element }) => JSX.Element
18+
19+
beforeEach(async () => {
20+
db = await PGlite.create({
21+
extensions: {
22+
live,
23+
},
24+
})
25+
wrapper = (props) => {
26+
return <PGliteProvider db={db}>{props.children}</PGliteProvider>
27+
}
28+
29+
await db.exec(`
30+
CREATE TABLE IF NOT EXISTS test (
31+
id SERIAL PRIMARY KEY,
32+
name TEXT
33+
);
34+
`)
35+
await db.exec(`TRUNCATE test;`)
36+
})
37+
38+
it.only('query with limit and offset', async () => {
39+
db.exec(`INSERT INTO test (name) VALUES ('test1'),('test2');`)
40+
41+
const [opts, setOpts] = createSignal({ limit: 1, offset: 0 })
42+
const { result } = renderHook(
43+
(props: { pagination: Accessor<{ limit: number; offset: number }> }) =>
44+
useLiveQuery(() => ({
45+
query: `SELECT * FROM test`,
46+
...props.pagination(),
47+
})),
48+
{ wrapper, initialProps: [{ pagination: opts }] },
49+
)
50+
51+
waitFor(() => expect(result()?.rows).toEqual([{ id: 1, name: 'test1' }]))
52+
53+
setOpts({ limit: 1, offset: 1 })
54+
waitFor(() => expect(result()?.rows).toEqual([{ id: 2, name: 'test2' }]))
55+
56+
setOpts({ limit: 2, offset: 0 })
57+
waitFor(() =>
58+
expect(result()?.rows).toEqual([
59+
{ id: 1, name: 'test1' },
60+
{ id: 2, name: 'test2' },
61+
]),
62+
)
63+
})
64+
})
65+
1566
describe('useLiveQuery.sql', () => {
1667
let db: PGliteWithLive
1768
let wrapper: (props: { children: JSX.Element }) => JSX.Element

0 commit comments

Comments
 (0)