Skip to content
This repository has been archived by the owner on Dec 4, 2022. It is now read-only.

Releases: SaltyAom/kingworld

exp.51 (ジャスト・ライト・スロウ)

22 Nov 11:21
3e26aee
Compare
Choose a tag to compare

0.0.0-experimental.51 - 22 Nov 2022

[Just Right Slow] introduce breaking major changes of KingWorld, specific on a plugin system.

Previously, we define plugin by accepting 2 parameters, KingWorld and Config like this:

const plugin = (app: KingWorld, config) => app

new KingWorld().use(plugin, {
    // Provide some config here
})

However, this has flaw by the design because:

  • No support for async plugin
  • No generic for type inference
  • Not possible to accept 3...n parameters (if need)
  • Hard/heavy work to get type inference

To fix all of the problem above, KingWorld now accept only one parameter.

A callback which return KingWorld Instance, but accept anything before that.

const plugin = (config) => (app: KingWorld) => app

new KingWorld().use(plugin({
    // provide some config here
}))

This is a workaround just like the way to register async plugin before exp.51, we accept any parameters in a function which return callback of a KingWorld instance.

This open a new possibility, plugin can now be async, generic type is now possible.

More over that, decorate can now accept any parameters as it doesn't really affect any performance or any real restriction.

Which means that something like this is now possible.

const a = <Name extends string = string>(name: Name) => (app: KingWorld) => app.decorate(name, {
    hi: () => 'hi'
})

new KingWorld()
    .use(a('customName'))
    // Retrieve generic from plugin, not possible before exp.51
    .get({ customName } => customName.hi())

This lead to even more safe with type safety, as you can now use any generic as you would like.

The first plugin to leverage this feature is jwt which can introduce jwt function with custom namespace which is type safe.

Change:

  • new decorators property for assigning fast Context

exp.39 (39みゅーじっく!)

08 Nov 12:54
28c4123
Compare
Choose a tag to compare

[39みゅーじっく!] is the 100th star release for KingWorld 🎉

This release doesn't have a big change for the code but has a big change for the community.

Nested Schema

.39 introduce better support for the nested schema.
Instead of inheriting the global schema first, KingWorld now handles the local schema first.

If a duplicated schema is found, KingWorld now infers type correctly instead of having infinite cycling.

Community Plugin: Controllers

Now we have another community plugin, Controllers is a plugin for defining decorator and controller-based routing.

import { Controller, Get, kwControllers } from 'kingworld-controllers'; 

// /users prefix
@Controller('/users/')
class UsersController {
  @Get()
  index() {
    return 'Hello World'
  }
}

const app = new KingWorld()

app.use(kwControllers, {
  controllers: [UsersController],
})

app.listen(3000);

GraphQL support with Yoga

Screenshot 2565-11-08 at 19 32 50

With @kingworldjs/graphql-yoga, you can now use GraphQL Yoga with KingWorld.

Change Log

Breaking Change:

  • method is changed to route

Improvement:

  • LocalHook now prefers the nearest type instead of the merge
  • Merge the nearest schema first
  • add contentType as a second parameter for BodyParser

Bug fix:

  • Correct type for after handle
  • Fix infinite cycling infer type for Handler

exp.37 (Sage)

05 Nov 17:21
57fd23b
Compare
Choose a tag to compare

[Sage] is one of the major experimental releases and breaking changes of KingWorld.

The major improvement of Sage is that it provides almost (if not) full support for TypeScript and type inference.

Type Inference

KingWorld has a complex type of system. It's built with the DRY principle in mind, to reduce the developer's workload.

That's why KingWorld tries to type everything at its best, inferring type from your code into TypeScript's type.

For example, writing schema with nested guard is instructed with type and validation.
This ensures that your type will always be valid no matter what, and inferring type to your IDE automatically.
FgqOZUYVUAAVv6a

You can even type response to make your that you didn't leak any important data by forgetting to update the response when you're doing a migration.

Validator

KingWorld's validator now replaced zod, and ajv with @sinclair/typebox.

With the new validator, validation is now faster than the previous version by 188x if you're using zod, and 4.1x if you're using ajv adapter.

With Edge Computing in mind, refactoring to new validate dropped the unused packages and reduced size by 181.2KB.
To give you an idea, KingWorld without a validator is around 10KB (non-gzipped).

Memory usage is also reduced by almost half by changing the validator.

According to M1 Max running example/simple.ts, running exp.36 uses 24MB of memory while exp.37 use 12MB of memory

