Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rxjs pipe syntax #668

Open
mdbetancourt opened this issue Jun 5, 2024 · 0 comments
Open

Rxjs pipe syntax #668

mdbetancourt opened this issue Jun 5, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@mdbetancourt
Copy link

mdbetancourt commented Jun 5, 2024

What is the problem this feature would solve?

Before rxjs used to uses chaining syntax (as elysia) but they changed to pipe syntax the reason they given was

Any library importing the patch operator augmenting the observable prototype would also augment it for all consumers. For example, when a library imports map extension from import 'rxjs/add/operators/map', it makes map available for all code importing the library itself. This could bring confusion due to the inconsistent way of importing extensions. Some places would not need to important map (those were the library is used) while in other place of the code we would have to else the compiler would complain. The other issue would be that if we did not import the extension and relied (intentionally or not) on the import of the library we consume, the day they remove the import, our application will break.
This point is more on the optimization side. Unused operators added on prototype can’t be removed during tree-shaking tools like webpack.
Operators patches imported but not used can’t be deleted by linters.
https://kimsereyblog.blogspot.com/2018/11/moving-from-chaining-to-piping-in-rxjs.html

i thing pipe syntax has some good advantage

What is the feature you are proposing to solve the problem?

I wrote a semi-working example of how would looks

function plugin<T extends Context, A>(
	fn1: UnaryFunction<T, A>,
): UnaryFunction<T, A>
function plugin<T extends Context, A, B>(
	fn1: UnaryFunction<T, A>,
	fn2: UnaryFunction<A, B>,
): UnaryFunction<T, B>
function plugin<T extends Context, A, B, C>(
	fn1: UnaryFunction<T, A>,
	fn2: UnaryFunction<A, B>,
	fn3: UnaryFunction<B, C>,
): UnaryFunction<T, C>
function group<T extends Context, A>(
	fn1: UnaryFunction<T, A>,
): UnaryFunction<T, A>
function group<T extends Context, A, B>(
	fn1: UnaryFunction<T, A>,
	fn2: UnaryFunction<A, B>,
): UnaryFunction<T, B>
function group<T extends Context, A, B, C>(
	fn1: UnaryFunction<T, A>,
	fn2: UnaryFunction<A, B>,
	fn3: UnaryFunction<B, C>,
): UnaryFunction<T, C>

type Context = {
	definitions: {
		type: {}
		error: {}
	}
	singleton: {
		decorator: {}
		derive: {}
		resolve: {}
		store: {}
	}
	metadata: {
		schema: {}
		macro: {}
	}
}

type Derive<T extends Context, Value> = T & { singleton: { derive: Value } }

type ContextObject<T extends Context> = T['singleton']['derive']

function derive<const Ctx extends Context, const Result>(
	fn: (ctx: ContextObject<Ctx>) => Result,
): UnaryFunction<Ctx, Derive<Ctx, Result>>

function post<
	const Ctx extends Context,
	const Path extends string,
	const Handle extends (app: ContextObject<Ctx>) => unknown,
>(path: Path, handler: Handle): UnaryFunction<Ctx, Ctx>

type UnaryFunction<T, R> = (source: T) => R


/**
   * USAGE
   */ 
function main() {
  const auth = plugin(
    derive(() => ({ signin: () => console.log('signin') }))
  )
  const t = plugin(
     derive(() => ({ logger: (msg: string) => console.log(msg) })),
   )
  plugin(
    auth,
    t,
    post('/', ({ signin, logger }) => {
      signin()
      logger('test')
    })
  )

  plugin(
//  scope('global'),
// guard(...) // global schema
    derive(() => ({ signin: () => console.log('signin') })),
    derive(() => ({ logger: (msg: string) => console.log(msg) })),
// schema({ ... }), // this schema only apply to next handler (post) not get handler
    post('/', ({ signin, logger }) => {
      signin()
      logger('test')
    }),
// get(.....)
  )

  plugin(
    derive(() => ({ signin: () => console.log('signin') })),
    derive(() => ({ logger: (msg: string) => console.log(msg) })),
    group(
//   prefix('/user'),
      post('/', ({ signin, logger }) => {
        signin()
        logger('test')
      })
    )
  )

  plugin(
    plugin(derive(() => ({ signin: () => console.log('signin') }))),
    plugin(derive(() => ({ logger: (msg: string) => console.log(msg) }))),
    post('/', ({ signin, logger }) => {
      signin()
      logger('test')
    })
  )
}

i think it would help to make the project easier to maintain, extend etc

What alternatives have you considered?

No response

@mdbetancourt mdbetancourt added the enhancement New feature or request label Jun 5, 2024
@mdbetancourt mdbetancourt changed the title Rxjs syntax Rxjs pipe syntax Jun 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant