Giter Site home page Giter Site logo

unadlib / reactant Goto Github PK

View Code? Open in Web Editor NEW
248.0 10.0 14.0 11.96 MB

A framework for building React applications

Home Page: https://reactant.js.org/

License: MIT License

TypeScript 96.20% HTML 0.12% JavaScript 3.44% Dockerfile 0.02% CSS 0.23%
react react-native redux framework reactant react-applications dependency-injection server-side-rendering server-side-render typescript

reactant's People

Contributors

dependabot[bot] avatar richardotvos avatar unadlib avatar zouyoushun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactant's Issues

Documentation missing how to create a new instance of a class for each injection

Reactant has been working great for our dependency injection and viewmodules. One thing we haven't figured out from Reactant's documentation, all classes/objects injected are effectively singletons because if 2 classes need the class Foo{}, they get the same instance of it if it already exists in the container. With the constructor injection, how can it request a new object instead of a pre-existing one thats already in the container? I'd prefer not to do useFactory in the modules as the class being injected does have a dependency of its own that is injected.

This might be good to add to the documentation.

For example, how can the 2 classes below, MainView and OtherView get their own instance of Foo?

@injectable({name:"foo"})
class Foo{
....
}

class MainView extends ViewModule {
   constructor(protected foo: Foo){   }
   component(....)
} 

class OtherView extends ViewModule {
   constructor(protected foo: Foo)  {   }
   component(....)
} 

I'd prefer to avoid:
modules: [
  { 
     provide: "foo",
     useFactory: ()=> {return new Foo(...);}
  }
]

As our Foo does have a dependency that Reactant is injecting

Resolve a module not in constructor

First of all, congratulations on this library, i like it ;)

Is it possible, in Module, to resolve an another module but not in constructor ?

Description

I want to make a generic plugin for Authentication with options.

export const AuthOptions = Symbol("AuthOptions");
export interface IAuthOptions {
    path: string
    loginView: Module<ViewModule>
}
const AuhtOptionsDefault: IAuthOptions = {
    path: "/login",
    loginView: LayoutView          /**  <== this is default ViewModule */
}
@injectable()
export class AuthModule extends PluginModule {
    readonly [storeKey]?: any

    authOptions: IAuthOptions;
    constructor(
        @optional(AuthOptions) options: IAuthOptions
    ){
        super();
        this.authOptions = {
            ...AuhtOptionsDefault,
            ...options
        }
    }
    provider = (props: PropsWithChildren<any>) => {
        const componentView = resolve(this.authOptions.loginView);  /** <== how resolve this ? */
        return (
            <>
                <Switch>
                    <Route path={this.authOptions.path} component={componentView.component} />
                </Switch>
                {props.children}
            </>
        )
    }
}

I want to make the component this.authOptions.loginView configurable by the users.
How can i make it ?
thank you.

Proposal: isolated state for reactant-share

Relevant Package

  • reactant-last-action
  • reactant-share

Description

Design a module identity api that can be unsynchronized, and the state in the instance marked by it will not be synchronized

If the synchronized and unsynchronized state is modified in a Redux action, reactant-last-action sequence counter will count normally and the synchronized state will be sent via reactant-share.

Proposal: Optimizing @computed based on deps collection of signal concepts

Relevant Package

  • reactant-module

Description

Since the access to a class's state is via a getter in Reactant, its derived state and that of computed can be implemented in a manner similar to the concept of signals for automatic dependency collection.

The usage is modified as follows:

@injectable()
class Counter {
  @state
  count = 0;

-  @computed((that) => [that.count])
+  @computed
  get num() {
    return this.count + 1;
  }
}

Documentation missing on runtime object creation from container

Hi,

Assuming a typical createSharedApp() app, is there a way at runtime for a class to get (or create a new object) from the "main container" for the app? Not sure if the following code is helpful, but typically if I do new Foo() on an object that uses @state/@action, I get errors even if I tried using @autoBind:

Uncaught Error: 'this' in method 'AddFoos' of class 'FooList' decorated by '@action' must be bound to the current class instance.

I am guessing I need to get the object from the container and not do New on it so the @action function is correctly bound to the class. Here is a simple example, although I understand the code could be changed to return a simple Array or Map instead of a FooList but trying to come up with a simple example of wanting to do New myClassName() at runtime instead of constructor injection; This could be good to also add to the documentation.

class Foo{
  @state
  Name: string = "";

  @state
   classifier: string = "";
}

class FooList
{
  @state
  Foos: Array<Foo> = [];
  
  @action
  UpdateFoos(foos: Array<Foo>){.....}
}

class FooView{
   constructor(inject("AllFoos") allFooList: FooList) {}

