Skip to content

Commit

Permalink
Merge pull request #113 from sima-land/38-examples-bun
Browse files Browse the repository at this point in the history
Шаг 66 #38
  • Loading branch information
krutoo committed Mar 11, 2024
2 parents 33e87cf + 4a33b5c commit e1379f0
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 66 deletions.
4 changes: 2 additions & 2 deletions examples/bun/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import type { CSSProperties, ReactNode } from 'react';

const style = {
const style: CSSProperties = {
padding: '40px',
margin: '0 auto',
maxWidth: '960px',
Expand Down
4 changes: 3 additions & 1 deletion examples/bun/src/pages/authors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ function provideRender(resolve: Resolve) {
}

function provideAuthorApi(resolve: Resolve) {
const fetch = resolve(TOKEN.Lib.Http.fetch);

return createAuthorApi({
host: 'https://jsonplaceholder.typicode.com/',
fetch: resolve(TOKEN.Lib.Http.fetch),
fetch,
});
}
4 changes: 3 additions & 1 deletion examples/bun/src/pages/posts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ function provideRender(resolve: Resolve) {
}

function providePostApi(resolve: Resolve) {
const fetch = resolve(TOKEN.Lib.Http.fetch);

return createPostApi({
host: 'https://jsonplaceholder.typicode.com/',
fetch: resolve(TOKEN.Lib.Http.fetch),
fetch,
});
}
4 changes: 2 additions & 2 deletions examples/node/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import type { CSSProperties, ReactNode } from 'react';

const style = {
const style: CSSProperties = {
padding: '40px',
margin: '0 auto',
maxWidth: '960px',
Expand Down
6 changes: 4 additions & 2 deletions examples/node/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/node';
import { PresetHandler } from '@sima-land/isomorph/preset/node-handler';
import { TOKEN } from '../../tokens';
import { Layout } from '../../components/Layout';
import { Nav } from '../../components/Nav';
Expand Down Expand Up @@ -47,8 +47,10 @@ function provideRender(resolve: Resolve) {
}

function provideAuthorApi(resolve: Resolve) {
const fetch = resolve(TOKEN.Lib.Http.fetch);

return createAuthorApi({
host: 'https://jsonplaceholder.typicode.com/',
fetch: resolve(TOKEN.Lib.Http.fetch),
fetch,
});
}
6 changes: 4 additions & 2 deletions examples/node/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/node';
import { PresetHandler } from '@sima-land/isomorph/preset/node-handler';
import { TOKEN } from '../../tokens';
import { Layout } from '../../components/Layout';
import { Nav } from '../../components/Nav';
Expand Down Expand Up @@ -47,8 +47,10 @@ function provideRender(resolve: Resolve) {
}

function providePostApi(resolve: Resolve) {
const fetch = resolve(TOKEN.Lib.Http.fetch);

return createPostApi({
host: 'https://jsonplaceholder.typicode.com/',
fetch: resolve(TOKEN.Lib.Http.fetch),
fetch,
});
}
3 changes: 2 additions & 1 deletion src/preset/bun/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ export function PresetBun(customize?: PresetTuner) {
return preset;
}

export { HandlerProvider } from './utils';
export { HandlerProvider } from '../server/utils/handler-provider';
export { getStatsHandler } from './utils/get-stats-handler';
4 changes: 2 additions & 2 deletions src/preset/bun/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getCurrentHub, init, runWithAsyncContext } from '@sentry/bun';
import { createSentryHandler } from '../../../log/handler/sentry';
import { provideFetch } from '../../isomorphic/providers';
import { ServerHandler, ServerMiddleware } from '../../server/types';
import { statsHandler } from '../utils';
import { getStatsHandler } from '../utils/get-stats-handler';
import { getHealthCheck } from '../../server/utils/get-health-check';
import { getServeLogging } from '../../server/utils/get-serve-logging';
import { getServeErrorLogging } from '../../server/utils/get-serve-error-logging';
Expand Down Expand Up @@ -87,7 +87,7 @@ export const BunProviders = {
return [
// служебные маршруты (без промежуточных слоев)
['/healthcheck', getHealthCheck()],
['/stats', statsHandler()],
['/stats', getStatsHandler()],
];
},

Expand Down
25 changes: 25 additions & 0 deletions src/preset/bun/utils/get-stats-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Handler } from '../../../http';

/**
* ВАЖНО: временная экспериментальная утилита, скорее всего будет удалена в будущем.
* @inheritdoc
*/
export function getStatsHandler(): 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' },
});
};
}
41 changes: 0 additions & 41 deletions src/preset/bun/utils/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/preset/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { getClientIp } from './utils/get-client-ip';
export { getForwardedHeaders } from './utils/get-forwarded-headers';
export { getHealthCheck } from './utils/get-health-check';
export { getPageResponseFormat } from './utils/get-page-response-format';
export { HandlerProvider } from './utils/handler-provider';
25 changes: 25 additions & 0 deletions src/preset/server/utils/handler-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ServerHandler } from '../../server/types';
import { KnownToken } from '../../../tokens';
import { CURRENT_APP, type Application, type Resolve, Provider } from '../../../di';

