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

feat: create YLS context for using baseURL #14

Merged
merged 8 commits into from
Jun 2, 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
1 change: 1 addition & 0 deletions apps/demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
2 changes: 1 addition & 1 deletion apps/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
<script type="module" src="./src/main.tsx"></script>
</body>
</html>
5 changes: 0 additions & 5 deletions apps/demo/main.tsx

This file was deleted.

1 change: 1 addition & 0 deletions apps/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dev": "vite"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.3.0",
"@yourssu/logging-system-react": "workspace:*",
"react-router-dom": "^6.21.3",
"vite": "^4.4.5",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions apps/demo/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { YLSWrapper } from '@yourssu/logging-system-react';
import ReactDOM from 'react-dom/client';

import { App } from './App';

const baseURL = import.meta.env.VITE_API_YLS_URL;

ReactDOM.createRoot(document.getElementById('root')!).render(
<YLSWrapper baseURL={baseURL}>
<App />
</YLSWrapper>
);
1 change: 1 addition & 0 deletions apps/demo/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
5 changes: 4 additions & 1 deletion apps/demo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "../../tsconfig.json"
"extends": "../../tsconfig.json",
"compilerOptions": {
"types": ["vite/client"]
}
}
7 changes: 7 additions & 0 deletions apps/demo/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
6 changes: 6 additions & 0 deletions packages/logging-system/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['../../.eslintrc.cjs'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
},
};
15 changes: 15 additions & 0 deletions packages/logging-system/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ YLS는 숭실대학교 동아리 유어슈에서 사용하는 로깅 시스템

## Installation

1. YLS를 설치합니다.

```
npm install @yourssu/logging-system-react

Expand All @@ -16,6 +18,19 @@ yarn add @yourssu/logging-system-react
pnpm install @yourssu/logging-system-react
```

2. Root Component에 YLSWrapper를 감싸고 baseURL을 설정합니다.

```jsx
// vite 사용 시
const baseURL = import.meta.env.VITE_API_YLS_URL;

ReactDOM.createRoot(document.getElementById('root')!).render(
<YLSWrapper baseURL={baseURL}>
<App />
</YLSWrapper>
);
```

## Usage

YLS 내부에서는 timestamp와 platform을 처리합니다.
Expand Down
35 changes: 24 additions & 11 deletions packages/logging-system/src/Logger.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SHA256 from 'crypto-js/sha256';
import CryptoJS from 'crypto-js';

import { SetLocalStorage, SetLocalStorageClear } from './SetLocalStorage';
import { postLog } from './apis/postLog';
import { LogPayloadParams, LogRequestList, LogType } from './types/LogType';
import { useYLSContext } from './hooks/useYLSContext';
import { LogPayloadParams, LogRequestList, LogResponse, LogType } from './types/LogType';

const createRandomId = () => {
let randomId = '';
Expand All @@ -29,7 +29,7 @@ const createHashedID = (userId: string) => {
userId = createRandomId();
}

hashedId = SHA256(userId).toString(CryptoJS.enc.Base64);
hashedId = CryptoJS.SHA256(userId).toString(CryptoJS.enc.Base64);

return localHashedId ? localHashedId : hashedId;
};
Expand All @@ -40,7 +40,12 @@ const createTimestamp = () => {
return now.toISOString();
};

