Skip to content

Commit

Permalink
fix: improve serializable typings for oracle and kpi token internal s…
Browse files Browse the repository at this point in the history
…tates (#479)

* fix(react): improve and fix typings for kpi token and oracle state

* chore(frontend): integrate new react lib with improved kpi token and oracle state typings

---------

Co-authored-by: luzzifoss <fedeluzzi00@gmail.com>
  • Loading branch information
luzzif and luzzifoss authored Oct 31, 2023
1 parent 39f5549 commit 302dff9
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 41 deletions.
5 changes: 5 additions & 0 deletions .changeset/pretty-planets-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@carrot-kpi/react": minor
---

Improve typings for serializable KPI token and oracle states
5 changes: 5 additions & 0 deletions .changeset/young-lobsters-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@carrot-kpi/host-frontend": minor
---

Integrate new React library KPI token and oracle state typings
12 changes: 6 additions & 6 deletions packages/frontend/src/pages/create-with-template-id/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
KPITokenCreationForm,
useIPFSGatewayURL,
usePreferDecentralization,
type SerializableObject,
} from "@carrot-kpi/react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
Expand All @@ -16,9 +17,8 @@ import { useInvalidateLatestKPITokens } from "../../hooks/useInvalidateLatestKPI
import { Layout } from "../../components/layout";
import { Permissioned } from "../../components/permissioned";
import { useIsCreatorAllowed } from "../../hooks/useIsCreatorAllowed";
import type { Serializable } from "@carrot-kpi/react";

