bazis 0.97.3 → 0.97.4
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.
|
@@ -112,6 +112,23 @@ export class ServiceProvider implements ServiceResolver {
|
|
|
112
112
|
return this.resolveSingleAsync(token, key, this.lifetime.root, []);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Creates every singleton registered with an async factory (keyed ones
|
|
117
|
+
* included), in registration order. Afterwards `resolve` and constructor
|
|
118
|
+
* injection return the cached instances. The kernel calls it at startup, so a
|
|
119
|
+
* failing factory stops the start instead of failing every request.
|
|
120
|
+
*/
|
|
121
|
+
public async initializeAsyncSingletons(): Promise<void> {
|
|
122
|
+
this.lifetime.assertLive(this.lifetime.root);
|
|
123
|
+
for (const group of this.registry.groups()) {
|
|
124
|
+
for (const registration of group) {
|
|
125
|
+
if (registration.lifetime === "singleton" && isAsyncFactoryProvider(registration.provider)) {
|
|
126
|
+
await this.resolveRegistrationAsync(registration, registration.key, this.lifetime.root, [], undefined);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
115
132
|
public tryResolve<T>(token: Token<T>, key?: ServiceKey): T | undefined {
|
|
116
133
|
return this.tryResolveForScope(token, key, this.lifetime.root);
|
|
117
134
|
}
|
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient implements CodexClient {
|
|
|
232
232
|
if (method === "account/updated") this.modelCache = undefined;
|
|
233
233
|
}, () => { this.clearLogin(); this.modelCache = undefined; });
|
|
234
234
|
const initialized = await client.request("initialize", {
|
|
235
|
-
clientInfo: { name: "bazis", title: "Bazis", version: "0.97.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.97.4" }, capabilities: { experimentalApi: true },
|
|
236
236
|
}, 15_000, signal);
|
|
237
237
|
if (resolve(text(initialized.codexHome, 4096)) !== this.paths.home) throw new CodexError("PROTOCOL_ERROR");
|
|
238
238
|
client.notify("initialized");
|
package/core/kernel/Kernel.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { UnhandledErrorPolicy } from "./types";
|
|
|
13
13
|
import { redactSensitive } from "../../library/redaction";
|
|
14
14
|
import { validateTimeout } from "./internal/validateTimeout";
|
|
15
15
|
import { awaitShutdown } from "./internal/awaitShutdown";
|
|
16
|
+
import { awaitAbortable } from "./internal/awaitAbortable";
|
|
16
17
|
import { reportDiagnosticFailure } from "./internal/reportDiagnosticFailure";
|
|
17
18
|
|
|
18
19
|
export interface KernelTimings {
|
|
@@ -97,6 +98,9 @@ export class Kernel {
|
|
|
97
98
|
);
|
|
98
99
|
}
|
|
99
100
|
try {
|
|
101
|
+
// Async singletons first: hosted services and controllers take them
|
|
102
|
+
// through constructors, which resolve synchronously.
|
|
103
|
+
await awaitAbortable(this.container.initializeAsyncSingletons(), abortController.signal);
|
|
100
104
|
await this.coordinator.start(abortController.signal, this.options.shutdownTimeoutMs);
|
|
101
105
|
coordinatorStarted = true;
|
|
102
106
|
this.startupMs = performance.now() - this.timings.buildStartedAt;
|
|
@@ -156,6 +156,8 @@ interface CollectedDependency { readonly name: string; readonly target?: ts.Clas
|
|
|
156
156
|
interface ConstructorDependencies {
|
|
157
157
|
readonly deps: CollectedDependency[];
|
|
158
158
|
readonly unsupportedInheritedParameter?: string;
|
|
159
|
+
/** An own constructor parameter whose type cannot name a DI dependency (`string`, `number`, an inline type). */
|
|
160
|
+
readonly unsupportedParameter?: { readonly index: number; readonly name: string; readonly type: string };
|
|
159
161
|
}
|
|
160
162
|
let classDeps = new Map<ts.ClassDeclaration, readonly CollectedDependency[]>();
|
|
161
163
|
let inferredDiClasses = new Set<ts.ClassDeclaration>();
|
|
@@ -796,6 +798,10 @@ function collectClassDeps(source: ts.SourceFile): void {
|
|
|
796
798
|
const visit = (node: ts.Node): void => {
|
|
797
799
|
if (ts.isClassDeclaration(node) && node.name) {
|
|
798
800
|
const result = readConstructorTypeNames(node);
|
|
801
|
+
if (result.unsupportedParameter !== undefined && needsInferredDiDeps(node)) {
|
|
802
|
+
const { index, name, type } = result.unsupportedParameter;
|
|
803
|
+
fatalErrors.push(`BAZIS_DI_DEPENDENCY_UNKNOWN: ${sourceLocation(node)}: constructor parameter ${index + 1} "${name}" of "${node.name.text}" has type "${type}", which cannot be injected: DI resolves dependencies by class, contract or token, and a plain type does not say which value to inject. Declare a token with the same name as a type alias (export type Prefix = string; export const Prefix = createToken<Prefix>("Prefix")) and register a value, or pass the deps explicitly: scoped(${node.name.text}, ${node.name.text}, [TOKEN] as const).`);
|
|
804
|
+
}
|
|
799
805
|
if (result.unsupportedInheritedParameter !== undefined && needsInferredDiDeps(node)) {
|
|
800
806
|
fatalErrors.push(`BAZIS_DI_CONSTRUCTOR_UNRESOLVED: ${sourceLocation(node)}: cannot infer inherited constructor parameter "${result.unsupportedInheritedParameter}" for "${node.name.text}". The parameter needs a runtime DI token or an explicit value/factory binding.`);
|
|
801
807
|
}
|
|
@@ -984,7 +990,7 @@ function readConstructorTypeNames(node: ts.ClassDeclaration): ConstructorDepende
|
|
|
984
990
|
const paramType = param.type;
|
|
985
991
|
const refName = paramType ? getDependencyTypeName(paramType) : undefined;
|
|
986
992
|
if (!refName || BUILTIN_DEPENDENCY_NAMES.has(refName)) {
|
|
987
|
-
return { deps: [] };
|
|
993
|
+
return { deps: [], unsupportedParameter: { index, name: param.name.getText(), type: paramType?.getText() ?? "(no type)" } };
|
|
988
994
|
}
|
|
989
995
|
|
|
990
996
|
// `Lazy<X>` is a deferred dependency on X: encode it with a marker prefix
|
package/package.json
CHANGED