-
Notifications
You must be signed in to change notification settings - Fork 1
reduce core DI bundle size - ideas #7
Comments
I am really not sure why github doesn't notify me for this important issue! I was thinking for this situation from the first moment when i introduce these features but i wanted to have everything working like a MVP and concept and then at later time removing these functionalities from the main bundle. I am really happy to see that there are some people interested in this Ecosystem :)!! For now it treats me very well without big problems and it is time to improve core features of the platform and reduce bundle size!! Thank you again for the issue! If you use Or searching P.S. One important thing i forgot to say: I was thinking to remove all dependencies from the project and leave it stand alone! So in the future we need to get rid of everything and leave only dependency injection here. We need to have ability to remove completely npm ecosystem in some period of time so we can have independent decentralized solution which can be helpful when we have nodes everywhere and create good ipfs module coverage. |
@jeremy-coleman hi there ! Just for let you know that i have manage to create really small DI 1.31 kb . https://github.com/r-html/rhtml/tree/master/packages/di These are the core features for DI without async behaviour introduced inside @rxdi/core so we cannot put Promise or Observable inside custom providers A simple example usage for @rhtml/di is: import { Injectable, Inject, set, get } from '@rhtml/di';
class User {
id = 1;
}
class UserService {
@Inject(User)
user: User;
}
@Injectable()
class InjectableService {
constructor(@Inject(User) private user: User) {}
}
@Module({
providers: [UserService, InjectableService]
})
class UserModule {}
@Module({
imports: [UserModule]
})
class AppModule {}
console.log(has(AppModule)); // False
set(AppModule);
const userService = get(UserService);
expect(userService.user.id).toBe(1); Example with reflections (removes the need of Inject decorator inside constructor as a property since we get can get metadata parameters for the injected class) : import '@abraham/reflection';
import { Injectable, Inject, set, get } from '@rhtml/di';
class User {
id = 1;
}
class UserService {
@Inject(User)
user: User;
}
@Injectable()
class InjectableService {
constructor(private user: User) {}
}
@Module({
providers: [UserService, InjectableService]
})
class UserModule {}
@Module({
imports: [UserModule]
}) |
@Stradivario great code, that's impressively concise, even more simple DI than hooks I was just looking over this the other day, and thought it could be a compliment to rxdi, its a small framework using lit and rx. https://github.com/raycar5/valv also, lit has a mechanism for resolving async data, check it out https://www.youtube.com/watch?v=Io6JjgckHbg , around 24 minutes 15 seconds |
@jeremy-coleman thank you very much i really appreciate it! I take a look at About lit html: It has ability to resolve async data but not Observable like data which is streamable. Why ? Because it doesn't This is why i decided to Fork lit-html and create @rxdi/lit-html with some Decorator modifications and better bundling. https://github.com/rxdi/lit-html/blob/master/src/decorators/component.decorator.ts#L133 Here you can check how i deal with subscriptions of the component. If there are any registered Observables inside After all that knowledge i decided to create Monadic approach for writing WebComponents and HTML in general which is kind of something that i don't see at the moment anywhere. Let me show you what is going on: <r-component>
<r-selector>r-counter</r-selector>
<r-props>
<r-prop key="value" type="Number"></r-prop>
</r-props>
<r-render .state=${({ value, loading }, setState) => html`
<button @click=${() => setState({ value: value + value, loading: false })}>
Increment
</button>
<r-if .exp=${loading}>
Loading...
</r-if>
<p>${value}</p>
`}>
</r-render>
</r-component> Then using it <r-counter value="5"></r-counter> Basically you can create Webcomponent Maybe you want to check this example also! :)) Another great thing that i use is @rxdi/ui-kit Demo website These are all created with @rxdi/lit-html Here is the first experiment with Monadic approach of building html blocks https://rxdi.github.io/ui-kit/graph Regards! |
@jeremy-coleman Managed to make it work with 80% of the functionalities of @rxdi/core you can try it out. Soon this old lady here will be replaced by import '@abraham/reflection';
import { Inject, Injectable, InjectionToken } from '@rhtml/di';
import { Bootstrap, Component, Module } from '@rhtml/di/module';
type UserId = number;
const UserId = new InjectionToken<UserId>();
const now = Date.now();
@Injectable()
export class UserService {
constructor(@Inject(UserId) public userId: number) {
console.log('[UserService]', userId);
}
}
@Component()
class AppComponent {
constructor(public userService: UserService) {
console.log('[AppComponent] ', userService.userId);
}
OnInit() {
console.log('[AppComponent] Init');
}
OnDestroy() {
console.log('[AppComponent] Destroy');
}
}
@Module({
providers: [
UserService,
{
provide: UserId,
useFactory: () =>
new Promise<number>(resolve => setTimeout(() => resolve(1234), 1000))
}
],
bootstrap: [AppComponent]
})
export class AppModule {}
Bootstrap(AppModule).then(() =>
console.log('Started', `after ${Date.now() - now}`)
); Only 2.5 KB :D |
Hi, i think its possible to get the core (DI only) bundle size down by about 1000% with a little effort. This will certainly have to happen in the future, so it's better to address it now imo.
check out https://github.com/jmankopf/mani-injector and replace 'reflect-metadata' with @abraham/reflection. works great. (like 300 loc vs rxdi 40k lol).
jupyter lab has a light weight DI system with similar semantics as rxdi , except without decorators. I think it uses bottlejs under the hood.
Also,
I also did a quick test without getting it actually working, removing the ipfs and systemjs stuff from rxdi and got it down to around 7k loc, which that alone could be a good start.
https://github.com/jeffijoe/awilix also is pretty great because it doesn't require any reflection polyfill, and works in the browser by dropping 2 fs methods, which could be kept and swapped for an ipfs solution.
awilix + rxjs container/di
https://github.com/mojzu/container.ts/blob/master/src/container/container.ts
Thought/solution generation and comparison only atm
The text was updated successfully, but these errors were encountered: