Last active
March 2, 2022 20:50
-
-
Save dgeb/42fbe4aebabe578707fa9c21c957ade6 to your computer and use it in GitHub Desktop.
React hooks for Orbit.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type {QueryOrExpressions, RequestOptions} from '@orbit/data'; | |
import {RecordQueryBuilder, RecordQueryExpression} from '@orbit/records'; | |
export type QueryDispatch = ( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
) => void; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useEffect, useState} from 'react'; | |
import { | |
buildQuery as bq, | |
RequestOptions, | |
QueryOrExpressions, | |
} from '@orbit/data'; | |
import type { | |
RecordQueryBuilder, | |
RecordQueryResult, | |
RecordQuery, | |
RecordQueryExpression, | |
} from '@orbit/records'; | |
import type {QueryDispatch} from './queries'; | |
export interface AsyncQueryable { | |
query( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
options?: RequestOptions, | |
id?: string, | |
): Promise<RecordQueryResult>; | |
queryBuilder: RecordQueryBuilder; | |
} | |
export default function useQuery( | |
queryable: AsyncQueryable, | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): { | |
data: RecordQueryResult | undefined; | |
error: Error | undefined; | |
loading: boolean; | |
retry: () => void; | |
reset: QueryDispatch; | |
} { | |
const [query, setQuery] = useState( | |
buildQuery(queryOrExpressions, queryOptions, queryId), | |
); | |
const [data, setData] = useState<RecordQueryResult | undefined>(); | |
const [error, setError] = useState<Error | undefined>(); | |
const [loading, setLoading] = useState(true); | |
function buildQuery( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): RecordQuery { | |
return bq( | |
queryOrExpressions, | |
queryOptions, | |
queryId, | |
queryable.queryBuilder, | |
); | |
} | |
async function performQuery() { | |
if (query) { | |
try { | |
setData(await queryable.query(query)); | |
} catch (e) { | |
setError(e); | |
} finally { | |
setLoading(false); | |
} | |
} else if (data !== undefined) { | |
setData(undefined); | |
} | |
} | |
const reset = ( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
) => { | |
setLoading(true); | |
setQuery(buildQuery(queryOrExpressions, queryOptions, queryId)); | |
}; | |
const retry = () => { | |
setLoading(true); | |
performQuery(); | |
}; | |
useEffect(() => { | |
performQuery(); | |
}, [query]); | |
return {data, error, loading, retry, reset}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useEffect, useState} from 'react'; | |
import type {SyncRecordCache} from '@orbit/record-cache'; | |
import { | |
buildQuery as bq, | |
QueryOrExpressions, | |
RequestOptions, | |
} from '@orbit/data'; | |
import type { | |
RecordQuery, | |
RecordQueryBuilder, | |
RecordQueryExpression, | |
RecordQueryResult, | |
} from '@orbit/records'; | |
import type {QueryDispatch} from './shared/queries'; | |
export default function useSyncLiveQuery<T extends RecordQueryResult>( | |
queryable: SyncRecordCache, | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): { | |
data: T | undefined; | |
error: Error | undefined; | |
reset: QueryDispatch; | |
} { | |
const [query, setQuery] = useState( | |
buildQuery(queryOrExpressions, queryOptions, queryId), | |
); | |
const [data, setData] = useState<RecordQueryResult | undefined>(); | |
const [error, setError] = useState(); | |
function buildQuery( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): RecordQuery { | |
return bq( | |
queryOrExpressions, | |
queryOptions, | |
queryId, | |
queryable.queryBuilder, | |
); | |
} | |
function performLiveQuery() { | |
if (query) { | |
try { | |
setData(queryable.query(query)); | |
} catch (e) { | |
setError(e); | |
} | |
let unsubscribe = queryable.liveQuery(query).subscribe(lq => { | |
setData(lq.query() as T); | |
}); | |
return () => { | |
unsubscribe(); | |
}; | |
} else if (data !== undefined) { | |
setData(undefined); | |
} | |
} | |
useEffect(() => performLiveQuery(), [query]); | |
const reset = ( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
) => { | |
setQuery(buildQuery(queryOrExpressions, queryOptions, queryId)); | |
}; | |
return {data: data as T, error, reset}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useEffect, useState} from 'react'; | |
import { | |
buildQuery as bq, | |
QueryOrExpressions, | |
RequestOptions, | |
} from '@orbit/data'; | |
import type { | |
RecordQueryResult, | |
RecordQueryBuilder, | |
RecordQuery, | |
RecordQueryExpression, | |
} from '@orbit/records'; | |
import type {QueryDispatch} from './queries'; | |
export interface SyncQueryable { | |
query( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
options?: RequestOptions, | |
id?: string, | |
): RecordQueryResult; | |
queryBuilder: RecordQueryBuilder; | |
} | |
export default function useSyncQuery( | |
queryable: SyncQueryable, | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): { | |
data: RecordQueryResult | undefined; | |
error: Error | undefined; | |
retry: () => void; | |
reset: QueryDispatch; | |
} { | |
const [query, setQuery] = useState( | |
buildQuery(queryOrExpressions, queryOptions, queryId), | |
); | |
const [data, setData] = useState<RecordQueryResult | undefined>(); | |
const [error, setError] = useState(); | |
function buildQuery( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
): RecordQuery { | |
return bq( | |
queryOrExpressions, | |
queryOptions, | |
queryId, | |
queryable.queryBuilder, | |
); | |
} | |
function performQuery() { | |
if (query) { | |
try { | |
setData(queryable.query(query)); | |
} catch (e) { | |
setError(e); | |
} | |
} else if (data !== undefined) { | |
setData(undefined); | |
} | |
} | |
const reset = ( | |
queryOrExpressions: QueryOrExpressions< | |
RecordQueryExpression, | |
RecordQueryBuilder | |
>, | |
queryOptions?: RequestOptions, | |
queryId?: string, | |
) => { | |
setQuery(buildQuery(queryOrExpressions, queryOptions, queryId)); | |
}; | |
const retry = () => performQuery(); | |
useEffect(() => performQuery(), [query]); | |
return {data, error, retry, reset}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment