better-effect 0.9.2 → 0.9.3
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 +81 -2
- package/dist/adapters/iti.d.mts +1 -1
- package/dist/effect-CZdZCZLW.mjs +522 -0
- package/dist/effect-CZdZCZLW.mjs.map +1 -0
- package/dist/hono.d.mts +67 -0
- package/dist/hono.d.mts.map +1 -0
- package/dist/hono.mjs +155 -0
- package/dist/hono.mjs.map +1 -0
- package/dist/{index-BJFBEsm5.d.mts → index-BsPr7qHf.d.mts} +92 -92
- package/dist/index-BsPr7qHf.d.mts.map +1 -0
- package/dist/index-CITM15SE.d.mts +182 -0
- package/dist/index-CITM15SE.d.mts.map +1 -0
- package/dist/{index-CYAgpM_5.d.mts → index-EJlskfAW.d.mts} +4 -2
- package/dist/{index-CYAgpM_5.d.mts.map → index-EJlskfAW.d.mts.map} +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -518
- package/dist/index.mjs.map +1 -1
- package/dist/standard-services-QseopL9g.mjs +340 -0
- package/dist/standard-services-QseopL9g.mjs.map +1 -0
- package/dist/standard-services.d.mts +3 -116
- package/dist/standard-services.mjs +3 -180
- package/package.json +7 -1
- package/dist/index-BJFBEsm5.d.mts.map +0 -1
- package/dist/standard-services.d.mts.map +0 -1
- package/dist/standard-services.mjs.map +0 -1
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { i as Service, r as Layer } from "./signal-Cl9tqGyX.mjs";
|
|
2
|
+
import { Result, TaggedError } from "better-result";
|
|
3
|
+
//#region src/standard-services/config.ts
|
|
4
|
+
/** A schema validation failure. Raw source values are intentionally omitted. */
|
|
5
|
+
var ConfigValidationError = class extends TaggedError("ConfigValidationError") {};
|
|
6
|
+
/** A dotenv or host-source loading failure. Raw source values are intentionally omitted. */
|
|
7
|
+
var ConfigSourceError = class extends TaggedError("ConfigSourceError") {};
|
|
8
|
+
const runtimeGlobal = globalThis;
|
|
9
|
+
const hostEnvironment = () => {
|
|
10
|
+
const processEnvironment = runtimeGlobal.process?.env;
|
|
11
|
+
if (processEnvironment !== void 0) return processEnvironment;
|
|
12
|
+
return runtimeGlobal.Bun?.env ?? {};
|
|
13
|
+
};
|
|
14
|
+
const readText = async (path) => {
|
|
15
|
+
const file = runtimeGlobal.Bun?.file;
|
|
16
|
+
if (file !== void 0) return await file(path).text();
|
|
17
|
+
const { readFile } = await import("node:fs/promises");
|
|
18
|
+
return await readFile(path, "utf8");
|
|
19
|
+
};
|
|
20
|
+
const parseDotEnv = (text) => {
|
|
21
|
+
const values = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const [lineIndex, rawLine] of text.replace(/^\uFEFF/, "").split(/\r?\n/u).entries()) {
|
|
23
|
+
let line = rawLine.trim();
|
|
24
|
+
if (line === "" || line.startsWith("#")) continue;
|
|
25
|
+
if (/^export\s/u.test(line)) line = line.replace(/^export\s+/u, "");
|
|
26
|
+
const separator = line.indexOf("=");
|
|
27
|
+
if (separator <= 0) throw new Error(`Invalid dotenv entry at line ${lineIndex + 1}`);
|
|
28
|
+
const key = line.slice(0, separator).trim();
|
|
29
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key)) throw new Error(`Invalid dotenv key at line ${lineIndex + 1}`);
|
|
30
|
+
let value = line.slice(separator + 1).trim();
|
|
31
|
+
const quote = value[0];
|
|
32
|
+
if (quote === "\"" || quote === "'") {
|
|
33
|
+
const closingQuote = value.indexOf(quote, 1);
|
|
34
|
+
const trailing = closingQuote < 0 ? "" : value.slice(closingQuote + 1).trim();
|
|
35
|
+
if (closingQuote < 0 || trailing !== "" && !trailing.startsWith("#")) throw new Error(`Unterminated dotenv value at line ${lineIndex + 1}`);
|
|
36
|
+
value = value.slice(1, closingQuote);
|
|
37
|
+
} else {
|
|
38
|
+
const comment = value.search(/\s+#/u);
|
|
39
|
+
if (comment >= 0) value = value.slice(0, comment).trimEnd();
|
|
40
|
+
}
|
|
41
|
+
values.set(key, value);
|
|
42
|
+
}
|
|
43
|
+
return Object.fromEntries(values);
|
|
44
|
+
};
|
|
45
|
+
const loadSource = async (options = {}) => {
|
|
46
|
+
const dotenv = options.dotEnvPath === void 0 ? {} : parseDotEnv(await readText(options.dotEnvPath));
|
|
47
|
+
const explicit = options.envSource ?? hostEnvironment();
|
|
48
|
+
return {
|
|
49
|
+
...dotenv,
|
|
50
|
+
...explicit
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const sourceError = (path, cause) => {
|
|
54
|
+
const message = path === void 0 ? "Failed to load configuration source" : `Failed to load configuration source at ${path}`;
|
|
55
|
+
if (path === void 0) return new ConfigSourceError({
|
|
56
|
+
cause,
|
|
57
|
+
message
|
|
58
|
+
});
|
|
59
|
+
return new ConfigSourceError({
|
|
60
|
+
cause,
|
|
61
|
+
message,
|
|
62
|
+
path
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
const validate = async (schema, source) => {
|
|
66
|
+
const checked = await Result.tryPromise(() => Promise.resolve(schema["~standard"].validate(source)));
|
|
67
|
+
if (checked.status === "error") return checked;
|
|
68
|
+
if (checked.value.issues !== void 0) return Result.err(new ConfigValidationError({
|
|
69
|
+
issues: Object.freeze([...checked.value.issues]),
|
|
70
|
+
message: "Configuration validation failed"
|
|
71
|
+
}));
|
|
72
|
+
return Result.ok(checked.value.value);
|
|
73
|
+
};
|
|
74
|
+
const evaluate = async (spec, provider) => {
|
|
75
|
+
const loaded = await Result.tryPromise({
|
|
76
|
+
try: async () => {
|
|
77
|
+
if (spec.source === "provider") {
|
|
78
|
+
const base = provider?.source;
|
|
79
|
+
if (base === void 0) throw new Error("Config provider did not expose a source");
|
|
80
|
+
if (spec.sourceOptions === void 0) return base;
|
|
81
|
+
return {
|
|
82
|
+
...base,
|
|
83
|
+
...await loadSource(spec.sourceOptions)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return await loadSource(spec.sourceOptions);
|
|
87
|
+
},
|
|
88
|
+
catch: (cause) => sourceError(spec.sourceOptions?.dotEnvPath, cause)
|
|
89
|
+
});
|
|
90
|
+
if (loaded.status === "error") return loaded;
|
|
91
|
+
return await validate(spec.schema, loaded.value);
|
|
92
|
+
};
|
|
93
|
+
const makeConfigValue = (spec) => {
|
|
94
|
+
return {
|
|
95
|
+
...spec,
|
|
96
|
+
async *[Symbol.asyncIterator]() {
|
|
97
|
+
let provider;
|
|
98
|
+
if (spec.source === "provider") provider = yield* Config;
|
|
99
|
+
return yield* Result.await(evaluate(spec, provider));
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/** Host-backed raw configuration source and provider token. */
|
|
104
|
+
var Config = class Config extends Service()("Config") {
|
|
105
|
+
source;
|
|
106
|
+
constructor(source) {
|
|
107
|
+
super();
|
|
108
|
+
this.source = source;
|
|
109
|
+
}
|
|
110
|
+
/** Read one raw value from the configured source. */
|
|
111
|
+
get(key) {
|
|
112
|
+
return this.source[key];
|
|
113
|
+
}
|
|
114
|
+
/** Create a provider from an already-loaded source. */
|
|
115
|
+
static layer(source) {
|
|
116
|
+
return Layer.succeed(Config, new Config(source));
|
|
117
|
+
}
|
|
118
|
+
/** Create a provider whose source is loaded from dotenv and the host environment. */
|
|
119
|
+
static layerFromEnv(options = {}) {
|
|
120
|
+
return Layer.make(Config, async () => {
|
|
121
|
+
try {
|
|
122
|
+
return new Config(await loadSource(options));
|
|
123
|
+
} catch (cause) {
|
|
124
|
+
throw sourceError(options.dotEnvPath, cause);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/** Describe a configuration read from the contextual Config provider. */
|
|
129
|
+
static schema(schema) {
|
|
130
|
+
return makeConfigValue({
|
|
131
|
+
schema,
|
|
132
|
+
source: "provider"
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Describe a reusable configuration loaded from dotenv and the host environment. */
|
|
136
|
+
static fromEnv(options) {
|
|
137
|
+
const sourceOptions = {};
|
|
138
|
+
if (options.dotEnvPath !== void 0) sourceOptions.dotEnvPath = options.dotEnvPath;
|
|
139
|
+
if (options.envSource !== void 0) sourceOptions.envSource = options.envSource;
|
|
140
|
+
return makeConfigValue({
|
|
141
|
+
schema: options.schema,
|
|
142
|
+
source: "bound",
|
|
143
|
+
sourceOptions
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** Add an environment source to a provider-backed descriptor for functional `pipe` composition. */
|
|
147
|
+
static withEnv(options) {
|
|
148
|
+
return (value) => {
|
|
149
|
+
const internal = value;
|
|
150
|
+
if (!("schema" in internal)) return value;
|
|
151
|
+
return makeConfigValue({
|
|
152
|
+
schema: internal.schema,
|
|
153
|
+
source: internal.source,
|
|
154
|
+
sourceOptions: options
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
/** The default lazy host-environment Config provider. */
|
|
160
|
+
const ConfigLive = Config.layerFromEnv();
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/standard-services/index.ts
|
|
163
|
+
const assertDelay = (milliseconds) => {
|
|
164
|
+
if (!Number.isFinite(milliseconds) || milliseconds < 0) throw new RangeError("Delay must be a finite non-negative number");
|
|
165
|
+
};
|
|
166
|
+
/** Host-backed time and waiting service. */
|
|
167
|
+
var Clock = class extends Service()("Clock") {
|
|
168
|
+
now() {
|
|
169
|
+
return /* @__PURE__ */ new Date();
|
|
170
|
+
}
|
|
171
|
+
sleep(milliseconds) {
|
|
172
|
+
assertDelay(milliseconds);
|
|
173
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
/** The default host Clock provider. */
|
|
177
|
+
const ClockLive = Layer.make(Clock);
|
|
178
|
+
/** Deterministic Clock implementation for tests. */
|
|
179
|
+
var ClockTest = class ClockTest {
|
|
180
|
+
currentTime;
|
|
181
|
+
waiters = [];
|
|
182
|
+
constructor(initial = 0) {
|
|
183
|
+
this.currentTime = initial instanceof Date ? initial.getTime() : initial;
|
|
184
|
+
if (!Number.isFinite(this.currentTime)) throw new RangeError("ClockTest time must be finite");
|
|
185
|
+
}
|
|
186
|
+
now() {
|
|
187
|
+
return new Date(this.currentTime);
|
|
188
|
+
}
|
|
189
|
+
setTime(value) {
|
|
190
|
+
const next = value instanceof Date ? value.getTime() : value;
|
|
191
|
+
if (!Number.isFinite(next)) throw new RangeError("ClockTest time must be finite");
|
|
192
|
+
this.currentTime = next;
|
|
193
|
+
this.flushWaiters();
|
|
194
|
+
}
|
|
195
|
+
advance(milliseconds) {
|
|
196
|
+
assertDelay(milliseconds);
|
|
197
|
+
this.currentTime += milliseconds;
|
|
198
|
+
this.flushWaiters();
|
|
199
|
+
}
|
|
200
|
+
sleep(milliseconds) {
|
|
201
|
+
assertDelay(milliseconds);
|
|
202
|
+
return new Promise((resolve) => {
|
|
203
|
+
this.waiters.push({
|
|
204
|
+
at: this.currentTime + milliseconds,
|
|
205
|
+
resolve
|
|
206
|
+
});
|
|
207
|
+
this.flushWaiters();
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
static layer(initial = 0) {
|
|
211
|
+
return Layer.succeed(Clock, new ClockTest(initial));
|
|
212
|
+
}
|
|
213
|
+
flushWaiters() {
|
|
214
|
+
for (let index = this.waiters.length - 1; index >= 0; index--) {
|
|
215
|
+
const waiter = this.waiters[index];
|
|
216
|
+
if (waiter.at <= this.currentTime) {
|
|
217
|
+
this.waiters.splice(index, 1);
|
|
218
|
+
waiter.resolve();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const ClockTestLayer = (initial = 0) => ClockTest.layer(initial);
|
|
224
|
+
/** Host-backed pseudo-random number service. */
|
|
225
|
+
var Random = class extends Service()("Random") {
|
|
226
|
+
next() {
|
|
227
|
+
return Math.random();
|
|
228
|
+
}
|
|
229
|
+
nextInt(maxExclusive) {
|
|
230
|
+
if (!Number.isInteger(maxExclusive) || maxExclusive <= 0) throw new RangeError("Random.nextInt maxExclusive must be a positive integer");
|
|
231
|
+
return Math.floor(this.next() * maxExclusive);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
/** The default host Random provider. */
|
|
235
|
+
const RandomLive = Layer.make(Random);
|
|
236
|
+
/** Reproducible pseudo-random implementation with isolated mutable state. */
|
|
237
|
+
var RandomSeeded = class RandomSeeded {
|
|
238
|
+
state;
|
|
239
|
+
constructor(seed) {
|
|
240
|
+
if (!Number.isFinite(seed)) throw new RangeError("RandomSeeded seed must be finite");
|
|
241
|
+
this.state = seed >>> 0;
|
|
242
|
+
}
|
|
243
|
+
next() {
|
|
244
|
+
this.state = 1664525 * this.state + 1013904223 >>> 0;
|
|
245
|
+
return this.state / 4294967296;
|
|
246
|
+
}
|
|
247
|
+
nextInt(maxExclusive) {
|
|
248
|
+
if (!Number.isInteger(maxExclusive) || maxExclusive <= 0) throw new RangeError("RandomSeeded.nextInt maxExclusive must be a positive integer");
|
|
249
|
+
return Math.floor(this.next() * maxExclusive);
|
|
250
|
+
}
|
|
251
|
+
static layer(seed) {
|
|
252
|
+
return Layer.succeed(Random, new RandomSeeded(seed));
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const RandomSeededLayer = (seed) => RandomSeeded.layer(seed);
|
|
256
|
+
const isLoggerLevel = (value) => value === "debug" || value === "info" || value === "warn" || value === "error";
|
|
257
|
+
const toLoggerEvent = (input, message, data) => {
|
|
258
|
+
if (!isLoggerLevel(input)) return input;
|
|
259
|
+
const event = {
|
|
260
|
+
level: input,
|
|
261
|
+
message: message ?? ""
|
|
262
|
+
};
|
|
263
|
+
if (data !== void 0) event.data = data;
|
|
264
|
+
return event;
|
|
265
|
+
};
|
|
266
|
+
/** Structured host logger bridge. */
|
|
267
|
+
var Logger = class extends Service()("Logger") {
|
|
268
|
+
log(first, message, data) {
|
|
269
|
+
const event = toLoggerEvent(first, message, data);
|
|
270
|
+
const write = console[event.level];
|
|
271
|
+
if (event.data === void 0) write.call(console, event.message);
|
|
272
|
+
else write.call(console, event.message, event.data);
|
|
273
|
+
}
|
|
274
|
+
debug(message, data) {
|
|
275
|
+
this.log("debug", message, data);
|
|
276
|
+
}
|
|
277
|
+
info(message, data) {
|
|
278
|
+
this.log("info", message, data);
|
|
279
|
+
}
|
|
280
|
+
warn(message, data) {
|
|
281
|
+
this.log("warn", message, data);
|
|
282
|
+
}
|
|
283
|
+
error(message, data) {
|
|
284
|
+
this.log("error", message, data);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
/** The default host Logger provider. */
|
|
288
|
+
const LoggerLive = Layer.make(Logger);
|
|
289
|
+
/** Ordered in-memory Logger implementation for tests. */
|
|
290
|
+
var LoggerTest = class LoggerTest {
|
|
291
|
+
events = [];
|
|
292
|
+
log(first, message, data) {
|
|
293
|
+
const event = toLoggerEvent(first, message, data);
|
|
294
|
+
this.events.push(event);
|
|
295
|
+
}
|
|
296
|
+
debug(message, data) {
|
|
297
|
+
this.log("debug", message, data);
|
|
298
|
+
}
|
|
299
|
+
info(message, data) {
|
|
300
|
+
this.log("info", message, data);
|
|
301
|
+
}
|
|
302
|
+
warn(message, data) {
|
|
303
|
+
this.log("warn", message, data);
|
|
304
|
+
}
|
|
305
|
+
error(message, data) {
|
|
306
|
+
this.log("error", message, data);
|
|
307
|
+
}
|
|
308
|
+
clear() {
|
|
309
|
+
this.events.length = 0;
|
|
310
|
+
}
|
|
311
|
+
static make() {
|
|
312
|
+
const logger = new LoggerTest();
|
|
313
|
+
return {
|
|
314
|
+
logger,
|
|
315
|
+
layer: Layer.succeed(Logger, logger)
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
static layer(logger = new LoggerTest()) {
|
|
319
|
+
return Layer.succeed(Logger, logger);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const LoggerTestLayer = () => LoggerTest.layer();
|
|
323
|
+
/** Execution-local request value carried by a normal Service provider. */
|
|
324
|
+
var CurrentRequest = class CurrentRequest extends Service()("CurrentRequest") {
|
|
325
|
+
value;
|
|
326
|
+
request;
|
|
327
|
+
constructor(value) {
|
|
328
|
+
super();
|
|
329
|
+
this.value = value;
|
|
330
|
+
this.request = value;
|
|
331
|
+
}
|
|
332
|
+
static layer(value) {
|
|
333
|
+
return Layer.succeed(CurrentRequest, new CurrentRequest(value));
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
const CurrentRequestLayer = (value) => CurrentRequest.layer(value);
|
|
337
|
+
//#endregion
|
|
338
|
+
export { ConfigSourceError as _, CurrentRequest as a, LoggerLive as c, Random as d, RandomLive as f, ConfigLive as g, Config as h, ClockTestLayer as i, LoggerTest as l, RandomSeededLayer as m, ClockLive as n, CurrentRequestLayer as o, RandomSeeded as p, ClockTest as r, Logger as s, Clock as t, LoggerTestLayer as u, ConfigValidationError as v };
|
|
339
|
+
|
|
340
|
+
//# sourceMappingURL=standard-services-QseopL9g.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-services-QseopL9g.mjs","names":[],"sources":["../src/standard-services/config.ts","../src/standard-services/index.ts"],"sourcesContent":["import {\n Result,\n TaggedError,\n type Err,\n type Result as ResultType,\n type StandardSchemaV1,\n type UnhandledException\n} from 'better-result'\n\nimport type { ServiceRequirement } from '../effect/types'\nimport { Layer } from '../layer'\nimport { Service } from '../service'\n\n/** Raw string values supplied to a configuration schema. */\nexport type ConfigSource = Readonly<Record<string, string | undefined>>\n\n/** Optional sources used by environment-backed configuration values. */\nexport type ConfigSourceOptions = {\n readonly dotEnvPath?: string\n readonly envSource?: ConfigSource\n}\n\n/** Options for the one-call schema-bound configuration API. */\nexport type ConfigFromEnvOptions<Schema extends StandardSchemaV1> = ConfigSourceOptions & {\n readonly schema: Schema\n}\n\n/** The decoded value produced by a Standard Schema. */\nexport type ConfigOutput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema>\n\n/** The raw input type described by a Standard Schema. */\nexport type ConfigInput<Schema extends StandardSchemaV1> = StandardSchemaV1.InferInput<Schema>\n\n/** A safe validation issue exposed by a configuration failure. */\nexport type ConfigIssue = StandardSchemaV1.Issue\n\n/** A schema validation failure. Raw source values are intentionally omitted. */\nexport class ConfigValidationError extends TaggedError('ConfigValidationError')<{\n readonly issues: ReadonlyArray<ConfigIssue>\n readonly message: string\n}> {}\n\n/** A dotenv or host-source loading failure. Raw source values are intentionally omitted. */\nexport class ConfigSourceError extends TaggedError('ConfigSourceError')<{\n readonly cause: unknown\n readonly message: string\n readonly path?: string\n}> {}\n\n/** Errors that may be returned while loading or validating configuration. */\nexport type ConfigError = ConfigValidationError | ConfigSourceError | UnhandledException\n\ntype ConfigYield<Requirements extends Service.Any, Error> =\n | Err<never, Error>\n | ServiceRequirement<Requirements>\n\n/** A reusable, async-yieldable Standard Schema configuration descriptor. */\nexport type ConfigValue<\n Schema extends StandardSchemaV1,\n Requirements extends Service.Any = never,\n Error = ConfigError\n> = {\n [Symbol.asyncIterator](): AsyncGenerator<\n ConfigYield<Requirements, Error>,\n ConfigOutput<Schema>,\n unknown\n >\n}\n\ntype RuntimeConfigYield = Err<never, ConfigError> | ServiceRequirement<Service.Any>\n\ntype ConfigValueSpec<Schema extends StandardSchemaV1> = {\n readonly schema: Schema\n readonly source: 'bound' | 'provider'\n readonly sourceOptions?: ConfigSourceOptions\n}\n\ntype MutableConfigSourceOptions = {\n dotEnvPath?: string\n envSource?: ConfigSource\n}\n\ntype RuntimeGlobal = typeof globalThis & {\n readonly process?: { readonly env?: ConfigSource }\n readonly Bun?: {\n readonly env?: ConfigSource\n readonly file?: (path: string) => { text(): Promise<string> }\n }\n}\n\n// SAFETY: Hosts may expose process/Bun globals at runtime without declaring them on globalThis.\nconst runtimeGlobal = globalThis as RuntimeGlobal\n\nconst hostEnvironment = (): ConfigSource => {\n const processEnvironment = runtimeGlobal.process?.env\n\n if (processEnvironment !== undefined) {\n return processEnvironment\n }\n\n return runtimeGlobal.Bun?.env ?? {}\n}\n\nconst readText = async (path: string): Promise<string> => {\n const file = runtimeGlobal.Bun?.file\n\n if (file !== undefined) {\n return await file(path).text()\n }\n\n const { readFile } = await import('node:fs/promises')\n\n return await readFile(path, 'utf8')\n}\n\nconst parseDotEnv = (text: string) => {\n const values = new Map<string, string>()\n\n for (const [lineIndex, rawLine] of text\n .replace(/^\\uFEFF/, '')\n .split(/\\r?\\n/u)\n .entries()) {\n let line = rawLine.trim()\n\n if (line === '' || line.startsWith('#')) {\n continue\n }\n\n if (/^export\\s/u.test(line)) {\n line = line.replace(/^export\\s+/u, '')\n }\n\n const separator = line.indexOf('=')\n\n if (separator <= 0) {\n throw new Error(`Invalid dotenv entry at line ${lineIndex + 1}`)\n }\n\n const key = line.slice(0, separator).trim()\n\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key)) {\n throw new Error(`Invalid dotenv key at line ${lineIndex + 1}`)\n }\n\n let value = line.slice(separator + 1).trim()\n const quote = value[0]\n\n if (quote === '\"' || quote === \"'\") {\n const closingQuote = value.indexOf(quote, 1)\n const trailing = closingQuote < 0 ? '' : value.slice(closingQuote + 1).trim()\n\n if (closingQuote < 0 || (trailing !== '' && !trailing.startsWith('#'))) {\n throw new Error(`Unterminated dotenv value at line ${lineIndex + 1}`)\n }\n\n value = value.slice(1, closingQuote)\n } else {\n const comment = value.search(/\\s+#/u)\n\n if (comment >= 0) {\n value = value.slice(0, comment).trimEnd()\n }\n }\n\n values.set(key, value)\n }\n\n return Object.fromEntries(values)\n}\n\nconst loadSource = async (options: ConfigSourceOptions = {}): Promise<ConfigSource> => {\n const dotenv =\n options.dotEnvPath === undefined ? {} : parseDotEnv(await readText(options.dotEnvPath))\n const explicit = options.envSource ?? hostEnvironment()\n\n return {\n ...dotenv,\n ...explicit\n }\n}\n\nconst sourceError = (path: string | undefined, cause: unknown): ConfigSourceError => {\n const message =\n path === undefined\n ? 'Failed to load configuration source'\n : `Failed to load configuration source at ${path}`\n\n if (path === undefined) {\n return new ConfigSourceError({ cause, message })\n }\n\n return new ConfigSourceError({ cause, message, path })\n}\n\nconst validate = async <Schema extends StandardSchemaV1>(\n schema: Schema,\n source: ConfigSource\n): Promise<ResultType<ConfigOutput<Schema>, ConfigValidationError | UnhandledException>> => {\n const checked = await Result.tryPromise(() =>\n Promise.resolve(schema['~standard'].validate(source))\n )\n\n if (checked.status === 'error') {\n return checked\n }\n\n if (checked.value.issues !== undefined) {\n return Result.err(\n new ConfigValidationError({\n issues: Object.freeze([...checked.value.issues]),\n message: 'Configuration validation failed'\n })\n )\n }\n\n // SAFETY: A successful Standard Schema result carries its declared output type.\n return Result.ok(checked.value.value as ConfigOutput<Schema>)\n}\n\nconst evaluate = async <Schema extends StandardSchemaV1>(\n spec: ConfigValueSpec<Schema>,\n provider?: Config\n): Promise<ResultType<ConfigOutput<Schema>, ConfigError>> => {\n const loaded = await Result.tryPromise({\n try: async () => {\n if (spec.source === 'provider') {\n const base = provider?.source\n\n if (base === undefined) {\n throw new Error('Config provider did not expose a source')\n }\n\n if (spec.sourceOptions === undefined) {\n return base\n }\n\n return {\n ...base,\n ...(await loadSource(spec.sourceOptions))\n }\n }\n\n return await loadSource(spec.sourceOptions)\n },\n catch: (cause) => sourceError(spec.sourceOptions?.dotEnvPath, cause)\n })\n\n if (loaded.status === 'error') {\n return loaded\n }\n\n return await validate(spec.schema, loaded.value)\n}\n\nconst makeConfigValue = <Schema extends StandardSchemaV1, Requirements extends Service.Any>(\n spec: ConfigValueSpec<Schema>\n): ConfigValue<Schema, Requirements> => {\n const value = {\n ...spec,\n async *[Symbol.asyncIterator](): AsyncGenerator<\n RuntimeConfigYield,\n ConfigOutput<Schema>,\n unknown\n > {\n let provider: Config | undefined\n\n if (spec.source === 'provider') {\n provider = yield* Config\n }\n\n return yield* Result.await(evaluate(spec, provider))\n }\n }\n\n // SAFETY: The runtime iterator only yields Result errors and Service values; the public cast restores the phantom requirement.\n return value as ConfigValue<Schema, Requirements>\n}\n\n/** Host-backed raw configuration source and provider token. */\nexport class Config extends Service<Config>()('Config') {\n constructor(readonly source: ConfigSource) {\n super()\n }\n\n /** Read one raw value from the configured source. */\n get(key: string): string | undefined {\n return this.source[key]\n }\n\n /** Create a provider from an already-loaded source. */\n static layer(source: ConfigSource) {\n return Layer.succeed(Config, new Config(source))\n }\n\n /** Create a provider whose source is loaded from dotenv and the host environment. */\n static layerFromEnv(options: ConfigSourceOptions = {}) {\n return Layer.make(Config, async () => {\n try {\n return new Config(await loadSource(options))\n } catch (cause) {\n throw sourceError(options.dotEnvPath, cause)\n }\n })\n }\n\n /** Describe a configuration read from the contextual Config provider. */\n static schema<Schema extends StandardSchemaV1>(schema: Schema): ConfigValue<Schema, Config> {\n return makeConfigValue({ schema, source: 'provider' })\n }\n\n /** Describe a reusable configuration loaded from dotenv and the host environment. */\n static fromEnv<Schema extends StandardSchemaV1>(\n options: ConfigFromEnvOptions<Schema>\n ): ConfigValue<Schema> {\n const sourceOptions: MutableConfigSourceOptions = {}\n\n if (options.dotEnvPath !== undefined) {\n sourceOptions.dotEnvPath = options.dotEnvPath\n }\n\n if (options.envSource !== undefined) {\n sourceOptions.envSource = options.envSource\n }\n\n return makeConfigValue({\n schema: options.schema,\n source: 'bound',\n sourceOptions\n })\n }\n\n /** Add an environment source to a provider-backed descriptor for functional `pipe` composition. */\n static withEnv(options: ConfigSourceOptions) {\n return <Schema extends StandardSchemaV1, Requirements extends Service.Any, Error = ConfigError>(\n value: ConfigValue<Schema, Requirements, Error>\n ): ConfigValue<Schema, Requirements, Error> => {\n // SAFETY: Values produced by this module retain their schema/source descriptor fields; custom iterables pass through unchanged.\n const internal = value as ConfigValue<Schema, Requirements> & ConfigValueSpec<Schema>\n\n if (!('schema' in internal)) {\n return value\n }\n\n // SAFETY: The internal descriptor preserves the original schema and requirement phantom.\n return makeConfigValue({\n schema: internal.schema,\n source: internal.source,\n sourceOptions: options\n }) as ConfigValue<Schema, Requirements, Error>\n }\n }\n}\n\n/** The default lazy host-environment Config provider. */\nexport const ConfigLive = Config.layerFromEnv()\n\nexport type { StandardSchemaV1 }\n","import { CurrentAbortSignal } from '../runtime'\nimport { Layer } from '../layer'\nimport { Service } from '../service'\n\nexport { CurrentAbortSignal }\n\nexport { Config, ConfigLive, ConfigSourceError, ConfigValidationError } from './config'\n\nexport type {\n ConfigError,\n ConfigFromEnvOptions,\n ConfigInput,\n ConfigIssue,\n ConfigOutput,\n ConfigSource,\n ConfigSourceOptions,\n ConfigValue,\n StandardSchemaV1\n} from './config'\n\nconst assertDelay = (milliseconds: number): void => {\n if (!Number.isFinite(milliseconds) || milliseconds < 0) {\n throw new RangeError('Delay must be a finite non-negative number')\n }\n}\n\n/** Host-backed time and waiting service. */\nexport class Clock extends Service<Clock>()('Clock') {\n now(): Date {\n return new Date()\n }\n\n sleep(milliseconds: number): Promise<void> {\n assertDelay(milliseconds)\n return new Promise((resolve) => setTimeout(resolve, milliseconds))\n }\n}\n\n/** The default host Clock provider. */\nexport const ClockLive = Layer.make(Clock)\n\ntype ClockWaiter = {\n readonly at: number\n readonly resolve: () => void\n}\n\n/** Deterministic Clock implementation for tests. */\nexport class ClockTest implements Service.Contract<Clock> {\n private currentTime: number\n\n private readonly waiters: ClockWaiter[] = []\n\n constructor(initial: Date | number = 0) {\n this.currentTime = initial instanceof Date ? initial.getTime() : initial\n\n if (!Number.isFinite(this.currentTime)) {\n throw new RangeError('ClockTest time must be finite')\n }\n }\n\n now(): Date {\n return new Date(this.currentTime)\n }\n\n setTime(value: Date | number): void {\n const next = value instanceof Date ? value.getTime() : value\n\n if (!Number.isFinite(next)) {\n throw new RangeError('ClockTest time must be finite')\n }\n\n this.currentTime = next\n this.flushWaiters()\n }\n\n advance(milliseconds: number): void {\n assertDelay(milliseconds)\n this.currentTime += milliseconds\n this.flushWaiters()\n }\n\n sleep(milliseconds: number): Promise<void> {\n assertDelay(milliseconds)\n\n return new Promise((resolve) => {\n this.waiters.push({ at: this.currentTime + milliseconds, resolve })\n this.flushWaiters()\n })\n }\n\n static layer(initial: Date | number = 0) {\n return Layer.succeed(Clock, new ClockTest(initial))\n }\n\n private flushWaiters(): void {\n for (let index = this.waiters.length - 1; index >= 0; index--) {\n const waiter = this.waiters[index]!\n\n if (waiter.at <= this.currentTime) {\n this.waiters.splice(index, 1)\n waiter.resolve()\n }\n }\n }\n}\n\nexport const ClockTestLayer = (initial: Date | number = 0) => ClockTest.layer(initial)\n\n/** Host-backed pseudo-random number service. */\nexport class Random extends Service<Random>()('Random') {\n next(): number {\n return Math.random()\n }\n\n nextInt(maxExclusive: number): number {\n if (!Number.isInteger(maxExclusive) || maxExclusive <= 0) {\n throw new RangeError('Random.nextInt maxExclusive must be a positive integer')\n }\n\n return Math.floor(this.next() * maxExclusive)\n }\n}\n\n/** The default host Random provider. */\nexport const RandomLive = Layer.make(Random)\n\n/** Reproducible pseudo-random implementation with isolated mutable state. */\nexport class RandomSeeded implements Service.Contract<Random> {\n private state: number\n\n constructor(seed: number) {\n if (!Number.isFinite(seed)) {\n throw new RangeError('RandomSeeded seed must be finite')\n }\n\n this.state = seed >>> 0\n }\n\n next(): number {\n this.state = (1664525 * this.state + 1013904223) >>> 0\n return this.state / 0x1_0000_0000\n }\n\n nextInt(maxExclusive: number): number {\n if (!Number.isInteger(maxExclusive) || maxExclusive <= 0) {\n throw new RangeError('RandomSeeded.nextInt maxExclusive must be a positive integer')\n }\n\n return Math.floor(this.next() * maxExclusive)\n }\n\n static layer(seed: number) {\n return Layer.succeed(Random, new RandomSeeded(seed))\n }\n}\n\nexport const RandomSeededLayer = (seed: number) => RandomSeeded.layer(seed)\n\nexport type LoggerLevel = 'debug' | 'info' | 'warn' | 'error'\n\nexport type LoggerEvent = {\n level: LoggerLevel\n message: string\n data?: LoggerData\n}\n\nexport type LoggerData =\n | string\n | number\n | boolean\n | bigint\n | null\n | readonly LoggerData[]\n | { readonly [key: string]: LoggerData }\ntype LoggerInput = LoggerEvent | LoggerLevel\n\nconst isLoggerLevel = (value: LoggerInput): value is LoggerLevel =>\n value === 'debug' || value === 'info' || value === 'warn' || value === 'error'\n\nconst toLoggerEvent = (input: LoggerInput, message?: string, data?: LoggerData): LoggerEvent => {\n if (!isLoggerLevel(input)) {\n return input\n }\n\n const event: LoggerEvent = { level: input, message: message ?? '' }\n\n if (data !== undefined) {\n event.data = data\n }\n\n return event\n}\n\n/** Structured host logger bridge. */\nexport class Logger extends Service<Logger>()('Logger') {\n log(event: LoggerEvent): void\n log(level: LoggerLevel, message: string, data?: LoggerData): void\n log(first: LoggerInput, message?: string, data?: LoggerData): void {\n const event = toLoggerEvent(first, message, data)\n\n const write = console[event.level]\n\n if (event.data === undefined) {\n write.call(console, event.message)\n } else {\n write.call(console, event.message, event.data)\n }\n }\n\n debug(message: string, data?: LoggerData): void {\n this.log('debug', message, data)\n }\n\n info(message: string, data?: LoggerData): void {\n this.log('info', message, data)\n }\n\n warn(message: string, data?: LoggerData): void {\n this.log('warn', message, data)\n }\n\n error(message: string, data?: LoggerData): void {\n this.log('error', message, data)\n }\n}\n\n/** The default host Logger provider. */\nexport const LoggerLive = Layer.make(Logger)\n\n/** Ordered in-memory Logger implementation for tests. */\nexport class LoggerTest implements Service.Contract<Logger> {\n readonly events: LoggerEvent[] = []\n\n log(event: LoggerEvent): void\n log(level: LoggerLevel, message: string, data?: LoggerData): void\n log(first: LoggerInput, message?: string, data?: LoggerData): void {\n const event = toLoggerEvent(first, message, data)\n\n this.events.push(event)\n }\n\n debug(message: string, data?: LoggerData): void {\n this.log('debug', message, data)\n }\n\n info(message: string, data?: LoggerData): void {\n this.log('info', message, data)\n }\n\n warn(message: string, data?: LoggerData): void {\n this.log('warn', message, data)\n }\n\n error(message: string, data?: LoggerData): void {\n this.log('error', message, data)\n }\n\n clear(): void {\n this.events.length = 0\n }\n\n static make() {\n const logger = new LoggerTest()\n return { logger, layer: Layer.succeed(Logger, logger) }\n }\n\n static layer(logger: LoggerTest = new LoggerTest()) {\n return Layer.succeed(Logger, logger)\n }\n}\n\nexport const LoggerTestLayer = () => LoggerTest.layer()\n\n/** Execution-local request value carried by a normal Service provider. */\nexport class CurrentRequest extends Service<CurrentRequest>()('CurrentRequest') {\n readonly request: unknown\n\n // oxlint-disable-next-line anti-slop/no-unknown-parameters\n constructor(readonly value: unknown) {\n super()\n this.request = value\n }\n\n // oxlint-disable-next-line anti-slop/no-unknown-parameters\n static layer(value: unknown) {\n return Layer.succeed(CurrentRequest, new CurrentRequest(value))\n }\n}\n\n// oxlint-disable-next-line anti-slop/no-unknown-parameters\nexport const CurrentRequestLayer = (value: unknown) => CurrentRequest.layer(value)\n"],"mappings":"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"}
|
|
@@ -1,116 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as
|
|
3
|
-
|
|
4
|
-
//#region src/standard-services/index.d.ts
|
|
5
|
-
declare const Clock_base: (abstract new () => ServiceIdentity<"Clock">) & {
|
|
6
|
-
readonly name: string;
|
|
7
|
-
readonly serviceTag: "Clock";
|
|
8
|
-
} & {
|
|
9
|
-
readonly of: Service.FactoryOf<Clock, "Clock">;
|
|
10
|
-
readonly [Symbol.asyncIterator]: (this: ServiceToken<"Clock", Clock & ServiceIdentity<"Clock">>) => AsyncGenerator<ServiceRequirement<Clock>, Clock, unknown>;
|
|
11
|
-
};
|
|
12
|
-
/** Host-backed time and waiting service. */
|
|
13
|
-
declare class Clock extends Clock_base {
|
|
14
|
-
now(): Date;
|
|
15
|
-
sleep(milliseconds: number): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
/** The default host Clock provider. */
|
|
18
|
-
declare const ClockLive: LayerResult<ProviderEntry<Clock, never>>;
|
|
19
|
-
/** Deterministic Clock implementation for tests. */
|
|
20
|
-
declare class ClockTest implements Service.Contract<Clock> {
|
|
21
|
-
private currentTime;
|
|
22
|
-
private readonly waiters;
|
|
23
|
-
constructor(initial?: Date | number);
|
|
24
|
-
now(): Date;
|
|
25
|
-
setTime(value: Date | number): void;
|
|
26
|
-
advance(milliseconds: number): void;
|
|
27
|
-
sleep(milliseconds: number): Promise<void>;
|
|
28
|
-
static layer(initial?: Date | number): LayerResult<ProviderEntry<Clock, never>>;
|
|
29
|
-
private flushWaiters;
|
|
30
|
-
}
|
|
31
|
-
declare const ClockTestLayer: (initial?: Date | number) => LayerResult<ProviderEntry<Clock, never>>;
|
|
32
|
-
declare const Random_base: (abstract new () => ServiceIdentity<"Random">) & {
|
|
33
|
-
readonly name: string;
|
|
34
|
-
readonly serviceTag: "Random";
|
|
35
|
-
} & {
|
|
36
|
-
readonly of: Service.FactoryOf<Random, "Random">;
|
|
37
|
-
readonly [Symbol.asyncIterator]: (this: ServiceToken<"Random", Random & ServiceIdentity<"Random">>) => AsyncGenerator<ServiceRequirement<Random>, Random, unknown>;
|
|
38
|
-
};
|
|
39
|
-
/** Host-backed pseudo-random number service. */
|
|
40
|
-
declare class Random extends Random_base {
|
|
41
|
-
next(): number;
|
|
42
|
-
nextInt(maxExclusive: number): number;
|
|
43
|
-
}
|
|
44
|
-
/** The default host Random provider. */
|
|
45
|
-
declare const RandomLive: LayerResult<ProviderEntry<Random, never>>;
|
|
46
|
-
/** Reproducible pseudo-random implementation with isolated mutable state. */
|
|
47
|
-
declare class RandomSeeded implements Service.Contract<Random> {
|
|
48
|
-
private state;
|
|
49
|
-
constructor(seed: number);
|
|
50
|
-
next(): number;
|
|
51
|
-
nextInt(maxExclusive: number): number;
|
|
52
|
-
static layer(seed: number): LayerResult<ProviderEntry<Random, never>>;
|
|
53
|
-
}
|
|
54
|
-
declare const RandomSeededLayer: (seed: number) => LayerResult<ProviderEntry<Random, never>>;
|
|
55
|
-
type LoggerLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
56
|
-
type LoggerEvent = {
|
|
57
|
-
level: LoggerLevel;
|
|
58
|
-
message: string;
|
|
59
|
-
data?: LoggerData;
|
|
60
|
-
};
|
|
61
|
-
type LoggerData = string | number | boolean | bigint | null | readonly LoggerData[] | {
|
|
62
|
-
readonly [key: string]: LoggerData;
|
|
63
|
-
};
|
|
64
|
-
declare const Logger_base: (abstract new () => ServiceIdentity<"Logger">) & {
|
|
65
|
-
readonly name: string;
|
|
66
|
-
readonly serviceTag: "Logger";
|
|
67
|
-
} & {
|
|
68
|
-
readonly of: Service.FactoryOf<Logger, "Logger">;
|
|
69
|
-
readonly [Symbol.asyncIterator]: (this: ServiceToken<"Logger", Logger & ServiceIdentity<"Logger">>) => AsyncGenerator<ServiceRequirement<Logger>, Logger, unknown>;
|
|
70
|
-
};
|
|
71
|
-
/** Structured host logger bridge. */
|
|
72
|
-
declare class Logger extends Logger_base {
|
|
73
|
-
log(event: LoggerEvent): void;
|
|
74
|
-
log(level: LoggerLevel, message: string, data?: LoggerData): void;
|
|
75
|
-
debug(message: string, data?: LoggerData): void;
|
|
76
|
-
info(message: string, data?: LoggerData): void;
|
|
77
|
-
warn(message: string, data?: LoggerData): void;
|
|
78
|
-
error(message: string, data?: LoggerData): void;
|
|
79
|
-
}
|
|
80
|
-
/** The default host Logger provider. */
|
|
81
|
-
declare const LoggerLive: LayerResult<ProviderEntry<Logger, never>>;
|
|
82
|
-
/** Ordered in-memory Logger implementation for tests. */
|
|
83
|
-
declare class LoggerTest implements Service.Contract<Logger> {
|
|
84
|
-
readonly events: LoggerEvent[];
|
|
85
|
-
log(event: LoggerEvent): void;
|
|
86
|
-
log(level: LoggerLevel, message: string, data?: LoggerData): void;
|
|
87
|
-
debug(message: string, data?: LoggerData): void;
|
|
88
|
-
info(message: string, data?: LoggerData): void;
|
|
89
|
-
warn(message: string, data?: LoggerData): void;
|
|
90
|
-
error(message: string, data?: LoggerData): void;
|
|
91
|
-
clear(): void;
|
|
92
|
-
static make(): {
|
|
93
|
-
logger: LoggerTest;
|
|
94
|
-
layer: LayerResult<ProviderEntry<Logger, never>>;
|
|
95
|
-
};
|
|
96
|
-
static layer(logger?: LoggerTest): LayerResult<ProviderEntry<Logger, never>>;
|
|
97
|
-
}
|
|
98
|
-
declare const LoggerTestLayer: () => LayerResult<ProviderEntry<Logger, never>>;
|
|
99
|
-
declare const CurrentRequest_base: (abstract new () => ServiceIdentity<"CurrentRequest">) & {
|
|
100
|
-
readonly name: string;
|
|
101
|
-
readonly serviceTag: "CurrentRequest";
|
|
102
|
-
} & {
|
|
103
|
-
readonly of: Service.FactoryOf<CurrentRequest, "CurrentRequest">;
|
|
104
|
-
readonly [Symbol.asyncIterator]: (this: ServiceToken<"CurrentRequest", CurrentRequest & ServiceIdentity<"CurrentRequest">>) => AsyncGenerator<ServiceRequirement<CurrentRequest>, CurrentRequest, unknown>;
|
|
105
|
-
};
|
|
106
|
-
/** Execution-local request value carried by a normal Service provider. */
|
|
107
|
-
declare class CurrentRequest extends CurrentRequest_base {
|
|
108
|
-
readonly value: unknown;
|
|
109
|
-
readonly request: unknown;
|
|
110
|
-
constructor(value: unknown);
|
|
111
|
-
static layer(value: unknown): LayerResult<ProviderEntry<CurrentRequest, never>>;
|
|
112
|
-
}
|
|
113
|
-
declare const CurrentRequestLayer: (value: unknown) => LayerResult<ProviderEntry<CurrentRequest, never>>;
|
|
114
|
-
//#endregion
|
|
115
|
-
export { Clock, ClockLive, ClockTest, ClockTestLayer, CurrentAbortSignal, CurrentRequest, CurrentRequestLayer, Logger, LoggerData, LoggerEvent, LoggerLevel, LoggerLive, LoggerTest, LoggerTestLayer, Random, RandomLive, RandomSeeded, RandomSeededLayer };
|
|
116
|
-
//# sourceMappingURL=standard-services.d.mts.map
|
|
1
|
+
import { d as CurrentAbortSignal } from "./index-BsPr7qHf.mjs";
|
|
2
|
+
import { A as StandardSchemaV1, C as ConfigLive, D as ConfigSourceOptions, E as ConfigSourceError, O as ConfigValidationError, S as ConfigIssue, T as ConfigSource, _ as RandomSeededLayer, a as CurrentRequest, b as ConfigFromEnvOptions, c as LoggerData, d as LoggerLive, f as LoggerTest, g as RandomSeeded, h as RandomLive, i as ClockTestLayer, k as ConfigValue, l as LoggerEvent, m as Random, n as ClockLive, o as CurrentRequestLayer, p as LoggerTestLayer, r as ClockTest, s as Logger, t as Clock, u as LoggerLevel, v as Config, w as ConfigOutput, x as ConfigInput, y as ConfigError } from "./index-CITM15SE.mjs";
|
|
3
|
+
export { Clock, ClockLive, ClockTest, ClockTestLayer, Config, type ConfigError, type ConfigFromEnvOptions, type ConfigInput, type ConfigIssue, ConfigLive, type ConfigOutput, type ConfigSource, ConfigSourceError, type ConfigSourceOptions, ConfigValidationError, type ConfigValue, CurrentAbortSignal, CurrentRequest, CurrentRequestLayer, Logger, LoggerData, LoggerEvent, LoggerLevel, LoggerLive, LoggerTest, LoggerTestLayer, Random, RandomLive, RandomSeeded, RandomSeededLayer, type StandardSchemaV1 };
|