katagami 1.1.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/dist/index.cjs ADDED
@@ -0,0 +1,264 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/index.ts
30
+ var exports_src = {};
31
+ __export(exports_src, {
32
+ createContainer: () => createContainer,
33
+ Scope: () => Scope,
34
+ ContainerError: () => ContainerError,
35
+ Container: () => Container
36
+ });
37
+ module.exports = __toCommonJS(exports_src);
38
+
39
+ // src/error/index.ts
40
+ class ContainerError extends Error {
41
+ constructor(message) {
42
+ super(message);
43
+ this.name = "ContainerError";
44
+ }
45
+ }
46
+
47
+ // src/resolver/index.ts
48
+ function tokenToString(token) {
49
+ if (typeof token === "function") {
50
+ return token.name || "anonymous function";
51
+ }
52
+ if (typeof token === "symbol") {
53
+ return token.toString();
54
+ }
55
+ return String(token);
56
+ }
57
+ function buildCircularPath(resolvingTokens, token) {
58
+ const path = [];
59
+ let found = false;
60
+ for (const t of resolvingTokens) {
61
+ if (t === token) {
62
+ found = true;
63
+ }
64
+ if (found) {
65
+ path.push(tokenToString(t));
66
+ }
67
+ }
68
+ path.push(tokenToString(token));
69
+ return path.join(" -> ");
70
+ }
71
+
72
+ // src/scope/index.ts
73
+ class Scope {
74
+ registrations;
75
+ singletonInstances;
76
+ scopedInstances;
77
+ resolvingTokens;
78
+ disposed = false;
79
+ constructor(registrations, singletonInstances) {
80
+ this.registrations = registrations;
81
+ this.singletonInstances = singletonInstances;
82
+ this.scopedInstances = new Map;
83
+ this.resolvingTokens = new Set;
84
+ }
85
+ resolve(token) {
86
+ return this.resolveToken(token, true);
87
+ }
88
+ tryResolve(token) {
89
+ return this.resolveToken(token, false);
90
+ }
91
+ resolveToken(token, required) {
92
+ if (this.disposed) {
93
+ throw new ContainerError("Cannot resolve from a disposed scope.");
94
+ }
95
+ const singletonCached = this.singletonInstances.get(token);
96
+ if (singletonCached !== undefined) {
97
+ return singletonCached;
98
+ }
99
+ const scopedCached = this.scopedInstances.get(token);
100
+ if (scopedCached !== undefined) {
101
+ return scopedCached;
102
+ }
103
+ const registration = this.registrations.get(token);
104
+ if (registration === undefined) {
105
+ if (required) {
106
+ throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
107
+ }
108
+ return;
109
+ }
110
+ if (this.resolvingTokens.has(token)) {
111
+ throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
112
+ }
113
+ this.resolvingTokens.add(token);
114
+ try {
115
+ const instance = registration.factory(this);
116
+ if (registration.lifetime === "singleton") {
117
+ this.singletonInstances.set(token, instance);
118
+ } else if (registration.lifetime === "scoped") {
119
+ this.scopedInstances.set(token, instance);
120
+ }
121
+ return instance;
122
+ } finally {
123
+ this.resolvingTokens.delete(token);
124
+ }
125
+ }
126
+ createScope() {
127
+ if (this.disposed) {
128
+ throw new ContainerError("Cannot create a scope from a disposed scope.");
129
+ }
130
+ return new Scope(this.registrations, this.singletonInstances);
131
+ }
132
+ async[Symbol.asyncDispose]() {
133
+ if (this.disposed) {
134
+ return;
135
+ }
136
+ this.disposed = true;
137
+ const instances = [...this.scopedInstances.values()].reverse();
138
+ const errors = [];
139
+ for (const instance of instances) {
140
+ try {
141
+ let resolved = instance;
142
+ if (instance instanceof Promise) {
143
+ resolved = await instance;
144
+ }
145
+ if (resolved != null && typeof resolved === "object") {
146
+ if (Symbol.asyncDispose in resolved) {
147
+ await resolved[Symbol.asyncDispose]();
148
+ } else if (Symbol.dispose in resolved) {
149
+ resolved[Symbol.dispose]();
150
+ }
151
+ }
152
+ } catch (error) {
153
+ errors.push(error);
154
+ }
155
+ }
156
+ this.scopedInstances.clear();
157
+ if (errors.length > 0) {
158
+ throw new AggregateError(errors, "One or more errors occurred during disposal.");
159
+ }
160
+ }
161
+ }
162
+
163
+ // src/container/index.ts
164
+ function createContainer() {
165
+ return new Container;
166
+ }
167
+
168
+ class Container {
169
+ registrations;
170
+ instances;
171
+ resolvingTokens;
172
+ disposed = false;
173
+ constructor() {
174
+ this.registrations = new Map;
175
+ this.instances = new Map;
176
+ this.resolvingTokens = new Set;
177
+ }
178
+ registerSingleton(token, factory) {
179
+ return this.addRegistration(token, factory, "singleton");
180
+ }
181
+ registerTransient(token, factory) {
182
+ return this.addRegistration(token, factory, "transient");
183
+ }
184
+ registerScoped(token, factory) {
185
+ return this.addRegistration(token, factory, "scoped");
186
+ }
187
+ createScope() {
188
+ if (this.disposed) {
189
+ throw new ContainerError("Cannot create a scope from a disposed container.");
190
+ }
191
+ return new Scope(this.registrations, this.instances);
192
+ }
193
+ resolve(token) {
194
+ return this.resolveToken(token, true);
195
+ }
196
+ tryResolve(token) {
197
+ return this.resolveToken(token, false);
198
+ }
199
+ resolveToken(token, required) {
200
+ if (this.disposed) {
201
+ throw new ContainerError("Cannot resolve from a disposed container.");
202
+ }
203
+ const cached = this.instances.get(token);
204
+ if (cached !== undefined) {
205
+ return cached;
206
+ }
207
+ const registration = this.registrations.get(token);
208
+ if (registration === undefined) {
209
+ if (required) {
210
+ throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
211
+ }
212
+ return;
213
+ }
214
+ if (registration.lifetime === "scoped") {
215
+ throw new ContainerError(`Cannot resolve scoped token "${tokenToString(token)}" from the root container. Use createScope() to create a scope first.`);
216
+ }
217
+ if (this.resolvingTokens.has(token)) {
218
+ throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
219
+ }
220
+ this.resolvingTokens.add(token);
221
+ try {
222
+ const instance = registration.factory(this);
223
+ if (registration.lifetime === "singleton") {
224
+ this.instances.set(token, instance);
225
+ }
226
+ return instance;
227
+ } finally {
228
+ this.resolvingTokens.delete(token);
229
+ }
230
+ }
231
+ async[Symbol.asyncDispose]() {
232
+ if (this.disposed) {
233
+ return;
234
+ }
235
+ this.disposed = true;
236
+ const instances = [...this.instances.values()].reverse();
237
+ const errors = [];
238
+ for (const instance of instances) {
239
+ try {
240
+ let resolved = instance;
241
+ if (instance instanceof Promise) {
242
+ resolved = await instance;
243
+ }
244
+ if (resolved != null && typeof resolved === "object") {
245
+ if (Symbol.asyncDispose in resolved) {
246
+ await resolved[Symbol.asyncDispose]();
247
+ } else if (Symbol.dispose in resolved) {
248
+ resolved[Symbol.dispose]();
249
+ }
250
+ }
251
+ } catch (error) {
252
+ errors.push(error);
253
+ }
254
+ }
255
+ this.instances.clear();
256
+ if (errors.length > 0) {
257
+ throw new AggregateError(errors, "One or more errors occurred during disposal.");
258
+ }
259
+ }
260
+ addRegistration(token, factory, lifetime) {
261
+ this.registrations.set(token, { factory, lifetime });
262
+ return this;
263
+ }
264
+ }
@@ -0,0 +1,4 @@
1
+ export { Container, createContainer } from './container';
2
+ export { ContainerError } from './error';
3
+ export type { Resolver } from './resolver';
4
+ export { Scope } from './scope';
package/dist/index.js ADDED
@@ -0,0 +1,232 @@
1
+ // src/error/index.ts
2
+ class ContainerError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "ContainerError";
6
+ }
7
+ }
8
+
9
+ // src/resolver/index.ts
10
+ function tokenToString(token) {
11
+ if (typeof token === "function") {
12
+ return token.name || "anonymous function";
13
+ }
14
+ if (typeof token === "symbol") {
15
+ return token.toString();
16
+ }
17
+ return String(token);
18
+ }
19
+ function buildCircularPath(resolvingTokens, token) {
20
+ const path = [];
21
+ let found = false;
22
+ for (const t of resolvingTokens) {
23
+ if (t === token) {
24
+ found = true;
25
+ }
26
+ if (found) {
27
+ path.push(tokenToString(t));
28
+ }
29
+ }
30
+ path.push(tokenToString(token));
31
+ return path.join(" -> ");
32
+ }
33
+
34
+ // src/scope/index.ts
35
+ class Scope {
36
+ registrations;
37
+ singletonInstances;
38
+ scopedInstances;
39
+ resolvingTokens;
40
+ disposed = false;
41
+ constructor(registrations, singletonInstances) {
42
+ this.registrations = registrations;
43
+ this.singletonInstances = singletonInstances;
44
+ this.scopedInstances = new Map;
45
+ this.resolvingTokens = new Set;
46
+ }
47
+ resolve(token) {
48
+ return this.resolveToken(token, true);
49
+ }
50
+ tryResolve(token) {
51
+ return this.resolveToken(token, false);
52
+ }
53
+ resolveToken(token, required) {
54
+ if (this.disposed) {
55
+ throw new ContainerError("Cannot resolve from a disposed scope.");
56
+ }
57
+ const singletonCached = this.singletonInstances.get(token);
58
+ if (singletonCached !== undefined) {
59
+ return singletonCached;
60
+ }
61
+ const scopedCached = this.scopedInstances.get(token);
62
+ if (scopedCached !== undefined) {
63
+ return scopedCached;
64
+ }
65
+ const registration = this.registrations.get(token);
66
+ if (registration === undefined) {
67
+ if (required) {
68
+ throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
69
+ }
70
+ return;
71
+ }
72
+ if (this.resolvingTokens.has(token)) {
73
+ throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
74
+ }
75
+ this.resolvingTokens.add(token);
76
+ try {
77
+ const instance = registration.factory(this);
78
+ if (registration.lifetime === "singleton") {
79
+ this.singletonInstances.set(token, instance);
80
+ } else if (registration.lifetime === "scoped") {
81
+ this.scopedInstances.set(token, instance);
82
+ }
83
+ return instance;
84
+ } finally {
85
+ this.resolvingTokens.delete(token);
86
+ }
87
+ }
88
+ createScope() {
89
+ if (this.disposed) {
90
+ throw new ContainerError("Cannot create a scope from a disposed scope.");
91
+ }
92
+ return new Scope(this.registrations, this.singletonInstances);
93
+ }
94
+ async[Symbol.asyncDispose]() {
95
+ if (this.disposed) {
96
+ return;
97
+ }
98
+ this.disposed = true;
99
+ const instances = [...this.scopedInstances.values()].reverse();
100
+ const errors = [];
101
+ for (const instance of instances) {
102
+ try {
103
+ let resolved = instance;
104
+ if (instance instanceof Promise) {
105
+ resolved = await instance;
106
+ }
107
+ if (resolved != null && typeof resolved === "object") {
108
+ if (Symbol.asyncDispose in resolved) {
109
+ await resolved[Symbol.asyncDispose]();
110
+ } else if (Symbol.dispose in resolved) {
111
+ resolved[Symbol.dispose]();
112
+ }
113
+ }
114
+ } catch (error) {
115
+ errors.push(error);
116
+ }
117
+ }
118
+ this.scopedInstances.clear();
119
+ if (errors.length > 0) {
120
+ throw new AggregateError(errors, "One or more errors occurred during disposal.");
121
+ }
122
+ }
123
+ }
124
+
125
+ // src/container/index.ts
126
+ function createContainer() {
127
+ return new Container;
128
+ }
129
+
130
+ class Container {
131
+ registrations;
132
+ instances;
133
+ resolvingTokens;
134
+ disposed = false;
135
+ constructor() {
136
+ this.registrations = new Map;
137
+ this.instances = new Map;
138
+ this.resolvingTokens = new Set;
139
+ }
140
+ registerSingleton(token, factory) {
141
+ return this.addRegistration(token, factory, "singleton");
142
+ }
143
+ registerTransient(token, factory) {
144
+ return this.addRegistration(token, factory, "transient");
145
+ }
146
+ registerScoped(token, factory) {
147
+ return this.addRegistration(token, factory, "scoped");
148
+ }
149
+ createScope() {
150
+ if (this.disposed) {
151
+ throw new ContainerError("Cannot create a scope from a disposed container.");
152
+ }
153
+ return new Scope(this.registrations, this.instances);
154
+ }
155
+ resolve(token) {
156
+ return this.resolveToken(token, true);
157
+ }
158
+ tryResolve(token) {
159
+ return this.resolveToken(token, false);
160
+ }
161
+ resolveToken(token, required) {
162
+ if (this.disposed) {
163
+ throw new ContainerError("Cannot resolve from a disposed container.");
164
+ }
165
+ const cached = this.instances.get(token);
166
+ if (cached !== undefined) {
167
+ return cached;
168
+ }
169
+ const registration = this.registrations.get(token);
170
+ if (registration === undefined) {
171
+ if (required) {
172
+ throw new ContainerError(`Token "${tokenToString(token)}" is not registered.`);
173
+ }
174
+ return;
175
+ }
176
+ if (registration.lifetime === "scoped") {
177
+ throw new ContainerError(`Cannot resolve scoped token "${tokenToString(token)}" from the root container. Use createScope() to create a scope first.`);
178
+ }
179
+ if (this.resolvingTokens.has(token)) {
180
+ throw new ContainerError(`Circular dependency detected: ${buildCircularPath(this.resolvingTokens, token)}`);
181
+ }
182
+ this.resolvingTokens.add(token);
183
+ try {
184
+ const instance = registration.factory(this);
185
+ if (registration.lifetime === "singleton") {
186
+ this.instances.set(token, instance);
187
+ }
188
+ return instance;
189
+ } finally {
190
+ this.resolvingTokens.delete(token);
191
+ }
192
+ }
193
+ async[Symbol.asyncDispose]() {
194
+ if (this.disposed) {
195
+ return;
196
+ }
197
+ this.disposed = true;
198
+ const instances = [...this.instances.values()].reverse();
199
+ const errors = [];
200
+ for (const instance of instances) {
201
+ try {
202
+ let resolved = instance;
203
+ if (instance instanceof Promise) {
204
+ resolved = await instance;
205
+ }
206
+ if (resolved != null && typeof resolved === "object") {
207
+ if (Symbol.asyncDispose in resolved) {
208
+ await resolved[Symbol.asyncDispose]();
209
+ } else if (Symbol.dispose in resolved) {
210
+ resolved[Symbol.dispose]();
211
+ }
212
+ }
213
+ } catch (error) {
214
+ errors.push(error);
215
+ }
216
+ }
217
+ this.instances.clear();
218
+ if (errors.length > 0) {
219
+ throw new AggregateError(errors, "One or more errors occurred during disposal.");
220
+ }
221
+ }
222
+ addRegistration(token, factory, lifetime) {
223
+ this.registrations.set(token, { factory, lifetime });
224
+ return this;
225
+ }
226
+ }
227
+ export {
228
+ createContainer,
229
+ Scope,
230
+ ContainerError,
231
+ Container
232
+ };
@@ -0,0 +1,68 @@
1
+ export type AbstractConstructor<T = unknown> = abstract new (...args: never[]) => T;
2
+ /**
3
+ * Resolver passed to factory callbacks.
4
+ *
5
+ * @template T PropertyKey-based type map (defined via interface, order-independent)
6
+ * @template Sync Union of registered sync class constructors (order-dependent)
7
+ * @template Async Union of registered async class constructors (order-dependent)
8
+ */
9
+ export interface Resolver<T, Sync extends AbstractConstructor = AbstractConstructor, Async extends AbstractConstructor = never> {
10
+ /**
11
+ * Resolve an instance for the given token.
12
+ *
13
+ * @param token A registered token
14
+ * @returns The instance associated with the token
15
+ */
16
+ resolve<V>(token: AbstractConstructor<V> & Async): Promise<V>;
17
+ resolve<V>(token: AbstractConstructor<V> & Sync): V;
18
+ resolve<K extends keyof T>(token: K): T[K];
19
+ /**
20
+ * Try to resolve an instance for the given token.
21
+ *
22
+ * Returns `undefined` instead of throwing when the token is not registered.
23
+ * Other errors (circular dependency, disposed container) are still thrown.
24
+ *
25
+ * @param token A token to resolve
26
+ * @returns The instance associated with the token, or `undefined` if not registered
27
+ */
28
+ tryResolve<V>(token: AbstractConstructor<V> & Async): Promise<V> | undefined;
29
+ tryResolve<V>(token: AbstractConstructor<V> & Sync): V | undefined;
30
+ tryResolve<K extends keyof T>(token: K): T[K] | undefined;
31
+ tryResolve<V>(token: AbstractConstructor<V>): V | Promise<V> | undefined;
32
+ tryResolve(token: PropertyKey): unknown;
33
+ }
34
+ /**
35
+ * Lifetime of a registration.
36
+ */
37
+ export type Lifetime = 'singleton' | 'transient' | 'scoped';
38
+ /**
39
+ * Factory registration entry.
40
+ */
41
+ export interface Registration {
42
+ /**
43
+ * Factory function.
44
+ *
45
+ * @param resolver Resolver
46
+ * @returns Instance
47
+ */
48
+ readonly factory: (resolver: Resolver<never, never>) => unknown;
49
+ /**
50
+ * Lifetime of the registration.
51
+ */
52
+ readonly lifetime: Lifetime;
53
+ }
54
+ /**
55
+ * Convert a token to a human-readable string.
56
+ */
57
+ export declare function tokenToString(token: unknown): string;
58
+ /**
59
+ * Build a human-readable circular dependency path from the resolving tokens.
60
+ *
61
+ * Uses the insertion order of Set to extract only the cycle portion.
62
+ * e.g. if resolvingTokens is [X, A, B, C] and token is A, returns "A -> B -> C -> A"
63
+ *
64
+ * @param resolvingTokens The set of tokens currently being resolved
65
+ * @param token The token that caused the circular dependency
66
+ * @returns Formatted cycle path string
67
+ */
68
+ export declare function buildCircularPath(resolvingTokens: Set<unknown>, token: unknown): string;
@@ -0,0 +1,81 @@
1
+ import type { AbstractConstructor, Registration } from '../resolver';
2
+ /**
3
+ * Scoped child container.
4
+ *
5
+ * Inherits all registrations from the parent container.
6
+ * Singleton instances are shared with the parent, while scoped instances are local to this scope.
7
+ * Transient instances are always newly created.
8
+ *
9
+ * @template T PropertyKey-based token type map
10
+ * @template Sync Union of registered sync class constructors
11
+ * @template Async Union of registered async class constructors
12
+ * @template ScopedT PropertyKey-based token type map for scoped registrations
13
+ * @template ScopedSync Union of scoped sync class constructors
14
+ * @template ScopedAsync Union of scoped async class constructors
15
+ */
16
+ export declare class Scope<T = Record<never, never>, Sync extends AbstractConstructor = never, Async extends AbstractConstructor = never, ScopedT = Record<never, never>, ScopedSync extends AbstractConstructor = never, ScopedAsync extends AbstractConstructor = never> implements AsyncDisposable {
17
+ private readonly registrations;
18
+ private readonly singletonInstances;
19
+ private readonly scopedInstances;
20
+ private readonly resolvingTokens;
21
+ private disposed;
22
+ constructor(registrations: Map<unknown, Registration>, singletonInstances: Map<unknown, unknown>);
23
+ /**
24
+ * Resolve an instance for the given token.
25
+ *
26
+ * - Singleton: Returns the shared instance from the parent container (creates and caches on first access).
27
+ * - Scoped: Returns an instance local to this scope (creates and caches on first access within the scope).
28
+ * - Transient: Creates a new instance on every call.
29
+ *
30
+ * @param token A registered token
31
+ * @returns The instance associated with the token
32
+ * @throws ContainerError if the token is not registered
33
+ */
34
+ resolve<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V>;
35
+ resolve<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V;
36
+ resolve<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K];
37
+ /**
38
+ * Try to resolve an instance for the given token.
39
+ *
40
+ * Returns `undefined` instead of throwing when the token is not registered.
41
+ * Other errors (circular dependency, disposed scope) are still thrown.
42
+ *
43
+ * @param token A token to resolve
44
+ * @returns The instance associated with the token, or `undefined` if not registered
45
+ */
46
+ tryResolve<V>(token: AbstractConstructor<V> & (Async | ScopedAsync)): Promise<V> | undefined;
47
+ tryResolve<V>(token: AbstractConstructor<V> & (Sync | ScopedSync)): V | undefined;
48
+ tryResolve<K extends keyof (T & ScopedT)>(token: K): (T & ScopedT)[K] | undefined;
49
+ tryResolve<V>(token: AbstractConstructor<V>): V | Promise<V> | undefined;
50
+ tryResolve(token: PropertyKey): unknown;
51
+ /**
52
+ * Internal resolution logic shared by resolve and tryResolve.
53
+ *
54
+ * @param token Token to resolve
55
+ * @param required If true, throws when the token is not registered. If false, returns undefined.
56
+ * @returns The resolved instance, or undefined if not registered and required is false
57
+ */
58
+ private resolveToken;
59
+ /**
60
+ * Create a nested scope.
61
+ *
62
+ * The nested scope shares singleton instances with the parent but has its own scoped instance cache.
63
+ *
64
+ * @returns A new Scope instance
65
+ * @throws ContainerError if the scope has been disposed
66
+ */
67
+ createScope(): Scope<T, Sync, Async, ScopedT, ScopedSync, ScopedAsync>;
68
+ /**
69
+ * Dispose all scoped instances managed by this scope.
70
+ *
71
+ * Iterates through scoped instances in reverse creation order (LIFO) and calls
72
+ * `[Symbol.asyncDispose]()` or `[Symbol.dispose]()` on each instance that implements them.
73
+ * Singleton instances are not disposed as they are owned by the parent container.
74
+ *
75
+ * This method is idempotent — subsequent calls after the first are no-ops.
76
+ * After disposal, `resolve()` and `createScope()` will throw `ContainerError`.
77
+ *
78
+ * @throws AggregateError if one or more instances throw during disposal
79
+ */
80
+ [Symbol.asyncDispose](): Promise<void>;
81
+ }
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "katagami",
3
+ "version": "1.1.0",
4
+ "description": "Lightweight DI container for TypeScript and JavaScript — full type inference, no decorators, no reflect-metadata, hybrid class & PropertyKey tokens.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ }
13
+ },
14
+ "main": "./dist/index.cjs",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "dependency-injection",
22
+ "di container",
23
+ "di",
24
+ "container",
25
+ "ioc",
26
+ "typescript",
27
+ "javascript"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/hiroiku/katagami.git"
32
+ },
33
+ "scripts": {
34
+ "clean": "rm -rf dist",
35
+ "build": "bun run clean && bun run build:types && bun run build:esm && bun run build:cjs",
36
+ "build:types": "tsc -p tsconfig.build.json",
37
+ "build:esm": "bun build ./src/index.ts --outdir dist --format esm",
38
+ "build:cjs": "bun build ./src/index.ts --outfile dist/index.cjs --format cjs",
39
+ "test": "bun test --coverage --dots",
40
+ "prepublishOnly": "bun run build",
41
+ "check": "bun run format",
42
+ "lint": "biome lint .",
43
+ "format": "biome check --write .",
44
+ "verify": "bun run build:types && bun run check && bun run test"
45
+ },
46
+ "dependencies": {
47
+ "@types/bun": "^1.3.8"
48
+ },
49
+ "devDependencies": {
50
+ "@biomejs/biome": "^2.3.14",
51
+ "typescript": "^5.9.3"
52
+ }
53
+ }