export const CreateWithTemplateId = () => {
export function CreateWithTemplateId<S extends SerializableObject<S>>() {
const { i18n, t } = useTranslation();
const { state } = useLocation();
const navigate = useNavigate();
Expand All @@ -39,10 +39,10 @@ export const CreateWithTemplateId = () => {
const [formKey, setFormKey] = useState(0);
const [draftState, setDraftState] = useState<{
templateId?: number;
state: Serializable;
state: S;
}>({
templateId: undefined,
state: {},
state: {} as S,
});

const { allowed: creatorAllowed, loading: loadingPermission } =
Expand Down Expand Up @@ -133,7 +133,7 @@ export const CreateWithTemplateId = () => {
templateId,
]);

const handleChange = useCallback((state: Serializable) => {
const handleChange = useCallback((state: S) => {
setDraftState((prevState) => ({
templateId: prevState.templateId,
state,
Expand Down Expand Up @@ -209,4 +209,4 @@ export const CreateWithTemplateId = () => {
</div>
</Layout>
);
};
}
4 changes: 2 additions & 2 deletions packages/react/src/components/kpi-token-creation-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React from "react";
import type { ReactElement } from "react";
import type {
KPITokenCreationFormProps,
Serializable,
SerializableObject,
} from "../types/templates";
import { TemplateComponent } from "./template-component";

export function KPITokenCreationForm<S extends Serializable = Serializable>({
export function KPITokenCreationForm<S extends SerializableObject<S>>({
template,
fallback,
error,
Expand Down
7 changes: 5 additions & 2 deletions packages/react/src/components/oracle-creation-form.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from "react";
import type { ReactElement } from "react";
import type { OracleCreationFormProps, Serializable } from "../types/templates";
import type {
OracleCreationFormProps,
SerializableObject,
} from "../types/templates";
import { TemplateComponent } from "./template-component";

export function OracleCreationForm<S extends Serializable = Serializable>({
export function OracleCreationForm<S extends SerializableObject<S>>({
template,
fallback,
error,
Expand Down
19 changes: 13 additions & 6 deletions packages/react/src/hooks/useTemplateModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ import { useStagingMode } from "./useStagingMode";
import { useNetwork } from "wagmi";
import type {
RemoteComponentProps,
SerializableObject,
TemplateEntity,
TemplateType,
} from "../types/templates";

type ComponentType<
E extends TemplateEntity,
T extends TemplateType,
> = FunctionComponent<RemoteComponentProps<E, T>>;
S extends SerializableObject<S>,
> = FunctionComponent<RemoteComponentProps<E, T, S>>;

interface CachedModule<E extends TemplateEntity, T extends TemplateType> {
Component: ComponentType<E, T>;
interface CachedModule<
E extends TemplateEntity,
T extends TemplateType,
S extends SerializableObject<S>,
> {
Component: ComponentType<E, T, S>;
bundle: TemplateBundle;
}

Expand All @@ -38,15 +44,16 @@ interface TemplateModuleParams<E, T> {
export const useTemplateModule = <
E extends TemplateEntity,
T extends TemplateType,
S extends SerializableObject<S>,
>(
params: TemplateModuleParams<E, T>,
): {
loading: boolean;
Component: ComponentType<E, T> | null;
Component: ComponentType<E, T, S> | null;
bundle: TemplateBundle | null;
} => {
const { entity, type, entry, template } = params;
const MODULE_CACHE = useRef<Record<string, CachedModule<E, T>>>({});
const MODULE_CACHE = useRef<Record<string, CachedModule<E, T, S>>>({});

const customBaseURL = useSelector<
State,
Expand Down Expand Up @@ -75,7 +82,7 @@ export const useTemplateModule = <

const [loadingExport, setLoadingExport] = useState(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [Component, setComponent] = useState<ComponentType<E, T> | null>(
const [Component, setComponent] = useState<ComponentType<E, T, S> | null>(
entry && MODULE_CACHE.current[entry]
? () => MODULE_CACHE.current[entry].Component
: null,
Expand Down
57 changes: 32 additions & 25 deletions packages/react/src/types/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ import { ResolvedTemplate } from "@carrot-kpi/sdk";
import type { ReactElement, ReactNode } from "react";
import type { Hex } from "viem";

export type Serializable =
| null
export type Serializable<T> = T extends
| string
| number
| boolean
| { [key: string | symbol | number]: Serializable }
| Serializable[];
| null
| undefined
? T
: T extends object
? { [K in keyof T]: Serializable<T[K]> }
: T extends Array<infer U>
? Array<Serializable<U>>
: never;

export type SerializableObject<T extends object> = {
[K in keyof T]: Serializable<T[K]>;
};

export type TemplateEntity = "kpiToken" | "oracle";

Expand Down Expand Up @@ -54,49 +63,47 @@ export interface OracleInitializationBundle {
export type OracleInitializationBundleGetter =
() => Promise<OracleInitializationBundle>;

export type OracleChangeCallback<S extends Serializable = Serializable> = (
export type OracleChangeCallback<S extends SerializableObject<S>> = (
internalState: S,
initializationBundleGetter?: OracleInitializationBundleGetter,
) => void;

export interface AdditionalRemoteOracleCreationFormProps<
S extends Serializable = Serializable,
> {
export type AdditionalRemoteOracleCreationFormProps<
S extends SerializableObject<S>,
> = {
state: S;
kpiToken?: Partial<KPIToken>;
onChange: OracleChangeCallback<S>;
navigate: NavigateFunction;
onTx: <T extends TxType>(tx: Tx<T>) => void;
}
};

export type OracleRemoteCreationFormProps<
S extends Serializable = Serializable,
> = BaseRemoteTemplateComponentProps &
AdditionalRemoteOracleCreationFormProps<S>;
export type OracleRemoteCreationFormProps<S extends SerializableObject<S>> =
BaseRemoteTemplateComponentProps &
AdditionalRemoteOracleCreationFormProps<S>;

export type KPITokenChangeCallback<S extends Serializable = Serializable> = (
export type KPITokenChangeCallback<S extends SerializableObject<S>> = (
state: S,
) => void;

export type OracleCreationFormProps<S extends Serializable = Serializable> =
export type OracleCreationFormProps<S extends SerializableObject<S>> =
TemplateComponentProps & AdditionalRemoteOracleCreationFormProps<S>;

export interface AdditionalRemoteKPITokenCreationFormProps<
S extends Serializable = Serializable,
> {
export type AdditionalRemoteKPITokenCreationFormProps<
S extends SerializableObject<S>,
> = {
state: S;
onChange: KPITokenChangeCallback<S>;
onCreate: () => void;
navigate: NavigateFunction;
onTx: <T extends TxType>(tx: Tx<T>) => void;
}
};

export type KPITokenRemoteCreationFormProps<
S extends Serializable = Serializable,
> = BaseRemoteTemplateComponentProps &
AdditionalRemoteKPITokenCreationFormProps<S>;
export type KPITokenRemoteCreationFormProps<S extends SerializableObject<S>> =
BaseRemoteTemplateComponentProps &
AdditionalRemoteKPITokenCreationFormProps<S>;

export type KPITokenCreationFormProps<S extends Serializable = Serializable> =
export type KPITokenCreationFormProps<S extends SerializableObject<S>> =
TemplateComponentProps & AdditionalRemoteKPITokenCreationFormProps<S>;

export interface AdditionalRemoteOraclePageProps {
Expand Down Expand Up @@ -125,7 +132,7 @@ export type KPITokenPageProps = TemplateComponentProps &
export type RemoteComponentProps<
E extends TemplateEntity,
T extends TemplateType,
S extends Serializable = Serializable,
S extends SerializableObject<S>,
> = E extends "kpiToken"
? T extends "creationForm"
? KPITokenRemoteCreationFormProps<S>
Expand Down

0 comments on commit 302dff9

Please sign in to comment.