Skip to content

Commit

Permalink
wip: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Jun 6, 2024
1 parent 5df7f07 commit e7dc174
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 34 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
"import": "./dist/mjs/react/index.js",
"types": "./dist/mjs/react/index.d.ts"
},
"./rsc": {
"import": "./dist/mjs/rsc/index.js",
"require": "./dist/cjs/rsc/index.js",
"types": "./dist/mjs/rsc/index.d.ts"
},
"./test": "./test/server.ts"
},
"files": [
Expand Down
1 change: 1 addition & 0 deletions packages/core/rsc.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/mjs/rsc';
2 changes: 2 additions & 0 deletions packages/core/rsc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/extensions
module.exports = require('./dist/cjs/rsc');
2 changes: 2 additions & 0 deletions packages/core/src/rsc/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './useFetch';
export * from './useFetchPost';
10 changes: 10 additions & 0 deletions packages/core/src/rsc/hooks/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FetchOptions } from '../../data';

export interface HookResponse {
data?: {};
isMainQuery: boolean;
}

export interface FetchHookOptions {
fetchStrategyOptions?: Partial<FetchOptions>;
}
63 changes: 63 additions & 0 deletions packages/core/src/rsc/hooks/useFetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import deepmerge from 'deepmerge';
import type { EndpointParams } from '../../data';
import { AbstractFetchStrategy } from '../../data';

import type { FetchHookOptions } from './types';
import { getHeadstartWPConfig, log, LOGTYPE } from '../../utils';

export interface useFetchOptions {}

/**
* The use Fetch Hook is the foundation for most hooks in the headless framework. It is a wrapper around
* `useSWR` and provides a consistent API for fetching data from the API. It requires a fetch strategy which implements
* the actual data fetching logic
*
* @param params The list of params to pass to the fetch strategy. It overrides the ones in the URL.
* @param fetchStrategy The fetch strategy.
* @param options The options to pass to the swr hook.
* @param path The path of the url to get url params from.
*
* @category Data Fetching Hooks
*
*/
export async function useFetch<E, Params extends EndpointParams, R = E>(
params: Params | {},
fetchStrategy: AbstractFetchStrategy<E, Params, R>,
options: FetchHookOptions = {},
path = '',
) {
const { sourceUrl, debug } = getHeadstartWPConfig();

fetchStrategy.setBaseURL(sourceUrl);

const defaultParams = fetchStrategy.getDefaultParams();
const urlParams = fetchStrategy.getParamsFromURL(path, params);
const isMainQuery = fetchStrategy.isMainQuery(path, params);

const finalParams = deepmerge.all([defaultParams, urlParams, params]) as Partial<Params>;

const { fetchStrategyOptions } = options;

const endpointUrl = fetchStrategy.buildEndpointURL(finalParams);
const key = fetchStrategy.getCacheKey(finalParams);

if (debug?.devMode) {
log(LOGTYPE.INFO, `[useFetch] key for ${key.url}`, key);
}

const fetchData = await fetchStrategy.fetcher(endpointUrl, finalParams, fetchStrategyOptions);

const { data /* additionalCacheObjects */ } = fetchStrategy.normalizeForCache(
fetchData,
finalParams,
);

// mutate additiional cache objects
/* if (additionalCacheObjects) {
additionalCacheObjects.forEach(({ key, data }) => {
// mutate(key, data);
});
} */

return { data, params: finalParams, isMainQuery };
}
65 changes: 65 additions & 0 deletions packages/core/src/rsc/hooks/useFetchPost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useFetch } from './useFetch';
import type { FetchHookOptions, HookResponse } from './types';
import {
FetchResponse,
getPostAuthor,
getPostTerms,
PostEntity,
PostParams,
SinglePostFetchStrategy,
} from '../../data';
import { getWPUrl } from '../../utils';

export interface usePostResponse<T extends PostEntity = PostEntity> extends HookResponse {
data: {
post: T;
pageInfo: FetchResponse<T>['pageInfo'];
queriedObject: FetchResponse<T>['queriedObject'];
};
}

