Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub(crate) fn generate_eager_reader_condition_artifact(
{}{reader_output_type}\n\
> = {{\n\
{}kind: \"EagerReaderArtifact\",\n\
{}resolver: ({{ data }}) => data.__typename === \"{concrete_type}\" ? data.link : null,\n\
{}resolver: ({{ firstParameter }}) => firstParameter.data.__typename === \"{concrete_type}\" ? firstParameter.data.link : null,\n\
{}readerAst,\n\
}};\n\n\
export default artifact;\n",
Expand Down
30 changes: 15 additions & 15 deletions crates/graphql_artifact_generation/src/iso_overload_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub(crate) fn build_iso_overload_artifact(
// of type TParam.
type IdentityWithParam<TParam extends object> = <TClientFieldReturn>(
clientField: (param: TParam) => TClientFieldReturn
) => (param: TParam) => TClientFieldReturn;
) => (data: { firstParameter: TParam }) => TClientFieldReturn;

// This is the type given it to client fields with @component.
// This means that the type of the exported iso literal is exactly
Expand All @@ -121,7 +121,7 @@ type IdentityWithParamComponent<TParam extends object> = <
TComponentProps = Record<PropertyKey, never>,
>(
clientComponentField: (data: TParam, componentProps: TComponentProps) => TClientFieldReturn
) => (data: TParam, componentProps: TComponentProps) => TClientFieldReturn;
) => (props: { firstParameter: TParam, additionalRuntimeProps: TComponentProps }) => TClientFieldReturn;

type WhitespaceCharacter = ' ' | '\\t' | '\\n';
type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
Expand Down Expand Up @@ -168,24 +168,24 @@ type MatchesWhitespaceAndString<
content.push_str(&entrypoint_overload);
}

content.push_str(
"
export function iso(_isographLiteralText: string):
content.push_str(match no_babel_transform {
false => {
"export function iso(clientFieldResolver: any):
| IdentityWithParam<any>
| IdentityWithParamComponent<any>
| IsographEntrypoint<any, any>
{\n",
);

content.push_str(match no_babel_transform {
false => {
" throw new Error('iso: Unexpected invocation at runtime. Either the Babel transform ' +
'was not set up, or it failed to identify this call site. Make sure it ' +
'is being used verbatim as `iso`. If you cannot use the babel transform, ' +
'set options.no_babel_transform to true in your Isograph config. ');"
{\n return (props: any) => {
return clientFieldResolver(props.firstParameter, props.additionalRuntimeProps)
};"
}
true => {
" return (clientFieldResolver: any) => clientFieldResolver;"
"export function iso(_isographLiteralText: string):
| IdentityWithParam<any>
| IdentityWithParamComponent<any>
| IsographEntrypoint<any, any>
{\n return (clientFieldResolver: any) => (props: any) => {
return clientFieldResolver(props.firstParameter, props.additionalRuntimeProps)
};"
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const artifact: EagerReaderArtifact<
Link | null
> = {
kind: "EagerReaderArtifact",
resolver: ({ data }) => data.__typename === "User" ? data.link : null,
resolver: ({ firstParameter }) => firstParameter.data.__typename === "User" ? firstParameter.data.link : null,
readerAst,
};

Expand Down
14 changes: 6 additions & 8 deletions demos/github-demo/src/isograph-components/__isograph/iso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import entrypoint_Query__UserPage from '../__isograph/Query/UserPage/entrypoint'
// of type TParam.
type IdentityWithParam<TParam extends object> = <TClientFieldReturn>(
clientField: (param: TParam) => TClientFieldReturn
) => (param: TParam) => TClientFieldReturn;
) => (data: { firstParameter: TParam }) => TClientFieldReturn;

// This is the type given it to client fields with @component.
// This means that the type of the exported iso literal is exactly
Expand All @@ -45,7 +45,7 @@ type IdentityWithParamComponent<TParam extends object> = <
TComponentProps = Record<PropertyKey, never>,
>(
clientComponentField: (data: TParam, componentProps: TComponentProps) => TClientFieldReturn
) => (data: TParam, componentProps: TComponentProps) => TClientFieldReturn;
) => (props: { firstParameter: TParam, additionalRuntimeProps: TComponentProps }) => TClientFieldReturn;

type WhitespaceCharacter = ' ' | '\t' | '\n';
type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
Expand Down Expand Up @@ -172,14 +172,12 @@ export function iso<T>(
export function iso<T>(
param: T & MatchesWhitespaceAndString<'entrypoint Query.UserPage', T>
): typeof entrypoint_Query__UserPage;

export function iso(_isographLiteralText: string):
export function iso(clientFieldResolver: any):
| IdentityWithParam<any>
| IdentityWithParamComponent<any>
| IsographEntrypoint<any, any>
{
throw new Error('iso: Unexpected invocation at runtime. Either the Babel transform ' +
'was not set up, or it failed to identify this call site. Make sure it ' +
'is being used verbatim as `iso`. If you cannot use the babel transform, ' +
'set options.no_babel_transform to true in your Isograph config. ');
return (props: any) => {
return clientFieldResolver(props.firstParameter, props.additionalRuntimeProps)
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const artifact: EagerReaderArtifact<
Link | null
> = {
kind: "EagerReaderArtifact",
resolver: ({ data }) => data.__typename === "AdItem" ? data.link : null,
resolver: ({ firstParameter }) => firstParameter.data.__typename === "AdItem" ? firstParameter.data.link : null,
readerAst,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const artifact: EagerReaderArtifact<
Link | null
> = {
kind: "EagerReaderArtifact",
resolver: ({ data }) => data.__typename === "BlogItem" ? data.link : null,
resolver: ({ firstParameter }) => firstParameter.data.__typename === "BlogItem" ? firstParameter.data.link : null,
readerAst,
};

Expand Down
14 changes: 6 additions & 8 deletions demos/pet-demo/src/components/__isograph/iso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import entrypoint_Query__PetFavoritePhrase from '../__isograph/Query/PetFavorite
// of type TParam.
type IdentityWithParam<TParam extends object> = <TClientFieldReturn>(
clientField: (param: TParam) => TClientFieldReturn
) => (param: TParam) => TClientFieldReturn;
) => (data: { firstParameter: TParam }) => TClientFieldReturn;

// This is the type given it to client fields with @component.
// This means that the type of the exported iso literal is exactly
Expand All @@ -58,7 +58,7 @@ type IdentityWithParamComponent<TParam extends object> = <
TComponentProps = Record<PropertyKey, never>,
>(
clientComponentField: (data: TParam, componentProps: TComponentProps) => TClientFieldReturn
) => (data: TParam, componentProps: TComponentProps) => TClientFieldReturn;
) => (props: { firstParameter: TParam, additionalRuntimeProps: TComponentProps }) => TClientFieldReturn;

type WhitespaceCharacter = ' ' | '\t' | '\n';
type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
Expand Down Expand Up @@ -237,14 +237,12 @@ export function iso<T>(
export function iso<T>(
param: T & MatchesWhitespaceAndString<'entrypoint Query.PetFavoritePhrase', T>
): typeof entrypoint_Query__PetFavoritePhrase;

export function iso(_isographLiteralText: string):
export function iso(clientFieldResolver: any):
| IdentityWithParam<any>
| IdentityWithParamComponent<any>
| IsographEntrypoint<any, any>
{
throw new Error('iso: Unexpected invocation at runtime. Either the Babel transform ' +
'was not set up, or it failed to identify this call site. Make sure it ' +
'is being used verbatim as `iso`. If you cannot use the babel transform, ' +
'set options.no_babel_transform to true in your Isograph config. ');
return (props: any) => {
return clientFieldResolver(props.firstParameter, props.additionalRuntimeProps)
};
}
14 changes: 6 additions & 8 deletions demos/vite-demo/src/components/__isograph/iso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import entrypoint_Query__HomePage from '../__isograph/Query/HomePage/entrypoint'
// of type TParam.
type IdentityWithParam<TParam extends object> = <TClientFieldReturn>(
clientField: (param: TParam) => TClientFieldReturn
) => (param: TParam) => TClientFieldReturn;
) => (data: { firstParameter: TParam }) => TClientFieldReturn;

// This is the type given it to client fields with @component.
// This means that the type of the exported iso literal is exactly
Expand All @@ -23,7 +23,7 @@ type IdentityWithParamComponent<TParam extends object> = <
TComponentProps = Record<PropertyKey, never>,
>(
clientComponentField: (data: TParam, componentProps: TComponentProps) => TClientFieldReturn
) => (data: TParam, componentProps: TComponentProps) => TClientFieldReturn;
) => (props: { firstParameter: TParam, additionalRuntimeProps: TComponentProps }) => TClientFieldReturn;

type WhitespaceCharacter = ' ' | '\t' | '\n';
type Whitespace<In> = In extends `${WhitespaceCharacter}${infer In}`
Expand Down Expand Up @@ -62,14 +62,12 @@ export function iso<T>(
export function iso<T>(
param: T & MatchesWhitespaceAndString<'entrypoint Query.HomePage', T>
): typeof entrypoint_Query__HomePage;

export function iso(_isographLiteralText: string):
export function iso(clientFieldResolver: any):
| IdentityWithParam<any>
| IdentityWithParamComponent<any>
| IsographEntrypoint<any, any>
{
throw new Error('iso: Unexpected invocation at runtime. Either the Babel transform ' +
'was not set up, or it failed to identify this call site. Make sure it ' +
'is being used verbatim as `iso`. If you cannot use the babel transform, ' +
'set options.no_babel_transform to true in your Isograph config. ');
return (props: any) => {
return clientFieldResolver(props.firstParameter, props.additionalRuntimeProps)
};
}
4 changes: 3 additions & 1 deletion docs-website/docs/how-isograph-works/babel-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ It is then used via adding the following to your `.babelrc.js`:
}
```

For HMR to work `@isograph/babel-plugin` must run before `react-refresh/babel`.

## Behavior

The babel plugin will replace calls to `iso` entrypoint with require calls to the appropriate `entrypoint.js` file.
Expand All @@ -31,7 +33,7 @@ export const foo = iso(`field Query.Foo { whatever }`)(({ data }) => {

```ts
// and this is transformed into
export const foo = ({ data }) => doStuff();
export const foo = iso(({ data }) => doStuff());
```

## Requirements
Expand Down
16 changes: 2 additions & 14 deletions libs/isograph-babel-plugin/compileTag.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,8 @@ function compileTag(t, path, config) {
// This throws if the tag is invalid
compileImportStatement(t, path, type, field, 'entrypoint', config);
} else if (keyword === 'field') {
if (t.isCallExpression(path.parentPath.node)) {
const firstArg = path.parentPath.node.arguments[0];
if (path.parentPath.node.arguments.length === 1 && firstArg != null) {
path.parentPath.replaceWith(firstArg);
} else {
throw new Error(
'Invalid iso tag usage. The iso function should be passed at most one argument.',
);
}
} else {
path.replaceWith(
t.arrowFunctionExpression([t.identifier('x')], t.identifier('x')),
);
}
// replace `iso("field ...")` with `iso`
path.replaceWith(path.node.callee);
} else {
throw new Error(
"Invalid iso tag usage. Expected 'entrypoint' or 'field'.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import { useReadAndSubscribe } from '../react/useReadAndSubscribe';
import { stableCopy } from './cache';
import { FragmentReference } from './FragmentReference';
Expand Down Expand Up @@ -47,12 +48,14 @@ export function getOrCreateCachedComponent(
rootLink: fragmentReference.root,
});

return readerWithRefetchQueries.readerArtifact.resolver(
{
data,
parameters: fragmentReference.variables,
},
additionalRuntimeProps,
return (
<readerWithRefetchQueries.readerArtifact.resolver
firstParameter={{
data,
parameters: fragmentReference.variables,
}}
additionalRuntimeProps={additionalRuntimeProps}
/>
);
}
Component.displayName = `${componentName} (id: ${fragmentReference.root}) @component`;
Expand Down
6 changes: 4 additions & 2 deletions libs/isograph-react/src/core/makeNetworkRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,10 @@ function readDataForOnComplete<
}
case 'EagerReaderArtifact': {
return readerArtifact.resolver({
data: fragmentResult,
parameters: variables,
firstParameter: {
data: fragmentResult,
parameters: variables,
},
});
}
default: {
Expand Down
11 changes: 7 additions & 4 deletions libs/isograph-react/src/core/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,10 @@ function readData<TReadFromStore>(
};
}
const condition = field.condition.resolver({
data: data.data,
parameters: {},
firstParameter: {
data: data.data,
parameters: {},
},
});
if (condition === true) {
link = root;
Expand Down Expand Up @@ -428,8 +430,9 @@ function readData<TReadFromStore>(
data: data.data,
parameters: variables,
};
target[field.alias] =
field.readerArtifact.resolver(firstParameter);
target[field.alias] = field.readerArtifact.resolver({
firstParameter,
});
}
break;
}
Expand Down
14 changes: 7 additions & 7 deletions libs/isograph-react/src/core/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export type EagerReaderArtifact<
> = {
readonly kind: 'EagerReaderArtifact';
readonly readerAst: ReaderAst<TReadFromStore>;
readonly resolver: (
data: ResolverFirstParameter<TReadFromStore>,
) => TClientFieldValue;
readonly resolver: (data: {
firstParameter: ResolverFirstParameter<TReadFromStore>;
}) => TClientFieldValue;
};

export type ComponentReaderArtifact<
Expand All @@ -44,10 +44,10 @@ export type ComponentReaderArtifact<
readonly kind: 'ComponentReaderArtifact';
readonly componentName: ComponentOrFieldName;
readonly readerAst: ReaderAst<TReadFromStore>;
readonly resolver: (
data: ResolverFirstParameter<TReadFromStore>,
runtimeProps: TComponentProps,
) => React.ReactNode;
readonly resolver: (props: {
firstParameter: ResolverFirstParameter<TReadFromStore>;
additionalRuntimeProps: TComponentProps;
}) => React.ReactNode;
};

export type ResolverFirstParameter<
Expand Down
13 changes: 11 additions & 2 deletions libs/isograph-react/src/core/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
export type ExtractSecondParam<T extends (arg1: any, arg2: any) => any> =
T extends (arg1: any, arg2: infer P) => any ? P : never;
export type ExtractSecondParam<
T extends (props: {
firstParameter: any;
additionalRuntimeProps: any;
}) => any,
> = T extends (props: {
firstParameter: any;
additionalRuntimeProps: infer P;
}) => any
? P
: never;
export type CombineWithIntrinsicAttributes<T> =
T extends Record<PropertyKey, never>
? JSX.IntrinsicAttributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ export function useConnectionSpecPagination<
);
}

return readerWithRefetchQueries.readerArtifact.resolver(firstParameter);
return readerWithRefetchQueries.readerArtifact.resolver({
firstParameter,
});
});

const items = flatten(results.map((result) => result.edges ?? []));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ export function useSkipLimitPagination<
);
}

return readerWithRefetchQueries.readerArtifact.resolver(firstParameter);
return readerWithRefetchQueries.readerArtifact.resolver({
firstParameter,
});
});

const items = flatten(results);
Expand Down
4 changes: 3 additions & 1 deletion libs/isograph-react/src/react/useResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export function useResult<
data: data,
parameters: fragmentReference.variables,
};
return readerWithRefetchQueries.readerArtifact.resolver(param);
return readerWithRefetchQueries.readerArtifact.resolver({
firstParameter: param,
});
}
}
}
Expand Down
Loading
Loading