  get SpecialFoo(): FooList
  {
      const foolist = new FooList(); //This line would be replaced with getting a new FooList from the container...
     foolist.UpdateFoos(this.allFooList.filter((foo)=>......);
     return foolist;
  } 
}

Thank you

Proposal: coworker for reactant-share

Relevant Package

  • reactant-share

Description

As projects become larger, we need a front-end architecture model that can handle multi-process programming. In reactant-share, we can call this a Coworker. Tasks that consume CPU or occupy request limits in the main process can be transferred to the Coworker for execution, and their status is synchronized back to the main process.

We will add interface in packages/reactant-share/src/interfaces.ts.

interface ISharedAppOptions {
  coworker?: {
    /**
     * Whether to be in coworker.
     */
    isCoworker: boolean;
    /**
     * Importing the injected dependency modules.
     */
    modules: ReactModuleOptions[];
    /**
     * Specify a SharedWorker URL
     */
    workerURL?: string;
  };
}

For example,

In coworker.ts

createSharedApp({
  modules: [],
  main: AppView,
  render: () => {
    //
  },
  share: {
    name: 'SharedWorkerApp',
    type: 'SharedWorker',
    coworker: {
      isCoworker: true,
      modules: [],
      workerURL: 'coworker.bundle.js',
    },
  },
});

Support for disabling decorator syntax

Relevant Package

  • reactant-module
  • reactant-di

Description

Many developers still have concerns about TS and JS decorators. In particular, the decorator is a feature of the language that is not stable over the long term, so support for disabling the decorator in reactant-module and reactant-di is open to discussion.

For example,

@injectable()
class Foo {
  @state
  foo = '';

  @action
  update(text: string) {
    this.foo = text;
  }
}

When disabling the decorator, it's equal to:

decorate(
  class Foo {
    constructor() {
       this.foo = '';
       decorate(this, {
         foo: state,
         update: action,
       });
    }

    update(text: string) {
      this.foo = text;
    }
  },
  injectable
)

Refactor the C/S proxy mechanism with the actor model

reactant-share uses a one-to-many client design, which relies on class method proxies that trigger the server's execution methods.

class Counter {
  @state
  count = 0;

  @action
  _increase() {
    this.count += 1;
  }
  
  @proxy
  async increase() {
    this._increase();
  }
  
  async doSomething() {
    await this.increase();
  }
}

For developers, the principle of using @proxy is difficult to grasp, and the decorated methods often have to be newly written in order to have to be asynchronous, thus necessitating a new simple asynchronous method, which is not worth it.

Therefore, reactant-share requires a more flexible and simple C/S proxy model, and the actor model is well suited for such a design.

class Counter {
  @state
  count = 0;

  @action
  increase() {
    this.count += 1;
  }
  
  async doSomething() {
     await spawn(this, 'increase', []);
  }
}

Proposal: multiprocessing coworker

Relevant Package

  • reactant-share

Description

To better adapt to the needs of multiprocessing, we want "coworker" to quickly support the multiprocessing module. This would allow for more efficient utilization of multiple modules in high-performance multiprocessing and concurrency, combining them into a higher-performing app.

APIs

We can create a proprietary coworker module using createCoworker().

const [CounterWorker, CounterWorkerOptions] = createCoworker('Counter');

createSharedApp({
  modules: [
    {
      provide: 'NewProxyCounter',
      useClass: ProxyCounter,
    },
    CounterWorker,
    {
      provide: CounterWorkerOptions,
      useValue: {
        useModules: ['NewProxyCounter'],
        worker: new Worker(new URL('./counter-coworker.ts', import.meta.url)),
        isCoworker: false
      } as ICoworkerOptions,
    },
  ],
  // more shared app config
});

Add clientIds for reactant-share

Relevant Package

  • reactant-share

Description

In order to better control multiple clients through the server port, we would like to add clientIds to the PortDetector module of the server port.

Subscribe method from another module

Description

I try to subscribe a method from another module but it's not reached

Minimal Reproduction

// layout.view.tsx
@injectable()
export class LayoutView extends ViewModule {
    @state
    drawerOpen: boolean = false
    @action
    toggleDrawer(){ this.drawerOpen = !this.drawerOpen; }
   ...
// parametres.service.ts
@injectable()
export class ParametresService {
    constructor(
        private readonly layout: LayoutView
    ){
        subscribe(this.layout, () => { console.log("this.layout.subscribe"); })
    }
   ...

Expected Behavior

I expect that the method was called.

if i do this it work

setTimeout(() => {
   subscribe(this.layout, () => { console.log("this.layout.subscribe"); })
},1)

But it's not very elegant.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.