/**
* The useFetchPost hook. Returns a single post entity
*
* See {@link usePost} for usage instructions.
*
* @param params The list of params to pass to the fetch strategy. It overrides the ones in the URL.
* @param options The options to pass to the swr hook.
* @param path The path of the url to get url params from.
*
* @module useFetchPost
* @category Data Fetching Hooks
*/
export async function useFetchPost<
T extends PostEntity = PostEntity,
P extends PostParams = PostParams,
>(params: P | {} = {}, options: FetchHookOptions = {}, path = ''): Promise<usePostResponse<T>> {
const { data, isMainQuery } = await useFetch<T[], P, T>(
params,
useFetchPost.fetcher<T, P>(),
options,
path,
);

const post = {
...data.result,
author: getPostAuthor(data.result),
terms: getPostTerms(data.result),
};

return {
data: { post, pageInfo: data.pageInfo, queriedObject: data.queriedObject },
isMainQuery,
};
}

/**
* @internal
*/
// eslint-disable-next-line no-redeclare
export namespace useFetchPost {
export const fetcher = <T extends PostEntity = PostEntity, P extends PostParams = PostParams>(
sourceUrl?: string,
defaultParams?: P,
) => new SinglePostFetchStrategy<T, P>(sourceUrl ?? getWPUrl(), defaultParams);
}
1 change: 1 addition & 0 deletions packages/core/src/rsc/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './components/BlocksRenderer';
export * from './hooks';
2 changes: 2 additions & 0 deletions projects/wp-nextjs-app/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NEXT_PUBLIC_HEADLESS_WP_URL=https://js1.10up.com
NEXT_PUBLIC_HOST_URL=https://js1.10up.com
10 changes: 10 additions & 0 deletions projects/wp-nextjs-app/headstartwp.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Headless Config
*
* @type {import('@headstartwp/core').HeadlessConfig}
*/
module.exports = {
sourceUrl: process.env.NEXT_PUBLIC_HEADLESS_WP_URL,

useWordPressPlugin: true,
};
6 changes: 6 additions & 0 deletions projects/wp-nextjs-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const { withHeadstartWPConfig } = require('@headstartwp/next/config');

/** @type {import('next').NextConfig} */
const nextConfig = {};

module.exports = withHeadstartWPConfig(nextConfig);
4 changes: 0 additions & 4 deletions projects/wp-nextjs-app/next.config.mjs

This file was deleted.

1 change: 1 addition & 0 deletions projects/wp-nextjs-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
},
"devDependencies": {
"@headstartwp/core": "^1.4.3",
"@headstartwp/next": "^1.4.2",
"@10up/eslint-config": "^4.0.0",
"typescript": "^5",
"@types/node": "^20",
Expand Down
40 changes: 10 additions & 30 deletions projects/wp-nextjs-app/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,20 @@
import { BlockProps, BlocksRenderer } from '@headstartwp/core/react';
// eslint-disable-next-line
import { DOMNode, Element } from 'html-react-parser';
import { BlocksRenderer } from '@headstartwp/core/react';
import { useFetchPost } from '@headstartwp/core/rsc';
import { setHeadstartWPConfig } from '@headstartwp/core';
import styles from './page.module.css';
import config from '../../headstartwp.config';

async function fetchBlockData() {
return new Promise((resolve) => {
setTimeout(() => resolve({ title: 'test' }), 200);
});
}

const DivToP = async ({ domNode, children }: BlockProps) => {
const { title } = await fetchBlockData();
setHeadstartWPConfig(config);

const className = domNode instanceof Element ? domNode?.attribs.class || undefined : undefined;
return (
<p className={className}>
{title}
{children}
</p>
);
};
const Home = async () => {
const { data } = await useFetchPost({
slug: '/distinctio-rerum-ratione-maxime-repudiandae-laboriosam-quam',
});

const Home = () => {
return (
<main className={styles.main}>
<div className={styles.description}>
<BlocksRenderer html="<div class='my-class'>This Will Become a p tag</div><div>This Will Become a p tag</div>">
<DivToP
test={(node: DOMNode) => {
if (!(node instanceof Element)) {
return false;
}
return node.type === 'tag' && node.name === 'div';
}}
/>
</BlocksRenderer>
<BlocksRenderer html={data.post.content.rendered ?? ''} />
</div>
</main>
);
Expand Down

0 comments on commit e7dc174

Please sign in to comment.