Skip to content

Commit

Permalink
0.0.394
Browse files Browse the repository at this point in the history
  • Loading branch information
ivansglazunov committed Jul 22, 2024
1 parent 38c4441 commit 3cc950d
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 48 deletions.
203 changes: 165 additions & 38 deletions imports/client-handler.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,52 @@
import { DeepClient } from './client.js';
import { memo, useEffect, useRef, useState } from 'react';
import { DeepClient, useDeep, useDeepSubscription } from './client.js';
import { gql } from '@apollo/client/index.js';

import React from 'react';
import { Id } from './minilinks.js';

export class CatchErrors extends React.Component<{
error?: any;
onMounted?: (setError: (error?: any) => void) => void;
errorRenderer?: (error: Error, reset: () => any) => React.ReactNode;
reset?: () => any;
children: any;
},any> {
reset: () => any;

constructor(props) {
super(props);
this.state = { error: undefined };

this.reset = () => {
this.setState({ error: undefined });
this?.props?.reset && this?.props?.reset();
};
}

static getDerivedStateFromError(error) {
console.log('getDerivedStateFromError', error);
return { error };
}
componentDidCatch(error, errorInfo) {
console.log('componentDidCatch', error, errorInfo);
}
componentDidMounted() {
this?.props?.onMounted && this?.props?.onMounted((error) => this.setState({ error: error }));
}

errorRenderer = (error, reset) => <></>;

render() {
const error = this.props.error || this.state.error;
if (error) {
return this?.props?.errorRenderer ? this?.props?.errorRenderer(error, this.reset) : this?.errorRenderer(error, this.reset);
}

return this.props.children;
}
}

/**
* Evaluates a client handler
* @returns A promise that resolves to an object with either an error property that contains error or data property that contains result of the handler.
Expand Down Expand Up @@ -39,40 +85,121 @@ export async function evalClientHandler(options: {
return {};
}

// export async function callClientHandler({
// linkId,
// deep,
// isolation_provider_id,
// execution_provider_id,
// }: {
// linkId: Id;
// deep: DeepClient;
// isolation_provider_id: Id;
// execution_provider_id: Id;
// }): Promise<{
// error?: any;
// data?: any;
// }> {
// const { data: handlers } = await deep.select({
// src_id: { _eq: linkId },
// isolation_provider_id: { _eq: isolation_provider_id },
// execution_provider_id: { _eq: execution_provider_id },
// }, {
// table: 'handlers',
// returning: `
// src_id
// dist_id
// dist {
// value
// }
// handler_id
// isolation_provider_id
// execution_provider_id
// `,
// });
// const handler = handlers[0];
// if (handler) return { error: '!handler' };
// const value = handler?.dist?.value?.value;
// if (handler?.dist?.value?.value) return { error: '!value' };
// return evalClientHandler({ value, deep });
// }
export const ClientHandler = memo(function ClientHandler(_props: ClientHandlerProps) {
const {
linkId,
handlerId,
context = [],
ml,
onClose,
fillSize,
error: outerError,
ErrorComponent,
...props
} = _props;
const deep = useDeep();
const _ml = ml || deep?.minilinks;
const hid = useFindClientHandler(_props);
const [file] = deep.useMinilinksQuery({
id: hid?.dist_id || 0,
});

const [{ Component, errored } = {} as any, setState] = useState<any>({ Component: undefined, errored: undefined });

// console.log('ClientHandler root', { linkId, handlerId, context, file, hid, files, Component });
const lastEvalRef = useRef(0);
useEffect(() => {
if (!hid) return;
const value = file?.value?.value;
if (!value) {
return;
}
const evalId = ++lastEvalRef.current;
evalClientHandler({ value, deep }).then(({ data, error }) => {
if (evalId === lastEvalRef.current) {
console.log('ClientHandler evalClientHandler setState', { file, data, error });
if (!error) {
setState(() => ({ Component: data }));
erroredResetRef?.current && (erroredResetRef?.current(), erroredResetRef.current = undefined);
}
else {
setErrorRef.current && setErrorRef.current(error);
setState({ Component: undefined, errored: error });
}
} else {
console.log('ClientHandler evalClientHandler outdated', { file, data, error, evalId, 'lastEvalRef.current': lastEvalRef.current });
}
});
}, [file?.value?.value, hid]);

const erroredResetRef = useRef<any>();
const setErrorRef = useRef<any>();

return (<>
<CatchErrors
error={errored || outerError}
errorRenderer={(error, reset) => {
erroredResetRef.current = reset;
return <ErrorComponent error={error} reset={reset}/>
}}
onMounted={(setError) => setErrorRef.current = setError}
>
{(typeof (Component) === 'function') ? <>
{[<ClientHandlerRenderer key={Component.toString()} Component={Component} {...props} fillSize={fillSize} link={_ml.byId[linkId]} ml={_ml} onClose={onClose} />]}
</> : <></>}
</CatchErrors>
</>);
});
export interface ClientHandlerRendererProps {
Component: any;
fillSize?: boolean;
onClose?: () => any;
[key: string]: any;
};

export const ClientHandlerRenderer = React.memo(function ClientHandlerRenderer({
Component,
fillSize = false,
onClose,
...props
}: ClientHandlerRendererProps) {
return <>{typeof (Component) === 'function' && <Component
onClose={onClose}
fillSize={fillSize}
{...props}
style={{
...(fillSize ? { width: '100%', height: '100%' } : {}),
...props?.style,
}}
/>}</>;
});

export interface ClientHandlerProps extends Partial<ClientHandlerRendererProps> {
linkId: Id;
handlerId?: Id;
context?: Id[];
ml?: any;
error?: any;
onClose?: () => any;
ErrorComponent: any;
[key: string]: any;
}

export function useFindClientHandler({
linkId,
handlerId,
context = [],
ml,
onClose,
fillSize,
...props
}: ClientHandlerProps) {
const deep = useDeep();
const [hid, setHid] = useState<any>();
useEffect(() => { (async () => {
if (hid) return;
const handler = await deep._findHandler({ context, handlerId });
if (handler) setHid(handler);
})(); }, [context, handlerId, hid]);
return hid;
}
23 changes: 14 additions & 9 deletions imports/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2118,15 +2118,20 @@ export function useDeepGenerator(generatorOptions?: DeepClientOptions<Link<Id>>)
if (!apolloClient?.jwt_token) {
log({ token, apolloClient });
}
return new DeepClient({
...otherGeneratorOptions,
apolloClient, linkId, token,
minilinks,
handleAuth: (linkId, token) => {
setToken(token);
setLinkId(linkId);
},
});
try {
return new DeepClient({
...otherGeneratorOptions,
apolloClient, linkId, token,
minilinks,
handleAuth: (linkId, token) => {
setToken(token);
setLinkId(linkId);
},
});
} catch(error) {
console.error(error);
return undefined;
}
}, [apolloClient]);
log({deep})
return deep;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@deep-foundation/deeplinks",
"version": "0.0.393",
"version": "0.0.394",
"license": "Unlicense",
"type": "module",
"scripts": {
Expand Down

0 comments on commit 3cc950d

Please sign in to comment.