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

Replace Lazy with LazyRef #141

Draft
wants to merge 17 commits into
base: develop
Choose a base branch
from

Conversation

freshgum-bubbles
Copy link
Owner

Replace the useless Lazy function with a new
LazyRef function in contrib.

Unlike Lazy, the LazyRef function is actually...
well, lazy -- it creates a reference host, much like
TransientRefHost, which allows for creating
an instance of the given reference at any time.

Copy link

changeset-bot bot commented Nov 28, 2023

🦋 Changeset detected

Latest commit: c8889a9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@freshgum/typedi Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@freshgum-bubbles freshgum-bubbles marked this pull request as draft November 29, 2023 16:16
Copy link
Owner Author

@freshgum-bubbles freshgum-bubbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few notes to self...

@@ -1274,7 +1274,7 @@ export class ContainerInstance implements Disposable {
* One important note is that the dependency *itself* is never resolved in the container.
*/
const parameters = serviceMetadata.dependencies.map(resolvable => ({
id: this.resolveTypeWrapper(resolvable.typeWrapper),
id: resolvable.typeWrapper.eagerType,
Copy link
Owner Author

@freshgum-bubbles freshgum-bubbles Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The now-removed method featured additional error-checking, e.g. null checks. This should either be reimplemented or added to changeset, as this is a breaking change.

@@ -1350,14 +1350,13 @@ export class ContainerInstance implements Disposable {
*/
private resolveResolvable(resolvable: Resolvable, guardBuiltIns: boolean): unknown {
const { typeWrapper } = resolvable;

const identifier = this.resolveTypeWrapper(resolvable.typeWrapper);
const identifier = resolvable.typeWrapper.eagerType;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here...

@@ -12,15 +12,6 @@ import { isTypeWrapper } from './is-type-wrapper.util.mjs';
* @param target the class definition of the target of the decorator
*/
export function resolveToTypeWrapper(typeOrIdentifier: AnyInjectIdentifier): TypeWrapper {
/**
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps these comments should be re-added (but actually relevant in the context of the API changes)? For context, these haven't changed since typestack -- they would probably just confuse readers more than help them.

@@ -1396,6 +1395,8 @@ export class ContainerInstance implements Disposable {
*/
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return typeWrapper.extract!(this, constraints ?? ResolutionConstraintFlag.None);
} else if (!identifier) {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably simpler just to hoist this to the top, which would still save the potentially unnecessary built-ins check.

@@ -1494,35 +1495,6 @@ export class ContainerInstance implements Disposable {
}
}

private resolveTypeWrapper(wrapper: TypeWrapper): ServiceIdentifier {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of this, even with it being private, should be in the changeset somewhere...


protected readonly container: ContainerInstance;
protected readonly constraints: number;
protected readonly getID: LazyRefFactory<TIdentifier>;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have some documentation for getID.


export type LazyRefFactory<TIdentifier extends ServiceIdentifier> = () => TIdentifier;

export class LazyRefHost<
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a sprinkling of TSDoc.

}

public createOrNull(): TInstance | null {
return this.resolve(ResolutionConstraintFlag.Optional);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could do with the comment in create, but inverted.


**This is a breaking change for anyone constructing `TypeWrapper` objects.**

Internal `TypeWrapper` objects have been refactored.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changesets are a right mess.


Now, the `eagerType` property is optional, and the `lazyType` property has been removed. This has been changed because the `lazyType` property was part of broader lazy functionality (alongside the `Lazy` function) which was mainly a remnant from the upstream TypeDI project.

Lazy reference functionality has been moved into a contributory package, appropriately named *lazy-ref*. This package contains a new `LazyRef` function, which allows for holding weak, or "lazy" references to services.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deserves its own changeset.

'@freshgum/typedi': patch
---

Two new type-wrapper helper interfaces have been added:
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some examples of these might be nice.

Copy link
Owner Author

@freshgum-bubbles freshgum-bubbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more notes to self.

Comment on lines -16 to -23
* ? We want to error out as soon as possible when looking up services to inject, however
* ? we cannot determine the type at decorator execution when cyclic dependencies are involved
* ? because calling the received `() => MyType` function right away would cause a JS error:
* ? "Cannot access 'MyType' before initialization", so we need to execute the function in the handler,
* ? when the classes are already created. To overcome this, we use a wrapper:
* ? - the lazyType is executed in the handler so we never have a JS error
* ? - the eagerType is checked when decorator is running and an error is raised if an unknown type is encountered
*/
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this documentation important? Should it be replaced with something more relevant, which details how type wrappers currently work?

Copy link
Owner Author

@freshgum-bubbles freshgum-bubbles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more ideas

@freshgum-bubbles freshgum-bubbles force-pushed the refactor/replace-lazy-with-lazyref branch from 7a216b8 to 68c1a15 Compare May 21, 2024 10:08
Goodbye to a pretty useless function.
It was handy for testing extractable
type-wrappers, but not for anything else.

It has also been removed from the index.
Welcome the newest member to the contrib
family: LazyRefHost!

This is basically the Lazy function, but...
it's actually lazy.  It performs very
similarly to TransientRefHost, though it
operates on lazy references instead of
transient ones.
Make the ID property of the DependencyDescriptor
interface optional, to support cases wherein the
eagerType of a TypeWrapper is not present.
@freshgum-bubbles freshgum-bubbles force-pushed the refactor/replace-lazy-with-lazyref branch from 68c1a15 to c8889a9 Compare August 1, 2024 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In progress
Development

Successfully merging this pull request may close these issues.

1 participant