Skip to content

Commit

Permalink
Merge pull request #107 from sima-land/38-examples-bun
Browse files Browse the repository at this point in the history
Шаг 60 #38
  • Loading branch information
krutoo committed Mar 6, 2024
2 parents 306999f + 25e318c commit 460d17c
Show file tree
Hide file tree
Showing 18 changed files with 284 additions and 111 deletions.
3 changes: 2 additions & 1 deletion examples/bun/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ SENTRY_RELEASE='example-release'
SENTRY_ENVIRONMENT='example-environment'

# misc
MAIN_HTTP_PORT='8080'
HTTP_PORT_MAIN='8080'
HTTP_PORT_METRICS='8081'
2 changes: 1 addition & 1 deletion examples/bun/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Example of http server application on Bun",
"scripts": {
"preparing": "cd ../.. && npm run build && npm pack && cd examples/bun && npm i --no-save ../../sima-land-isomorph-0.0.0.tgz",
"dev": "NODE_ENV=development bun run ./src/index.ts",
"dev": "NODE_ENV=development bun --watch run ./src/index.ts",
"type-check": "tsc -p . --noEmit"
},
"author": "www.sima-land.ru team",
Expand Down
6 changes: 4 additions & 2 deletions examples/bun/src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PresetBun, HandlerProvider } from '@sima-land/isomorph/preset/bun';
import { TOKEN } from '../tokens';
import { PostsPageApp } from '../pages/posts';
import { AuthorsPageApp } from '../pages/authors';
import { ServerHandler } from '@sima-land/isomorph/preset/server';

