Skip to content

Commit

Permalink
Touch up SSR. Logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
GirlBossRush committed Oct 12, 2023
1 parent d169779 commit d184ac7
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 92 deletions.
4 changes: 3 additions & 1 deletion cli/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export type ServeArgs = StrictYargsOptionsToInterface<typeof serveCommand>
*/
export async function serveBuilder({ port, host, ...serveArgs }: ServeArgs) {
const logger = new KeyworkLogger('Keywork Server')
logger.info('>>>>', serveArgs)
logger.info('CLI Args', serveArgs)

const absolutePublicDirPath = path.resolve(serveArgs.publicDir)
const absoluteScriptPath = path.resolve(serveArgs.routerScript)
Expand Down Expand Up @@ -103,6 +103,8 @@ export async function serveBuilder({ port, host, ...serveArgs }: ServeArgs) {
})
)

fetcher.$prettyPrintRoutes()

// And then wrap the router with `createServerHandler`
const server = http.createServer(createNodeServerHandler(fetcher))

Expand Down
4 changes: 2 additions & 2 deletions client/BrowserRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

import { FetchEventProvider, IsomorphicFetchEvent } from 'keywork/events'
import { DEFAULT_LOG_LEVEL, DEFAULT_LOG_PREFIX, KeyworkLogLevelValue, KeyworkLogger } from 'keywork/logging'
import { DEFAULT_LOG_LEVEL, DEFAULT_LOG_PREFIX, KeyworkLogLevel, KeyworkLogger } from 'keywork/logging'
import { RoutePatternsProps, URLContext } from 'keywork/uri'
import { createContext, useContext, useMemo } from 'react'
import { KeyworkPatternToPageComponent } from './KeyworkPatternToPageComponent.js'
Expand All @@ -38,7 +38,7 @@ export const useBrowserRouter = () => {

export interface BrowserRouterProps extends RoutePatternsProps {
logPrefix?: string
logLevel?: KeyworkLogLevelValue
logLevel?: KeyworkLogLevel
history?: History
}

Expand Down
4 changes: 2 additions & 2 deletions client/hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
* @see LICENSE.md in the project root for further licensing information.
*/
import { KeyworkResourceError } from 'keywork/errors'
import { KeyworkLogLevel, KeyworkLogLevelValue, KeyworkLogger } from 'keywork/logging'
import { KeyworkLogLevel, KeyworkLogger } from 'keywork/logging'
import { isKeyworkClientModule } from 'keywork/uri'
import { hydrateRoot } from 'react-dom/client'
import { pluckKeyworkHydrationElement, waitUntilDOMReady } from './dom.js'

export interface KeyworkHydrationOptions {
logLevel?: KeyworkLogLevelValue
logLevel?: KeyworkLogLevel
logPrefix?: string
scriptPath?: string
}
Expand Down
1 change: 0 additions & 1 deletion examples/simple/_worker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import AppBrowserRouter from './public/main.js'
import { TodoItemPageProps } from './public/pages/TodoItem.js'

const router = new RequestRouter({
logLevel: 'Debug',
document: {
title: 'Keywork example app',
themeColor: '#65b9e2',
Expand Down
59 changes: 59 additions & 0 deletions examples/simple/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @file This file is part of the Keywork project.
* @copyright Nirrius, LLC. All rights reserved.
* @author Teffen Ellis, et al.
* @license AGPL-3.0
*
* @remarks Keywork is free software for non-commercial purposes.
* You can be released from the requirements of the license by purchasing a commercial license.
* Buying such a license is mandatory as soon as you develop commercial activities
* involving the Keywork software without disclosing the source code of your own applications.
*
* @see LICENSE.md in the project root for further licensing information.
*/

import { KeyworkResourceError, RequestRouter } from 'keywork'
import type { TodoItemPageProps } from './public/pages/TodoItem.js'

const mockTodos = new Map<string, TodoItemPageProps>([
[
'1',
{
id: '1',
title: 'Todo 1',
completed: false,
},
],
[
'2',
{
id: '2',
title: 'Todo 2',
completed: false,
},
],
[
'3',
{
id: '3',
title: 'Todo 3',
completed: true,
},
],
])

export const apiRouter = new RequestRouter()

apiRouter.get('/todos', () => {
return mockTodos
})

apiRouter.get<{ id: string }>('/todo/:id', async ({ params }) => {
const todo = mockTodos.get(params.id)

if (!todo) {
return new KeyworkResourceError(`Todo ${params.id} not found`, 404)
}

return todo
})
6 changes: 3 additions & 3 deletions http/castToResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { isInstanceOfResponse } from './isInstanceOfResponse.js'
/**
* @ignore
*/
export interface PageElementProps<StaticProps extends {} | null = null> extends React.ReactElement<StaticProps> {
export interface PageElementComponent<StaticProps extends {} | null = {}> extends React.ReactElement<StaticProps> {
children?: React.ReactNode
}

Expand Down Expand Up @@ -86,12 +86,12 @@ export async function castToResponse(
}

if (isStaticPropsRequestURL(event.request.url)) {
const staticProps = isValidElement<PageElementProps>(responseLike) ? responseLike.props : responseLike
const staticProps = isValidElement<PageElementComponent>(responseLike) ? responseLike.props : responseLike

return new JSONResponse(staticProps)
}

if (isValidElement<PageElementProps>(responseLike)) {
if (isValidElement<PageElementComponent>(responseLike)) {
const stream = await renderJSXToStream(event, responseLike, reactRenderOptions)
return new HTMLResponse(stream)
}
Expand Down
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,4 @@ export * from 'keywork/router'
export * from 'keywork/utils'
export * from 'keywork/cloudflare'
export * from 'keywork/client'
export * from 'keywork/logging'
59 changes: 24 additions & 35 deletions logging/KeyworkLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,26 @@ _timestamp.toString = () => _timestamp()

export interface KeyworkLoggerConfig {
readonly method: keyof GlobalConsoleLike | null
readonly level: KeyworkLogLevelValue
readonly level: KeyworkLogLevel
readonly prefix?: string
}

/**
* @internal
*/
export const _KEYWORK_LOG_LEVELS = ['None', 'Trace', 'Error', 'Warning', 'Log', 'Info', 'Debug'] as const

/**
* Levels available to the Keywork logger.
*/
export type KeyworkLogLevelValue = (typeof _KEYWORK_LOG_LEVELS)[number]

/**
* Enum-like record of Keywork log levels.
*/
export const KeyworkLogLevel = {
None: 'None',
Trace: 'Trace',
Error: 'Error',
Warning: 'Warning',
Log: 'Log',
Info: 'Info',
Debug: 'Debug',
} as const satisfies Record<KeyworkLogLevelValue, KeyworkLogLevelValue>
export const enum KeyworkLogLevel {
None = 0,
Trace = 1,
Error = 2,
Warning = 3,
Log = 4,
Info = 5,
Debug = 6,
}
/**
* The default level used by the Keywork logger.
*/
export const DEFAULT_LOG_LEVEL = 'Info' satisfies KeyworkLogLevelValue
export const DEFAULT_LOG_LEVEL = KeyworkLogLevel.Info

/**
* The default prefix used by the Keywork logger.
Expand All @@ -81,35 +71,35 @@ export const DEFAULT_LOG_PREFIX = 'Keywork'
*/
export const _KeyworkLogLevelConfigs = [
{
level: 'None',
level: KeyworkLogLevel.None,
method: null,
},
{
level: 'Trace',
level: KeyworkLogLevel.Trace,
method: 'trace',
prefix: '👀 ',
},
{
level: 'Log',
level: KeyworkLogLevel.Log,
method: 'log',
prefix: '💬 ',
},
{
level: 'Info',
level: KeyworkLogLevel.Info,
method: 'info',
prefix: '💡 ',
},
{
level: 'Error',
level: KeyworkLogLevel.Error,
method: 'error',
},
{
level: 'Warning',
level: KeyworkLogLevel.Warning,
method: 'warn',
prefix: '⚠️ ',
},
{
level: 'Debug',
level: KeyworkLogLevel.Debug,
method: 'debug',
prefix: '🔎 ',
},
Expand All @@ -119,7 +109,7 @@ export const _KeyworkLogLevelConfigs = [
* A map of log levels to their respective configuration.
* @internal
*/
const _KeyworkLogLevelConfigMap = new Map<KeyworkLogLevelValue, KeyworkLoggerConfig>()
const _KeyworkLogLevelConfigMap = new Map<KeyworkLogLevel, KeyworkLoggerConfig>()
/**
* A map of log levels to their respective indexes.
*
Expand Down Expand Up @@ -162,7 +152,7 @@ export class KeyworkLogger {
public info!: GlobalConsoleLike['info']
public warn!: GlobalConsoleLike['warn']

constructor(logPrefix = 'Keywork', level: KeyworkLogLevelValue | number = KeyworkLogLevel.Info, color = 'cyan') {
constructor(logPrefix = 'Keywork', level?: KeyworkLogLevel, color = 'cyan') {
if (typeof console !== 'undefined') {
this.globalConsole = console as GlobalConsoleLike
} else {
Expand All @@ -171,11 +161,10 @@ export class KeyworkLogger {

this.logPrefix = `[${logPrefix}]`

if (typeof level === 'number') {
this.config = _KeyworkLogLevelConfigs[level] || _KeyworkLogLevelConfigMap.get('Info')!
} else {
this.config = _KeyworkLogLevelConfigMap.get(level) || _KeyworkLogLevelConfigMap.get('Info')!
}
this.config =
typeof level === 'undefined'
? _KeyworkLogLevelConfigMap.get(KeyworkLogLevel.Info)!
: _KeyworkLogLevelConfigMap.get(level)!

const levelIndex = _KeyworkLogLevelIndexes.get(this.config)!

Expand Down
4 changes: 2 additions & 2 deletions logging/LoggerContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import { createContext, useContext, useMemo } from 'react'

import { DEFAULT_LOG_LEVEL, DEFAULT_LOG_PREFIX, KeyworkLogLevelValue, KeyworkLogger } from './KeyworkLogger.js'
import { DEFAULT_LOG_LEVEL, DEFAULT_LOG_PREFIX, KeyworkLogLevel, KeyworkLogger } from './KeyworkLogger.js'

export const KeyworkLoggerContext = createContext<KeyworkLogger>(undefined as any)
KeyworkLoggerContext.displayName = 'KeyworkLoggerContext'
Expand All @@ -26,7 +26,7 @@ export const useKeyworkLogger = () => useContext(KeyworkLoggerContext)

export interface KeyworkLoggerProviderProps {
logPrefix?: string
logLevel?: KeyworkLogLevelValue
logLevel?: KeyworkLogLevel
children: React.ReactNode
}

Expand Down
4 changes: 2 additions & 2 deletions node/createServerHandler.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* @see LICENSE.md in the project root for further licensing information.
*/

import { KeyworkLogger } from 'keywork/logging'
import { KeyworkLogLevel, KeyworkLogger } from 'keywork/logging'
import { RequestRouter } from 'keywork/router'
import * as http from 'node:http'
import { createNodeServerHandler } from './createServerHandler.js'
Expand All @@ -24,7 +24,7 @@ const logger = new KeyworkLogger('Test Server')

// Create a router as you usually do...
const router = new RequestRouter({
logLevel: 'Debug',
logLevel: KeyworkLogLevel.Debug,
})
router.get('/', () => 'Hello from Node')

Expand Down
5 changes: 4 additions & 1 deletion node/import-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export function transformTSConfigToImportMap(
const importMap: ImportMap = {
_comment: 'This importmap was generated for the Keywork project.',
packageVersion: packageJSON.version,
imports: {},
imports: {
[`${packageName}/package.json`]: './package.json',
[`${packageName}/importmap.json`]: './dist/importmap.json',
},
}

if (!tsConfigPaths) return importMap
Expand Down
1 change: 0 additions & 1 deletion node/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export function transformIncomingMessageToRequest(
let bodyInit: BodyInit | null = null

if (hasReadableBody(incomingMessage)) {
console.log('>>> hasReadableBody', incomingMessage.method, incomingMessage.readable)
bodyInit = new ReadableStream({
async pull(controller) {
const chunk = incomingMessage.read()
Expand Down
12 changes: 6 additions & 6 deletions router/RequestRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,17 +358,17 @@ export class RequestRouter<BoundAliases = {}> implements Fetcher<BoundAliases>,
* The given middleware will execute _before_ any other request handlers
* that are defined _after_ invoking `use(...)`.
*/
fetcher: FetcherLike<BoundAliases>
fetcher: FetcherLike<any>
): void
public use(
/** A `URLpattern` of where the given middleware should be mounted. */
mountURLPattern: URLPatternLike,
/** The middleware to mount. */
fetcher: FetcherLike<BoundAliases>
fetcher: FetcherLike<any>
): void
public use(...args: unknown[]): void {
let mountURLPattern: URLPatternLike
let fetcher: FetcherLike<BoundAliases>
let fetcher: FetcherLike<any>

if (args.length > 1) {
// Path pattern was provided...
Expand Down Expand Up @@ -447,10 +447,10 @@ export class RequestRouter<BoundAliases = {}> implements Fetcher<BoundAliases>,
for (const { httpMethod, entries } of routesByHttpMethod) {
if (!entries.length) continue

this.logger.log('METHOD:', httpMethod)
this.logger.info('METHOD:', httpMethod)

for (const route of entries) {
this.logger.log(route.displayName || '', route.urlPattern?.pathname)
this.logger.info(route.displayName || '', route.urlPattern?.pathname)

this.$prettyPrintRoutes(route.entries)
}
Expand Down Expand Up @@ -651,7 +651,7 @@ export class RequestRouter<BoundAliases = {}> implements Fetcher<BoundAliases>,

constructor(options?: RequestRouterOptions) {
this.displayName = options?.displayName || 'Keywork Router'
this.logger = new KeyworkLogger(this.displayName, options?.logLevel || 'Log')
this.logger = new KeyworkLogger(this.displayName, options?.logLevel)

this.reactOptions = {
streamRenderer: renderReactStream,
Expand Down
4 changes: 2 additions & 2 deletions router/RequestRouterOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import type { SSRDocument } from 'keywork/events'
import type { HTTPMethod } from 'keywork/http'
import type { KeyworkLogLevelValue } from 'keywork/logging'
import type { KeyworkLogLevel } from 'keywork/logging'
import type { ReactRendererOptions } from 'keywork/ssr'
import type { ClientModuleInput, IURLPattern } from 'keywork/uri'
import type { MiddlewareDeclarationLike } from './MiddlewareDeclarationLike.js'
Expand Down Expand Up @@ -86,5 +86,5 @@ export interface RequestRouterOptions {
* @see {@linkcode KeyworkLogLevelValue}
* @defaultValue 'Info'
*/
logLevel?: KeyworkLogLevelValue
logLevel?: KeyworkLogLevel
}
Loading

0 comments on commit d184ac7

Please sign in to comment.