Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@strav/kernel

Package Overview
Dependencies
Maintainers
1
Versions
110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@strav/kernel - npm Package Compare versions

Comparing version
1.0.0-alpha.31
to
1.0.0-alpha.33
+1
-1
package.json
{
"name": "@strav/kernel",
"version": "1.0.0-alpha.31",
"version": "1.0.0-alpha.33",
"description": "Strav kernel — IoC container, service providers, lifecycle, config, events, helpers",

@@ -5,0 +5,0 @@ "type": "module",

@@ -26,3 +26,3 @@ /**

import { Application } from '../core/application.ts'
import type { ServiceProvider } from '../core/service_provider.ts'
import type { ServiceProviderEntry } from '../core/service_provider.ts'
import { asStravError } from '../exceptions/as_strav_error.ts'

@@ -43,3 +43,3 @@ import { ConfigError } from '../exceptions/config_error.ts'

/** Providers to register before boot. Ignored when `app` is already booted. */
providers?: readonly ServiceProvider[]
providers?: readonly ServiceProviderEntry[]
/** Commands to register. */

@@ -46,0 +46,0 @@ commands?: readonly CommandClass[]

@@ -16,3 +16,3 @@ /**

import { Container } from './container.ts'
import type { ServiceProvider } from './service_provider.ts'
import { ServiceProvider, type ServiceProviderEntry } from './service_provider.ts'
import type { Constructor } from './types.ts'

@@ -35,2 +35,23 @@

async function resolveProviderEntry(entry: ServiceProviderEntry): Promise<ServiceProvider> {
if (entry instanceof ServiceProvider) return entry
if (typeof entry === 'function') {
// Constructor: a class whose prototype derives from ServiceProvider.
if (entry.prototype instanceof ServiceProvider) {
return new (entry as new () => ServiceProvider)()
}
// Closure: returns (or resolves to) a ServiceProvider instance.
const result = await (entry as () => ServiceProvider | Promise<ServiceProvider>)()
if (!(result instanceof ServiceProvider)) {
throw new Error(
'Application: provider closure must return a ServiceProvider instance.',
)
}
return result
}
throw new Error(
'Application: provider entry must be a ServiceProvider, a constructor, or a closure.',
)
}
export class Application extends Container {

@@ -57,3 +78,3 @@ /**

private _providers: ServiceProvider[] = []
private _providerEntries: ServiceProviderEntry[] = []
private _bootedProviders: ServiceProvider[] = []

@@ -78,10 +99,12 @@ private _booted = false

/** Add one provider. Must be called before `start()`. */
use(provider: ServiceProvider): this {
/**
* Add one provider. Must be called before `start()`. Accepts an instance,
* a zero-arg constructor, or a closure that builds (and optionally awaits)
* the instance.
*/
use(entry: ServiceProviderEntry): this {
if (this._booted) {
throw new Error(
`Application: cannot add provider "${provider.name}" after the application has started.`,
)
throw new Error('Application: cannot add provider after the application has started.')
}
this._providers.push(provider)
this._providerEntries.push(entry)
return this

@@ -91,7 +114,7 @@ }

/** Add several providers at once. Must be called before `start()`. */
useProviders(providers: ServiceProvider[]): this {
useProviders(entries: ServiceProviderEntry[]): this {
if (this._booted) {
throw new Error('Application: cannot add providers after the application has started.')
}
this._providers.push(...providers)
this._providerEntries.push(...entries)
return this

@@ -129,3 +152,7 @@ }

const sorted = this.topologicalSort(this._providers)
const resolved: ServiceProvider[] = []
for (const entry of this._providerEntries) {
resolved.push(await resolveProviderEntry(entry))
}
const sorted = this.topologicalSort(resolved)

@@ -132,0 +159,0 @@ // Phase 1 — synchronous register pass.

@@ -6,3 +6,3 @@ // Core kernel exports: Application, Container, ServiceProvider, inject, types.

export { getParamTypes, INJECTABLE, inject, isInjectable } from './inject.ts'
export { ServiceProvider } from './service_provider.ts'
export { ServiceProvider, type ServiceProviderEntry } from './service_provider.ts'
export type {

@@ -9,0 +9,0 @@ Binding,

@@ -33,2 +33,17 @@ /**

/**
* Anything `Application.use(...)` / `useProviders([...])` accepts:
* - a `ServiceProvider` instance (`new HttpProvider()`)
* - a zero-arg constructor (`HttpProvider`)
* - a closure that builds (and optionally awaits) the instance
* (`() => ConfigProvider.fromDirectory('config')`)
*
* Constructors and closures are resolved during `start()`, before the
* topological sort.
*/
export type ServiceProviderEntry =
| ServiceProvider
| (new () => ServiceProvider)
| (() => ServiceProvider | Promise<ServiceProvider>)
export abstract class ServiceProvider {

@@ -35,0 +50,0 @@ /** Unique name used for dependency resolution between providers. */