di-craft 0.0.18 → 0.0.20
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/README.md +128 -4
- package/dist/container-C6GcrdNn.mjs +1 -0
- package/dist/hydration-BJ-gWd38.d.mts +174 -0
- package/dist/hydration-DsCFyhuJ.mjs +1 -0
- package/dist/index.d.mts +32 -169
- package/dist/index.mjs +1 -1
- package/dist/next/client.d.mts +2 -0
- package/dist/next/client.mjs +1 -0
- package/dist/next/server.d.mts +33 -0
- package/dist/next/server.mjs +1 -0
- package/dist/types-BzLfq9VA.d.mts +140 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -17,10 +17,6 @@
|
|
|
17
17
|
</a>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
|
-
> [!NOTE]
|
|
21
|
-
> This README was generated with a bit of AI help — don't believe everything you see 🙂
|
|
22
|
-
|
|
23
|
-
|
|
24
20
|
## Contents
|
|
25
21
|
|
|
26
22
|
- [Quick start](#quick-start)
|
|
@@ -38,6 +34,8 @@
|
|
|
38
34
|
- [Child containers](#child-containers)
|
|
39
35
|
- [Cycle detection](#cycle-detection)
|
|
40
36
|
- [Async dependencies](#async-dependencies)
|
|
37
|
+
- [Adapters](#adapters)
|
|
38
|
+
- [Next.js App Router](#nextjs-app-router)
|
|
41
39
|
- [Dependency injection vs service location](#dependency-injection-vs-service-location)
|
|
42
40
|
- [Error handling](#error-handling)
|
|
43
41
|
- [API reference](#api-reference)
|
|
@@ -437,6 +435,125 @@ provideFactory(POOL, {
|
|
|
437
435
|
});
|
|
438
436
|
```
|
|
439
437
|
|
|
438
|
+
## Adapters
|
|
439
|
+
|
|
440
|
+
Adapters are optional framework integrations built around the core container.
|
|
441
|
+
They live behind subpath exports, so the root import stays framework-agnostic:
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
import { createContainer } from "di-craft"; // core only
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Next.js App Router
|
|
448
|
+
|
|
449
|
+
The Next adapter helps connect di-craft to the App Router request lifecycle
|
|
450
|
+
without making React or Next.js part of the core import.
|
|
451
|
+
|
|
452
|
+
Use `di-craft/next/server` from a server-only composition file. Pass React's
|
|
453
|
+
`cache` function so React/Next owns request memoization while di-craft owns only
|
|
454
|
+
the dependency graph:
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
// app/di.server.ts
|
|
458
|
+
import "server-only";
|
|
459
|
+
import { cache } from "react";
|
|
460
|
+
import { provideValue } from "di-craft";
|
|
461
|
+
import { createNextDi } from "di-craft/next/server";
|
|
462
|
+
|
|
463
|
+
export const {
|
|
464
|
+
getRequestContainer,
|
|
465
|
+
getRootContainer,
|
|
466
|
+
runWithRequestContainer,
|
|
467
|
+
} = createNextDi({
|
|
468
|
+
cache,
|
|
469
|
+
providers,
|
|
470
|
+
requestProviders: () => [
|
|
471
|
+
provideValue(REQUEST_ID, crypto.randomUUID()),
|
|
472
|
+
],
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Then resolve dependencies in Server Components at the composition edge:
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
import { getRequestContainer } from "./di.server";
|
|
480
|
+
|
|
481
|
+
export default async function Page() {
|
|
482
|
+
const users = getRequestContainer().get(USERS_SERVICE);
|
|
483
|
+
|
|
484
|
+
return <UsersView users={await users.list()} />;
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
Next.js does not expose a general "RSC render is finished" hook, so the adapter
|
|
489
|
+
does not pretend it can automatically dispose a cached Server Component request
|
|
490
|
+
container. If you own the lifecycle, for example in a Route Handler, Server
|
|
491
|
+
Action, test, or job, use `runWithRequestContainer`. It creates a fresh child
|
|
492
|
+
container and disposes it in a `finally` block:
|
|
493
|
+
|
|
494
|
+
```ts
|
|
495
|
+
import { runWithRequestContainer } from "./di.server";
|
|
496
|
+
|
|
497
|
+
export async function GET() {
|
|
498
|
+
return runWithRequestContainer({
|
|
499
|
+
run: async (container) => {
|
|
500
|
+
const users = await container.get(USERS_SERVICE).list();
|
|
501
|
+
|
|
502
|
+
return Response.json(users);
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
State hydration is explicit. The server reads serializable snapshots with
|
|
509
|
+
`di-craft/next/server`; the client restores them with `di-craft/next/client`.
|
|
510
|
+
The DI container itself is never hydrated.
|
|
511
|
+
|
|
512
|
+
Import boundary-specific runtime helpers from their own subpath:
|
|
513
|
+
|
|
514
|
+
- `di-craft/next/server` — `createNextDi`, `dehydrate`, server-only adapter types.
|
|
515
|
+
- `di-craft/next/client` — `hydrate`, client-boundary hydration types.
|
|
516
|
+
- Shared hydration contracts like `Hydratable`, `HydrationSchema`, and
|
|
517
|
+
`HydrationSnapshot` are exported from both subpaths for convenience.
|
|
518
|
+
|
|
519
|
+
```ts
|
|
520
|
+
import {
|
|
521
|
+
dehydrate,
|
|
522
|
+
type Hydratable,
|
|
523
|
+
type HydrationSchema,
|
|
524
|
+
} from "di-craft/next/server";
|
|
525
|
+
|
|
526
|
+
class UserState implements Hydratable<UserSnapshot> {
|
|
527
|
+
dehydrate(): UserSnapshot {
|
|
528
|
+
return { users: this.users };
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
hydrate(snapshot: UserSnapshot): void {
|
|
532
|
+
this.users = snapshot.users;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const hydration = {
|
|
537
|
+
user: USER_STATE,
|
|
538
|
+
} satisfies HydrationSchema;
|
|
539
|
+
const snapshot = dehydrate({
|
|
540
|
+
container: getRequestContainer(),
|
|
541
|
+
schema: hydration,
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
```ts
|
|
546
|
+
"use client";
|
|
547
|
+
|
|
548
|
+
import { hydrate } from "di-craft/next/client";
|
|
549
|
+
|
|
550
|
+
hydrate({
|
|
551
|
+
container: clientContainer,
|
|
552
|
+
schema: hydration,
|
|
553
|
+
snapshot,
|
|
554
|
+
});
|
|
555
|
+
```
|
|
556
|
+
|
|
440
557
|
## Dependency injection vs service location
|
|
441
558
|
|
|
442
559
|
di-craft is built for **dependency injection**: dependencies are declared up
|
|
@@ -526,6 +643,13 @@ Exported types: `Container`, `Token`, `Provider`, `ValueProvider`,
|
|
|
526
643
|
Exported errors: `DiError`, `MissingProviderError`, `DuplicateProviderError`,
|
|
527
644
|
`CircularDependencyError`, `InvalidDependencyError`, `InvalidProviderError`.
|
|
528
645
|
|
|
646
|
+
Subpath exports:
|
|
647
|
+
|
|
648
|
+
| Export | Description |
|
|
649
|
+
| --------------------------- | ------------------------------------------------------- |
|
|
650
|
+
| `di-craft/next/server` | Next.js server adapter for request-scoped containers. |
|
|
651
|
+
| `di-craft/next/client` | Client-boundary helpers for restoring state snapshots. |
|
|
652
|
+
|
|
529
653
|
## License
|
|
530
654
|
|
|
531
655
|
[MIT](./LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class extends Error{constructor(e){super(e),this.name=`DiError`,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}},t=class extends e{constructor(e){super(e),this.name=`InvalidProviderError`}};const n={Singleton:`singleton`,Transient:`transient`,Scoped:`scoped`},r=(e,t)=>({provide:e,useValue:t}),i=(e,r)=>{if(r.scope===n.Transient&&r.onDispose)throw new t(`onDispose is not supported for transient providers (token "${e.name}"): transient instances are not tracked, so the hook would never run.`);return{provide:e,useFactory:r.useFactory,scope:r.scope??n.Singleton,...r.deps?{deps:r.deps}:{},...r.onDispose?{onDispose:r.onDispose}:{}}},a=e=>({token:e,optional:!0}),o=e=>e.optional===!0,s=e=>`useValue`in e;var c=class extends e{constructor(e){super(`Provider for token "${e}" is already registered`),this.name=`DuplicateProviderError`}},l=class{providers=new Map;register(e,t){let n=this.providers.has(e.provide.id);if(n&&!t?.allowOverride)throw new c(e.provide.name);return this.providers.set(e.provide.id,e),n}get(e){return this.providers.get(e.id)}has(e){return this.providers.has(e.id)}};const u=()=>new l;var d=class extends e{constructor(e){super(`Provider for token "${e}" is not registered`),this.name=`MissingProviderError`}},f=class extends e{constructor(e){super(`Invalid dependency "${e}"`),this.name=`InvalidDependencyError`}},p=class extends e{constructor(e){super(`Circular dependency detected: ${e.join(` -> `)}`),this.name=`CircularDependencyError`}},m=class{instances=new Map;get(e){return this.instances.get(e.id)}set(e,t){this.instances.set(e.id,t)}delete(e){this.instances.delete(e.id)}async dispose(){let e=[...this.instances.values()].reverse();this.instances.clear();for(let t of e)t.onDispose&&await t.onDispose(t.value)}};const h=()=>new m;var g=class{resolving=new Set;path=[];enter(e){if(this.resolving.has(e.id)){let t=this.path.findIndex(t=>t.id===e.id);throw new p([...this.path.slice(t),e].map(e=>e.name))}this.resolving.add(e.id),this.path.push(e)}exit(e){this.path.pop(),this.resolving.delete(e.id)}};const _=e=>e===n.Scoped?1:e===n.Transient?2:0;var v=class{registry;store=h();parent;constructor(e,t){this.registry=e,this.parent=t}resolve(e){return this.resolveToken(e,void 0)}resolveOptional(e){return this.lookupOptional(e,void 0)}invalidate(e){this.store.delete(e)}hasDisposableInstance(e){return this.store.get(e)?.onDispose!==void 0}dispose(){return this.store.dispose()}resolveToken(e,r,i,a){let o=this,c;for(;o&&(c=o.registry.get(e),!c);)o=o.parent;if(!c||!o)throw new d(e.name);if(s(c))return c.useValue;if(i!==void 0&&_(c.scope)>_(i))throw new t(`"${a}" (${i}) cannot depend on "${e.name}" (${c.scope??n.Singleton}): a longer-lived provider would capture a shorter-lived one. Widen the dependency's scope or narrow the consumer's.`);let l=this.selectHost(c.scope,o);if(l){let t=l.store.get(e);if(t)return t.value}let u=r??new g;u.enter(e);try{let t=(l??this).resolveDeps(c.deps,u,c.scope,e.name),n=c.useFactory(t);return l&&l.store.set(e,{value:n,...c.onDispose?{onDispose:c.onDispose}:{}}),n}finally{u.exit(e)}}selectHost(e,t){if(e!==n.Transient)return e===n.Scoped?this:t}resolveDeps(e,t,n,r){if(!e)return{};let i={};for(let a of Object.keys(e)){let s=e[a];if(s===void 0)throw new f(String(a));i[a]=o(s)?this.lookupOptional(s.token,t,n,r):this.resolveToken(s,t,n,r)}return i}lookupOptional(e,t,n,r){let i=this;for(;i;){if(i.registry.has(e))return this.resolveToken(e,t,n,r);i=i.parent}}};const y=(e,t)=>new v(e,t);var b=class{registry;resolver;parent;constructor(e=[],t){this.parent=t,this.registry=u();for(let t of e)this.registry.register(t);this.resolver=y(this.registry,t?.resolver)}register(e,n){if(n?.allowOverride&&this.resolver.hasDisposableInstance(e.provide))throw new t(`Cannot override token "${e.provide.name}": its instance was already created and has an onDispose hook. Dispose the container before replacing it.`);this.registry.register(e,n)&&this.resolver.invalidate(e.provide)}get(e){return o(e)?this.resolver.resolveOptional(e.token):this.resolver.resolve(e)}has(e){return this.registry.has(e)||(this.parent?.has(e)??!1)}dispose(){return this.resolver.dispose()}};const x=(e=[])=>new b(e),S=(e,t=[])=>new b(t,e);export{d as a,i as c,t as d,e as f,f as i,r as l,x as n,c as o,p as r,a as s,S as t,n as u};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { d as Token, l as Provider, t as Container } from "./types-BzLfq9VA.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/next/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Minimal shape of React's `cache` function needed by the adapter.
|
|
6
|
+
*
|
|
7
|
+
* Passing it in keeps React out of di-craft's dependency graph while still
|
|
8
|
+
* letting React/Next own the current request cache.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { cache } from "react";
|
|
13
|
+
*
|
|
14
|
+
* createNextDi({ cache, providers });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
type RequestCache = <T>(factory: () => T) => () => T;
|
|
18
|
+
/**
|
|
19
|
+
* Options for `createNextDi`.
|
|
20
|
+
*/
|
|
21
|
+
type CreateNextDiOptions = {
|
|
22
|
+
/**
|
|
23
|
+
* Providers registered once in the root server container.
|
|
24
|
+
*/
|
|
25
|
+
readonly providers?: readonly Provider[];
|
|
26
|
+
/**
|
|
27
|
+
* React request cache, imported from `react` in a Next server file.
|
|
28
|
+
*/
|
|
29
|
+
readonly cache: RequestCache;
|
|
30
|
+
/**
|
|
31
|
+
* Providers registered in each request-scoped child container.
|
|
32
|
+
*/
|
|
33
|
+
readonly requestProviders?: () => readonly Provider[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Options for running work inside a fresh request-scoped child container.
|
|
37
|
+
*/
|
|
38
|
+
type RunWithRequestContainerOptions<TResult> = {
|
|
39
|
+
/**
|
|
40
|
+
* Extra providers registered only for this manual request container.
|
|
41
|
+
*/
|
|
42
|
+
readonly providers?: readonly Provider[];
|
|
43
|
+
/**
|
|
44
|
+
* Work that owns the request lifecycle. The container is disposed after this
|
|
45
|
+
* callback settles.
|
|
46
|
+
*/
|
|
47
|
+
readonly run: (container: Container) => TResult | Promise<TResult>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Next.js server adapter instance created by `createNextDi`.
|
|
51
|
+
*/
|
|
52
|
+
type NextDiAdapter = {
|
|
53
|
+
/**
|
|
54
|
+
* Returns the long-lived root server container.
|
|
55
|
+
*/
|
|
56
|
+
readonly getRootContainer: () => Container;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the current request-scoped child container.
|
|
59
|
+
*/
|
|
60
|
+
readonly getRequestContainer: () => Container;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a fresh child container manually, useful in route handlers or tests.
|
|
63
|
+
*/
|
|
64
|
+
readonly createRequestContainer: (providers?: readonly Provider[]) => Container;
|
|
65
|
+
/**
|
|
66
|
+
* Runs work inside a fresh child container and disposes it in a `finally`
|
|
67
|
+
* block. Use this in Route Handlers, Server Actions, or tests where the
|
|
68
|
+
* request lifecycle is explicit.
|
|
69
|
+
*/
|
|
70
|
+
readonly runWithRequestContainer: <TResult>(options: RunWithRequestContainerOptions<TResult>) => Promise<Awaited<TResult>>;
|
|
71
|
+
/**
|
|
72
|
+
* Disposes cached instances owned by the root container.
|
|
73
|
+
*/
|
|
74
|
+
readonly disposeRootContainer: () => Promise<void>;
|
|
75
|
+
};
|
|
76
|
+
type SerializablePrimitive = string | number | boolean | null;
|
|
77
|
+
/**
|
|
78
|
+
* JSON-like value that can safely cross a Server Component boundary.
|
|
79
|
+
*/
|
|
80
|
+
type Serializable = SerializablePrimitive | readonly Serializable[] | {
|
|
81
|
+
readonly [key: string]: Serializable;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Entity that can expose and restore a serializable state snapshot.
|
|
85
|
+
*
|
|
86
|
+
* The snapshot, not the DI container, is what crosses the RSC/client boundary.
|
|
87
|
+
*/
|
|
88
|
+
type Hydratable<TSnapshot extends Serializable> = {
|
|
89
|
+
/**
|
|
90
|
+
* Returns the minimal serializable state needed by the client.
|
|
91
|
+
*/
|
|
92
|
+
dehydrate(): TSnapshot;
|
|
93
|
+
/**
|
|
94
|
+
* Restores state from a previously serialized snapshot.
|
|
95
|
+
*/
|
|
96
|
+
hydrate(snapshot: TSnapshot): void;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Named hydratable tokens that define a client-boundary snapshot shape.
|
|
100
|
+
*
|
|
101
|
+
* Use it with `satisfies` to validate the schema without losing literal keys or
|
|
102
|
+
* token-specific snapshot inference.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* const hydration = {
|
|
107
|
+
* user: USER_STATE,
|
|
108
|
+
* } satisfies HydrationSchema;
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
type HydrationSchema = Readonly<Record<string, Token<Hydratable<Serializable>>>>;
|
|
112
|
+
/**
|
|
113
|
+
* Snapshot object inferred from a hydration schema.
|
|
114
|
+
*/
|
|
115
|
+
type HydrationSnapshot<TSchema extends HydrationSchema> = { readonly [TKey in keyof TSchema]: TSchema[TKey] extends Token<Hydratable<infer TSnapshot>> ? TSnapshot : never };
|
|
116
|
+
/**
|
|
117
|
+
* Options for reading a serializable snapshot from a container.
|
|
118
|
+
*/
|
|
119
|
+
type DehydrateOptions<TSchema extends HydrationSchema> = {
|
|
120
|
+
/**
|
|
121
|
+
* Container that owns the hydratable state entities.
|
|
122
|
+
*/
|
|
123
|
+
readonly container: Container;
|
|
124
|
+
/**
|
|
125
|
+
* Hydratable tokens keyed by snapshot field name.
|
|
126
|
+
*/
|
|
127
|
+
readonly schema: TSchema;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Options for restoring a serializable snapshot into a container.
|
|
131
|
+
*/
|
|
132
|
+
type HydrateOptions<TSchema extends HydrationSchema> = DehydrateOptions<TSchema> & {
|
|
133
|
+
/**
|
|
134
|
+
* Serializable state produced by `dehydrate` for the same schema.
|
|
135
|
+
*/
|
|
136
|
+
readonly snapshot: HydrationSnapshot<TSchema>;
|
|
137
|
+
};
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/adapters/next/hydration.d.ts
|
|
140
|
+
/**
|
|
141
|
+
* Reads serializable snapshots from hydratable entities declared in a schema.
|
|
142
|
+
*
|
|
143
|
+
* Use this on the server side before crossing into a Client Component. Only the
|
|
144
|
+
* returned snapshot should cross the boundary, not the container or service
|
|
145
|
+
* instances themselves.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* const hydration = { user: USER_STATE };
|
|
150
|
+
* const snapshot = dehydrate({
|
|
151
|
+
* container: getRequestContainer(),
|
|
152
|
+
* schema: hydration,
|
|
153
|
+
* });
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
declare const dehydrate: <const TSchema extends HydrationSchema>(options: DehydrateOptions<TSchema>) => HydrationSnapshot<TSchema>;
|
|
157
|
+
/**
|
|
158
|
+
* Restores serializable snapshots into hydratable entities declared in a schema.
|
|
159
|
+
*
|
|
160
|
+
* Use this with a client-safe container and the snapshot received through a
|
|
161
|
+
* Client Component prop.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* hydrate({
|
|
166
|
+
* container: clientContainer,
|
|
167
|
+
* schema: hydration,
|
|
168
|
+
* snapshot,
|
|
169
|
+
* });
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
declare const hydrate: <const TSchema extends HydrationSchema>(options: HydrateOptions<TSchema>) => void;
|
|
173
|
+
//#endregion
|
|
174
|
+
export { Hydratable as a, HydrationSnapshot as c, RunWithRequestContainerOptions as d, Serializable as f, DehydrateOptions as i, NextDiAdapter as l, hydrate as n, HydrateOptions as o, SerializablePrimitive as p, CreateNextDiOptions as r, HydrationSchema as s, dehydrate as t, RequestCache as u };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=e=>{let t={};for(let n of Object.keys(e.schema)){let r=e.schema[n],i=r===void 0,a=String(n);if(i)throw Error(`Missing hydration token for key "${a}".`);t[a]=e.container.get(r).dehydrate()}return t},t=e=>{let t=e.snapshot;for(let n of Object.keys(e.schema)){let r=e.schema[n],i=String(n),a=t[i],o=r===void 0,s=a===void 0;if(o)throw Error(`Missing hydration token for key "${i}".`);if(s)throw Error(`Missing hydration snapshot for key "${i}".`);e.container.get(r).hydrate(a)}};export{t as n,e as t};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { a as DisposeHook, c as OptionalDependency, d as Token, f as Scope, i as DepsMap, l as Provider, n as RegisterOptions, o as Factory, p as Scopes, r as Dependency, s as FactoryProvider, t as Container, u as ValueProvider } from "./types-BzLfq9VA.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/error/error.d.ts
|
|
2
4
|
/**
|
|
3
5
|
* Base class for all di-craft runtime errors.
|
|
4
6
|
*/
|
|
@@ -6,7 +8,7 @@ declare class DiError extends Error {
|
|
|
6
8
|
constructor(message: string);
|
|
7
9
|
}
|
|
8
10
|
//#endregion
|
|
9
|
-
//#region src/provider/errors.d.ts
|
|
11
|
+
//#region src/core/provider/errors.d.ts
|
|
10
12
|
/**
|
|
11
13
|
* Error thrown when a provider configuration cannot be used safely.
|
|
12
14
|
*/
|
|
@@ -14,41 +16,7 @@ declare class InvalidProviderError extends DiError {
|
|
|
14
16
|
constructor(message: string);
|
|
15
17
|
}
|
|
16
18
|
//#endregion
|
|
17
|
-
//#region src/
|
|
18
|
-
/**
|
|
19
|
-
* Built-in provider lifetimes.
|
|
20
|
-
*/
|
|
21
|
-
declare const Scopes: {
|
|
22
|
-
readonly Singleton: "singleton";
|
|
23
|
-
readonly Transient: "transient";
|
|
24
|
-
readonly Scoped: "scoped";
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Provider lifetime.
|
|
28
|
-
*
|
|
29
|
-
* - `singleton`: one cached instance in the container that owns the provider.
|
|
30
|
-
* - `scoped`: one cached instance in the container that resolves the provider.
|
|
31
|
-
* - `transient`: a new instance for every resolution.
|
|
32
|
-
*/
|
|
33
|
-
type Scope = (typeof Scopes)[keyof typeof Scopes];
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/token/types.d.ts
|
|
36
|
-
/** A unique, typed key used to register and resolve a dependency. */
|
|
37
|
-
type Token<T> = {
|
|
38
|
-
/**
|
|
39
|
-
* Runtime identity of the token.
|
|
40
|
-
*
|
|
41
|
-
* Tokens with the same name still have different identities.
|
|
42
|
-
*/
|
|
43
|
-
readonly id: symbol;
|
|
44
|
-
/**
|
|
45
|
-
* Human-readable name used in error messages and diagnostics.
|
|
46
|
-
*/
|
|
47
|
-
readonly name: string;
|
|
48
|
-
readonly __type?: T;
|
|
49
|
-
};
|
|
50
|
-
//#endregion
|
|
51
|
-
//#region src/token/token.d.ts
|
|
19
|
+
//#region src/core/token/token.d.ts
|
|
52
20
|
/**
|
|
53
21
|
* Creates a unique typed token.
|
|
54
22
|
*
|
|
@@ -62,59 +30,7 @@ type Token<T> = {
|
|
|
62
30
|
*/
|
|
63
31
|
declare const createToken: <T>(name: string) => Token<T>;
|
|
64
32
|
//#endregion
|
|
65
|
-
//#region src/provider/
|
|
66
|
-
/**
|
|
67
|
-
* A token wrapped as an optional dependency.
|
|
68
|
-
*
|
|
69
|
-
* Optional dependencies resolve to `undefined` when no provider is registered
|
|
70
|
-
* in the container chain.
|
|
71
|
-
*/
|
|
72
|
-
type OptionalDependency<T> = {
|
|
73
|
-
readonly token: Token<T>;
|
|
74
|
-
readonly optional: true;
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* A dependency accepted by factory providers and `container.get`.
|
|
78
|
-
*/
|
|
79
|
-
type Dependency<T> = Token<T> | OptionalDependency<T>;
|
|
80
|
-
type DepsMap = Record<string, Dependency<unknown>>;
|
|
81
|
-
type DependencyValue$1<TDep> = TDep extends OptionalDependency<infer T> ? T | undefined : TDep extends Token<infer T> ? T : never;
|
|
82
|
-
type ResolveDeps<TDeps extends DepsMap> = { readonly [TKey in keyof TDeps]: DependencyValue$1<TDeps[TKey]> };
|
|
83
|
-
type Factory<T, TDeps extends DepsMap> = (deps: ResolveDeps<TDeps>) => T;
|
|
84
|
-
/**
|
|
85
|
-
* Cleanup hook called for a cached instance during container disposal.
|
|
86
|
-
*
|
|
87
|
-
* Transient providers cannot use disposal hooks because their instances are not
|
|
88
|
-
* cached or tracked by the container.
|
|
89
|
-
*/
|
|
90
|
-
type DisposeHook<T> = (instance: T) => void | Promise<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Provider that resolves a token to an existing value.
|
|
93
|
-
*/
|
|
94
|
-
type ValueProvider<T> = {
|
|
95
|
-
readonly provide: Token<T>;
|
|
96
|
-
readonly useValue: T;
|
|
97
|
-
};
|
|
98
|
-
/**
|
|
99
|
-
* Provider that lazily creates a token value from typed dependencies.
|
|
100
|
-
*
|
|
101
|
-
* `deps` keys become the properties passed to `useFactory`, `scope` controls
|
|
102
|
-
* caching lifetime, and `onDispose` runs for cached singleton/scoped instances.
|
|
103
|
-
*/
|
|
104
|
-
type FactoryProvider<T, TDeps extends DepsMap = Record<never, never>> = {
|
|
105
|
-
readonly provide: Token<T>;
|
|
106
|
-
readonly deps?: TDeps;
|
|
107
|
-
readonly scope?: Scope;
|
|
108
|
-
readonly useFactory: Factory<T, TDeps>;
|
|
109
|
-
readonly onDispose?: DisposeHook<T>;
|
|
110
|
-
};
|
|
111
|
-
type AnyFactoryProvider = FactoryProvider<any, any>;
|
|
112
|
-
/**
|
|
113
|
-
* Provider accepted by `createContainer` and `container.register`.
|
|
114
|
-
*/
|
|
115
|
-
type Provider = ValueProvider<unknown> | AnyFactoryProvider;
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region src/provider/provider.d.ts
|
|
33
|
+
//#region src/core/provider/provider.d.ts
|
|
118
34
|
/**
|
|
119
35
|
* Creates a provider for an already constructed value.
|
|
120
36
|
*
|
|
@@ -160,7 +76,30 @@ declare const provideFactory: <T, TDeps extends DepsMap = Record<never, never>>(
|
|
|
160
76
|
*/
|
|
161
77
|
declare const optional: <T>(token: Token<T>) => OptionalDependency<T>;
|
|
162
78
|
//#endregion
|
|
163
|
-
//#region src/
|
|
79
|
+
//#region src/core/registry/errors.d.ts
|
|
80
|
+
/**
|
|
81
|
+
* Error thrown when registering a provider for an already registered token.
|
|
82
|
+
*/
|
|
83
|
+
declare class DuplicateProviderError extends DiError {
|
|
84
|
+
constructor(tokenName: string);
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/core/container/container.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* Creates a root container with optional initial providers.
|
|
90
|
+
*
|
|
91
|
+
* Root containers own singleton instances for providers registered in them.
|
|
92
|
+
*/
|
|
93
|
+
declare const createContainer: (providers?: readonly Provider[]) => Container;
|
|
94
|
+
/**
|
|
95
|
+
* Creates a child container that can resolve providers from its parent.
|
|
96
|
+
*
|
|
97
|
+
* Child containers may register their own providers while still reusing parent
|
|
98
|
+
* providers. Scoped providers create one cached instance per resolving child.
|
|
99
|
+
*/
|
|
100
|
+
declare const createChildContainer: (parent: Container, providers?: readonly Provider[]) => Container;
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/core/annotation/types.d.ts
|
|
164
103
|
type InjectableDeps = readonly Dependency<unknown>[];
|
|
165
104
|
type DependencyValue<TDependency> = TDependency extends OptionalDependency<infer T> ? T | undefined : TDependency extends Token<infer T> ? T : never;
|
|
166
105
|
type ResolveDependencyTuple<TDeps extends InjectableDeps> = { -readonly [TKey in keyof TDeps]: DependencyValue<TDeps[TKey]> };
|
|
@@ -203,7 +142,7 @@ type InjectableOptions<T, TDeps extends InjectableDeps = InjectableDeps> = {
|
|
|
203
142
|
readonly onDispose?: DisposeHook<T>;
|
|
204
143
|
};
|
|
205
144
|
//#endregion
|
|
206
|
-
//#region src/annotation/annotation.d.ts
|
|
145
|
+
//#region src/core/annotation/annotation.d.ts
|
|
207
146
|
type InjectableDecorator<TTarget> = (target: TTarget, context: ClassDecoratorContext) => void;
|
|
208
147
|
type InjectableOptionsWithoutDeps<T> = Omit<InjectableOptions<T, readonly []>, "deps">;
|
|
209
148
|
declare function Injectable<T, const TDeps extends readonly Dependency<unknown>[]>(options: InjectableOptions<T, TDeps> & {
|
|
@@ -219,83 +158,7 @@ declare function Injectable<T>(options: InjectableOptionsWithoutDeps<T>): Inject
|
|
|
219
158
|
*/
|
|
220
159
|
declare function provideInjectable<T>(target: InjectableClass<T>): FactoryProvider<T, DepsMap>;
|
|
221
160
|
//#endregion
|
|
222
|
-
//#region src/
|
|
223
|
-
/**
|
|
224
|
-
* Error thrown when registering a provider for an already registered token.
|
|
225
|
-
*/
|
|
226
|
-
declare class DuplicateProviderError extends DiError {
|
|
227
|
-
constructor(tokenName: string);
|
|
228
|
-
}
|
|
229
|
-
//#endregion
|
|
230
|
-
//#region src/registry/types.d.ts
|
|
231
|
-
/**
|
|
232
|
-
* Options for provider registration.
|
|
233
|
-
*/
|
|
234
|
-
type RegisterOptions = {
|
|
235
|
-
/**
|
|
236
|
-
* Replace an existing provider for the same token.
|
|
237
|
-
*
|
|
238
|
-
* Overriding an already resolved disposable singleton is rejected to avoid
|
|
239
|
-
* dropping resources without running their cleanup hook.
|
|
240
|
-
*/
|
|
241
|
-
readonly allowOverride?: boolean;
|
|
242
|
-
};
|
|
243
|
-
//#endregion
|
|
244
|
-
//#region src/container/types.d.ts
|
|
245
|
-
/**
|
|
246
|
-
* Container that stores providers and resolves typed dependencies.
|
|
247
|
-
*/
|
|
248
|
-
type Container = {
|
|
249
|
-
/**
|
|
250
|
-
* Registers a provider in this container.
|
|
251
|
-
*
|
|
252
|
-
* Pass `{ allowOverride: true }` to intentionally replace an existing
|
|
253
|
-
* provider for the same token.
|
|
254
|
-
*/
|
|
255
|
-
register(provider: Provider, options?: RegisterOptions): void;
|
|
256
|
-
/**
|
|
257
|
-
* Resolves a required token.
|
|
258
|
-
*
|
|
259
|
-
* Throws `MissingProviderError` when no provider exists in this container or
|
|
260
|
-
* any parent container.
|
|
261
|
-
*/
|
|
262
|
-
get<T>(token: Token<T>): T;
|
|
263
|
-
/**
|
|
264
|
-
* Resolves an optional dependency.
|
|
265
|
-
*
|
|
266
|
-
* Returns `undefined` when no provider exists in this container or any parent
|
|
267
|
-
* container.
|
|
268
|
-
*/
|
|
269
|
-
get<T>(dependency: OptionalDependency<T>): T | undefined;
|
|
270
|
-
/**
|
|
271
|
-
* Checks whether this container or one of its parents has a provider.
|
|
272
|
-
*/
|
|
273
|
-
has(token: Token<unknown>): boolean;
|
|
274
|
-
/**
|
|
275
|
-
* Disposes cached instances owned by this container.
|
|
276
|
-
*
|
|
277
|
-
* Disposal hooks run in reverse creation order. Calling `dispose` more than
|
|
278
|
-
* once is safe.
|
|
279
|
-
*/
|
|
280
|
-
dispose(): Promise<void>;
|
|
281
|
-
};
|
|
282
|
-
//#endregion
|
|
283
|
-
//#region src/container/container.d.ts
|
|
284
|
-
/**
|
|
285
|
-
* Creates a root container with optional initial providers.
|
|
286
|
-
*
|
|
287
|
-
* Root containers own singleton instances for providers registered in them.
|
|
288
|
-
*/
|
|
289
|
-
declare const createContainer: (providers?: readonly Provider[]) => Container;
|
|
290
|
-
/**
|
|
291
|
-
* Creates a child container that can resolve providers from its parent.
|
|
292
|
-
*
|
|
293
|
-
* Child containers may register their own providers while still reusing parent
|
|
294
|
-
* providers. Scoped providers create one cached instance per resolving child.
|
|
295
|
-
*/
|
|
296
|
-
declare const createChildContainer: (parent: Container, providers?: readonly Provider[]) => Container;
|
|
297
|
-
//#endregion
|
|
298
|
-
//#region src/resolver/errors.d.ts
|
|
161
|
+
//#region src/core/resolver/errors.d.ts
|
|
299
162
|
/**
|
|
300
163
|
* Error thrown when resolving a token without a registered provider.
|
|
301
164
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./container-C6GcrdNn.mjs";const f=e=>{if(e.length!==0)return Object.fromEntries(e.entries())},p=new WeakMap,m=e=>p.get(e),h=e=>{p.set(e.target,e.metadata)},g=e=>{let{context:t,target:r}=e;if(!(t.kind===`class`&&typeof r==`function`))throw new n(`@Injectable can only decorate classes`)};function _(e){return(t,n)=>{g({target:t,context:n}),h({target:t,metadata:e})}}function v(e){let r=m(e);if(!r)throw new n(`Class "${e.name||`<anonymous>`}" is not marked as injectable. Add @Injectable({ token: TOKEN }) before calling provideInjectable().`);let{deps:i=[],onDispose:a,scope:o,token:s}=r,c=f(i),l=e;return t(s,{useFactory:e=>new l(...i.map((t,n)=>e[String(n)])),...c?{deps:c}:{},...o?{scope:o}:{},...a?{onDispose:a}:{}})}var y=class{name;id;constructor(e){this.name=e,this.id=Symbol(e)}};const b=e=>new y(e);export{c as CircularDependencyError,r as DiError,s as DuplicateProviderError,_ as Injectable,i as InvalidDependencyError,n as InvalidProviderError,e as MissingProviderError,d as Scopes,u as createChildContainer,o as createContainer,b as createToken,l as optional,t as provideFactory,v as provideInjectable,a as provideValue};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as Hydratable, c as HydrationSnapshot, f as Serializable, n as hydrate, o as HydrateOptions, p as SerializablePrimitive, s as HydrationSchema } from "../hydration-BJ-gWd38.mjs";
|
|
2
|
+
export { type Hydratable, type HydrateOptions, type HydrationSchema, type HydrationSnapshot, type Serializable, type SerializablePrimitive, hydrate };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"../hydration-DsCFyhuJ.mjs";export{e as hydrate};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { a as Hydratable, c as HydrationSnapshot, d as RunWithRequestContainerOptions, f as Serializable, i as DehydrateOptions, l as NextDiAdapter, p as SerializablePrimitive, r as CreateNextDiOptions, s as HydrationSchema, t as dehydrate, u as RequestCache } from "../hydration-BJ-gWd38.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/next/server.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Creates a server adapter for Next.js App Router and React Server Components.
|
|
6
|
+
*
|
|
7
|
+
* The root container is created once. `getRequestContainer` creates a child
|
|
8
|
+
* container through the provided React request cache, so repeated calls inside
|
|
9
|
+
* one RSC request resolve through the same scoped dependency graph.
|
|
10
|
+
*
|
|
11
|
+
* Import this helper from a server-only composition file. The adapter does not
|
|
12
|
+
* import React itself; pass `cache` from `react` so React/Next owns request
|
|
13
|
+
* memoization.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import "server-only";
|
|
18
|
+
* import { cache } from "react";
|
|
19
|
+
* import { createNextDi } from "di-craft/next/server";
|
|
20
|
+
*
|
|
21
|
+
* export const { getRequestContainer } = createNextDi({
|
|
22
|
+
* cache,
|
|
23
|
+
* providers,
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
declare const createNextDi: ({
|
|
28
|
+
cache,
|
|
29
|
+
providers,
|
|
30
|
+
requestProviders
|
|
31
|
+
}: CreateNextDiOptions) => NextDiAdapter;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { type CreateNextDiOptions, type DehydrateOptions, type Hydratable, type HydrationSchema, type HydrationSnapshot, type NextDiAdapter, type RequestCache, type RunWithRequestContainerOptions, type Serializable, type SerializablePrimitive, createNextDi, dehydrate };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,t}from"../container-C6GcrdNn.mjs";import{t as n}from"../hydration-DsCFyhuJ.mjs";const r=()=>{if(`window`in globalThis)throw Error(`di-craft/next/server can only be used in a server runtime.`)},i=({cache:n,providers:i=[],requestProviders:a})=>{r();let o=e(i),s=(e=[])=>t(o,[...a?.()??[],...e]);return{getRootContainer:()=>o,getRequestContainer:n(()=>s()),createRequestContainer:s,runWithRequestContainer:async({providers:e=[],run:t})=>{let n=s(e);try{return await t(n)}finally{await n.dispose()}},disposeRootContainer:()=>o.dispose()}};export{i as createNextDi,n as dehydrate};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region src/core/scope/scope.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Built-in provider lifetimes.
|
|
4
|
+
*/
|
|
5
|
+
declare const Scopes: {
|
|
6
|
+
readonly Singleton: "singleton";
|
|
7
|
+
readonly Transient: "transient";
|
|
8
|
+
readonly Scoped: "scoped";
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Provider lifetime.
|
|
12
|
+
*
|
|
13
|
+
* - `singleton`: one cached instance in the container that owns the provider.
|
|
14
|
+
* - `scoped`: one cached instance in the container that resolves the provider.
|
|
15
|
+
* - `transient`: a new instance for every resolution.
|
|
16
|
+
*/
|
|
17
|
+
type Scope = (typeof Scopes)[keyof typeof Scopes];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/core/token/types.d.ts
|
|
20
|
+
/** A unique, typed key used to register and resolve a dependency. */
|
|
21
|
+
type Token<T> = {
|
|
22
|
+
/**
|
|
23
|
+
* Runtime identity of the token.
|
|
24
|
+
*
|
|
25
|
+
* Tokens with the same name still have different identities.
|
|
26
|
+
*/
|
|
27
|
+
readonly id: symbol;
|
|
28
|
+
/**
|
|
29
|
+
* Human-readable name used in error messages and diagnostics.
|
|
30
|
+
*/
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly __type?: T;
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/core/provider/types.d.ts
|
|
36
|
+
/**
|
|
37
|
+
* A token wrapped as an optional dependency.
|
|
38
|
+
*
|
|
39
|
+
* Optional dependencies resolve to `undefined` when no provider is registered
|
|
40
|
+
* in the container chain.
|
|
41
|
+
*/
|
|
42
|
+
type OptionalDependency<T> = {
|
|
43
|
+
readonly token: Token<T>;
|
|
44
|
+
readonly optional: true;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A dependency accepted by factory providers and `container.get`.
|
|
48
|
+
*/
|
|
49
|
+
type Dependency<T> = Token<T> | OptionalDependency<T>;
|
|
50
|
+
type DepsMap = Record<string, Dependency<unknown>>;
|
|
51
|
+
type DependencyValue<TDep> = TDep extends OptionalDependency<infer T> ? T | undefined : TDep extends Token<infer T> ? T : never;
|
|
52
|
+
type ResolveDeps<TDeps extends DepsMap> = { readonly [TKey in keyof TDeps]: DependencyValue<TDeps[TKey]> };
|
|
53
|
+
type Factory<T, TDeps extends DepsMap> = (deps: ResolveDeps<TDeps>) => T;
|
|
54
|
+
/**
|
|
55
|
+
* Cleanup hook called for a cached instance during container disposal.
|
|
56
|
+
*
|
|
57
|
+
* Transient providers cannot use disposal hooks because their instances are not
|
|
58
|
+
* cached or tracked by the container.
|
|
59
|
+
*/
|
|
60
|
+
type DisposeHook<T> = (instance: T) => void | Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Provider that resolves a token to an existing value.
|
|
63
|
+
*/
|
|
64
|
+
type ValueProvider<T> = {
|
|
65
|
+
readonly provide: Token<T>;
|
|
66
|
+
readonly useValue: T;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Provider that lazily creates a token value from typed dependencies.
|
|
70
|
+
*
|
|
71
|
+
* `deps` keys become the properties passed to `useFactory`, `scope` controls
|
|
72
|
+
* caching lifetime, and `onDispose` runs for cached singleton/scoped instances.
|
|
73
|
+
*/
|
|
74
|
+
type FactoryProvider<T, TDeps extends DepsMap = Record<never, never>> = {
|
|
75
|
+
readonly provide: Token<T>;
|
|
76
|
+
readonly deps?: TDeps;
|
|
77
|
+
readonly scope?: Scope;
|
|
78
|
+
readonly useFactory: Factory<T, TDeps>;
|
|
79
|
+
readonly onDispose?: DisposeHook<T>;
|
|
80
|
+
};
|
|
81
|
+
type AnyFactoryProvider = FactoryProvider<any, any>;
|
|
82
|
+
/**
|
|
83
|
+
* Provider accepted by `createContainer` and `container.register`.
|
|
84
|
+
*/
|
|
85
|
+
type Provider = ValueProvider<unknown> | AnyFactoryProvider;
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/core/registry/types.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* Options for provider registration.
|
|
90
|
+
*/
|
|
91
|
+
type RegisterOptions = {
|
|
92
|
+
/**
|
|
93
|
+
* Replace an existing provider for the same token.
|
|
94
|
+
*
|
|
95
|
+
* Overriding an already resolved disposable singleton is rejected to avoid
|
|
96
|
+
* dropping resources without running their cleanup hook.
|
|
97
|
+
*/
|
|
98
|
+
readonly allowOverride?: boolean;
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/core/container/types.d.ts
|
|
102
|
+
/**
|
|
103
|
+
* Container that stores providers and resolves typed dependencies.
|
|
104
|
+
*/
|
|
105
|
+
type Container = {
|
|
106
|
+
/**
|
|
107
|
+
* Registers a provider in this container.
|
|
108
|
+
*
|
|
109
|
+
* Pass `{ allowOverride: true }` to intentionally replace an existing
|
|
110
|
+
* provider for the same token.
|
|
111
|
+
*/
|
|
112
|
+
register(provider: Provider, options?: RegisterOptions): void;
|
|
113
|
+
/**
|
|
114
|
+
* Resolves a required token.
|
|
115
|
+
*
|
|
116
|
+
* Throws `MissingProviderError` when no provider exists in this container or
|
|
117
|
+
* any parent container.
|
|
118
|
+
*/
|
|
119
|
+
get<T>(token: Token<T>): T;
|
|
120
|
+
/**
|
|
121
|
+
* Resolves an optional dependency.
|
|
122
|
+
*
|
|
123
|
+
* Returns `undefined` when no provider exists in this container or any parent
|
|
124
|
+
* container.
|
|
125
|
+
*/
|
|
126
|
+
get<T>(dependency: OptionalDependency<T>): T | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* Checks whether this container or one of its parents has a provider.
|
|
129
|
+
*/
|
|
130
|
+
has(token: Token<unknown>): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Disposes cached instances owned by this container.
|
|
133
|
+
*
|
|
134
|
+
* Disposal hooks run in reverse creation order. Calling `dispose` more than
|
|
135
|
+
* once is safe.
|
|
136
|
+
*/
|
|
137
|
+
dispose(): Promise<void>;
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
export { DisposeHook as a, OptionalDependency as c, Token as d, Scope as f, DepsMap as i, Provider as l, RegisterOptions as n, Factory as o, Scopes as p, Dependency as r, FactoryProvider as s, Container as t, ValueProvider as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "di-craft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "A tiny, type-safe dependency injection container for TypeScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
"types": "./dist/index.d.mts",
|
|
21
21
|
"default": "./dist/index.mjs"
|
|
22
22
|
},
|
|
23
|
+
"./next/client": {
|
|
24
|
+
"types": "./dist/next/client.d.mts",
|
|
25
|
+
"default": "./dist/next/client.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./next/server": {
|
|
28
|
+
"types": "./dist/next/server.d.mts",
|
|
29
|
+
"default": "./dist/next/server.mjs"
|
|
30
|
+
},
|
|
23
31
|
"./package.json": "./package.json"
|
|
24
32
|
},
|
|
25
33
|
"files": [
|