diff --git a/examples/benchmark/core.js b/examples/benchmark/core.js index 838dd28618f7..cf85c2b0d08c 100644 --- a/examples/benchmark/core.js +++ b/examples/benchmark/core.js @@ -137,7 +137,7 @@ export default function addReducerSuite(suite) { } }) .add('getResponse Query-sorted', () => { - return controller.getResponse(ProjectQuerySorted, cachedState); + return controller.query(ProjectQuerySorted, cachedState); }) .add('getResponse Collection', () => { return controllerCollection.getResponse( diff --git a/examples/benchmark/schemas.js b/examples/benchmark/schemas.js index 811f0ade77b9..07b1b1f8516e 100644 --- a/examples/benchmark/schemas.js +++ b/examples/benchmark/schemas.js @@ -1,4 +1,4 @@ -import { Entity, schema, Query } from './dist/index.js'; +import { Entity, schema } from './dist/index.js'; export class BuildTypeDescription extends Entity { id = ''; @@ -100,7 +100,7 @@ export const ProjectSchemaMixin = { export const ProjectQuery = { project: new schema.All(ProjectWithBuildTypesDescription), }; -export const ProjectQuerySorted = new Query( +export const ProjectQuerySorted = new schema.Query( new schema.All(ProjectWithBuildTypesDescription), entries => { return [...entries].sort((a, b) => a.internalId - b.internalId); diff --git a/examples/coin-app/src/resources/Currency.ts b/examples/coin-app/src/resources/Currency.ts index 260490f435fb..6d326063d338 100644 --- a/examples/coin-app/src/resources/Currency.ts +++ b/examples/coin-app/src/resources/Currency.ts @@ -1,4 +1,4 @@ -import { Entity, Query, createResource, schema } from '@data-client/rest'; +import { Entity, createResource, schema } from '@data-client/rest'; import { Stats } from './Stats'; @@ -61,7 +61,7 @@ export const CurrencyResource = createResource({ interface Args { type?: string; } -export const queryCurrency = new Query( +export const queryCurrency = new schema.Query( new schema.All(Currency), (entries, { type = 'crypto' }: Args) => { let sorted = entries.filter( diff --git a/examples/coin-app/src/resources/Product.ts b/examples/coin-app/src/resources/Product.ts index 8afe0e23bd90..fd9bb199a5d5 100644 --- a/examples/coin-app/src/resources/Product.ts +++ b/examples/coin-app/src/resources/Product.ts @@ -1,4 +1,4 @@ -import { Entity, Query, createResource, schema } from '@data-client/rest'; +import { Entity, createResource, schema } from '@data-client/rest'; import { Stats } from './Stats'; @@ -34,7 +34,7 @@ export const ProductResource = createResource({ interface Args { quote_currency?: string; } -export const queryProduct = new Query( +export const queryProduct = new schema.Query( new schema.All(Product), (entries, { quote_currency }: Args) => { let sorted = entries.filter(product => product.stats); diff --git a/examples/nextjs/resources/TodoResource.ts b/examples/nextjs/resources/TodoResource.ts index d886d6cd2632..cca3cfb2c56f 100644 --- a/examples/nextjs/resources/TodoResource.ts +++ b/examples/nextjs/resources/TodoResource.ts @@ -1,4 +1,4 @@ -import { Query, schema } from '@data-client/rest'; +import { schema } from '@data-client/rest'; import { createPlaceholderResource, @@ -20,7 +20,7 @@ export const TodoResource = createPlaceholderResource({ searchParams: {} as { userId?: string | number } | undefined, }); -export const queryRemainingTodos = new Query( +export const queryRemainingTodos = new schema.Query( TodoResource.getList.schema, (entries) => entries && entries.filter((todo) => !todo.completed).length, ); diff --git a/examples/todo-app/src/pages/Home/TodoStats.tsx b/examples/todo-app/src/pages/Home/TodoStats.tsx index 1d2544dd9cbe..a7a085440731 100644 --- a/examples/todo-app/src/pages/Home/TodoStats.tsx +++ b/examples/todo-app/src/pages/Home/TodoStats.tsx @@ -1,8 +1,8 @@ -import { useCache } from '@data-client/react'; +import { useQuery } from '@data-client/react'; import { queryRemainingTodos } from 'resources/TodoResource'; export default function TodoStats({ userId }: { userId?: number }) { - const remaining = useCache(queryRemainingTodos, { userId }); + const remaining = useQuery(queryRemainingTodos, { userId }); return
> +{ + declare schema: S; + declare process: P; + declare thingy: ProcessParameters
;
+
+ constructor(schema: S, process?: P) {
+ this.schema = schema;
+ if (process) this.process = process;
+ // allows for inheritance overrides
+ else if (!this.process)
+ this.process = ((entries: Denormalize) => entries) as any;
+ }
+
+ normalize(...args: any) {
+ return (this.schema as any).normalize(...args);
+ }
+
+ denormalize(input: {}, args: any, unvisit: any): ReturnType
| undefined { + const value = unvisit(input, this.schema); + return typeof value === 'symbol' ? undefined : this.process(value, ...args); + } + + infer( + args: ProcessParameters
, + indexes: any, + recurse: ( + schema: any, + args: any, + indexes: NormalizedIndex, + entities: EntityTable, + ) => any, + entities: EntityTable, + ) { + return recurse(this.schema, args, indexes, entities); + } + + declare _denormalizeNullable: ( + input: {}, + args: readonly any[], + unvisit: (input: any, schema: any) => any, + ) => ReturnType
| undefined; +} + +type ProcessParameters
=
+ P extends (entries: any, ...args: infer Par) => any ?
+ Par extends [] ?
+ SchemaArgs
+ : Par & SchemaArgs
+ : SchemaArgs;
diff --git a/packages/endpoint/src/schemas/__tests__/Collection.test.ts b/packages/endpoint/src/schemas/__tests__/Collection.test.ts
index 53ca84309b93..f3e964683461 100644
--- a/packages/endpoint/src/schemas/__tests__/Collection.test.ts
+++ b/packages/endpoint/src/schemas/__tests__/Collection.test.ts
@@ -88,7 +88,6 @@ describe(`${schema.Collection.name} normalization`, () => {
() => undefined,
{},
{},
- // @ts-expect-error
[],
);
}
diff --git a/packages/endpoint/src/schemas/__tests__/Query.test.ts b/packages/endpoint/src/schemas/__tests__/Query.test.ts
index 14d0e6033fa0..5e4bcdb024a4 100644
--- a/packages/endpoint/src/schemas/__tests__/Query.test.ts
+++ b/packages/endpoint/src/schemas/__tests__/Query.test.ts
@@ -4,7 +4,7 @@ import { IDEntity } from '__tests__/new';
import { fromJS } from 'immutable';
import { denormalizeSimple } from './denormalize';
-import { schema, Query, Denormalize, DenormalizeNullable } from '../..';
+import { schema, DenormalizeNullable } from '../..';
let dateSpy: jest.SpyInstance =
+export type SchemaArgs =
S extends EntityInterface =
}
) ?
Args
- : [];
+ : unknown;
diff --git a/packages/react/src/__tests__/integration-endpoint.web.tsx b/packages/react/src/__tests__/integration-endpoint.web.tsx
index 010eb9c81971..7ba4f1557d32 100644
--- a/packages/react/src/__tests__/integration-endpoint.web.tsx
+++ b/packages/react/src/__tests__/integration-endpoint.web.tsx
@@ -1,4 +1,4 @@
-import { schema, Entity, Query } from '@data-client/endpoint';
+import { schema, Entity } from '@data-client/endpoint';
import { Endpoint } from '@data-client/endpoint';
import { CacheProvider } from '@data-client/react';
import { CacheProvider as ExternalCacheProvider } from '@data-client/redux';
@@ -20,7 +20,13 @@ import nock from 'nock';
// relative imports to avoid circular dependency in tsconfig references
import { makeRenderDataClient, act } from '../../../test';
-import { useCache, useController, useFetch, useSuspense } from '../hooks';
+import {
+ useCache,
+ useController,
+ useFetch,
+ useQuery,
+ useSuspense,
+} from '../hooks';
import {
payload,
createPayload,
@@ -238,11 +244,11 @@ describe.each([
const getList = CoolerArticleResource.getList.extend({
schema: new schema.All(CoolerArticle),
});
- const queryArticle = new Query(new schema.All(CoolerArticle));
+ const queryArticle = new schema.Query(new schema.All(CoolerArticle));
const { result, waitForNextUpdate } = renderDataClient(() => {
useFetch(getList);
- return useCache(queryArticle);
+ return useQuery(queryArticle);
});
expect(result.current).toBeUndefined();
await waitForNextUpdate();
@@ -256,7 +262,7 @@ describe.each([
});
it('should filter Query based on arguments', async () => {
- const queryArticle = new Query(
+ const queryArticle = new schema.Query(
new schema.All(CoolerArticle),
(entries, { tags }: { tags: string }) => {
if (!tags) return entries;
@@ -268,8 +274,8 @@ describe.each([
renderDataClient(
({ tags }: { tags: string }) => {
useFetch(CoolerArticleResource.getList);
- const data = useCache(queryArticle, { tags });
- return useCache(queryArticle, { tags });
+ const data = useQuery(queryArticle, { tags });
+ return useQuery(queryArticle, { tags });
},
{ initialProps: { tags: 'a' } },
);
diff --git a/packages/react/src/hooks/useCache.ts b/packages/react/src/hooks/useCache.ts
index 38950da490cc..1cf04228ea55 100644
--- a/packages/react/src/hooks/useCache.ts
+++ b/packages/react/src/hooks/useCache.ts
@@ -23,9 +23,10 @@ export default function useCache<
EndpointInterface