export function MainApp() {
const app = createApplication();
Expand All @@ -11,7 +12,7 @@ export function MainApp() {
app.preset(
PresetBun(({ override }) => {
// переопределяем провайдеры пресета
override(TOKEN.Lib.Http.Serve.routes, provideRoutes);
override(TOKEN.Lib.Http.Serve.routes, providePageRoutes);
}),
);

Expand All @@ -22,7 +23,8 @@ export function MainApp() {
return app;
}

function provideRoutes(resolve: Resolve) {
function providePageRoutes(resolve: Resolve): Array<[string, ServerHandler]> {
// определяем маршруты страниц
return [
['/', resolve(TOKEN.Pages.posts)],
['/posts', resolve(TOKEN.Pages.posts)],
Expand Down
13 changes: 10 additions & 3 deletions examples/bun/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import { MainApp } from './app';
import { TOKEN } from './tokens';

MainApp().invoke(
[TOKEN.Lib.Config.source, TOKEN.Lib.logger, TOKEN.Lib.Http.serve],
(config, logger, serve) => {
[TOKEN.Lib.Config.source, TOKEN.Lib.logger, TOKEN.Lib.Http.serve, TOKEN.Lib.Metrics.httpHandler],
(config, logger, serve, serveMetrics) => {
const server = Bun.serve({
port: config.require('MAIN_HTTP_PORT'),
port: config.require('HTTP_PORT_MAIN'),
fetch: serve,
});

logger.info(`Server started on ${server.url}`);

const metricsServer = Bun.serve({
port: config.require('HTTP_PORT_METRICS'),
fetch: serveMetrics,
});

logger.info(`Metrics server started on ${metricsServer.url}`);
},
);
4 changes: 2 additions & 2 deletions examples/bun/src/pages/authors/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createApplication, Resolve } from '@sima-land/isomorph/di';
import { PresetHandler } from '@sima-land/isomorph/preset/bun';
import { PresetBunHandler } from '@sima-land/isomorph/preset/bun-handler';
import { TOKEN } from '../../tokens';
import { Layout } from '../../components/Layout';
import { Nav } from '../../components/Nav';
Expand All @@ -10,7 +10,7 @@ export function AuthorsPageApp() {

// используем пресет "PresetHandler"
app.preset(
PresetHandler(({ override }) => {
PresetBunHandler(({ override }) => {
// переопределяем провайдеры пресета
override(TOKEN.Lib.Http.Handler.Page.render, provideRender);
}),
Expand Down
4 changes: 2 additions & 2 deletions examples/bun/src/pages/posts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createApplication, Resolve } from '@sima-land/isomorph/di';
import { PresetHandler } from '@sima-land/isomorph/preset/bun';
import { PresetBunHandler } from '@sima-land/isomorph/preset/bun-handler';
import { TOKEN } from '../../tokens';
import { Layout } from '../../components/Layout';
import { Nav } from '../../components/Nav';
Expand All @@ -10,7 +10,7 @@ export function PostsPageApp() {

// используем пресет "PresetHandler"
app.preset(
PresetHandler(({ override }) => {
PresetBunHandler(({ override }) => {
// переопределяем провайдеры пресета
override(TOKEN.Lib.Http.Handler.Page.render, provideRender);
}),
Expand Down
6 changes: 3 additions & 3 deletions examples/bun/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createToken } from '@sima-land/isomorph/di';
import { KnownToken } from '@sima-land/isomorph/tokens';

// чтобы токены можно было использовать как в браузере так и на сервере импорты должны содержать только типы
import type { Handler } from '@sima-land/isomorph/http';
import type { ServerHandler } from '@sima-land/isomorph/preset/server';
import type { AuthorApi } from './entities/author';
import type { PostApi } from './entities/post';

Expand All @@ -20,7 +20,7 @@ export const TOKEN = {
},
},
Pages: {
posts: createToken<Handler>('pages/posts'),
authors: createToken<Handler>('pages/authors'),
posts: createToken<ServerHandler>('pages/posts'),
authors: createToken<ServerHandler>('pages/authors'),
},
} as const;
1 change: 1 addition & 0 deletions examples/node/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module.exports = {
new EnvPlugin(),
new NodemonPlugin({
script: './dist/index.js',
exec: 'node --inspect',
watch: path.resolve('./dist'),
}),
new MiniCssExtractPlugin({
Expand Down
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@
"import": "./dist/esm/preset/bun/index.js",
"default": "./dist/esm/preset/bun/index.js"
},
"./preset/bun-handler": {
"types": "./dist/types/preset/bun-handler/index.d.ts",
"require": "./dist/cjs/preset/bun-handler/index.js",
"import": "./dist/esm/preset/bun-handler/index.js",
"default": "./dist/esm/preset/bun-handler/index.js"
},
"./utils": {
"types": "./dist/types/utils/index.d.ts",
"require": "./dist/cjs/utils/index.js",
Expand Down Expand Up @@ -306,6 +312,9 @@
"preset/bun": [
"./dist/types/preset/bun/index.d.ts"
],
"preset/bun-handler": [
"./dist/types/preset/bun-handler/index.d.ts"
],
"utils": [
"./dist/types/utils/index.d.ts"
],
Expand Down
56 changes: 9 additions & 47 deletions src/preset/bun-handler/providers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ import {
cookie,
createCookieStore,
defaultHeaders,
log,
LogHandler,
LogHandlerFactory,
} from '../../../http';
import { Fragment } from 'react';
import { FetchLogging } from '../../isomorphic/utils';
import {
FetchLogging,
getFetchErrorLogging,
getFetchExtraAborting,
getFetchLogging,
} from '../../isomorphic/utils';
import { getForwardedHeaders, getPageResponseFormat } from '../../server/utils';
import { PageAssets } from '../../isomorphic/types';
import { RESPONSE_EVENT_TYPE } from '../../isomorphic/constants';
Expand Down Expand Up @@ -177,40 +181,10 @@ export const HandlerProviders = {

return [
// ВАЖНО: слой логирования ошибки ПЕРЕД остальными слоями чтобы не упустить ошибки выше
log(initData => {
if (typeof logHandler === 'function') {
return {
onCatch: data => logHandler(initData).onCatch?.(data),
};
}

return {
onCatch: data => logHandler.onCatch?.(data),
};
}),
getFetchErrorLogging(logHandler),

// обрывание по сигналу из обработчика входящего запроса и по сигналу из конфига исходящего запроса
(request, next) => {
const innerController = new AbortController();

request.signal?.addEventListener(
'abort',
() => {
innerController.abort();
},
{ once: true },
);

abortController.signal.addEventListener(
'abort',
() => {
innerController.abort();
},
{ once: true },
);

return next(new Request(request, { signal: innerController.signal }));
},
getFetchExtraAborting(abortController),

cookie(cookieStore),

Expand All @@ -219,19 +193,7 @@ export const HandlerProviders = {
// @todo metrics, tracing

// ВАЖНО: слой логирования запроса и ответа ПОСЛЕ остальных слоев чтобы использовать актуальные данные
log(initData => {
if (typeof logHandler === 'function') {
return {
onRequest: data => logHandler(initData).onRequest?.(data),
onResponse: data => logHandler(initData).onResponse?.(data),
};
}

return {
onRequest: data => logHandler.onRequest?.(data),
onResponse: data => logHandler.onResponse?.(data),
};
}),
getFetchLogging(logHandler),
];
},

Expand Down
2 changes: 2 additions & 0 deletions src/preset/bun/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getServeMeasuring,
} from '../../server/utils';
import PromClient from 'prom-client';
import { statsHandler } from '../utils';

export const BunProviders = {
configSource(): ConfigSource {
Expand Down Expand Up @@ -88,6 +89,7 @@ export const BunProviders = {
return [
// служебные маршруты (без промежуточных слоев)
['/healthcheck', healthCheck()],
['/stats', statsHandler()],
];
},

Expand Down
22 changes: 22 additions & 0 deletions src/preset/bun/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import type { Handler } from '../../../http';
import type { ServerHandler } from '../../server/types';
import { KnownToken } from '../../../tokens';
import { CURRENT_APP, type Application, type Resolve, Provider } from '../../../di';
Expand All @@ -17,3 +18,24 @@ export function HandlerProvider(getApp: () => Application): Provider<ServerHandl
};
};
}

// ВАЖНО: временная экспериментальная утилита, скорее всего будет удалена в будущем
export function statsHandler(): Handler {
/** @inheritdoc */
const getHeapStats = async () => {
const jsc = await import(
/* webpackIgnore: true */
`bun:jsc`
);

return jsc.heapStats();
};

return async () => {
const stats = await getHeapStats();

return new Response(JSON.stringify(stats, null, 2), {
headers: { 'content-type': 'application/json' },
});
};
}
Loading

0 comments on commit 460d17c

Please sign in to comment.