PenguLoader / PenguLoader

✨ The ultimate JavaScript plugin loader, build your unmatched LoL Client.
https://pengu.lol
Do What The F*ck You Want To Public License
346 stars 56 forks source link

Shared TS types & enhancement #101

Open draylegend opened 4 months ago

draylegend commented 4 months ago

Idea

I need types for life cycle hooks (entry points) like init or load. As far as I know there're two ways to get typesafety with typescript:

Explicit

Exported interfaces from 'pengu-loader'

export interface InitFn {
  (context: Context): void;
}

Interfaces that can be exported from 'pengu-loader', too

export interface Context {
  socket: Socket;
  rcp: Rcp;
}

export interface Socket {
  observe<Data = any>(api: string, listener: Listener<Data>): DisconnectFn;
  disconnect: DisconnectFn;
}

export interface Listener<Data = any> {
  (event: Event<Data>): void;
}

export interface Event<Data = any> {
  data: Data; // or `data?: Data`
  uri: string;
  eventType: EventType;
}

export interface DisconnectFn {
  (): void;
}

export type EventType = 'Create' | 'Update' | 'Delete';

Usage

import { InitFn } from 'pengu-loader';

interface Data { id: string; gamerName: string }

export const init: InitFn = ctx => {
  ctx.socket.observe<Data>('some/api', event => {
    console.log(event.data.id, event.data.gamerName);
  });
};

Implicit

At this point we need some dev server running in the background that generates interfaces silently. I think about vite.

Usage

interface Data { id: string; gamerName: string }

export const init = ctx => {
  ctx.socket.observe<Data>('some/api', event => {
    console.log(event.data.id, event.data.gamerName);
  });
};

Obviously the first option is way simpler than the second one.

It'd be great to get some feedback, whether that fits the philosophy etc. or not.

nomi-san commented 4 months ago

Planned to publish it to npm @pengu.lol/types or @types/pengu. Pengu TS core is currently using global implicit typed via plugins/src/types.d.ts. It's easy to support both two cases, but implicit typed entry points could not be possible.

Explicit exported module/namespace:

import type { InitFn } from '@pengu.lol/types'

export const init: InitFn = ctx => { /*...*/ }

Global implicit, like vite/client does:

/// <reference types="pengu/global" />

Or using tsconfig.json:

  "typeRoots": ["pengu/global"]