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

RFC: // @factory #917

Open
Kelin2025 opened this issue Jun 9, 2023 · 5 comments
Open

RFC: // @factory #917

Kelin2025 opened this issue Jun 9, 2023 · 5 comments
Labels
RFC Request for Comments

Comments

@Kelin2025
Copy link
Member

In current state, you might sometimes get weird bugs and spend a couple of hours troubleshooting just to end up discovering that some store has missing sid and/or some factory isn't wrapped

Then you get fun time figuring out what paths you need to add to babel plugin
Here's the list of what I need to add just for a single factory that uses local clone of keyval library

@/entities/widget
./lib/create-widget-api // Nested in the previous one

@/shared/lib/keyval
./consumerPort
./createComputedField
./createGroup
./createItemApi
./createListApi
./createSelection

And getting to this config takes time. Add path -> wait for a full rebuild -> sid not affected -> search for more -> repeat

There're also cases when babel plugin won't even help

import { Widget } from '@/entities/widget'

// store has the same sid for each call
const { store } = Widget.createWidgetApi(...)

Which means you need to wrap it into withFactory, which is a secret method with no types and no documentation

And frameworks like Next.js with their weird bundlers might patch imports/exports so this function might not even exist for some reason

That's a really poor DX, and sometimes you might spend a really long time fixing it

Proposal

Like I proposed long ago, I think it's better to accept the fate and add extra optional // @factory comment support which helps plugins to easier detect factories

Something like:

import { createWidgetApi } from './lib/create-widget-api'

export const Widget = {
  // @factory
  createWidgetApi
}

Pros:

  1. Doesn't require importing stealth method which produces TS errors and other bundler issues
  2. Doesn't require modifying babel config and waiting for rebuilds
  3. Simple overall, just add the comment in place wherever you need it

Cons:

  1. Will make babel plugin more complicated (and probably slower?)

Questions:

  1. What about SWC? Can it track the comments like that?
@Kelin2025 Kelin2025 added the RFC Request for Comments label Jun 9, 2023
@sergeysova
Copy link
Collaborator

All tools like Babel and SWC work on the File-level, not the project level.

When you process a factory call you have just the import statement, and the call itself.

You need to resolve import, then read the file, and check the comments. Looks like it will be VERY slow, or not available at all.

@zerobias
Copy link
Member

zerobias commented Jun 9, 2023

I thought you were suggesting this

import {anything} from './factory'

// @effector-factory
const foo = anything()

// @effector-factory
const bar = anything.widget()

And it's possible

@Kelin2025
Copy link
Member Author

Kelin2025 commented Jun 9, 2023

This might work too, although it might be more repetitive
We can also add it near import too

// @factory
import { factory } from 'smth'

So if imported thing is marked as factory, all its calls in this file should be wrapped. Doesn't require reading another file

@kireevmp

This comment has been minimized.

@igorkamyshev
Copy link
Member

I suggest using https://withease.pages.dev/factories/ instead. It has runtime checks and does exactly the same without any changes in plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request for Comments
Projects
None yet
Development

No branches or pull requests

5 participants