Skip to content

Commit

Permalink
Support custom server (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
mildronize committed Feb 7, 2024
2 parents 81ed46b + 9866db9 commit 2c2ef6a
Show file tree
Hide file tree
Showing 41 changed files with 7,919 additions and 136 deletions.
74 changes: 74 additions & 0 deletions .changeset/brave-points-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
'@thaitype/data-viewer-server': major
---

Release first stable version

## Breaking Changes

- Type changed from `ServerOptions` to `DataViewerOptions`
- Moved `logger?: LoggerOptions;` from `DataViewerOptions` to `StartOptions` with new option name `loggerOption?: LoggerOptions;` for `start` method
- Used `logger?: Logger;` in `DataViewerOptions` for custom logger
- Moved `port` from `DataViewerOptions` to `start` method (with type `StartOptions`)
`DataViewerOptions` is now dataViewer.addOption
- `TableComponent` interface `data` property is allow `(Record<string, unknown> | object)[];` type.

## New Features

## **Create Data Container**

Sometimes, you may want to create a data container and add data to it later.

```ts
export function myReport(){
const container = new Container();
container.addHeader('My Header');
return container.get();
}

dataViewer.addContainer(myReport());
dataViewer.start();
```

## Support Custom Server

You can use the `registerMiddleware` method to integrate with your existing server.

```ts
const getUsers = async () => (await fetch('https://jsonplaceholder.typicode.com/users')).json();

const dataViewer = new DataViewer({
path: '/viewer',
});

dataViewer.addHeader('User Table');
dataViewer.addTable(await getUsers());

const app = express();
dataViewer.registerMiddleware(app);

app.listen(3000, async () => console.log(`Already servered on http://localhost:3000/viewer`));
```

## Support Custom Logger

You can use the `logger` option to integrate with your existing log,
this example uses [pino](https://github.com/pinojs/pino) log

```ts
import pino from 'pino';
const logger = pino();

const stringLogger = {
log: (message: string) => logger.info(message),
debug: (message: string) => logger.debug(message),
info: (message: string) => logger.info(message),
warn: (message: string) => logger.warn(message),
error: (message: string) => logger.error(message),
};

const dataViewer = new DataViewer({
path: '/viewer',
logger: stringLogger,
}).start();
```
35 changes: 35 additions & 0 deletions .github/workflows/end-to-end.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Test E2E
on:
pull_request:
branches:
- 'main'
push:
branches:
- 'main'

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
project-path:
- 'end-to-end/test-cjs'
- 'end-to-end/test-esm'

steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8

- uses: actions/setup-node@v3
with:
node-version: 18.x
cache: 'pnpm'
cache-dependency-path: ${{ matrix.project-path }}/pnpm-lock.yaml

- run: pnpm install --frozen-lockfile
working-directory: ${{ matrix.project-path }}

- run: pnpm run test
working-directory: ${{ matrix.project-path }}
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build
name: CI
on:
push:
branches:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,6 @@ dist
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.pnp.*

.tmp
103 changes: 92 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@ When developing Node.js applications, it's often crucial to inspect and visualiz

- **Live Reload:** Automatically updates the displayed data when the server is restarted.
- **Dynamic Table Support:** Works seamlessly with **`Record<string, unknown>[]`** data type and straightforward headers.
- **Support Custom Server:** Integrate with your existing server.
- **Custom Logger:** Integrate with your existing log.

## Demo

![](images/demo.gif)

## Installation

```bash
npm install @thaitype/data-viewer-server
```

## Getting Started

1. Create a file named **`main.ts`**:
Expand All @@ -31,7 +39,7 @@ When developing Node.js applications, it's often crucial to inspect and visualiz

async function main() {
dataViewer.addHeader('User Table');
dataViewer.addTable((await getUsers()));
dataViewer.addTable(await getUsers());
dataViewer.addHeader('Post Table');
dataViewer.addTable(await getPosts());
dataViewer.start();
Expand All @@ -47,13 +55,84 @@ When developing Node.js applications, it's often crucial to inspect and visualiz
```
3. The view is automatically updated when the server restarts.

## **Create Data Container**

Sometimes, you may want to create a data container and add data to it later.

```ts
export function myReport(){
const container = new Container();
container.addHeader('My Header');
return container.get();
}

dataViewer.addContainer(myReport());
dataViewer.start();
```

## Support Custom Server

You can use the `registerMiddleware` method to integrate with your existing server.

```ts
const getUsers = async () => (await fetch('https://jsonplaceholder.typicode.com/users')).json();

const dataViewer = new DataViewer({
path: '/viewer',
});

dataViewer.addHeader('User Table');
dataViewer.addTable(await getUsers());

const app = express();
dataViewer.registerMiddleware(app);

app.listen(3000, async () => console.log(`Already servered on http://localhost:3000/viewer`));
```

## Support Custom Logger

You can use the `logger` option to integrate with your existing log,
this example uses [pino](https://github.com/pinojs/pino) log

```ts
import pino from 'pino';
const logger = pino();

const stringLogger = {
log: (message: string) => logger.info(message),
debug: (message: string) => logger.debug(message),
info: (message: string) => logger.info(message),
warn: (message: string) => logger.warn(message),
error: (message: string) => logger.error(message),
};

const dataViewer = new DataViewer({
path: '/viewer',
logger: stringLogger,
}).start();
```

## Idea Behind the Scene

- Utilizes [Express.js](https://expressjs.com/) to run [EJS Templates](https://ejs.co/) by taking data from the server-side (Node.js) and rendering it using [DataTables](https://datatables.net/) jQuery to create the table.
- Implements [Socket.io](https://socket.io/) for handling real-time events.

## **Manual**

### Disable Live Reload

By default, `start` method enables live reload automatically. You can disable live reload by setting the `enableLiveReload` option to `false`.

```ts
const dataViewer = new DataViewer({
enableLiveReload: false,
})
dataViewer.start();
```

When use use the custom server by `DataViewer.registerMiddleware` method, you don't need to set `enableLiveReload` option. Because it's already disabled by default.

### **Custom Cell Formatter Function**

You can define a custom cell formatting function to tailor the appearance of individual cells. This function takes a cell value as input and returns the formatted string to be displayed in the table.
Expand All @@ -75,23 +154,25 @@ In this example, the cell formatter checks if the cell value is an object, and i

### **Setup Log Level**

The package uses the [pino](https://github.com/pinojs/pino) package internally. Example: set up **`debug`** log level.
`DataViewer.start` method has built-in express server and uses the [pino](https://github.com/pinojs/pino) package internally. Example: set up **`debug`** log level.

```ts
dataViewer.setOption({
logger: {
level: 'debug',
},
});
dataViewer
.start({
loggerOption: {
level: 'debug',
}
});
```

### **Setup Port**

Example: Set up the server to run on port 5000.
```ts
dataViewer.setOption({
port: 5000
});
dataViewer
.start({
port: 5000,
});
```

### **Setup View (EJS Template) Directory**
Expand All @@ -108,7 +189,7 @@ By default, the viewDirectory is set to `__dirname + '/views'`.

### **Create a New Instance**

Rarely needed, but you can create a new instance.
You can create a new instance.

```ts
import { DataViewer } from '@thaitype/data-viewer-server';
Expand Down
11 changes: 11 additions & 0 deletions end-to-end/test-cjs/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-env node */
module.exports = {
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
root: true,
ignorePatterns: ["**.test.ts"],
rules: {
'@typescript-eslint/consistent-type-imports': 'error',
}
};

0 comments on commit 2c2ef6a

Please sign in to comment.