Skip to content

Commit

Permalink
Clean up some TypeScript problems
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyr committed Oct 7, 2024
1 parent 826d6d2 commit 84759a1
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 65 deletions.
2 changes: 1 addition & 1 deletion node_package/src/Authenticity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { AuthenticityHeaders } from './types/index';
export default {
authenticityToken(): string | null {
const token = document.querySelector('meta[name="csrf-token"]');
if (token && (token instanceof window.HTMLMetaElement)) {
if (token instanceof HTMLMetaElement) {
return token.content;
}
return null;
Expand Down
7 changes: 4 additions & 3 deletions node_package/src/ComponentRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { RegisteredComponent, ReactComponentOrRenderFunction, RenderFunction } from './types/index';
import isRenderFunction from './isRenderFunction';

const registeredComponents = new Map();
const registeredComponents = new Map<string, RegisteredComponent>();

export default {
/**
Expand Down Expand Up @@ -35,8 +35,9 @@ export default {
* @returns { name, component, isRenderFunction, isRenderer }
*/
get(name: string): RegisteredComponent {
if (registeredComponents.has(name)) {
return registeredComponents.get(name);
const registeredComponent = registeredComponents.get(name);
if (registeredComponent !== undefined) {
return registeredComponent;
}

const keys = Array.from(registeredComponents.keys()).join(', ');
Expand Down
9 changes: 5 additions & 4 deletions node_package/src/StoreRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { StoreGenerator } from './types';
/* eslint-disable @typescript-eslint/no-explicit-any */
type Store = any;

const registeredStoreGenerators = new Map();
const hydratedStores = new Map();
const registeredStoreGenerators = new Map<string, StoreGenerator>();
const hydratedStores = new Map<string, Store>();

export default {
/**
Expand Down Expand Up @@ -66,8 +66,9 @@ This can happen if you are server rendering and either:
* @returns storeCreator with given name
*/
getStoreGenerator(name: string): StoreGenerator {
if (registeredStoreGenerators.has(name)) {
return registeredStoreGenerators.get(name);
const registeredStoreGenerator = registeredStoreGenerators.get(name);
if (registeredStoreGenerator) {
return registeredStoreGenerator;
}

const storeKeys = Array.from(registeredStoreGenerators.keys()).join(', ');
Expand Down
16 changes: 8 additions & 8 deletions node_package/src/buildConsoleReplay.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import RenderUtils from './RenderUtils';
import scriptSanitizedVal from './scriptSanitizedVal';

/* eslint-disable @typescript-eslint/no-explicit-any */

declare global {
interface Console {
history?: {
Expand All @@ -13,24 +11,26 @@ declare global {

export function consoleReplay(): string {
// console.history is a global polyfill used in server rendering.
// $FlowFixMe
if (!(console.history instanceof Array)) {
return '';
}

const lines = console.history.map(msg => {
const stringifiedList = msg.arguments.map(arg => {
let val;
let val: string | undefined;
try {
val = (typeof arg === 'string' || arg instanceof String) ? arg : JSON.stringify(arg);
// eslint-disable-next-line no-nested-ternary
val = typeof arg === 'string' ? arg :
arg instanceof String ? String(arg) :
JSON.stringify(arg);
if (val === undefined) {
val = 'undefined';
}
} catch (e: any) {
val = `${e.message}: ${arg}`;
} catch (e) {
val = `${(e as Error).message}: ${arg}`;
}

return scriptSanitizedVal(val as string);
return scriptSanitizedVal(val);
});

return `console.${msg.level}.apply(console, ${JSON.stringify(stringifiedList)});`;
Expand Down
2 changes: 1 addition & 1 deletion node_package/src/handleError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import ReactDOMServer from 'react-dom/server';
import type { ErrorOptions } from './types/index';

function handleRenderFunctionIssue(options: {e: Error; name?: string}): string {
function handleRenderFunctionIssue(options: ErrorOptions): string {
const { e, name } = options;

let msg = '';
Expand Down
8 changes: 3 additions & 5 deletions node_package/src/isRenderFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import { ReactComponentOrRenderFunction, RenderFunction } from "./types/index";
* @param component
* @returns {boolean}
*/
export default function isRenderFunction(component: ReactComponentOrRenderFunction): boolean {
export default function isRenderFunction(component: ReactComponentOrRenderFunction): component is RenderFunction {
// No for es5 or es6 React Component
if (
(component as RenderFunction).prototype &&
(component as RenderFunction).prototype.isReactComponent) {
if ((component as RenderFunction).prototype?.isReactComponent) {
return false;
}

Expand All @@ -22,7 +20,7 @@ export default function isRenderFunction(component: ReactComponentOrRenderFuncti

// If zero or one args, then we know that this is a regular function that will
// return a React component
if (component.length >= 2) {
if ((component as RenderFunction).length >= 2) {
return true;
}

Expand Down
63 changes: 31 additions & 32 deletions node_package/src/serverRenderReactComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import type { ReactElement } from 'react';

import ComponentRegistry from './ComponentRegistry';
import createReactOutput from './createReactOutput';
import {isServerRenderHash, isPromise} from
'./isServerRenderResult';
import { isPromise, isServerRenderHash } from './isServerRenderResult';
import buildConsoleReplay from './buildConsoleReplay';
import handleError from './handleError';
import type { RenderParams, RenderResult, RenderingError } from './types/index';
import type { RenderParams, RenderResult, RenderingError, ServerRenderResult } from './types';

/* eslint-disable @typescript-eslint/no-explicit-any */

Expand Down Expand Up @@ -35,37 +34,37 @@ See https://github.com/shakacode/react_on_rails#renderer-functions`);
});

const processServerRenderHash = () => {
// We let the client side handle any redirect
// Set hasErrors in case we want to throw a Rails exception
hasErrors = !!(reactRenderingResult as {routeError: Error}).routeError;

if (hasErrors) {
console.error(
`React Router ERROR: ${JSON.stringify((reactRenderingResult as {routeError: Error}).routeError)}`,
);
}
// We let the client side handle any redirect
// Set hasErrors in case we want to throw a Rails exception
const { redirectLocation, routeError } = reactRenderingResult as ServerRenderResult;
hasErrors = !!routeError;

if (hasErrors) {
console.error(
`React Router ERROR: ${JSON.stringify(routeError)}`,
);
}

if ((reactRenderingResult as {redirectLocation: {pathname: string; search: string}}).redirectLocation) {
if (trace) {
const { redirectLocation } = (reactRenderingResult as {redirectLocation: {pathname: string; search: string}});
const redirectPath = redirectLocation.pathname + redirectLocation.search;
console.log(`\
if (redirectLocation) {
if (trace) {
const redirectPath = redirectLocation.pathname + redirectLocation.search;
console.log(`\
ROUTER REDIRECT: ${name} to dom node with id: ${domNodeId}, redirect to ${redirectPath}`,
);
}
// For redirects on server rendering, we can't stop Rails from returning the same result.
// Possibly, someday, we could have the rails server redirect.
return '';
);
}
return (reactRenderingResult as { renderedHtml: string }).renderedHtml;
// For redirects on server rendering, we can't stop Rails from returning the same result.
// Possibly, someday, we could have the rails server redirect.
return '';
}
return (reactRenderingResult as ServerRenderResult).renderedHtml as string;
};

const processPromise = () => {
if (!renderingReturnsPromises) {
console.error('Your render function returned a Promise, which is only supported by a node renderer, not ExecJS.')
console.error('Your render function returned a Promise, which is only supported by a node renderer, not ExecJS.');
}
return reactRenderingResult;
}
};

const processReactElement = () => {
try {
Expand Down Expand Up @@ -105,11 +104,11 @@ as a renderFunction and not a simple React Function Component.`);
message: renderError.message,
stack: renderError.stack,
};
}
};

if(renderingReturnsPromises) {
if (renderingReturnsPromises) {
const resolveRenderResult = async () => {
let promiseResult;
let promiseResult: RenderResult;

try {
promiseResult = {
Expand All @@ -129,7 +128,7 @@ as a renderFunction and not a simple React Function Component.`);
}),
consoleReplayScript,
hasErrors: true,
}
};
renderingError = e;
}

Expand All @@ -143,11 +142,11 @@ as a renderFunction and not a simple React Function Component.`);
return resolveRenderResult();
}

const result = {
html: renderResult,
const result: RenderResult = {
html: await renderResult,

Check failure on line 146 in node_package/src/serverRenderReactComponent.ts

View workflow job for this annotation

GitHub Actions / examples (oldest)

'await' expressions are only allowed within async functions and at the top levels of modules.

Check failure on line 146 in node_package/src/serverRenderReactComponent.ts

View workflow job for this annotation

GitHub Actions / build-dummy-app-webpack-test-bundles (oldest)

'await' expressions are only allowed within async functions and at the top levels of modules.

Check failure on line 146 in node_package/src/serverRenderReactComponent.ts

View workflow job for this annotation

GitHub Actions / examples (newest)

'await' expressions are only allowed within async functions and at the top levels of modules.

Check failure on line 146 in node_package/src/serverRenderReactComponent.ts

View workflow job for this annotation

GitHub Actions / build-dummy-app-webpack-test-bundles (newest)

'await' expressions are only allowed within async functions and at the top levels of modules.
consoleReplayScript,
hasErrors,
} as RenderResult;
};

if (renderingError) {
addRenderingErrors(result, renderingError);
Expand Down
16 changes: 5 additions & 11 deletions node_package/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ interface RenderFunction {
(props?: any, railsContext?: RailsContext, domNodeId?: string): RenderFunctionResult;
// We allow specifying that the function is RenderFunction and not a React Function Component
// by setting this property
renderFunction?: boolean;
renderFunction?: true;
}

type ReactComponentOrRenderFunction = ReactComponent | RenderFunction;
Expand Down Expand Up @@ -87,22 +87,16 @@ export interface CreateParams extends Params {
shouldHydrate?: boolean;
}

interface FileError extends Error {
fileName: string;
lineNumber: string;
}

export interface ErrorOptions {
e: FileError;
// fileName and lineNumber are non-standard, but useful if present
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/fileName
e: Error & { fileName?: string; lineNumber?: string };
name?: string;
jsCode?: string;
serverSide: boolean;
}

export interface RenderingError {
message: string;
stack: string;
}
export type RenderingError = Pick<Error, 'message' | 'stack'>;

export interface RenderResult {
html: string | null;
Expand Down

0 comments on commit 84759a1

Please sign in to comment.