@ontrails/core 1.0.0-beta.11 → 1.0.0-beta.13
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/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +67 -30
- package/README.md +19 -19
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +5 -4
- package/dist/context.js.map +1 -1
- package/dist/derive.d.ts +8 -3
- package/dist/derive.d.ts.map +1 -1
- package/dist/derive.js +7 -7
- package/dist/derive.js.map +1 -1
- package/dist/event.d.ts +4 -41
- package/dist/event.d.ts.map +1 -1
- package/dist/event.js +4 -14
- package/dist/event.js.map +1 -1
- package/dist/execute.d.ts +11 -9
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +34 -151
- package/dist/execute.js.map +1 -1
- package/dist/gate.d.ts +17 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +21 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +5 -16
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +3 -20
- package/dist/layer.js.map +1 -1
- package/dist/provision-config.d.ts +22 -0
- package/dist/provision-config.d.ts.map +1 -0
- package/dist/provision-config.js +210 -0
- package/dist/provision-config.js.map +1 -0
- package/dist/provision.d.ts +71 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +56 -0
- package/dist/provision.js.map +1 -0
- package/dist/run.d.ts +27 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +34 -0
- package/dist/run.js.map +1 -0
- package/dist/service-config.d.ts +22 -0
- package/dist/service-config.d.ts.map +1 -0
- package/dist/service-config.js +210 -0
- package/dist/service-config.js.map +1 -0
- package/dist/service.d.ts +39 -37
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +21 -21
- package/dist/service.js.map +1 -1
- package/dist/signal.d.ts +33 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +17 -0
- package/dist/signal.js.map +1 -0
- package/dist/topo.d.ts +10 -10
- package/dist/topo.d.ts.map +1 -1
- package/dist/topo.js +48 -35
- package/dist/topo.js.map +1 -1
- package/dist/trail.d.ts +19 -17
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +5 -4
- package/dist/trail.js.map +1 -1
- package/dist/types.d.ts +26 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/validate-topo.d.ts +2 -2
- package/dist/validate-topo.js +31 -31
- package/dist/validate-topo.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/context.test.ts +8 -8
- package/src/__tests__/execute.test.ts +124 -122
- package/src/__tests__/{layer.test.ts → gate.test.ts} +26 -26
- package/src/__tests__/{dispatch.test.ts → run.test.ts} +39 -39
- package/src/__tests__/service-config.test.ts +228 -0
- package/src/__tests__/service.test.ts +71 -71
- package/src/__tests__/{event.test.ts → signal.test.ts} +15 -15
- package/src/__tests__/topo.test.ts +54 -54
- package/src/__tests__/trail-permit.test.ts +60 -0
- package/src/__tests__/trail.test.ts +58 -58
- package/src/__tests__/type-utils.test.ts +3 -3
- package/src/__tests__/validate-topo.test.ts +38 -38
- package/src/context.ts +5 -4
- package/src/derive.ts +8 -8
- package/src/event.ts +11 -73
- package/src/execute.ts +59 -238
- package/src/{layer.ts → gate.ts} +13 -13
- package/src/index.ts +26 -21
- package/src/provision-config.ts +373 -0
- package/src/provision.ts +148 -0
- package/src/{dispatch.ts → run.ts} +8 -8
- package/src/signal.ts +65 -0
- package/src/topo.ts +74 -52
- package/src/trail.ts +30 -23
- package/src/types.ts +30 -10
- package/src/validate-topo.ts +33 -33
- package/tsconfig.tsbuildinfo +1 -1
- package/src/service.ts +0 -139
package/src/service.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { NotFoundError } from './errors.js';
|
|
2
|
-
import type { Result } from './result.js';
|
|
3
|
-
import type { ServiceLookup, TrailContext } from './types.js';
|
|
4
|
-
import type { z } from 'zod';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Stable process-scoped fields available when constructing a service.
|
|
8
|
-
*
|
|
9
|
-
* Services are app-level singletons, so they intentionally do not receive the
|
|
10
|
-
* full per-request TrailContext.
|
|
11
|
-
*/
|
|
12
|
-
export type ServiceContext = Pick<
|
|
13
|
-
TrailContext,
|
|
14
|
-
'cwd' | 'env' | 'workspaceRoot'
|
|
15
|
-
>;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Everything needed to describe a service before a factory is introduced.
|
|
19
|
-
*/
|
|
20
|
-
export interface ServiceSpec<T> {
|
|
21
|
-
/** Create the service instance from stable process-scoped context. */
|
|
22
|
-
readonly create: (
|
|
23
|
-
svc: ServiceContext
|
|
24
|
-
) => Result<T, Error> | Promise<Result<T, Error>>;
|
|
25
|
-
/** Reserved config schema for follow-up config composition work. */
|
|
26
|
-
readonly config?: z.ZodType | undefined;
|
|
27
|
-
/** Optional cleanup performed when the hosting surface shuts down. */
|
|
28
|
-
readonly dispose?: ((service: T) => void | Promise<void>) | undefined;
|
|
29
|
-
/** Optional operational readiness probe for introspection tooling. */
|
|
30
|
-
readonly health?:
|
|
31
|
-
| ((service: T) => Result<unknown, Error> | Promise<Result<unknown, Error>>)
|
|
32
|
-
| undefined;
|
|
33
|
-
/** Optional test factory used by higher-level helpers. */
|
|
34
|
-
readonly mock?: (() => T | Promise<T>) | undefined;
|
|
35
|
-
/** Human-readable description. */
|
|
36
|
-
readonly description?: string | undefined;
|
|
37
|
-
/** Arbitrary metadata for tooling and filtering. */
|
|
38
|
-
readonly metadata?: Readonly<Record<string, unknown>> | undefined;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* A typed service definition.
|
|
43
|
-
*
|
|
44
|
-
* TRL-73 introduces the structural contract only. The `service()` factory and
|
|
45
|
-
* runtime helpers land in follow-up branches.
|
|
46
|
-
*/
|
|
47
|
-
export interface Service<T> extends ServiceSpec<T> {
|
|
48
|
-
readonly kind: 'service';
|
|
49
|
-
readonly id: string;
|
|
50
|
-
/** Read the resolved service instance from a trail context. */
|
|
51
|
-
from(ctx: TrailContext): T;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Existential type for heterogeneous service collections.
|
|
56
|
-
*
|
|
57
|
-
* `Service<T>` includes function parameters in `dispose`/`health`, so `unknown`
|
|
58
|
-
* is too narrow for mixed service arrays. `any` is the correct existential here.
|
|
59
|
-
*/
|
|
60
|
-
// oxlint-disable-next-line no-explicit-any -- existential type for heterogeneous service collections
|
|
61
|
-
export type AnyService = Service<any>;
|
|
62
|
-
|
|
63
|
-
/** Explicit runtime overrides keyed by service ID. */
|
|
64
|
-
export type ServiceOverrideMap = Readonly<Record<string, unknown>>;
|
|
65
|
-
|
|
66
|
-
const getServiceId = <T>(
|
|
67
|
-
serviceOrId: string | Pick<Service<T>, 'id'>
|
|
68
|
-
): string => (typeof serviceOrId === 'string' ? serviceOrId : serviceOrId.id);
|
|
69
|
-
|
|
70
|
-
const getServiceInstance = <T>(
|
|
71
|
-
ctx: Pick<TrailContext, 'extensions'>,
|
|
72
|
-
serviceOrId: string | Pick<Service<T>, 'id'>
|
|
73
|
-
): T => {
|
|
74
|
-
const id = getServiceId(serviceOrId);
|
|
75
|
-
return ctx.extensions?.[id] as T;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const hasServiceInstance = (
|
|
79
|
-
ctx: Pick<TrailContext, 'extensions'>,
|
|
80
|
-
serviceOrId: string | Pick<AnyService, 'id'>
|
|
81
|
-
): boolean => Object.hasOwn(ctx.extensions ?? {}, getServiceId(serviceOrId));
|
|
82
|
-
|
|
83
|
-
/** Create a `ctx.service(...)` accessor bound to a concrete context snapshot. */
|
|
84
|
-
export const createServiceLookup = (
|
|
85
|
-
getContext: () => Pick<TrailContext, 'extensions'>
|
|
86
|
-
): ServiceLookup =>
|
|
87
|
-
((serviceOrId: string | Pick<AnyService, 'id'>) => {
|
|
88
|
-
const id = getServiceId(serviceOrId);
|
|
89
|
-
const ctx = getContext();
|
|
90
|
-
if (!hasServiceInstance(ctx, id)) {
|
|
91
|
-
throw new NotFoundError(`Service "${id}" not found in trail context`);
|
|
92
|
-
}
|
|
93
|
-
return getServiceInstance(ctx, id);
|
|
94
|
-
}) as ServiceLookup;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Create a typed service definition.
|
|
98
|
-
*
|
|
99
|
-
* The service object is inert until a later execution branch resolves concrete
|
|
100
|
-
* instances into TrailContext extensions.
|
|
101
|
-
*/
|
|
102
|
-
export const service = <T>(id: string, spec: ServiceSpec<T>): Service<T> =>
|
|
103
|
-
Object.freeze({
|
|
104
|
-
...spec,
|
|
105
|
-
from(ctx: TrailContext): T {
|
|
106
|
-
const lookup = ctx.service ?? createServiceLookup(() => ctx);
|
|
107
|
-
return lookup(this);
|
|
108
|
-
},
|
|
109
|
-
id,
|
|
110
|
-
kind: 'service' as const,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
/** Narrow unknown values to service definitions during topo discovery. */
|
|
114
|
-
export const isService = (value: unknown): value is AnyService => {
|
|
115
|
-
if (typeof value !== 'object' || value === null) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
const v = value as { kind?: unknown; id?: unknown };
|
|
119
|
-
return v.kind === 'service' && typeof v.id === 'string';
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Return the first duplicate service ID in a collection, if any.
|
|
124
|
-
*
|
|
125
|
-
* This supports later topo registration without each caller duplicating the
|
|
126
|
-
* same scan logic.
|
|
127
|
-
*/
|
|
128
|
-
export const findDuplicateServiceId = (
|
|
129
|
-
services: readonly Pick<AnyService, 'id'>[]
|
|
130
|
-
): string | undefined => {
|
|
131
|
-
const seen = new Set<string>();
|
|
132
|
-
for (const candidate of services) {
|
|
133
|
-
if (seen.has(candidate.id)) {
|
|
134
|
-
return candidate.id;
|
|
135
|
-
}
|
|
136
|
-
seen.add(candidate.id);
|
|
137
|
-
}
|
|
138
|
-
return undefined;
|
|
139
|
-
};
|