Coder Social home page Coder Social logo

async-injection's People

Contributors

pcafstockf avatar tripodsgames avatar

Stargazers

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

Watchers

 avatar

async-injection's Issues

ESM is broken

The imports in ESM build appear to be missing .js extensions, so when I try to import it from a project that uses ESM, I get the following error:

node:internal/errors:490
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/xxxxxx/node_modules/async-injection/lib/esm/container' imported from /xxxxxx/node_modules/async-injection/lib/esm/index.js
    at new NodeError (node:internal/errors:399:5)
    at finalizeResolution (node:internal/modules/esm/resolve:326:11)
    at moduleResolve (node:internal/modules/esm/resolve:945:10)
    at defaultResolve (node:internal/modules/esm/resolve:1153:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

All bindings are undefiened in jest-tests

Hi,

i have the following problem:
When i try to use injection in my jest-tests I am getting undefined for all dependencies -> No Symbol not found, but plain undefined.

Basic example:

import { Container, Inject, Injectable } from 'async-injection';
import 'reflect-metadata';

@Injectable()
class TestM {
  constructor(@Inject('TEST') public t: number) {}
}

test('basic injection', async () => {
  const c = new Container();
  c.bindConstant('TEST', 1);
  c.bindClass(TestM);

  const test = await c.resolve(TestM);

  expect(test.t).toBe(1);
});

Output:

 FAIL   core  packages/core/src/lib/core.test.ts
  ✕ basic injection (3 ms)

  ● basic injection

    expect(received).toBe(expected) // Object.is equality

    Expected: 1
    Received: undefined

      14 |   const test = await c.resolve(TestM);
      15 |
    > 16 |   expect(test.t).toBe(1);
         |                  ^
      17 | });
      18 |

      at Object.<anonymous> (src/lib/core.test.ts:16:18)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.288 s, estimated 1 s
Ran all test suites.

TS-Config:

{
  "compileOnSave": false,
  "compilerOptions": {
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "ES2022",
    "module": "esnext",
    "lib": ["es2022", "dom"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {
     ...
    }
  },
  "exclude": ["node_modules", "tmp"]
}

Jest Config:

export default {
  displayName: 'core',
  preset: '../../jest.preset.js',
  testEnvironment: 'node',
  transform: {
    '^.+\\.[tj]sx?$': [
      '@swc/jest',
      {
        jsc: {
          parser: {
            syntax: 'typescript',
            tsx: false,
            decorators: true,
            dynamicImport: true,
          },
          transform: { react: { runtime: 'automatic' } },
        },
      },
    ],
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
  coverageDirectory: '../../coverage/packages/core',
};

Any idea on this? Thanks for your help :)

[Proposal] Syntax Sugar Decorators.

Proposal of new decorators.

This decorators are only syntax sugar, they will work with any container.

@Factory - Syntax sugar for bindFactory

@Factory(factory: SyncFactory<T>)

// Default
@Factory(() => new FactoryExample())
class FactoryExample{}

// Will run the Factory.
container.bindClass(FactoryExample);

@AsyncFactory - Syntax sugar for bindAsyncFactory

@AsyncFactory(factory: AsyncFactory<T>)

// Default
@AsyncFactory(async () => {
    const instance = new FactoryExample();
    await instance.connect();
    return instance;
})
class AsyncFactoryExample{
    connect(): Promise<void> { ... }
}

// Create the bind.
container.bindClass(AsyncFactoryExample);

// Now it's the same as Asynchronous Usage.

Child bindings not used to resolve bindings registered on the parent

Note: I'm pretty new to DI; this may be entirely expected behaviour or I may be thinking about it the wrong way, it just seemed a little counterintuitive to me!

Basically, I'm trying to use this alongside MikroORM, which expects you to create a new "entity manager" object for each request. I assumed I could do something like

@Injectable()
class SomeClassUsingOrm {
  constructor(private readonly entityManager: EntityManager) {}
}

rootContainer.bindClass(SomeClassUsingOrm)

// on each request
const child = new Container(rootContainer)
child.bindFactory(EntityManager, () => makeNewEntityManager()).asSingleton()

console.log(child.get(SomeClassUsingOrm)) // expecting this to use the factory from the child

However, this gives a Error: Symbol not bound: class EntityManager error. It seems like because I used bindClass on the parent, the EntityManager parameter will only be resolved with the parent's providers and will ignore anything added to the child.

My goal here is to have a "abstract container" with a set of classes that depend on an type I can't yet construct. Or, to put it another way, I want a singleton factory that's called exactly once per clone of the parent container.

Add clone method to the container.

Add an option to clone the container.

Example:
For each request in a server, clone the container for specific request binds.

const container = new Container();

container.bind(ExampleRepository).asSingleton();

app.use((req, res, next) => {
    req.container = container.clone();
    // Just an Example.
    req.container.bindFactory(Request, () => req).asSingleton();
    req.container.bindFactory(Response, () => res).asSingleton();
});

@pcafstockf i can make the pull request if you like the idea.

Build in webpack failed

I updated my dependencies and now webpack displays an error like this:
image

Log as plain text
WARNING in ./src/scripts/node/event-dispatcher.ts 63:15-21
export 'Inject' (imported as 'Inject') was not found in 'async-injection' (module has no exports)
@ ./src/scripts/main.ts 12:0-58 27:28-43 28:32-47

ERROR in ./node_modules/async-injection/lib/esm/index.js 1:0-40
Module not found: Error: Can't resolve './container' in 'C:\Coding\gen-world\node_modules\async-injection\lib\esm'
Did you mean 'container.js'?
BREAKING CHANGE: The request './container' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
resolve './container' in 'C:\Coding\gen-world\node_modules\async-injection\lib\esm'
using description file: C:\Coding\gen-world\node_modules\async-injection\lib\esm\package.json (relative path: .)
  Field 'browser' doesn't contain a valid alias configuration
  using description file: C:\Coding\gen-world\node_modules\async-injection\lib\esm\package.json (relative path: ./container)
    Field 'browser' doesn't contain a valid alias configuration
    C:\Coding\gen-world\node_modules\async-injection\lib\esm\container doesn't exist
@ ./src/scripts/main.ts 11:0-44 22:30-39

ERROR in ./node_modules/async-injection/lib/esm/index.js 2:0-75
Module not found: Error: Can't resolve './decorators' in 'C:\Coding\gen-world\node_modules\async-injection\lib\esm'
Did you mean 'decorators.js'?
BREAKING CHANGE: The request './decorators' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
resolve './decorators' in 'C:\Coding\gen-world\node_modules\async-injection\lib\esm'
using description file: C:\Coding\gen-world\node_modules\async-injection\lib\esm\package.json (relative path: .)
  Field 'browser' doesn't contain a valid alias configuration
  using description file: C:\Coding\gen-world\node_modules\async-injection\lib\esm\package.json (relative path: ./decorators)
    Field 'browser' doesn't contain a valid alias configuration
    C:\Coding\gen-world\node_modules\async-injection\lib\esm\decorators doesn't exist
@ ./src/scripts/main.ts 11:0-44 22:30-39

As a workaround, I added a rule for webpack:

rules: [
    {
        test: /async-injection/,
        resolve: {
            fullySpecified: false
        }
    },
    // ...
],

Presumably the new behavior of webpack is related to:
webpack/webpack#11467

Remove `reflect-metadata` from dependencies.

In my project im using @abraham/reflection, i want to keep it and use this package as well, its possible to remove reflect-metadata and let the user select the reflection polyfill?

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.