Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task: Remove ServerContext #10

Merged
merged 1 commit into from
Jan 12, 2024
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"build": "yarn clean && yarn tsc --project tsconfig.json && yarn babel --config-file ./config/babel.config.js src --out-dir . --extensions \".tsx,.ts,.js,.jsx\"",
"clean": "rm -rf index.d.ts index.d.ts.map index.js server.d.ts server.d.ts.map server.js client.d.ts client.d.ts.map client.js api lib types utils server",
"dev": "yarn clean && yarn watch",
"watch": "yarn tsc --project tsconfig.dev.json",
"watch": "yarn tsc --project tsconfig.dev.json --watch",
"lint": "eslint src config"
},
"dependencies": {
Expand Down
1 change: 0 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export { default as ContentComponent } from './server/components/ContentComponen
export { default as ContentComponentProvider } from './server/components/ContentComponentProvider';
export { default as Editable } from './server/components/Editable';
export { default as NodeRenderer } from './server/components/NodeRenderer';
export { NeosServerContext } from './server/utils/context';
export {
loadDocumentProps,
loadDocumentPropsCached,
Expand Down
9 changes: 6 additions & 3 deletions src/server/components/ContentCollection.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { ContextProps } from 'src/types';

import { useInBackend } from '../utils/hooks';
import ContentCollectionProvider from './ContentCollectionProvider';

type ContentCollectionProps = {
ctx: ContextProps;
as?: keyof JSX.IntrinsicElements;
nodeName?: string;
[x: string]: any;
};

const ContentCollection = async ({ as = 'div', nodeName, ...rest }: ContentCollectionProps) => {
const inBackend = useInBackend();
const ContentCollection = async ({ ctx, as = 'div', nodeName, ...rest }: ContentCollectionProps) => {
const inBackend = useInBackend(ctx);

const { className, ...restAttributes } = rest;
const Component = as;

return (
<ContentCollectionProvider nodeName={nodeName}>
<ContentCollectionProvider ctx={ctx} nodeName={nodeName}>
{({ collectionProps, children }) => (
<Component
className={[inBackend ? 'neos-contentcollection' : '', className].join(' ')}
Expand Down
11 changes: 7 additions & 4 deletions src/server/components/ContentCollectionProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { ContextProps } from 'src/types';

import { useInBackend } from '../utils/hooks';
import { useContentCollection } from '../utils/hooks';
import ContentComponentIncludes from './client/ContentComponentIncludes';
import NodeRenderer from './NodeRenderer';

type ContentCollectionProviderProps = {
ctx: ContextProps;
nodeName?: string;
children: ({
collectionProps,
Expand All @@ -14,9 +17,9 @@ type ContentCollectionProviderProps = {
}) => React.ReactNode;
};

const ContentCollectionProvider = async ({ nodeName, children }: ContentCollectionProviderProps) => {
const inBackend = useInBackend();
const { collectionNode, collectionProps } = await useContentCollection(nodeName)();
const ContentCollectionProvider = async ({ ctx, nodeName, children }: ContentCollectionProviderProps) => {
const inBackend = useInBackend(ctx);
const { collectionNode, collectionProps } = await useContentCollection(ctx, nodeName)();

if (!collectionNode) {
return null;
Expand All @@ -29,7 +32,7 @@ const ContentCollectionProvider = async ({ nodeName, children }: ContentCollecti
children: (
<>
{collectionNode.children?.map((child) => (
<NodeRenderer key={child.identifier} node={child} />
<NodeRenderer key={child.identifier} ctx={ctx} node={child} />
))}
{inBackend && (
<ContentComponentIncludes
Expand Down
7 changes: 5 additions & 2 deletions src/server/components/ContentComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { ContextProps } from 'src/types';

import ContentComponentProvider from './ContentComponentProvider';

type ContentComponentProps = {
ctx: ContextProps;
as?: keyof JSX.IntrinsicElements;
children: React.ReactNode;
[x: string]: any;
};

const ContentComponent = async ({ as = 'div', children, ...rest }: ContentComponentProps) => {
const ContentComponent = async ({ ctx, as = 'div', children, ...rest }: ContentComponentProps) => {
const Component = as;

return (
<ContentComponentProvider>
<ContentComponentProvider ctx={ctx}>
{({ componentProps, includes }) => (
<Component {...componentProps} {...rest}>
{children}
Expand Down
9 changes: 6 additions & 3 deletions src/server/components/ContentComponentProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ContextProps } from 'src/types';

import { useInBackend } from '../utils/hooks';
import { useContentComponent } from '../utils/hooks';
import ContentComponentIncludes from './client/ContentComponentIncludes';

type ContentComponentProviderProps = {
ctx: ContextProps;
children: ({
componentProps,
includes,
Expand All @@ -12,9 +15,9 @@ type ContentComponentProviderProps = {
}) => React.ReactNode;
};

const ContentComponentProvider = async ({ children }: ContentComponentProviderProps) => {
const inBackend = useInBackend();
const { componentNode, componentProps } = await useContentComponent()();
const ContentComponentProvider = async ({ ctx, children }: ContentComponentProviderProps) => {
const inBackend = useInBackend(ctx);
const { componentNode, componentProps } = await useContentComponent(ctx)();

if (!componentNode) {
return null;
Expand Down
11 changes: 7 additions & 4 deletions src/server/components/Editable.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { ContextProps } from 'src/types';

import { useEditPreviewMode, useInBackend, useNode } from '../utils/hooks';

type EditableProps = {
ctx: ContextProps;
as?: keyof JSX.IntrinsicElements;
property: string;
[x: string]: any;
};

const Editable = async ({ as = 'div', property, ...rest }: EditableProps) => {
const inBackend = useInBackend();
const loadNode = useNode();
const loadEditPreviewMode = useEditPreviewMode();
const Editable = async ({ ctx, as = 'div', property, ...rest }: EditableProps) => {
const inBackend = useInBackend(ctx);
const loadNode = useNode(ctx);
const loadEditPreviewMode = useEditPreviewMode(ctx);

const node = await loadNode();
const editPreviewMode = await loadEditPreviewMode();
Expand Down
29 changes: 14 additions & 15 deletions src/server/components/NodeRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { useContext } from 'react';

import { NeosContentNode } from '../../types';
import { NeosServerContext } from '../utils/context';
import { ContextProps, NeosContentNode } from '../../types';
import { loadDocumentPropsCached, loadPreviewDocumentPropsCached } from '../utils/dataLoader';
import { getNodeType } from '../utils/nodeTypes';

const NodeRenderer = async ({ node }: { node: NeosContentNode }) => {
const neosContext = useContext(NeosServerContext);
type NodeRendererProps = {
ctx: ContextProps;
node: NeosContentNode;
};

const NodeRenderer = async ({ ctx, node }: NodeRendererProps) => {
// We just fetch again and hope it will be cached
const neosData = neosContext.inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
const neosData = ctx.inBackend
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

if (!neosData) {
return <div>Could not load data</div>;
Expand All @@ -24,14 +24,13 @@ const NodeRenderer = async ({ node }: { node: NeosContentNode }) => {
}

return (
<NeosServerContext.Provider
value={{
...neosContext,
<Component
ctx={{
...ctx,
contextNodePath: node.contextPath,
currentNodeIdentifier: node.identifier,
}}
>
<Component />
</NeosServerContext.Provider>
/>
);
};

Expand Down
5 changes: 0 additions & 5 deletions src/server/utils/context.ts

This file was deleted.

11 changes: 4 additions & 7 deletions src/server/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { NeosContentNode, NeosData, NeosServerContextProps } from '../../types';
import { ContextProps, NeosContentNode, NeosData } from '../../types';

export function resolveCurrentNode(
neosContext: NeosServerContextProps,
neosData: NeosData
): NeosContentNode | undefined {
export function resolveCurrentNode(ctx: ContextProps, neosData: NeosData): NeosContentNode | undefined {
// Recurse into neosData.node / .children to find a node where identifier == currentNodeIdentifier
// and return that node

if (!neosContext.currentNodeIdentifier) {
if (!ctx.currentNodeIdentifier) {
return undefined;
}

return resolveCurrentNodeRecursive(neosContext.currentNodeIdentifier, neosData.node);
return resolveCurrentNodeRecursive(ctx.currentNodeIdentifier, neosData.node);
}

export function resolveCurrentNodeRecursive(
Expand Down
73 changes: 30 additions & 43 deletions src/server/utils/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,86 +1,73 @@
import { useContext } from 'react';
import { ContextProps } from 'src/types';

import { NeosServerContext } from './context';
import { loadDocumentPropsCached, loadPreviewDocumentPropsCached } from './dataLoader';
import { resolveCurrentNode } from './helper';

export const useMeta = () => {
const neosContext = useContext(NeosServerContext);

export const useMeta = (ctx: ContextProps) => {
return async () => {
const neosData = neosContext.inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
const neosData = ctx.inBackend
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

return neosData?.meta;
};
};

export const useNode = () => {
const neosContext = useContext(NeosServerContext);

export const useNode = (ctx: ContextProps) => {
return async () => {
const neosData = neosContext.inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
const neosData = ctx.inBackend
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

if (!neosData) {
return undefined;
}

const node = resolveCurrentNode(neosContext, neosData);
const node = resolveCurrentNode(ctx, neosData);

return node;
};
};

export const useDocumentNode = () => {
const neosContext = useContext(NeosServerContext);

export const useDocumentNode = (ctx: ContextProps) => {
return async () => {
const neosData = neosContext.inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
const neosData = ctx.inBackend
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

return neosData?.node;
};
};

export const useSiteNode = () => {
const neosContext = useContext(NeosServerContext);

export const useSiteNode = (ctx: ContextProps) => {
return async () => {
const neosData = neosContext.inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
const neosData = ctx.inBackend
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

return neosData?.site;
};
};

export const useInBackend = () => {
const neosContext = useContext(NeosServerContext);
return !!neosContext?.inBackend;
export const useInBackend = (ctx: ContextProps) => {
return !!ctx?.inBackend;
};

export const useEditPreviewMode = () => {
const neosContext = useContext(NeosServerContext);

export const useEditPreviewMode = (ctx: ContextProps) => {
return async () => {
const neosData = await loadPreviewDocumentPropsCached(neosContext.contextNodePath);
const neosData = await loadPreviewDocumentPropsCached(ctx.contextNodePath);

return neosData?.backend?.editPreviewMode;
};
};

export const useContentCollection = (nodeName?: string) => {
const inBackend = useInBackend();
const neosContext = useContext(NeosServerContext);
export const useContentCollection = (ctx: ContextProps, nodeName?: string) => {
const inBackend = useInBackend(ctx);

return async () => {
const neosData = inBackend
? await loadPreviewDocumentPropsCached(neosContext.contextNodePath)
: await loadDocumentPropsCached(neosContext.routePath);
? await loadPreviewDocumentPropsCached(ctx.contextNodePath)
: await loadDocumentPropsCached(ctx.routePath);

if (!neosData) {
return {
Expand All @@ -89,7 +76,7 @@ export const useContentCollection = (nodeName?: string) => {
};
}

const currentNode = resolveCurrentNode(neosContext, neosData);
const currentNode = resolveCurrentNode(ctx, neosData);
const collectionNode = nodeName ? currentNode?.children?.find((child) => child.nodeName === nodeName) : currentNode;

if (!collectionNode) {
Expand All @@ -111,11 +98,11 @@ export const useContentCollection = (nodeName?: string) => {
};
};

export const useContentComponent = () => {
const inBackend = useInBackend();
export const useContentComponent = (ctx: ContextProps) => {
const inBackend = useInBackend(ctx);

return async () => {
const node = await useNode()();
const node = await useNode(ctx)();

if (!node) {
return {
Expand Down
4 changes: 2 additions & 2 deletions src/server/utils/nodeTypes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { NeosNodeTypes } from '../../types';
import { ContextProps, NeosNodeTypes } from '../../types';

let nodeTypes: NeosNodeTypes;

export function initNodeTypes(data: NeosNodeTypes) {
nodeTypes = data;
}

export function getNodeType(nodeTypeName: string): React.FC | undefined {
export function getNodeType(nodeTypeName: string): React.FC<{ ctx: ContextProps }> | undefined {
return nodeTypes?.[nodeTypeName];
}
2 changes: 1 addition & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export interface ApiErrors {
errors?: { message: string; code: number }[];
}

export type NeosServerContextProps = {
export type ContextProps = {
routePath?: string;
contextNodePath?: string;
inBackend?: boolean;
Expand Down
1 change: 0 additions & 1 deletion tsconfig.dev.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"watch": true,
"emitDeclarationOnly": false
},
"watchOptions": {
Expand Down