const initialLog = (userId: string, version: number, event: LogPayloadParams['event']) => {
const initialLog = (
userId: string,
version: number,
event: LogPayloadParams['event'],
postLog: (data: LogRequestList) => Promise<LogResponse>
) => {
const loggerType: LogPayloadParams = {
userId: userId,
version: version,
Expand All @@ -49,16 +54,18 @@ const initialLog = (userId: string, version: number, event: LogPayloadParams['ev

const logger = Logger(loggerType);

SetLocalStorage(logger);
SetLocalStorage(logger, postLog);
};

export const useYLSLogger = () => {
const { postLog } = useYLSContext();

const screen = ({ userId, version, event }: LogPayloadParams) => {
initialLog(userId, version, event);
initialLog(userId, version, event, postLog);
};

const click = ({ userId, version, event }: LogPayloadParams) => {
initialLog(userId, version, event);
initialLog(userId, version, event, postLog);
};

return {
Expand All @@ -82,12 +89,18 @@ export const Logger = ({ userId, version, event }: LogPayloadParams) => {
window.addEventListener('unload', async (event) => {
event.preventDefault();

const { postLog } = useYLSContext();
const logList: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) || [];
const req: LogRequestList = {
logRequestList: logList,
};
const res = await postLog(req);
if (res.success) {
SetLocalStorageClear();

try {
const res = await postLog(req);
if (res.success) {
SetLocalStorageClear();
}
} catch (e) {
console.error('Failed to post log');
}
});
18 changes: 12 additions & 6 deletions packages/logging-system/src/SetLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { postLog } from './apis/postLog';
import { LogRequestList, LogType } from './types/LogType';
import { LogRequestList, LogResponse, LogType } from './types/LogType';

export const SetLocalStorageClear = () => {
const list: any[] = [];
localStorage.setItem('yls-web', JSON.stringify(list));
};

export const SetLocalStorage = async (logger: LogType) => {
export const SetLocalStorage = async (
logger: LogType,
postLog: (data: LogRequestList) => Promise<LogResponse>
) => {
if (window.localStorage.getItem('yls-web') == undefined) {
const list: any[] = [];
list.push(logger);
Expand All @@ -20,10 +22,14 @@ export const SetLocalStorage = async (logger: LogType) => {
const req: LogRequestList = {
logRequestList: remainList,
};
const res = await postLog(req);

if (res.success) {
SetLocalStorageClear();
try {
const res = await postLog(req);
if (res.success) {
SetLocalStorageClear();
}
} catch (e) {
console.error('Failed to post log');
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions packages/logging-system/src/apis/createAxiosInstance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from 'axios';

export const createAxiosInstance = (baseURL: string) => {
return axios.create({
baseURL,
headers: {
'Content-Type': 'application/json',
withCredentials: true,
},
});
};
10 changes: 0 additions & 10 deletions packages/logging-system/src/apis/customedAxios.ts

This file was deleted.

8 changes: 0 additions & 8 deletions packages/logging-system/src/apis/postLog.ts

This file was deleted.

14 changes: 14 additions & 0 deletions packages/logging-system/src/components/YLSWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { YLSProvider } from '@/contexts/YLSProvider';

interface YLSWrapperProps {
children: React.ReactNode;
baseURL: string;
}

/**
* YLS에 사용되는 Context를 위한 컴포넌트입니다.
* YLS를 사용하는 프로젝트의 최상위 컴포넌트로 사용해야 합니다.
*/
export const YLSWrapper = ({ children, baseURL }: YLSWrapperProps) => {
return <YLSProvider baseURL={baseURL}>{children}</YLSProvider>;
};
44 changes: 44 additions & 0 deletions packages/logging-system/src/contexts/YLSProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { createContext } from 'react';

import { createAxiosInstance } from '@/apis/createAxiosInstance';
import { LogRequestList, LogResponse } from '@/types/LogType';

interface YLSProviderProps {
children: React.ReactNode;
baseURL: string;
}

export interface YLSContextType {
postLog: (data: LogRequestList) => Promise<LogResponse>;
}

export const YLSContext = createContext<YLSContextType | undefined>(undefined);

/**
* YLS에 사용되는 Context Provider를 위한 컴포넌트입니다.
* 일반적으로 YLSWrapper 컴포넌트를 사용하시면 됩니다.
* @param param0
* @returns
*/
export const YLSProvider = ({ children, baseURL }: YLSProviderProps) => {
const axiosInstance = createAxiosInstance(baseURL);

const postLog = async (data: LogRequestList): Promise<LogResponse> => {
try {
const res = await axiosInstance.put('/log/list', data);
return res.data;
} catch (e) {
throw new Error('Failed to post log');
}
};

return (
<YLSContext.Provider
value={{
postLog,
}}
>
{children}
</YLSContext.Provider>
);
};
11 changes: 11 additions & 0 deletions packages/logging-system/src/hooks/useYLSContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useContext } from 'react';

import { YLSContext } from '@/contexts/YLSProvider';

export const useYLSContext = () => {
const context = useContext(YLSContext);
if (!context) {
throw new Error('useYLSContext must be used within a YLSProvider');
}
return context;
};
1 change: 1 addition & 0 deletions packages/logging-system/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { YLSWrapper } from './components/YLSWrapper';
export { useYLSLogger } from './Logger';
export { LogClick } from './components/LogClick';
export { LogScreen } from './components/LogScreen';
2 changes: 1 addition & 1 deletion packages/logging-system/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
resolve: true,
},
external: ['react', 'react-dom'],
noExternal: ['crypto-js/sha256'],
noExternal: ['crypto-js'],
splitting: false,
clean: true,
sourcemap: true,
Expand Down
Loading