This greatly improves the performance of KingWorld in a long run.

Changelog

Breaking Change:

  • Replace zod, zod-to-json-schema, ajv, with @sinclair/typebox

Improvement:

  • use now accept any non KingWorld<{}, any>
  • use now combine typed between current instance and plugin
  • use now auto infer type if function is inline
  • LocalHook can now infer params type from path string

Change:

  • TypedSchema is now replaced with Instance['schema']

exp.29 (Regulus)

02 Nov 14:40
8cb9b60
Compare
Choose a tag to compare

Regulus

This version introduces rework for internal architecture. Refine, and unify the structure of how KingWorld works internally.

Although many refactoring might require, I can assure you that this is for the greater good, as the API refinement lay down a solid structure for the future of KingWorld.

Thanks to API refinement, this version also introduced a lot of new interesting features, and many APIs simplified.

Notable improvements and new features:

  • Define Schema, auto-infer type, and validation
  • Simplifying Handler's generic
  • Unifying Life Cycle into one property
  • Custom Error handler, and body-parser
  • Before start/stop and clean up effect

New Feature:

  • add schema to the local hook for strict-type validation and type inference.

    • Example:
    import { z } from 'zod'
    
    app.post("/id/:id", ({ body }) => body, {
        schema: {
            body: z.object({
                username: z.string(),
                password: z.string()
            }),
            params: {
                id: z.string()
            }
        }
    })
  • add onError for handling custom error

  • add onStart, onStop for handling server state

  • add stop for stopping the server

Breaking Change:

  • Remove TypedRoute generic on httpMethod, replaced with schema.

    • To migrate:
    // From
    app.post<{
        body: {
            username: string
            password: string
        },
        params: {
            id: string
        }
    }>('/id/:id', ({ body }) => body)
    
    // To
    import { z } from 'zod'
    
    app.post("/id/:id", ({ body }) => body, {
        schema: {
            body: z.object({
                username: z.string(),
                password: z.string()
            }),
            params: {
                id: z.string()
            }
        }
    })
  • Method Hook is now replaced with LocalHook

  • Rename preHandler to beforeHandle

  • Rename bodyParser to onParse, on('parse')

  • Rename .when(event) to on(event)

  • Rename .on(HttpMethod) to .method(HttpMethod)

  • Replace HookEvent for LifeCycle

  • Move bodyParser, errorHandler to event: LifeCycleStore

  • Remove ability for local hook to accept RegisterHook[]

  • Remove onRequest on local hook, as it doesn't execute

Bug fix:

  • JSON body parsed as string

exp.28 (GHOST FOOD)

30 Oct 14:37
1d1b0ed
Compare
Choose a tag to compare

0.0.0-experimental.28 - 30 Oct 2022

Happy Halloween.

This version named [GHOST FOOD] is one of the big improvements for KingWorld, I have been working on lately.
It has a lot of feature change for better performance, and introduce lots of deprecation.
Be sure to follow the migration section in Breaking Change.

GHOST FOOD introduce a lot of breaking change, laying down a better foundation for KingWorld in the future.
However, the API is still marked as unstable and some might change in the future before moving out of the experiment version.

GHOST FOOD has better performance in every aspect, with an even better type system for KingWorld.

Like auto infer type for state, inheriting type from plugins, and auto typing path parameters.

And thanking you all for following this experimental project of mine, happy hacking until next time.


New Feature:

  • Auto infer type from plugin after merging with use
  • decorate to extends Context method
  • add addParser, for custom handler for parsing body

Breaking Change:

  • Moved store into context.store

    • To migrate:
    // From
    app.get(({}, store) => store.a)
    
    // To
    app.get(({ store }) => store.a)
  • ref, and refFn is now removed

  • Remove Plugin type, simplified Plugin type declaration

    • To migrate:
    // From
    import type { Plugin } from 'kingworld'
    const a: Plugin = (app) => app
    
    // To
    import type KingWorld from 'kingworld'
    const a = (app: KingWorld) => app
  • Migrate Header to Record<string, unknown>

    • To migrate:
    app.get("/", ({ responseHeader }) => {
        // From
        responseHeader.append('X-Powered-By', 'KingWorld')
    
        // To
        responseHeader['X-Powered-By', 'KingWorld']
    
        return "KingWorld"
    })

Change:

  • Store is now globally mutable

Improvement:

  • Faster header initialization
  • Faster hook initialization