/**
* Получив фабрику DI-приложения вернёт провайдер обработчика.
* После получения запроса фабрика будет вызвана.
* Далее будет произведена попытка получить компонент обработчика.
* @param getApp Фабрика DI-приложения.
* @return Провайдер обработчика.
*/
export function HandlerProvider(getApp: () => Application): Provider<ServerHandler> {
return (resolve: Resolve): ServerHandler => {
const parent = resolve(CURRENT_APP);

return (request, context) => {
const app = getApp();

app.attach(parent);
app.bind(KnownToken.Http.Handler.context).toValue({ request, ...context });

return app.get(KnownToken.Http.Handler.main)(request, context);
};
};
}
91 changes: 79 additions & 12 deletions src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,27 @@ import type { CookieStore, Handler, LogHandler, LogHandlerFactory, Middleware }
import type { HttpApiHostPool } from './preset/isomorphic/utils/http-api-host-pool';
import type { ServerHandlerContext, ServerHandler, ServerMiddleware } from './preset/server/types';

/**
* Токены компонентов.
* Данные токены используются в DI-пресетах, доступных из пакета.
*/
export const KnownToken = {
// config
/** Токены компонентов конфигурации приложения. */
Config: {
/** Токен "источника конфигурации". */
source: createToken<ConfigSource>('config/source'),

/** Токен базовой конфигурации. */
base: createToken<BaseConfig>('config/base'),
},

// cache
/** Токен компонента кеша. */
cache: createToken<Cache>('cache'),

// log
/** Токен компонента логгера. */
logger: createToken<Logger>('logger'),

// tracing
/** Токены компонентов трассировки и телеметрии. */
Tracing: {
tracer: createToken<Tracer>('tracing/tracer'),
spanExporter: createToken<SpanExporter>('tracing/span-exporter'),
Expand All @@ -44,71 +51,123 @@ export const KnownToken = {
tracerProviderResource: createToken<Resource>('tracing/resource'),
},

// metrics
/** Токены компонентов сбора метрик. */
Metrics: {
httpApp: createToken<express.Application>('metrics/http-app'),
httpHandler: createToken<Handler>('metrics/http-handler'),
},

// http
/** Токены компонентов для работы по HTTP. */
Http: {
/** Токены компонентов API. */
Api: {
/** Токен пула хостов известных HTTP API. */
knownHosts: createToken<HttpApiHostPool<KnownHttpApiKey>>('http/api/known-hosts'),
},

/** Токен функции fetch. */
fetch: createToken<typeof fetch>('fetch'),

/** Токены компонентов формирующих работу функции fetch. */
Fetch: {
/** Токен AbortController для функции fetch. */
abortController: createToken<AbortController>('fetch/abort-controller'),

/** Токен хранилища cookie. */
cookieStore: createToken<CookieStore>('fetch/cookie-store'),

/** Токен списка промежуточных слоев для функции fetch. */
middleware: createToken<Middleware[]>('fetch/middleware'),

/** Токены компонентов промежуточных слоев для функции fetch. */
Middleware: {
/** Токены компонентов промежуточного слоя логирования. */
Log: {
/** Токены обработчика логирования работы функции fetch. */
handler: createToken<LogHandler | LogHandlerFactory>('fetch/middleware/log/handler'),
},
},
},

/** Токен функции обработки входящего HTTP-запроса. */
serve: createToken<Handler>('serve'),

/** Токены компонентов функции обработки входящего HTTP-запроса. */
Serve: {
/** Токен списка маршрутов. */
routes: createToken<Array<[string, ServerHandler]>>('serve/routes'),

/** Токен списка "служебных" маршрутов. К "служебным" маршрутам не применяются промежуточные слои. */
serviceRoutes: createToken<Array<[string, ServerHandler]>>('serve/service-routes'),

/** Токен списка промежуточных слоев обработки входящего HTTP-запроса. */
middleware: createToken<ServerMiddleware[]>('serve/middleware'),
},

/** Токены компонентов обработчиков входящих HTTP-запросов. */
Handler: {
/** Токен главной функции (точки входа) обработчика. */
main: createToken<ServerHandler>('handler/main'),

/** Токен "контекста" обработчика. Контекст содержит объект запроса а также реализует EventTarget. */
context: createToken<ServerHandlerContext & { request: Request }>('handler/context'),

/** Токен компонентов входящего запроса. */
Request: {
/** Токен "специфичных" параметров запроса. В зависимости от реализации определит параметры на основе объекта запроса. */
specificParams: createToken<Record<string, unknown>>('request/specific-params'),
},

/** Токены компонентов исходящего ответа. */
Response: {
/** Токен "специфичных" дополнительных данных. В зависимости от реализации сформирует дополнительные данные ответа. */
specificExtras: createToken<SpecificExtras>('response/specific-extras'),
},

/** Токены компонентов HTML-документа, формируемого в рамках обработчика. */
Page: {
/** Токен рендер-функции. */
render: createToken<() => JSX.Element | Promise<JSX.Element>>('page/render'),

/** Токен ассетов HTML-документа. */
assets: createToken<PageAssets | (() => PageAssets | Promise<PageAssets>)>('page/assets'),

/** Токен "шлема". Шлем - UI-компонент, внутри которого будет выведен результат render-функции. */
helmet: createToken<ElementType<{ children: ReactNode }>>('page/helmet'),
render: createToken<() => JSX.Element | Promise<JSX.Element>>('page/render'),
},
},
},

// axios
/** Токены компонентов для работы с библиотекой axios. */
Axios: {
/** Токен фабрики экземпляров axios. Фабрика вернет расширенный экземпляр с возможностью применять промежуточные слои. */
factory: createToken<(config?: CreateAxiosDefaults) => AxiosInstanceWrapper>('axios/factory'),

/** Токен промежуточных слоев. */
middleware: createToken<AxiosMiddleware<any>[]>('axios/middleware'),

/** Токен компонентов промежуточных слоев. */
Middleware: {
/** Токен компонентов слоя логирования. */
Log: {
/** Токен обработчика логирования. */
handler: createToken<LogMiddlewareHandlerInit>('axios/middleware/log/handler'),
},
},
},

// express
/** Токены компонентов для работы с библиотекой express. */
Express: {
/** Токен фабрики express-приложений. */
factory: createToken<() => express.Application>('express/factory'),

/** Токен express-обработчиков. */
Handlers: {
/** Токен обработчика "health check". */
healthCheck: createToken<express.Handler>('express/handler/health-check'),
},

/** Токены промежуточных слоев express-приложения. */
Middleware: {
request: createToken<express.Handler>('express/middleware/request'),
log: createToken<express.Handler>('express/middleware/log'),
Expand All @@ -118,22 +177,30 @@ export const KnownToken = {
},
},

// express handler
/** Токены компонентов express-обработчика. */
ExpressHandler: {
/** Токен главной функции (точки входа) обработчика. */
main: createToken<() => void>('express-handler/main'),

/** Токен "контекста" обработчика. Контекст содержит все аргументы, доступные обработчику (req, res, next). */
context: createToken<ExpressHandlerContext>('express-handler/context'),
},

// redux
/** Токены компонентов для работы с библиотекой redux. */
Redux: {
/** Токены компонентов промежуточных слоев. */
Middleware: {
/** Токен промежуточного слоя redux-saga. */
saga: createToken<SagaMiddleware>('saga-middleware'),
},
},

// SSR
/** Токены компонентов передачи данных страницы между клиентом и сервером. */
SsrBridge: {
/** Токены компонента "клиентской стороны". */
clientSide: createToken<BridgeClientSide<unknown>>('ssr-bridge/client-side'),

/** Токены компонента "серверной стороны". */
serverSide: createToken<BridgeServerSide>('ssr-bridge/server-side'),
},
} as const;

0 comments on commit e1379f0

Please sign in to comment.