tiny-di.js 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/core/container.js +92 -0
- package/dist/core/container.js.map +1 -0
- package/dist/core/entry.builder.js +49 -0
- package/dist/core/entry.builder.js.map +1 -0
- package/dist/core/index.js +19 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/scope.js +54 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/types/definition.js +3 -0
- package/dist/types/definition.js.map +1 -0
- package/dist/types/index.js +18 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# dijs
|
|
2
|
+
|
|
3
|
+
A lightweight, type-safe **Dependency Injection** container for TypeScript and Node.js. Define your dependencies programmatically with full type inference — no decorators required.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **3 lifetime strategies** — singleton, transient, and scoped (per-request)
|
|
8
|
+
- **Multiple provider types** — class constructor, value, factory, and self-resolution
|
|
9
|
+
- **Automatic dependency injection** — declare imports; the container resolves them
|
|
10
|
+
- **Circular dependency detection** — DFS-based cycle detection with descriptive error messages
|
|
11
|
+
- **Scoped hierarchies** — per-request scopes for Express or similar frameworks
|
|
12
|
+
- **Type-safe** — full TypeScript generics from registration to resolution
|
|
13
|
+
- **No decorators** — pure programmatic API
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install dijs
|
|
19
|
+
# or
|
|
20
|
+
pnpm add dijs
|
|
21
|
+
# or
|
|
22
|
+
yarn add dijs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Container } from "dijs";
|
|
29
|
+
|
|
30
|
+
class Logger {
|
|
31
|
+
log(msg: string) {
|
|
32
|
+
console.log(msg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class Database {
|
|
37
|
+
constructor(private logger: Logger) {}
|
|
38
|
+
|
|
39
|
+
query(sql: string) {
|
|
40
|
+
this.logger.log(`Executing: ${sql}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const container = new Container();
|
|
45
|
+
|
|
46
|
+
container.singleton(Logger).toSelf();
|
|
47
|
+
container.singleton(Database).import(Logger).toSelf();
|
|
48
|
+
|
|
49
|
+
const db = container.get(Database);
|
|
50
|
+
db.query("SELECT 1"); // "Executing: SELECT 1"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
### Container
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const container = new Container();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Method | Description |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `singleton<T>(token)` | Register a singleton provider (one instance per container) |
|
|
64
|
+
| `transient<T>(token)` | Register a transient provider (new instance each time) |
|
|
65
|
+
| `scoped<T>(token)` | Register a scoped provider (one instance per `Scope`) |
|
|
66
|
+
| `get<T>(token)` | Resolve a dependency |
|
|
67
|
+
| `createScope(id?)` | Create a child `Scope` |
|
|
68
|
+
|
|
69
|
+
### EntryBuilder (fluent registration)
|
|
70
|
+
|
|
71
|
+
Every registration method returns an `EntryBuilder` that lets you chain configuration:
|
|
72
|
+
|
|
73
|
+
| Method | Description |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `.import(...tokens)` | Declare dependencies to inject |
|
|
76
|
+
| `.to(class)` | Map token to a class constructor |
|
|
77
|
+
| `.to(value)` | Map token to an already-created value |
|
|
78
|
+
| `.toSelf()` | Use the token itself as the constructor |
|
|
79
|
+
| `.toFactory(fn)` | Provide a factory function |
|
|
80
|
+
| `.none()` | Register with no provider (set later via scope) |
|
|
81
|
+
|
|
82
|
+
### Lifetimes
|
|
83
|
+
|
|
84
|
+
- **Singleton** — lazy on first `get()`. Same instance for every call.
|
|
85
|
+
- **Transient** — always returns a fresh instance. Cannot be used with `.to(value)`.
|
|
86
|
+
- **Scoped** — cached inside a `Scope` object. Created via `container.createScope()`.
|
|
87
|
+
|
|
88
|
+
### Scopes
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const scope = container.createScope("request-1");
|
|
92
|
+
|
|
93
|
+
// Scoped registrations are cached per scope
|
|
94
|
+
const a = scope.get(MyScopedService);
|
|
95
|
+
const b = scope.get(MyScopedService);
|
|
96
|
+
// a === b (same scope)
|
|
97
|
+
|
|
98
|
+
// Different scope = different instance
|
|
99
|
+
const scope2 = container.createScope("request-2");
|
|
100
|
+
const c = scope2.get(MyScopedService);
|
|
101
|
+
// a !== c
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Express Integration
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import express, { Request } from "express";
|
|
108
|
+
import { Container, Scope } from "dijs";
|
|
109
|
+
import { scopedMiddleware, ScopedRequest } from "dijs/express";
|
|
110
|
+
|
|
111
|
+
const container = new Container();
|
|
112
|
+
container.scoped(AUTH_CTX).none();
|
|
113
|
+
|
|
114
|
+
const app = express();
|
|
115
|
+
app.use(scopedMiddleware(container));
|
|
116
|
+
|
|
117
|
+
app.use((req: ScopedRequest, _res, next) => {
|
|
118
|
+
const scope = req.scope;
|
|
119
|
+
scope.set(AUTH_CTX, { username: req.headers["x-user-id"] });
|
|
120
|
+
next();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
app.get("/me", (req: ScopedRequest, res) => {
|
|
124
|
+
const ctx = req.scope.get(AUTH_CTX);
|
|
125
|
+
res.json(ctx);
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Circular Dependency Detection
|
|
130
|
+
|
|
131
|
+
If a cycle is detected, a descriptive error is thrown before a stack overflow can occur:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Error: Circular dependency: A => B => C => A
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Tokens
|
|
138
|
+
|
|
139
|
+
Tokens can be a class constructor, a string, or a symbol:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
container.singleton<Config>("CONFIG").to({ host: "localhost" });
|
|
143
|
+
container.singleton<Logger>(Symbol("logger")).to(Logger);
|
|
144
|
+
container.singleton(Database).toSelf();
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Building
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
pnpm build
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Testing
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
pnpm test
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
MIT
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Container = void 0;
|
|
4
|
+
const entry_builder_1 = require("./entry.builder");
|
|
5
|
+
const scope_1 = require("./scope");
|
|
6
|
+
class Container {
|
|
7
|
+
resolving = new Set();
|
|
8
|
+
singletons = new Map();
|
|
9
|
+
entries = new Map();
|
|
10
|
+
createScope(id) {
|
|
11
|
+
return new scope_1.Scope(this, id);
|
|
12
|
+
}
|
|
13
|
+
singleton(provide) {
|
|
14
|
+
return new entry_builder_1.EntryBuilder(this, "singleton").provide(provide);
|
|
15
|
+
}
|
|
16
|
+
transient(provide) {
|
|
17
|
+
return new entry_builder_1.EntryBuilder(this, "transient").provide(provide);
|
|
18
|
+
}
|
|
19
|
+
scoped(provide) {
|
|
20
|
+
return new entry_builder_1.EntryBuilder(this, "scoped").provide(provide);
|
|
21
|
+
}
|
|
22
|
+
add(dc) {
|
|
23
|
+
this.entries.set(dc.provide, dc);
|
|
24
|
+
}
|
|
25
|
+
get(key, scope) {
|
|
26
|
+
const entry = this.entries.get(key);
|
|
27
|
+
if (!entry)
|
|
28
|
+
throw new Error("No provider");
|
|
29
|
+
const visiting = new Set();
|
|
30
|
+
const checked = new Set();
|
|
31
|
+
this.detectCycle(key, [], visiting, checked);
|
|
32
|
+
if (entry.lifetime === "singleton") {
|
|
33
|
+
if (this.singletons.has(key))
|
|
34
|
+
return this.singletons.get(key);
|
|
35
|
+
const instance = this.create(entry, scope);
|
|
36
|
+
this.singletons.set(key, instance);
|
|
37
|
+
return instance;
|
|
38
|
+
}
|
|
39
|
+
if (entry.lifetime === "scoped" && scope) {
|
|
40
|
+
if (scope.cache.has(key))
|
|
41
|
+
return scope.cache.get(key);
|
|
42
|
+
const instance = this.create(entry, scope);
|
|
43
|
+
scope.cache.set(key, instance);
|
|
44
|
+
return instance;
|
|
45
|
+
}
|
|
46
|
+
return this.create(entry, scope);
|
|
47
|
+
}
|
|
48
|
+
create(entry, scope) {
|
|
49
|
+
let deps = entry.imports.map((d) => this.get(d, scope));
|
|
50
|
+
if (entry.useValue)
|
|
51
|
+
return entry.useValue;
|
|
52
|
+
if (entry.useFactory)
|
|
53
|
+
return entry.useFactory(...deps);
|
|
54
|
+
if (entry.useClass)
|
|
55
|
+
return new entry.useClass(...deps);
|
|
56
|
+
throw new Error("Cannot create provider");
|
|
57
|
+
}
|
|
58
|
+
strKey(key) {
|
|
59
|
+
if (typeof key === "string") {
|
|
60
|
+
return key;
|
|
61
|
+
}
|
|
62
|
+
else if (typeof key === "symbol") {
|
|
63
|
+
return key.description ?? key.toString();
|
|
64
|
+
}
|
|
65
|
+
else if (typeof key === "function") {
|
|
66
|
+
return key.name;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return JSON.stringify(key, null, 2);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
detectCycle(key, path = [], visiting, checked) {
|
|
73
|
+
if (checked.has(key))
|
|
74
|
+
return;
|
|
75
|
+
if (visiting.has(key)) {
|
|
76
|
+
const cIndex = path.indexOf(key);
|
|
77
|
+
const cyclePath = [...path.slice(cIndex), key];
|
|
78
|
+
throw new Error(`Circular dependency: ${cyclePath.map((k) => this.strKey(k)).join(" => ")}`);
|
|
79
|
+
}
|
|
80
|
+
visiting.add(key);
|
|
81
|
+
path.push(key);
|
|
82
|
+
const deps = this.entries.get(key)?.imports ?? [];
|
|
83
|
+
for (const dep of deps) {
|
|
84
|
+
this.detectCycle(dep, path, visiting, checked);
|
|
85
|
+
}
|
|
86
|
+
path.pop();
|
|
87
|
+
visiting.delete(key);
|
|
88
|
+
checked.add(key);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.Container = Container;
|
|
92
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/core/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntryBuilder = void 0;
|
|
4
|
+
class EntryBuilder {
|
|
5
|
+
container;
|
|
6
|
+
config = {
|
|
7
|
+
imports: [],
|
|
8
|
+
};
|
|
9
|
+
constructor(container, mode = "singleton") {
|
|
10
|
+
this.container = container;
|
|
11
|
+
this.config.lifetime = mode;
|
|
12
|
+
}
|
|
13
|
+
provide(token) {
|
|
14
|
+
this.config.provide = token;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
import(...deps) {
|
|
18
|
+
this.config.imports = deps;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
toFactory(fn) {
|
|
22
|
+
this.config.useFactory = fn;
|
|
23
|
+
this.container.add(this.config);
|
|
24
|
+
}
|
|
25
|
+
to(v) {
|
|
26
|
+
if (typeof v !== "function") {
|
|
27
|
+
this.config.useValue = v;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
this.config.useClass = v;
|
|
31
|
+
}
|
|
32
|
+
if (this.config.lifetime === "transient" && this.config.useValue) {
|
|
33
|
+
throw new Error("transient mode cannot be used with useValue provider");
|
|
34
|
+
}
|
|
35
|
+
this.container.add(this.config);
|
|
36
|
+
}
|
|
37
|
+
none() {
|
|
38
|
+
this.container.add(this.config);
|
|
39
|
+
}
|
|
40
|
+
toSelf() {
|
|
41
|
+
if (typeof this.config.provide !== "function") {
|
|
42
|
+
throw new Error("toSelf cannot be used if provide is not a constructor");
|
|
43
|
+
}
|
|
44
|
+
this.config.useClass = this.config.provide;
|
|
45
|
+
this.container.add(this.config);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.EntryBuilder = EntryBuilder;
|
|
49
|
+
//# sourceMappingURL=entry.builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.builder.js","sourceRoot":"","sources":["../../src/core/entry.builder.ts"],"names":[],"mappings":";;;AAIA,MAAa,YAAY;IAMJ;IALF,MAAM,GAAsB;QAC3C,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,YACmB,SAAoB,EACrC,OAAiB,WAAW;QADX,cAAS,GAAT,SAAS,CAAW;QAGrC,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,KAAe;QACrB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,GAAG,IAAsB;QAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,EAAiB;QACzB,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAkB,CAAC,CAAC;IAC9C,CAAC;IAID,EAAE,CAAC,CAAqB;QACtB,IAAI,OAAO,CAAC,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAmB,CAAC;QAC7C,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAkB,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAkB,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM;QACJ,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAkB,CAAC,CAAC;IAC9C,CAAC;CACF;AAtDD,oCAsDC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./container"), exports);
|
|
18
|
+
__exportStar(require("./scope"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,0CAAwB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Scope = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
class Scope {
|
|
39
|
+
container;
|
|
40
|
+
id;
|
|
41
|
+
cache = new Map();
|
|
42
|
+
constructor(container, id = crypto.randomUUID()) {
|
|
43
|
+
this.container = container;
|
|
44
|
+
this.id = id;
|
|
45
|
+
}
|
|
46
|
+
get(key) {
|
|
47
|
+
return this.container.get(key, this);
|
|
48
|
+
}
|
|
49
|
+
set(key, value) {
|
|
50
|
+
this.cache.set(key, value);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.Scope = Scope;
|
|
54
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/core/scope.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,+CAAiC;AAGjC,MAAa,KAAK;IAIG;IAHV,EAAE,CAAC;IACH,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACpD,YACmB,SAAoB,EACrC,KAAa,MAAM,CAAC,UAAU,EAAE;QADf,cAAS,GAAT,SAAS,CAAW;QAGrC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,GAAG,CAAI,GAAa;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAAI,GAAa,EAAE,KAAQ;QAC5B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF;AAjBD,sBAiBC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./core"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,0CAAwB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/types/definition.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./definition"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tiny-di.js",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight dependency injection container",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": ["dist"],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"test": "vitest"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"packageManager": "pnpm@10.26.2+sha512.0e308ff2005fc7410366f154f625f6631ab2b16b1d2e70238444dd6ae9d630a8482d92a451144debc492416896ed16f7b114a86ec68b8404b2443869e68ffda6",
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/express": "^5.0.6",
|
|
24
|
+
"@types/node": "^25.9.3",
|
|
25
|
+
"@types/supertest": "^7.2.0",
|
|
26
|
+
"express": "^5.2.1",
|
|
27
|
+
"supertest": "^7.2.2",
|
|
28
|
+
"typescript": "^6.0.3",
|
|
29
|
+
"vitest": "^4.1.8"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"reflect-metadata": "^0.2.2"
|
|
33
|
+
}
|
|
34
|
+
}
|