@venn-lang/contracts 0.1.0
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/LICENSE +21 -0
- package/README.md +254 -0
- package/dist/index.d.ts +620 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1342 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.mts +287 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +387 -0
- package/dist/node.mjs.map +1 -0
- package/dist/signal-source.types-BI3TYaCi.d.ts +317 -0
- package/dist/signal-source.types-BI3TYaCi.d.ts.map +1 -0
- package/dist/testing.d.ts +84 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +276 -0
- package/dist/testing.js.map +1 -0
- package/package.json +77 -0
- package/src/capabilities/host-capability.ts +18 -0
- package/src/capabilities/index.ts +2 -0
- package/src/conformance/expect-venn-error.ts +18 -0
- package/src/conformance/harness.types.ts +14 -0
- package/src/conformance/index.ts +2 -0
- package/src/dotenv/dotenv-files.ts +30 -0
- package/src/dotenv/index.ts +2 -0
- package/src/dotenv/parse-dotenv.ts +34 -0
- package/src/errors/contract-codes.ts +37 -0
- package/src/errors/index.ts +7 -0
- package/src/errors/venn-error.ts +20 -0
- package/src/host/create-host.ts +16 -0
- package/src/host/create-node-host.ts +29 -0
- package/src/host/create-test-host.ts +28 -0
- package/src/host/create-worker-host.ts +32 -0
- package/src/host/host.types.ts +26 -0
- package/src/host/index.ts +5 -0
- package/src/host/unavailable.ts +23 -0
- package/src/index.ts +10 -0
- package/src/logger/console-logger.ts +12 -0
- package/src/logger/index.ts +3 -0
- package/src/logger/logger.types.ts +18 -0
- package/src/logger/memory-logger.ts +12 -0
- package/src/node.ts +8 -0
- package/src/port/assert-capabilities.ts +18 -0
- package/src/port/assert-port-shape.ts +18 -0
- package/src/port/bind-port.ts +28 -0
- package/src/port/index.ts +5 -0
- package/src/port/missing-capabilities.ts +14 -0
- package/src/port/port.types.ts +36 -0
- package/src/ports/clock/clock.port.ts +15 -0
- package/src/ports/clock/clock.types.ts +17 -0
- package/src/ports/clock/index.ts +4 -0
- package/src/ports/clock/system-clock.ts +9 -0
- package/src/ports/clock/virtual-clock.ts +22 -0
- package/src/ports/console/console.port.ts +13 -0
- package/src/ports/console/console.types.ts +17 -0
- package/src/ports/console/index.ts +3 -0
- package/src/ports/console/memory-console.ts +36 -0
- package/src/ports/console/node-console.ts +80 -0
- package/src/ports/file-system/file-system.errors.ts +10 -0
- package/src/ports/file-system/file-system.port.ts +12 -0
- package/src/ports/file-system/file-system.types.ts +27 -0
- package/src/ports/file-system/index.ts +6 -0
- package/src/ports/file-system/memory-fs.ts +46 -0
- package/src/ports/file-system/node-fs.ts +93 -0
- package/src/ports/index.ts +9 -0
- package/src/ports/lock-provider/fake-lock.ts +6 -0
- package/src/ports/lock-provider/in-process-lock.ts +26 -0
- package/src/ports/lock-provider/index.ts +4 -0
- package/src/ports/lock-provider/lock-provider.port.ts +16 -0
- package/src/ports/lock-provider/lock-provider.types.ts +8 -0
- package/src/ports/manifest-provider/default-manifest.ts +31 -0
- package/src/ports/manifest-provider/edit/edit-dependency.ts +82 -0
- package/src/ports/manifest-provider/edit/index.ts +7 -0
- package/src/ports/manifest-provider/edit/table-span.ts +39 -0
- package/src/ports/manifest-provider/index.ts +31 -0
- package/src/ports/manifest-provider/manifest.port.ts +16 -0
- package/src/ports/manifest-provider/manifest.types.ts +54 -0
- package/src/ports/manifest-provider/memory-manifest.ts +14 -0
- package/src/ports/manifest-provider/project.types.ts +94 -0
- package/src/ports/manifest-provider/read/index.ts +15 -0
- package/src/ports/manifest-provider/read/read-dependencies.ts +27 -0
- package/src/ports/manifest-provider/read/read-package.ts +32 -0
- package/src/ports/manifest-provider/read/read-profiles.ts +32 -0
- package/src/ports/manifest-provider/read/read-targets.ts +37 -0
- package/src/ports/manifest-provider/read/read-tooling.ts +15 -0
- package/src/ports/manifest-provider/read/read-workspace.ts +22 -0
- package/src/ports/manifest-provider/read/scalars.ts +35 -0
- package/src/ports/manifest-provider/read-run-settings.ts +38 -0
- package/src/ports/manifest-provider/resolve-alias.ts +22 -0
- package/src/ports/manifest-provider/toml/index.ts +3 -0
- package/src/ports/manifest-provider/toml/parse-toml.ts +52 -0
- package/src/ports/manifest-provider/toml/read-value.ts +104 -0
- package/src/ports/manifest-provider/toml/sections.ts +39 -0
- package/src/ports/manifest-provider/toml-docs.ts +27 -0
- package/src/ports/manifest-provider/toml-manifest.ts +41 -0
- package/src/ports/process-provider/fake-process.ts +32 -0
- package/src/ports/process-provider/index.ts +10 -0
- package/src/ports/process-provider/node-spawn.ts +52 -0
- package/src/ports/process-provider/process-provider.port.ts +13 -0
- package/src/ports/process-provider/process-provider.types.ts +47 -0
- package/src/ports/random/fixed-random.ts +10 -0
- package/src/ports/random/index.ts +4 -0
- package/src/ports/random/random.port.ts +13 -0
- package/src/ports/random/random.types.ts +10 -0
- package/src/ports/random/seeded-random.ts +19 -0
- package/src/ports/secret-provider/env-secrets.ts +19 -0
- package/src/ports/secret-provider/index.ts +6 -0
- package/src/ports/secret-provider/memory-secrets.ts +15 -0
- package/src/ports/secret-provider/secret-provider.port.ts +13 -0
- package/src/ports/secret-provider/secret-provider.types.ts +17 -0
- package/src/ports/secret-provider/secret.ts +17 -0
- package/src/ports/signal-source/fake-signals.ts +44 -0
- package/src/ports/signal-source/index.ts +11 -0
- package/src/ports/signal-source/node-signals.ts +33 -0
- package/src/ports/signal-source/signal-source.port.ts +13 -0
- package/src/ports/signal-source/signal-source.types.ts +24 -0
- package/src/testing.ts +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/capabilities/host-capability.ts","../src/dotenv/dotenv-files.ts","../src/dotenv/parse-dotenv.ts","../src/errors/venn-error.ts","../src/errors/contract-codes.ts","../src/logger/console-logger.ts","../src/logger/memory-logger.ts","../src/ports/clock/clock.port.ts","../src/ports/clock/system-clock.ts","../src/ports/clock/virtual-clock.ts","../src/ports/file-system/file-system.errors.ts","../src/ports/file-system/file-system.port.ts","../src/ports/file-system/memory-fs.ts","../src/ports/lock-provider/fake-lock.ts","../src/ports/lock-provider/in-process-lock.ts","../src/ports/lock-provider/lock-provider.port.ts","../src/ports/process-provider/fake-process.ts","../src/ports/process-provider/process-provider.port.ts","../src/ports/random/fixed-random.ts","../src/ports/random/random.port.ts","../src/ports/random/seeded-random.ts","../src/ports/secret-provider/secret.ts","../src/ports/secret-provider/env-secrets.ts","../src/ports/secret-provider/memory-secrets.ts","../src/ports/secret-provider/secret-provider.port.ts","../src/host/create-test-host.ts","../src/host/unavailable.ts","../src/host/create-worker-host.ts","../src/host/create-host.ts","../src/port/missing-capabilities.ts","../src/port/assert-capabilities.ts","../src/port/assert-port-shape.ts","../src/port/bind-port.ts","../src/ports/console/console.port.ts","../src/ports/console/memory-console.ts","../src/ports/manifest-provider/read/scalars.ts","../src/ports/manifest-provider/read/read-dependencies.ts","../src/ports/manifest-provider/read/read-package.ts","../src/ports/manifest-provider/read/read-profiles.ts","../src/ports/manifest-provider/read/read-targets.ts","../src/ports/manifest-provider/read/read-tooling.ts","../src/ports/manifest-provider/read/read-workspace.ts","../src/ports/manifest-provider/default-manifest.ts","../src/ports/manifest-provider/edit/table-span.ts","../src/ports/manifest-provider/edit/edit-dependency.ts","../src/ports/manifest-provider/manifest.port.ts","../src/ports/manifest-provider/memory-manifest.ts","../src/ports/manifest-provider/resolve-alias.ts","../src/ports/manifest-provider/toml/read-value.ts","../src/ports/manifest-provider/toml/sections.ts","../src/ports/manifest-provider/toml/parse-toml.ts","../src/ports/manifest-provider/toml-docs.ts","../src/ports/manifest-provider/read-run-settings.ts","../src/ports/manifest-provider/toml-manifest.ts","../src/ports/signal-source/fake-signals.ts","../src/ports/signal-source/signal-source.port.ts","../src/ports/signal-source/signal-source.types.ts"],"sourcesContent":["/**\n * Every capability a Host may expose. A port or plugin declares which it\n * requires, a host advertises which it provides, and negotiation compares the\n * two before anything binds.\n */\nexport const ALL_CAPABILITIES = [\n \"fs\",\n \"process\",\n \"net\",\n \"clock\",\n \"random\",\n \"secrets\",\n \"log\",\n \"io\",\n] as const;\n\n/** One capability name, drawn from {@link ALL_CAPABILITIES}. */\nexport type HostCapability = (typeof ALL_CAPABILITIES)[number];\n","// biome-ignore-all lint/suspicious/noTemplateCurlyInString: ${name} is a placeholder in a path, not a JavaScript template.\n\n/**\n * The dotenv files read when `venn.toml` does not name its own.\n *\n * The order is the precedence, lowest first: what everyone shares, then what\n * this environment adds, then what this machine keeps to itself. The `.local`\n * ones are what a `.gitignore` is for.\n */\nexport const DOTENV_CONVENTION: readonly string[] = [\n \".env\",\n \".env.${name}\",\n \".env.local\",\n \".env.${name}.local\",\n];\n\n/**\n * Which files to read, in order, for one environment.\n *\n * The runner and the editor both ask this, so they cannot disagree about where\n * a value lives.\n *\n * @param args.configured - `[env] files` from `venn.toml`. Empty or absent\n * falls back to {@link DOTENV_CONVENTION}.\n * @param args.name - the selected environment, substituted for `${name}`.\n */\nexport function dotenvFiles(args: { configured?: readonly string[]; name: string }): string[] {\n const names = args.configured?.length ? args.configured : DOTENV_CONVENTION;\n return names.map((each) => each.replaceAll(\"${name}\", args.name));\n}\n","/**\n * Read a `.env` file: `NAME=value`, one per line.\n *\n * Deliberately small. It understands comments, blank lines, an `export `\n * prefix, and quotes around a value that needs them. No variable expansion:\n * `${OTHER}` is left alone, because Venn already interpolates in its own\n * strings and two syntaxes for one idea is how people get surprised.\n *\n * @returns every name found, later lines winning over earlier ones.\n */\nexport function parseDotenv(content: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const line of content.split(/\\r?\\n/)) {\n const entry = readLine(line);\n if (entry) out[entry.name] = entry.value;\n }\n return out;\n}\n\nconst LINE = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*)$/;\n\nfunction readLine(line: string): { name: string; value: string } | undefined {\n if (/^\\s*(#|$)/.test(line)) return undefined;\n const match = LINE.exec(line);\n if (!match?.[1]) return undefined;\n return { name: match[1], value: unquote((match[2] ?? \"\").trim()) };\n}\n\n/** A quoted value keeps its spaces and its `#`; an unquoted one stops at a comment. */\nfunction unquote(raw: string): string {\n const quoted = /^(['\"])([\\s\\S]*)\\1$/.exec(raw);\n if (quoted) return quoted[2] as string;\n return (raw.split(\" #\")[0] ?? \"\").trim();\n}\n","/** Structured, serializable, redaction-safe detail attached to a {@link VennError}. */\nexport type VennErrorDetail = Readonly<Record<string, unknown>>;\n\n/**\n * The single error type that crosses a contracts boundary.\n *\n * Every failure carries a stable `VNxxxx` code, so conformance suites assert on\n * `.code` and never on prose. Messages stay free to improve.\n */\nexport class VennError extends Error {\n readonly code: string;\n readonly detail: VennErrorDetail | undefined;\n\n constructor(args: { code: string; message: string; detail?: VennErrorDetail }) {\n super(args.message);\n this.name = \"VennError\";\n this.code = args.code;\n this.detail = args.detail;\n }\n}\n","import type { HostCapability } from \"../capabilities/index.js\";\nimport { VennError } from \"./venn-error.js\";\n\n/** VN2010: a port requires capabilities the host does not provide. */\nexport function hostMissingCapability(args: {\n portId: string;\n missing: readonly HostCapability[];\n present: readonly HostCapability[];\n}): VennError {\n const message =\n `Port \"${args.portId}\" requires capability ${quote(args.missing)}, ` +\n `which this host does not provide. Present: ${list(args.present)}.`;\n return new VennError({ code: \"VN2010\", message, detail: { ...args } });\n}\n\n/** VN2011: an implementation is missing one or more methods the port declares. */\nexport function portShapeMismatch(args: { portId: string; missing: readonly string[] }): VennError {\n const message = `Implementation of \"${args.portId}\" is missing method(s): ${args.missing.join(\", \")}.`;\n return new VennError({ code: \"VN2011\", message, detail: { ...args } });\n}\n\n/** VN2012: code reached a capability the host declared unavailable. */\nexport function capabilityUnavailable(args: {\n capability: HostCapability;\n method: string;\n}): VennError {\n const message = `Capability \"${args.capability}\" is not available on this host (called \"${args.method}\").`;\n return new VennError({ code: \"VN2012\", message, detail: { ...args } });\n}\n\nfunction quote(caps: readonly string[]): string {\n return caps.map((c) => `\"${c}\"`).join(\", \");\n}\n\nfunction list(caps: readonly string[]): string {\n return caps.length === 0 ? \"(none)\" : caps.join(\", \");\n}\n","import type { Logger } from \"./logger.types.js\";\n\n/** Logger backed by the global console, so it works in a Worker and in Node. */\nexport function createConsoleLogger(): Logger {\n return {\n log(entry) {\n const line = `[${entry.level}] ${entry.message}`;\n if (entry.level === \"error\") console.error(line);\n else console.log(line);\n },\n };\n}\n","import type { LogEntry, MemoryLogger } from \"./logger.types.js\";\n\n/** The double: keeps every entry in `entries` instead of printing it. */\nexport function createMemoryLogger(): MemoryLogger {\n const entries: LogEntry[] = [];\n return {\n entries,\n log(entry) {\n entries.push(entry);\n },\n };\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { Clock } from \"./clock.types.js\";\n\n/**\n * The {@link Clock} contract. Implementations: `system-clock`, `virtual-clock`.\n *\n * `advance` and `setTime` are absent on purpose: they are how a test drives a\n * virtual clock, not something a caller of the port may reach for.\n */\nexport const ClockPort: Port<Clock> = {\n id: \"venn.port.clock\",\n version: 1,\n requires: [\"clock\"],\n methods: [\"now\", \"sleep\"],\n};\n","import type { Clock } from \"./clock.types.js\";\n\n/** Wall-clock time, on the `Date` and `setTimeout` globals. */\nexport function createSystemClock(): Clock {\n return {\n now: () => Date.now(),\n sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n };\n}\n","import type { VirtualClock } from \"./clock.types.js\";\n\n/**\n * The double. `sleep` advances internal time and resolves at once, so a test\n * about a timeout costs nothing to run.\n *\n * @param args.start - the epoch this clock begins at. Defaults to 0.\n */\nexport function createVirtualClock(args: { start?: number } = {}): VirtualClock {\n let time = args.start ?? 0;\n const advance = (ms: number): void => {\n time += Math.max(0, ms);\n };\n return {\n now: () => time,\n sleep: async (ms) => advance(ms),\n advance,\n setTime: (epochMs) => {\n time = epochMs;\n },\n };\n}\n","import { VennError } from \"../../errors/index.js\";\n\n/** VN8010: a read or a remove targeted a path that does not exist. */\nexport function fsNotFound(args: { path: string }): VennError {\n return new VennError({\n code: \"VN8010\",\n message: `File not found: \"${args.path}\".`,\n detail: { path: args.path },\n });\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { FileSystem } from \"./file-system.types.js\";\n\n/**\n * The {@link FileSystem} contract. Implementations: `node-fs`, `memory-fs`.\n */\nexport const FileSystemPort: Port<FileSystem> = {\n id: \"venn.port.filesystem\",\n version: 1,\n requires: [\"fs\"],\n methods: [\"read\", \"write\", \"exists\", \"remove\", \"list\"],\n};\n","import { fsNotFound } from \"./file-system.errors.js\";\nimport type { DirEntry, FileSystem } from \"./file-system.types.js\";\n\n/** The double: byte-exact, isolated per instance, no disk. */\nexport function createMemoryFs(): FileSystem {\n const files = new Map<string, Uint8Array>();\n return {\n async read(path) {\n const bytes = files.get(path);\n if (!bytes) throw fsNotFound({ path });\n return bytes.slice();\n },\n async write(path, bytes) {\n files.set(path, bytes.slice());\n },\n async exists(path) {\n return files.has(path);\n },\n async remove(path) {\n if (!files.delete(path)) throw fsNotFound({ path });\n },\n async list(path) {\n return listUnder([...files.keys()], path);\n },\n };\n}\n\n/**\n * What a directory holds, worked out from the paths written.\n *\n * There are no directories here, only paths, so a directory is whatever a path\n * implies one to be. For everything the language does with a directory that is\n * the same answer the real file system gives, which is what lets the TCK ask\n * both the same questions.\n */\nfunction listUnder(paths: readonly string[], directory: string): DirEntry[] {\n const prefix = directory === \"\" || directory === \".\" ? \"\" : `${directory.replace(/\\/+$/, \"\")}/`;\n const seen = new Map<string, boolean>();\n for (const path of paths) {\n if (!path.startsWith(prefix)) continue;\n const rest = path.slice(prefix.length);\n const slash = rest.indexOf(\"/\");\n if (rest !== \"\") seen.set(slash < 0 ? rest : rest.slice(0, slash), slash >= 0);\n }\n return [...seen].map(([name, isDirectory]) => ({ name, directory: isDirectory }));\n}\n","import type { LockProvider } from \"./lock-provider.types.js\";\n\n/** The double: grants immediately and serialises nothing. */\nexport function createFakeLock(): LockProvider {\n return { acquire: async () => () => {} };\n}\n","import type { LockProvider, Release } from \"./lock-provider.types.js\";\n\n/**\n * The real one: a chained-promise mutex per name. Waiters are served in the\n * order they asked, and the chain lives only in this process.\n */\nexport function createInProcessLock(): LockProvider {\n const tails = new Map<string, Promise<void>>();\n return {\n acquire: (name) => acquire(tails, name),\n };\n}\n\nasync function acquire(tails: Map<string, Promise<void>>, name: string): Promise<Release> {\n const previous = tails.get(name) ?? Promise.resolve();\n let release: Release = () => {};\n const held = new Promise<void>((resolve) => {\n release = resolve;\n });\n tails.set(\n name,\n previous.then(() => held),\n );\n await previous;\n return release;\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { LockProvider } from \"./lock-provider.types.js\";\n\n/**\n * The {@link LockProvider} contract. Implementations: `in-process-lock`,\n * `fake-lock`.\n *\n * Requires nothing: a mutex is bookkeeping, so it binds even on a host with no\n * capabilities at all.\n */\nexport const LockProviderPort: Port<LockProvider> = {\n id: \"venn.port.lock\",\n version: 1,\n requires: [],\n methods: [\"acquire\"],\n};\n","import type { ProcessHandle, ProcessProvider } from \"./process-provider.types.js\";\n\n/**\n * The double: a scripted process that never touches the OS.\n *\n * Output is streamed before the wait resolves, exactly as the real one does it,\n * so a caller that shows progress is exercised here and not only against a real\n * machine.\n *\n * @param args.exitCode - what every run reports. Defaults to 0.\n * @param args.output - what every run writes. Defaults to nothing.\n */\nexport function createFakeProcess(\n args: { exitCode?: number; output?: string } = {},\n): ProcessProvider {\n const code = args.exitCode ?? 0;\n const output = args.output ?? \"\";\n return {\n spawn: (spawned) => {\n if (output !== \"\") spawned.onOutput?.(output);\n return handle(code, output);\n },\n };\n}\n\nfunction handle(code: number, output: string): ProcessHandle {\n return {\n pid: 0,\n wait: async () => ({ code, output }),\n kill: () => {},\n };\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { ProcessProvider } from \"./process-provider.types.js\";\n\n/**\n * The {@link ProcessProvider} contract. Implementations: `node-spawn`,\n * `fake-process`.\n */\nexport const ProcessProviderPort: Port<ProcessProvider> = {\n id: \"venn.port.process\",\n version: 1,\n requires: [\"process\"],\n methods: [\"spawn\"],\n};\n","import type { Random } from \"./random.types.js\";\n\n/** The double: always the same value, and always `min` from `int`. */\nexport function createFixedRandom(args: { value?: number } = {}): Random {\n const value = args.value ?? 0;\n return {\n next: () => value,\n int: (min) => min,\n };\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { Random } from \"./random.types.js\";\n\n/**\n * The {@link Random} contract. Implementations: `seeded-random`,\n * `fixed-random`.\n */\nexport const RandomPort: Port<Random> = {\n id: \"venn.port.random\",\n version: 1,\n requires: [\"random\"],\n methods: [\"next\", \"int\"],\n};\n","import type { Random } from \"./random.types.js\";\n\n/**\n * The real one: a mulberry32 PRNG, seeded once per worker. Same seed, same\n * sequence, so a run reproduces.\n */\nexport function createSeededRandom(args: { seed: number }): Random {\n let state = args.seed >>> 0;\n const next = (): number => {\n state = (state + 0x6d2b79f5) | 0;\n let t = Math.imul(state ^ (state >>> 15), 1 | state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n return {\n next,\n int: (min, max) => min + Math.floor(next() * (max - min + 1)),\n };\n}\n","import type { Secret } from \"./secret-provider.types.js\";\n\n/** What every serialised secret collapses to. */\nexport const REDACTED = \"‹redigido›\";\n\n/**\n * Wrap a raw value so it cannot leak through `toString` or `toJSON`.\n *\n * @param args.reveal - the raw value, reachable only via `Secret.reveal()`.\n */\nexport function makeSecret(args: { reveal: string }): Secret {\n return {\n reveal: () => args.reveal,\n toString: () => REDACTED,\n toJSON: () => REDACTED,\n };\n}\n","import { makeSecret } from \"./secret.js\";\nimport type { SecretProvider } from \"./secret-provider.types.js\";\n\n/**\n * The real one: secrets from `process.env`.\n *\n * The `process` global is probed rather than imported, so this file stays\n * neutral and reports every name as absent in a Worker instead of throwing.\n */\nexport function createEnvSecrets(): SecretProvider {\n const env: Record<string, string | undefined> = typeof process === \"undefined\" ? {} : process.env;\n return {\n get: (name) => {\n const value = env[name];\n return value === undefined ? undefined : makeSecret({ reveal: value });\n },\n has: (name) => env[name] !== undefined,\n };\n}\n","import { makeSecret } from \"./secret.js\";\nimport type { SecretProvider } from \"./secret-provider.types.js\";\n\n/**\n * The double: secrets given by name, wrapped so they still redact.\n *\n * @param args.values - the raw values, keyed by secret name.\n */\nexport function createMemorySecrets(args: { values: Record<string, string> }): SecretProvider {\n const values = args.values;\n return {\n get: (name) => (name in values ? makeSecret({ reveal: values[name] as string }) : undefined),\n has: (name) => name in values,\n };\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { SecretProvider } from \"./secret-provider.types.js\";\n\n/**\n * The {@link SecretProvider} contract. Implementations: `env-secrets`,\n * `memory-secrets`.\n */\nexport const SecretProviderPort: Port<SecretProvider> = {\n id: \"venn.port.secrets\",\n version: 1,\n requires: [\"secrets\"],\n methods: [\"get\", \"has\"],\n};\n","import { ALL_CAPABILITIES } from \"../capabilities/index.js\";\nimport { createMemoryLogger } from \"../logger/index.js\";\nimport { createVirtualClock } from \"../ports/clock/index.js\";\nimport { createMemoryFs } from \"../ports/file-system/index.js\";\nimport { createInProcessLock } from \"../ports/lock-provider/index.js\";\nimport { createFakeProcess } from \"../ports/process-provider/index.js\";\nimport { createSeededRandom } from \"../ports/random/index.js\";\nimport { createMemorySecrets } from \"../ports/secret-provider/index.js\";\nimport type { Host } from \"./host.types.js\";\n\n/**\n * A host of doubles, every capability granted. The default for tests.\n *\n * @param overrides - replaces individual members, e.g. a real clock.\n */\nexport function createTestHost(overrides: Partial<Host> = {}): Host {\n return {\n fs: createMemoryFs(),\n proc: createFakeProcess(),\n clock: createVirtualClock(),\n random: createSeededRandom({ seed: 1 }),\n secrets: createMemorySecrets({ values: {} }),\n log: createMemoryLogger(),\n lock: createInProcessLock(),\n caps: ALL_CAPABILITIES,\n ...overrides,\n };\n}\n","import type { HostCapability } from \"../capabilities/index.js\";\nimport { capabilityUnavailable } from \"../errors/index.js\";\n\n/**\n * A stand-in for a port the host cannot provide, such as `process` in a Worker.\n *\n * @param args.capability - the capability the host lacks, named in the error.\n * @param args.methods - the port's declared methods, usually `SomePort.methods`.\n * @returns an object shaped like `T` whose every method throws VN2012 when\n * called, rather than failing as a `TypeError` mid-run.\n */\nexport function unavailable<T>(args: {\n capability: HostCapability;\n methods: readonly string[];\n}): T {\n const bag: Record<string, unknown> = {};\n for (const method of args.methods) {\n bag[method] = () => {\n throw capabilityUnavailable({ capability: args.capability, method });\n };\n }\n return bag as T;\n}\n","import { createMemoryLogger } from \"../logger/index.js\";\nimport { createSystemClock } from \"../ports/clock/index.js\";\nimport { createMemoryFs } from \"../ports/file-system/index.js\";\nimport { createInProcessLock } from \"../ports/lock-provider/index.js\";\nimport type { ProcessProvider } from \"../ports/process-provider/index.js\";\nimport { ProcessProviderPort } from \"../ports/process-provider/index.js\";\nimport { createSeededRandom } from \"../ports/random/index.js\";\nimport { createMemorySecrets } from \"../ports/secret-provider/index.js\";\nimport type { Host } from \"./host.types.js\";\nimport { unavailable } from \"./unavailable.js\";\n\n/**\n * Host for a Web Worker: an in-memory file system, no `process`, no `net`.\n *\n * `proc` is a stand-in whose every method throws VN2012, so reaching for a\n * subprocess in the editor fails with a diagnostic instead of a `TypeError`.\n */\nexport function createWorkerHost(): Host {\n return {\n fs: createMemoryFs(),\n proc: unavailable<ProcessProvider>({\n capability: \"process\",\n methods: ProcessProviderPort.methods,\n }),\n clock: createSystemClock(),\n random: createSeededRandom({ seed: 1 }),\n secrets: createMemorySecrets({ values: {} }),\n log: createMemoryLogger(),\n lock: createInProcessLock(),\n caps: [\"fs\", \"clock\", \"random\", \"secrets\", \"log\"],\n };\n}\n","import { createTestHost } from \"./create-test-host.js\";\nimport { createWorkerHost } from \"./create-worker-host.js\";\n\n/**\n * The neutral host assemblers.\n *\n * `node` is deliberately absent: it pulls `node:*`, so it lives behind\n * `@venn-lang/contracts/node` as `createNodeHost` and this entry stays Worker-safe.\n */\nexport const createHost: {\n readonly worker: typeof createWorkerHost;\n readonly test: typeof createTestHost;\n} = {\n worker: createWorkerHost,\n test: createTestHost,\n};\n","import type { HostCapability } from \"../capabilities/index.js\";\n\n/**\n * The gap between what is required and what the host offers.\n *\n * @returns the required capabilities absent from `caps`, in the order required.\n */\nexport function missingCapabilities(args: {\n requires: readonly HostCapability[];\n caps: readonly HostCapability[];\n}): readonly HostCapability[] {\n const present = new Set(args.caps);\n return args.requires.filter((cap) => !present.has(cap));\n}\n","import type { HostCapability } from \"../capabilities/index.js\";\nimport { hostMissingCapability } from \"../errors/index.js\";\nimport { missingCapabilities } from \"./missing-capabilities.js\";\nimport type { Port } from \"./port.types.js\";\n\n/**\n * Checks the host against what the port requires.\n *\n * @throws VennError VN2010 when a required capability is absent.\n */\nexport function assertCapabilities<T>(args: {\n port: Port<T>;\n caps: readonly HostCapability[];\n}): void {\n const missing = missingCapabilities({ requires: args.port.requires, caps: args.caps });\n if (missing.length === 0) return;\n throw hostMissingCapability({ portId: args.port.id, missing, present: args.caps });\n}\n","import { portShapeMismatch } from \"../errors/index.js\";\nimport type { Port } from \"./port.types.js\";\n\n/**\n * Checks the implementation against the methods the port declares.\n *\n * @throws VennError VN2011 when a declared method is missing or is not callable.\n */\nexport function assertPortShape<T>(args: { port: Port<T>; impl: unknown }): void {\n const missing = missingMethods(args.port, args.impl);\n if (missing.length === 0) return;\n throw portShapeMismatch({ portId: args.port.id, missing });\n}\n\nfunction missingMethods<T>(port: Port<T>, impl: unknown): readonly string[] {\n const bag = impl as Record<string, unknown> | null | undefined;\n return port.methods.filter((m) => typeof bag?.[m] !== \"function\");\n}\n","import type { HostCapability } from \"../capabilities/index.js\";\nimport { assertCapabilities } from \"./assert-capabilities.js\";\nimport { assertPortShape } from \"./assert-port-shape.js\";\nimport type { Port } from \"./port.types.js\";\n\n/**\n * The single loader entry. Negotiates capabilities, checks the implementation's\n * shape, then hands it back typed as `T`.\n *\n * Both checks run before anything is bound, so a mismatch is reported at start\n * up rather than as a `TypeError` in the middle of a test.\n *\n * @param args.port - the descriptor to bind against.\n * @param args.impl - the candidate implementation, untrusted.\n * @param args.caps - the capabilities the host advertises.\n * @returns `args.impl` typed as `T`.\n * @throws VennError VN2010 when the host lacks a required capability, VN2011\n * when the implementation is missing a declared method.\n */\nexport function bindPort<T>(args: {\n port: Port<T>;\n impl: unknown;\n caps: readonly HostCapability[];\n}): T {\n assertCapabilities({ port: args.port, caps: args.caps });\n assertPortShape({ port: args.port, impl: args.impl });\n return args.impl as T;\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { Console } from \"./console.types.js\";\n\n/**\n * The {@link Console} contract. Implementations: `node-console`,\n * `memory-console`.\n */\nexport const ConsolePort: Port<Console> = {\n id: \"venn.port.console\",\n version: 1,\n requires: [\"io\"],\n methods: [\"write\", \"writeError\", \"readLine\", \"args\"],\n};\n","import type { Console } from \"./console.types.js\";\n\n/** A {@link Console} that keeps its transcript instead of printing it. */\nexport interface MemoryConsole extends Console {\n readonly out: string;\n readonly err: string;\n}\n\n/**\n * The double: records what was written, reads from a scripted input.\n *\n * @param args.input - the lines `readLine` hands back, in order.\n * @param args.argv - what `args()` reports.\n */\nexport function createMemoryConsole(\n args: { input?: readonly string[]; argv?: readonly string[] } = {},\n): MemoryConsole {\n const state = { out: \"\", err: \"\" };\n const input = [...(args.input ?? [])];\n return {\n write: (text) => {\n state.out += text;\n },\n writeError: (text) => {\n state.err += text;\n },\n readLine: () => Promise.resolve(input.length > 0 ? (input.shift() ?? null) : null),\n args: () => args.argv ?? [],\n get out() {\n return state.out;\n },\n get err() {\n return state.err;\n },\n };\n}\n","// Reading a parsed TOML value as the shape the manifest expects. None of these\n// throw: a malformed table reads as an empty one, so one bad line never stops a\n// project from opening.\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null ? (value as Record<string, unknown>) : {};\n}\n\nexport function asStringMap(value: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, item] of Object.entries(asRecord(value))) out[key] = String(item);\n return out;\n}\n\nexport function asList(value: unknown): readonly string[] {\n return Array.isArray(value) ? value.map(String) : [];\n}\n\nexport function asRecords(value: unknown): readonly Record<string, unknown>[] {\n return Array.isArray(value) ? value.map(asRecord) : [];\n}\n\nexport function asString(value: unknown): string | undefined {\n return value === undefined || value === null ? undefined : String(value);\n}\n\nexport function asNumber(value: unknown): number | undefined {\n const parsed = Number(value);\n return value === undefined || Number.isNaN(parsed) ? undefined : parsed;\n}\n\nexport function asBoolean(value: unknown): boolean | undefined {\n if (value === undefined) return undefined;\n return value === true || value === \"true\";\n}\n","import type { Dependency } from \"../project.types.js\";\nimport { asBoolean, asRecord, asString } from \"./scalars.js\";\n\n/**\n * A dependency table, in either spelling TOML allows.\n *\n * `zod = \"^4\"` and `zod = { version = \"^4\", optional = true }` say the same\n * thing about the version, so both read into one shape rather than two the rest\n * of the code would have to keep apart.\n */\nexport function readDependencies(value: unknown): Dependency[] {\n return Object.entries(asRecord(value)).map(([name, spec]) => readOne(name, spec));\n}\n\nfunction readOne(name: string, spec: unknown): Dependency {\n if (typeof spec === \"string\") {\n return { name, version: spec, fromWorkspace: false, optional: false };\n }\n const table = asRecord(spec);\n return {\n name,\n version: asString(table.version),\n path: asString(table.path),\n fromWorkspace: asBoolean(table.workspace) ?? false,\n optional: asBoolean(table.optional) ?? false,\n };\n}\n","import type { PackageInfo } from \"../project.types.js\";\nimport { asList, asRecord, asString } from \"./scalars.js\";\n\n/** `[package]`: who this is. A missing table reads as a nameless package. */\nexport function readPackage(data: Record<string, unknown>): PackageInfo {\n const table = asRecord(data.package);\n return {\n name: String(table.name ?? \"\"),\n version: asString(table.version),\n description: asString(table.description),\n license: asString(table.license),\n authors: asList(table.authors),\n edition: asString(table.edition),\n };\n}\n\n/**\n * The same table, reduced to what a member may inherit from its workspace.\n *\n * A name is never inherited, being the one thing that must differ between two\n * members, so `[workspace.package]` carrying one is read as carrying none.\n */\nexport function readInheritable(data: Record<string, unknown>): Partial<PackageInfo> {\n const table = asRecord(data);\n const found: Partial<PackageInfo> = {};\n for (const key of [\"version\", \"description\", \"license\", \"edition\"] as const) {\n const value = asString(table[key]);\n if (value !== undefined) found[key] = value;\n }\n const authors = asList(table.authors);\n return authors.length > 0 ? { ...found, authors } : found;\n}\n","import type { Profile } from \"../project.types.js\";\nimport { asBoolean, asRecord } from \"./scalars.js\";\n\n/**\n * What each build is for, and what that costs.\n *\n * `dev` reports what it finds and carries on, because a project being worked on\n * is half-written most of the time. `release` refuses to build over a problem.\n * Neither has to be written in a manifest for the defaults to apply.\n */\nexport const DEFAULT_PROFILES: Readonly<Record<string, Profile>> = {\n dev: { strict: false },\n release: { strict: true },\n};\n\n/** `[profile.<name>]`, merged over {@link DEFAULT_PROFILES}. */\nexport function readProfiles(data: Record<string, unknown>): Record<string, Profile> {\n const out: Record<string, Profile> = { ...DEFAULT_PROFILES };\n for (const [name, table] of Object.entries(asRecord(data.profile))) {\n out[name] = { ...out[name], ...readProfile(asRecord(table)) };\n }\n return out;\n}\n\nfunction readProfile(table: Record<string, unknown>): Profile {\n const found: Profile = {};\n for (const key of [\"strict\"] as const) {\n const value = asBoolean(table[key]);\n if (value !== undefined) found[key] = value;\n }\n return found;\n}\n","import type { BuildTarget } from \"../project.types.js\";\nimport { asRecord, asRecords, asString } from \"./scalars.js\";\n\n/** Where a `lib` target starts when the manifest does not say. */\nexport const LIB_ROOT = \"src/lib.vn\";\n/** Where the default `bin` target starts when the manifest does not say. */\nexport const MAIN_ROOT = \"src/main.vn\";\n/** Where additional `bin` targets are looked for by convention. */\nexport const BIN_DIR = \"src/bin\";\n\n/**\n * `[lib]` and `[[bin]]`: what this package builds.\n *\n * Only what the manifest *declares*. The conventional roots are filled in by\n * whoever can look at the disk, because a convention is a claim about files\n * existing and this reader is pure. A manifest declaring nothing is the common\n * case, not an empty one.\n */\nexport function readTargets(data: Record<string, unknown>, packageName: string): BuildTarget[] {\n const found: BuildTarget[] = [];\n if (data.lib !== undefined) found.push(readLib(asRecord(data.lib), packageName));\n for (const entry of asRecords(data.bin)) found.push(readBin(entry, packageName));\n return found;\n}\n\nfunction readLib(table: Record<string, unknown>, packageName: string): BuildTarget {\n return {\n kind: \"lib\",\n name: asString(table.name) ?? packageName,\n path: asString(table.path) ?? LIB_ROOT,\n };\n}\n\nfunction readBin(table: Record<string, unknown>, packageName: string): BuildTarget {\n const name = asString(table.name) ?? packageName;\n return { kind: \"bin\", name, path: asString(table.path) ?? `${BIN_DIR}/${name}.vn` };\n}\n","import type { PackageManagerName, ToolingSettings } from \"../project.types.js\";\nimport { asRecord, asString } from \"./scalars.js\";\n\nconst MANAGERS = new Set<string>([\"pnpm\", \"npm\", \"bun\", \"yarn\"]);\n\n/**\n * `[tooling]`: which package manager runs underneath.\n *\n * An unrecognised name falls back to pnpm rather than failing, so a manifest\n * written against a newer toolchain still opens.\n */\nexport function readTooling(data: Record<string, unknown>): ToolingSettings {\n const name = asString(asRecord(data.tooling).manager);\n return { manager: name && MANAGERS.has(name) ? (name as PackageManagerName) : \"pnpm\" };\n}\n","import type { WorkspaceSettings } from \"../project.types.js\";\nimport { readDependencies } from \"./read-dependencies.js\";\nimport { readInheritable } from \"./read-package.js\";\nimport { asList, asRecord } from \"./scalars.js\";\n\n/**\n * `[workspace]`, or undefined when the manifest is a plain package.\n *\n * A root may also be a package, so `[workspace]` and `[package]` are read\n * separately and never merged.\n */\nexport function readWorkspace(data: Record<string, unknown>): WorkspaceSettings | undefined {\n if (data.workspace === undefined) return undefined;\n const table = asRecord(data.workspace);\n return {\n members: asList(table.members),\n exclude: asList(table.exclude),\n defaultMembers: asList(table[\"default-members\"]),\n package: readInheritable(asRecord(table.package)),\n dependencies: readDependencies(table.dependencies),\n };\n}\n","import type { Manifest } from \"./manifest.types.js\";\nimport { DEFAULT_PROFILES } from \"./read/index.js\";\n\n/**\n * A manifest with nothing declared: what a project without a `venn.toml` is.\n *\n * The one place stating what a project gets for saying nothing at all, so a\n * caller who wants one field need not spell the other dozen.\n *\n * @param overrides - fields to state explicitly. `name` and `version` fall back\n * to `[package]` before falling back to the defaults.\n */\nexport function defaultManifest(overrides: Partial<Manifest> = {}): Manifest {\n const pkg = { name: \"\", authors: [], ...overrides.package };\n return {\n name: overrides.name ?? pkg.name,\n version: overrides.version ?? pkg.version ?? \"0.0.0\",\n package: pkg,\n targets: [],\n dependencies: [],\n devDependencies: [],\n patch: [],\n profiles: { ...DEFAULT_PROFILES },\n tooling: { manager: \"pnpm\" },\n env: {},\n envFiles: [],\n paths: {},\n format: {},\n ...overrides,\n };\n}\n","/** Where a table's entries live in a manifest's lines. */\nexport interface TableSpan {\n /** The line holding `[name]`. */\n header: number;\n /** First line after the header, and the line after the table's last entry. */\n from: number;\n to: number;\n}\n\n/**\n * Where a `[table]` is written, or undefined when the file has none.\n *\n * Found by reading lines rather than by re-serialising the parse tree. A\n * manifest carries its author's comments, blank lines and chosen order, and\n * rebuilding it from a tree would throw all of that away.\n */\nexport function tableSpan(lines: readonly string[], name: string): TableSpan | undefined {\n const header = lines.findIndex((line) => line.trim() === `[${name}]`);\n if (header < 0) return undefined;\n let to = header + 1;\n for (let at = header + 1; at < lines.length; at++) {\n if (lines[at]?.trimStart().startsWith(\"[\")) break;\n if (lines[at]?.trim() !== \"\") to = at + 1;\n }\n return { header, from: header + 1, to };\n}\n\n/** The key a `key = value` line writes, or undefined for a comment or a blank. */\nexport function keyOf(line: string): string | undefined {\n const text = line.trim();\n if (text === \"\" || text.startsWith(\"#\") || text.startsWith(\"[\")) return undefined;\n const equals = text.indexOf(\"=\");\n return equals < 0\n ? undefined\n : text\n .slice(0, equals)\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\");\n}\n","import { keyOf, tableSpan } from \"./table-span.js\";\n\n/** What to change, and in which table. */\nexport interface DependencyEdit {\n /** The manifest as written. */\n text: string;\n name: string;\n /** Defaults to {@link DEPENDENCIES}. Pass `\"dev-dependencies\"` for the other. */\n table?: string;\n}\n\n/** The table an edit touches unless told otherwise. */\nexport const DEPENDENCIES = \"dependencies\";\n\n/**\n * The manifest with one dependency written in, everything else untouched.\n *\n * Entries are kept in name order, so two people adding two packages produce two\n * one-line diffs rather than a conflict. A name already there is replaced where\n * it stands, because an upgrade should not move the line.\n *\n * @returns the whole manifest as text. A missing table is appended at the end.\n */\nexport function addDependency(args: DependencyEdit & { version: string }): string {\n const table = args.table ?? DEPENDENCIES;\n const lines = args.text.split(\"\\n\");\n const entry = `${args.name} = \"${args.version}\"`;\n const span = tableSpan(lines, table);\n if (!span) return appended(args.text, table, entry);\n const at = lines.findIndex((line, index) => inside(span, index) && keyOf(line) === args.name);\n if (at >= 0) return replaced(lines, at, entry);\n return replaced(lines, insertionPoint(lines, span, args.name), entry, \"insert\");\n}\n\n/**\n * The manifest without that dependency.\n *\n * @returns the text unchanged when the name is not there: absent is already the\n * wanted state.\n */\nexport function removeDependency(args: DependencyEdit): string {\n const table = args.table ?? DEPENDENCIES;\n const lines = args.text.split(\"\\n\");\n const span = tableSpan(lines, table);\n if (!span) return args.text;\n const at = lines.findIndex((line, index) => inside(span, index) && keyOf(line) === args.name);\n if (at < 0) return args.text;\n return [...lines.slice(0, at), ...lines.slice(at + 1)].join(\"\\n\");\n}\n\nfunction inside(span: { from: number; to: number }, index: number): boolean {\n return index >= span.from && index < span.to;\n}\n\n/** Where the name belongs, in order, among the entries already there. */\nfunction insertionPoint(\n lines: readonly string[],\n span: { from: number; to: number },\n name: string,\n): number {\n for (let at = span.from; at < span.to; at++) {\n const key = keyOf(lines[at] ?? \"\");\n if (key && key > name) return at;\n }\n return span.to;\n}\n\nfunction replaced(\n lines: readonly string[],\n at: number,\n entry: string,\n how: \"replace\" | \"insert\" = \"replace\",\n): string {\n const after = how === \"insert\" ? lines.slice(at) : lines.slice(at + 1);\n return [...lines.slice(0, at), entry, ...after].join(\"\\n\");\n}\n\n/** A table the manifest does not have yet, written at the end where it reads. */\nfunction appended(text: string, table: string, entry: string): string {\n const body = text.endsWith(\"\\n\") ? text : `${text}\\n`;\n return `${body}\\n[${table}]\\n${entry}\\n`;\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { ManifestProvider } from \"./manifest.types.js\";\n\n/**\n * The {@link ManifestProvider} contract. Implementations: `toml-manifest`,\n * `memory-manifest`.\n *\n * Requires nothing: reading the file is the caller's job, and what arrives here\n * is already text.\n */\nexport const ManifestProviderPort: Port<ManifestProvider> = {\n id: \"venn.port.manifest\",\n version: 1,\n requires: [],\n methods: [\"load\"],\n};\n","import { defaultManifest } from \"./default-manifest.js\";\nimport type { Manifest, ManifestProvider } from \"./manifest.types.js\";\n\n/**\n * The double: a preset manifest, with no file involved.\n *\n * Takes only what the caller cares about. The rest is what a project that\n * declared nothing would get, which is exactly what the real provider gives a\n * `venn.toml` silent on those tables.\n */\nexport function createMemoryManifest(args: { manifest: Partial<Manifest> }): ManifestProvider {\n const manifest: Manifest = defaultManifest(args.manifest);\n return { load: () => manifest };\n}\n","/** Where a `#alias/…` specifier points. */\nexport interface AliasTarget {\n /** The directory `[paths]` maps the alias to. */\n dir: string;\n /** What followed the alias, with the separating slash removed. */\n rest: string;\n}\n\n/**\n * Split a `#alias/rest` import specifier against `[paths]` from `venn.toml`.\n *\n * @returns undefined when the specifier names no configured alias, which the\n * caller reads as a relative or bare path.\n */\nexport function resolveAlias(args: {\n spec: string;\n paths: Record<string, string>;\n}): AliasTarget | undefined {\n const alias = Object.keys(args.paths).find((key) => args.spec.startsWith(`${key}/`));\n if (!alias) return undefined;\n return { dir: args.paths[alias] as string, rest: args.spec.slice(alias.length + 1) };\n}\n","/** A position in the text being read. Mutable, because reading advances it. */\nexport interface Cursor {\n readonly text: string;\n index: number;\n}\n\n/** A cursor over `text`, positioned at the start. */\nexport function cursor(text: string): Cursor {\n return { text, index: 0 };\n}\n\n/**\n * One TOML value: a string, a number, a bool, an array, or an inline table.\n *\n * Reads by walking rather than by splitting, because a comma can sit inside a\n * value: splitting turns `[\"a,b\"]` into two items and leaves\n * `{ version = \"^4\" }` as the text it was written in.\n */\nexport function readValue(cur: Cursor): unknown {\n skipSpace(cur);\n const ch = cur.text[cur.index];\n if (ch === '\"' || ch === \"'\") return readString(cur);\n if (ch === \"[\") return readArray(cur);\n if (ch === \"{\") return readInlineTable(cur);\n return readBare(cur);\n}\n\nexport function skipSpace(cur: Cursor): void {\n while (/\\s/.test(cur.text[cur.index] ?? \"\")) cur.index++;\n}\n\n/** A basic string reads escapes; a literal one, in single quotes, does not. */\nfunction readString(cur: Cursor): string {\n const quote = cur.text[cur.index];\n cur.index++;\n let out = \"\";\n while (cur.index < cur.text.length && cur.text[cur.index] !== quote) {\n if (quote === '\"' && cur.text[cur.index] === \"\\\\\") out += unescaped(cur);\n else out += cur.text[cur.index++];\n }\n cur.index++;\n return out;\n}\n\nconst ESCAPES: Record<string, string> = { n: \"\\n\", t: \"\\t\", r: \"\\r\", \"\\\\\": \"\\\\\", '\"': '\"' };\n\nfunction unescaped(cur: Cursor): string {\n const code = cur.text[cur.index + 1] ?? \"\";\n cur.index += 2;\n return ESCAPES[code] ?? code;\n}\n\nfunction readArray(cur: Cursor): unknown[] {\n cur.index++;\n const out: unknown[] = [];\n while (!atClose(cur, \"]\")) {\n out.push(readValue(cur));\n skipSeparator(cur);\n }\n cur.index++;\n return out;\n}\n\nfunction readInlineTable(cur: Cursor): Record<string, unknown> {\n cur.index++;\n const out: Record<string, unknown> = {};\n while (!atClose(cur, \"}\")) {\n const key = readKey(cur);\n if (key === undefined) break;\n out[key] = readValue(cur);\n skipSeparator(cur);\n }\n cur.index++;\n return out;\n}\n\nfunction readKey(cur: Cursor): string | undefined {\n skipSpace(cur);\n const equals = cur.text.indexOf(\"=\", cur.index);\n if (equals < 0) return undefined;\n const raw = cur.text.slice(cur.index, equals).trim();\n cur.index = equals + 1;\n return raw.replace(/^[\"']|[\"']$/g, \"\");\n}\n\nfunction atClose(cur: Cursor, close: string): boolean {\n skipSpace(cur);\n return cur.index >= cur.text.length || cur.text[cur.index] === close;\n}\n\nfunction skipSeparator(cur: Cursor): void {\n skipSpace(cur);\n if (cur.text[cur.index] === \",\") cur.index++;\n}\n\n/** Anything unquoted: `true`, `12`, `1.5`, or a word the manifest gives meaning. */\nfunction readBare(cur: Cursor): unknown {\n const start = cur.index;\n while (cur.index < cur.text.length && !\",]}\".includes(cur.text[cur.index] ?? \"\")) cur.index++;\n const raw = cur.text.slice(start, cur.index).trim();\n if (raw === \"true\" || raw === \"false\") return raw === \"true\";\n const num = Number(raw);\n return raw !== \"\" && !Number.isNaN(num) ? num : raw;\n}\n","// Opening `[a.b]` or `[[a.b]]`: working out where the keys that follow go.\n\n/** The table `[path]` names, created along the way if it is not there yet. */\nexport function enterSection(root: Record<string, unknown>, path: string): Record<string, unknown> {\n let node = root;\n for (const key of keysOf(path)) {\n node[key] ??= {};\n node = node[key] as Record<string, unknown>;\n }\n return node;\n}\n\n/**\n * `[[bin]]`: one more of something there may be several of.\n *\n * Returns the table just appended, so two `[[bin]]` sections give two bins\n * rather than one bin written twice.\n */\nexport function enterTableArray(\n root: Record<string, unknown>,\n path: string,\n): Record<string, unknown> {\n const keys = keysOf(path);\n const last = keys.pop();\n if (!last) return root;\n const parent = enterSection(root, keys.join(\".\"));\n const found = Array.isArray(parent[last]) ? (parent[last] as unknown[]) : [];\n parent[last] = found;\n const table: Record<string, unknown> = {};\n found.push(table);\n return table;\n}\n\nfunction keysOf(path: string): string[] {\n return path\n .split(\".\")\n .map((part) => part.trim().replace(/^[\"']|[\"']$/g, \"\"))\n .filter((part) => part !== \"\");\n}\n","import { cursor, readValue } from \"./read-value.js\";\nimport { enterSection, enterTableArray } from \"./sections.js\";\n\n/**\n * A TOML reader for `venn.toml`: sections, nested `[a.b]`, arrays of tables\n * (`[[bin]]`), `key = value`, strings, numbers, bools, arrays and inline tables.\n *\n * Not a full TOML parser. No dates, no multi-line strings, no dotted keys.\n * `venn.toml` is our own format, so the subset is a decision rather than a\n * shortfall.\n *\n * @returns the root table. Malformed lines are skipped, never thrown on.\n */\nexport function parseToml(content: string): Record<string, unknown> {\n const root: Record<string, unknown> = {};\n let section = root;\n for (const raw of content.split(/\\r?\\n/)) {\n const line = stripComment(raw).trim();\n if (line === \"\") continue;\n if (line.startsWith(\"[\")) section = openSection(root, line);\n else assign(section, line);\n }\n return root;\n}\n\n/** `[[bin]]` appends another table, `[bin]` opens the one and only. */\nfunction openSection(root: Record<string, unknown>, line: string): Record<string, unknown> {\n if (line.startsWith(\"[[\")) {\n return enterTableArray(root, line.slice(2, line.indexOf(\"]]\")));\n }\n return enterSection(root, line.slice(1, line.indexOf(\"]\")));\n}\n\nfunction stripComment(line: string): string {\n let quote: string | undefined;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === '\"' || ch === \"'\") quote = quote === ch ? undefined : (quote ?? ch);\n else if (ch === \"#\" && !quote) return line.slice(0, i);\n }\n return line;\n}\n\nfunction assign(section: Record<string, unknown>, line: string): void {\n const eq = line.indexOf(\"=\");\n if (eq < 0) return;\n const key = line\n .slice(0, eq)\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\");\n section[key] = readValue(cursor(line.slice(eq + 1)));\n}\n","const COMMENT = /^\\s*#\\s?(.*)$/;\nconst KEY = /^\\s*([A-Za-z_][\\w-]*)\\s*=/;\n\n/**\n * The comment block written directly above a key, read as that key's\n * documentation. The same idea as `##` above a declaration in a `.vn`.\n *\n * A blank line breaks the block, so a comment separated from a key belongs to\n * nobody and is never attributed to the next one down.\n *\n * @returns documentation keyed by the key it sits above.\n */\nexport function tomlDocs(content: string): Record<string, string> {\n const docs: Record<string, string> = {};\n let block: string[] = [];\n for (const line of content.split(/\\r?\\n/)) {\n const comment = COMMENT.exec(line);\n if (comment) {\n block.push(comment[1] ?? \"\");\n continue;\n }\n const key = KEY.exec(line)?.[1];\n if (key && block.length > 0) docs[key] = block.join(\"\\n\").trim();\n block = [];\n }\n return docs;\n}\n","import type { FormatSettings, Manifest } from \"./manifest.types.js\";\nimport { asBoolean, asList, asNumber, asRecord, asStringMap } from \"./read/index.js\";\n\ntype RunSettings = Pick<Manifest, \"env\" | \"envFiles\" | \"paths\" | \"format\">;\n\n/**\n * How the project runs, as against what it is: environments, path aliases and\n * formatting.\n */\nexport function readRunSettings(data: Record<string, unknown>): RunSettings {\n return {\n env: readEnv(data.env),\n envFiles: asList(asRecord(data.env).files),\n paths: asStringMap(data.paths),\n format: readFormat(data.format),\n };\n}\n\nfunction readFormat(value: unknown): FormatSettings {\n const table = asRecord(value);\n return {\n indent: asNumber(table.indent),\n tabs: asBoolean(table.tabs),\n organize: asBoolean(table.organize),\n sort: asBoolean(table.sort),\n };\n}\n\n/** `files` configures where to read from; every other key names an environment. */\nconst RESERVED = new Set([\"files\"]);\n\nfunction readEnv(value: unknown): Record<string, Record<string, string>> {\n const out: Record<string, Record<string, string>> = {};\n for (const [name, vars] of Object.entries(asRecord(value))) {\n if (!RESERVED.has(name)) out[name] = asStringMap(vars);\n }\n return out;\n}\n","import type { Manifest, ManifestProvider } from \"./manifest.types.js\";\nimport {\n readDependencies,\n readPackage,\n readProfiles,\n readTargets,\n readTooling,\n readWorkspace,\n} from \"./read/index.js\";\nimport { readRunSettings } from \"./read-run-settings.js\";\nimport { parseToml } from \"./toml/index.js\";\n\n/**\n * The real one: parse `venn.toml` into a {@link Manifest}.\n *\n * Parsing happens once, at construction, so repeated `load()` calls are free\n * and always agree.\n *\n * @param args.content - the manifest as written.\n */\nexport function createTomlManifest(args: { content: string }): ManifestProvider {\n const manifest = toManifest(parseToml(args.content));\n return { load: () => manifest };\n}\n\nfunction toManifest(data: Record<string, unknown>): Manifest {\n const pkg = readPackage(data);\n return {\n name: pkg.name,\n version: pkg.version ?? \"0.0.0\",\n package: pkg,\n targets: readTargets(data, pkg.name),\n dependencies: readDependencies(data.dependencies),\n devDependencies: readDependencies(data[\"dev-dependencies\"]),\n patch: readDependencies(data.patch),\n profiles: readProfiles(data),\n tooling: readTooling(data),\n workspace: readWorkspace(data),\n ...readRunSettings(data),\n };\n}\n","import type {\n SignalHandler,\n SignalSource,\n SystemSignal,\n Unsubscribe,\n} from \"./signal-source.types.js\";\n\n/** A {@link SignalSource} with the bell a test rings. */\nexport interface FakeSignals extends SignalSource {\n /** Deliver `signal` to everyone still listening for it. */\n raise(signal: SystemSignal): void;\n /** Which signals are currently being listened for, for assertions. */\n readonly listening: readonly SystemSignal[];\n}\n\n/**\n * The double: a signal arrives because a test said so. No process, no operating\n * system, no risk of stopping the test runner along with the code under test.\n */\nexport function createFakeSignals(): FakeSignals {\n const handlers = new Map<SystemSignal, Set<SignalHandler>>();\n return {\n get listening() {\n return [...handlers].filter(([, set]) => set.size > 0).map(([signal]) => signal);\n },\n on: (signal, handler) => subscribe({ handlers, signal, handler }),\n raise: (signal) => {\n for (const handler of [...(handlers.get(signal) ?? [])]) handler(signal);\n },\n };\n}\n\nfunction subscribe(args: {\n handlers: Map<SystemSignal, Set<SignalHandler>>;\n signal: SystemSignal;\n handler: SignalHandler;\n}): Unsubscribe {\n const set = args.handlers.get(args.signal) ?? new Set<SignalHandler>();\n set.add(args.handler);\n args.handlers.set(args.signal, set);\n return () => {\n set.delete(args.handler);\n };\n}\n","import type { Port } from \"../../port/index.js\";\nimport type { SignalSource } from \"./signal-source.types.js\";\n\n/**\n * The {@link SignalSource} contract. Implementations: `node-signals`,\n * `fake-signals`.\n */\nexport const SignalSourcePort: Port<SignalSource> = {\n id: \"venn.port.signals\",\n version: 1,\n requires: [\"process\"],\n methods: [\"on\"],\n};\n","/**\n * The ways a system asks a program to stop. `SIGBREAK` is Windows' Ctrl+Break,\n * `SIGHUP` is the terminal itself going away.\n */\nexport const ALL_SIGNALS = [\"SIGINT\", \"SIGTERM\", \"SIGBREAK\", \"SIGHUP\"] as const;\n\n/** One signal name, drawn from {@link ALL_SIGNALS}. */\nexport type SystemSignal = (typeof ALL_SIGNALS)[number];\n\n/** Called on every delivery of the signal it was registered for. */\nexport type SignalHandler = (signal: SystemSignal) => void;\n\n/** Drops a subscription. Calling it more than once is harmless. */\nexport type Unsubscribe = () => void;\n\n/**\n * Where a program hears the system asking it to stop.\n *\n * The double matters more than usual here: raising a true SIGINT inside a test\n * run stops the test runner, not the code under test.\n */\nexport interface SignalSource {\n on(signal: SystemSignal, handler: SignalHandler): Unsubscribe;\n}\n"],"mappings":"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"}
|
package/dist/node.d.mts
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
//#region src/capabilities/host-capability.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Every capability a Host may expose. A port or plugin declares which it
|
|
4
|
+
* requires, a host advertises which it provides, and negotiation compares the
|
|
5
|
+
* two before anything binds.
|
|
6
|
+
*/
|
|
7
|
+
declare const ALL_CAPABILITIES: readonly ["fs", "process", "net", "clock", "random", "secrets", "log", "io"];
|
|
8
|
+
/** One capability name, drawn from {@link ALL_CAPABILITIES}. */
|
|
9
|
+
type HostCapability = (typeof ALL_CAPABILITIES)[number];
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/logger/logger.types.d.ts
|
|
12
|
+
/** How loudly one entry asks to be heard. */
|
|
13
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
14
|
+
/** One line of log, as data rather than as formatted text. */
|
|
15
|
+
interface LogEntry {
|
|
16
|
+
readonly level: LogLevel;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
}
|
|
19
|
+
/** The minimal structured logger a host exposes. */
|
|
20
|
+
interface Logger {
|
|
21
|
+
log(entry: LogEntry): void;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/ports/clock/clock.types.d.ts
|
|
25
|
+
/** Now, sleeping, deadlines. */
|
|
26
|
+
interface Clock {
|
|
27
|
+
/** Milliseconds since the epoch, or since the virtual clock's start. */
|
|
28
|
+
now(): number;
|
|
29
|
+
sleep(ms: number): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/ports/file-system/file-system.types.d.ts
|
|
33
|
+
/**
|
|
34
|
+
* Read and write bytes.
|
|
35
|
+
*
|
|
36
|
+
* This is the port that lets `@venn-lang/core` run both in Node (the CLI) and in a
|
|
37
|
+
* Web Worker (the LSP). A leaked `import fs from "node:fs"` in core would break
|
|
38
|
+
* the editor, so all byte I/O goes through here.
|
|
39
|
+
*/
|
|
40
|
+
interface FileSystem {
|
|
41
|
+
/** @throws VennError VN8010 when the path does not exist. */
|
|
42
|
+
read(path: string): Promise<Uint8Array>;
|
|
43
|
+
write(path: string, bytes: Uint8Array): Promise<void>;
|
|
44
|
+
exists(path: string): Promise<boolean>;
|
|
45
|
+
/** @throws VennError VN8010 when the path does not exist. */
|
|
46
|
+
remove(path: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* What a directory holds, one level deep, in no promised order. A path that
|
|
49
|
+
* is not a directory reads as empty rather than raising: asking what is
|
|
50
|
+
* inside something that holds nothing has an answer.
|
|
51
|
+
*/
|
|
52
|
+
list(path: string): Promise<readonly DirEntry[]>;
|
|
53
|
+
}
|
|
54
|
+
/** One name inside a directory, and whether it holds more. */
|
|
55
|
+
interface DirEntry {
|
|
56
|
+
name: string;
|
|
57
|
+
directory: boolean;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/ports/lock-provider/lock-provider.types.d.ts
|
|
61
|
+
/** Releases a held lock. Calling it more than once is a no-op. */
|
|
62
|
+
type Release = () => void;
|
|
63
|
+
/** Named mutexes: the semantics behind `@lock` and `@serial`. */
|
|
64
|
+
interface LockProvider {
|
|
65
|
+
/** Resolves once the lock named `name` is held by this caller alone. */
|
|
66
|
+
acquire(name: string): Promise<Release>;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/ports/process-provider/process-provider.types.d.ts
|
|
70
|
+
/** What to run, where, and how to hear from it while it runs. */
|
|
71
|
+
interface SpawnArgs {
|
|
72
|
+
command: string;
|
|
73
|
+
args?: readonly string[];
|
|
74
|
+
/** Where it runs. The current directory unless this says otherwise. */
|
|
75
|
+
cwd?: string;
|
|
76
|
+
/** Added to the environment the host was started with. */
|
|
77
|
+
env?: Record<string, string>;
|
|
78
|
+
/**
|
|
79
|
+
* Whether to go through the platform shell.
|
|
80
|
+
*
|
|
81
|
+
* Needed for a command that is a script rather than an executable: on Windows
|
|
82
|
+
* `pnpm` is a `.cmd`, and nothing runs it without one. Off by default,
|
|
83
|
+
* because a shell re-reads the arguments and a quote that meant one thing to
|
|
84
|
+
* the caller means another to `cmd.exe`. Only the caller knows which of the
|
|
85
|
+
* two it is holding.
|
|
86
|
+
*/
|
|
87
|
+
shell?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Called with each chunk the command writes, as it writes it.
|
|
90
|
+
*
|
|
91
|
+
* A package manager installing a hundred packages takes half a minute, and a
|
|
92
|
+
* command silent for half a minute reads as one that has hung. What is
|
|
93
|
+
* streamed here is kept as well, so a caller can show it and read it after.
|
|
94
|
+
*/
|
|
95
|
+
onOutput?: (chunk: string) => void;
|
|
96
|
+
}
|
|
97
|
+
/** How a run ended. */
|
|
98
|
+
interface ProcessResult {
|
|
99
|
+
code: number;
|
|
100
|
+
/** Everything it wrote, stdout and stderr together, in the order written. */
|
|
101
|
+
output: string;
|
|
102
|
+
}
|
|
103
|
+
/** A spawned subprocess. */
|
|
104
|
+
interface ProcessHandle {
|
|
105
|
+
readonly pid: number;
|
|
106
|
+
/** Resolves when the command ends. Never rejects: a failure is a result. */
|
|
107
|
+
wait(): Promise<ProcessResult>;
|
|
108
|
+
kill(): void;
|
|
109
|
+
}
|
|
110
|
+
/** Spawn subprocesses: a package manager, a driver, anything the host allows. */
|
|
111
|
+
interface ProcessProvider {
|
|
112
|
+
spawn(args: SpawnArgs): ProcessHandle;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/ports/random/random.types.d.ts
|
|
116
|
+
/**
|
|
117
|
+
* A source of randomness. Every implementation is reproducible, so a failing
|
|
118
|
+
* run can be replayed.
|
|
119
|
+
*/
|
|
120
|
+
interface Random {
|
|
121
|
+
/** Uniform float in [0, 1). */
|
|
122
|
+
next(): number;
|
|
123
|
+
/** Uniform integer in the inclusive range [min, max]. */
|
|
124
|
+
int(min: number, max: number): number;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/ports/secret-provider/secret-provider.types.d.ts
|
|
128
|
+
/**
|
|
129
|
+
* A value that redacts itself. Serialising one, by any route, yields the
|
|
130
|
+
* redaction marker: redaction happens at the producer, because redacting in the
|
|
131
|
+
* UI is already too late.
|
|
132
|
+
*/
|
|
133
|
+
interface Secret {
|
|
134
|
+
/** The only way to the raw value, and deliberately something you must ask for. */
|
|
135
|
+
reveal(): string;
|
|
136
|
+
toString(): string;
|
|
137
|
+
toJSON(): string;
|
|
138
|
+
}
|
|
139
|
+
/** Resolves `secrets.*` names to redaction-marked values. */
|
|
140
|
+
interface SecretProvider {
|
|
141
|
+
get(name: string): Secret | undefined;
|
|
142
|
+
has(name: string): boolean;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/host/host.types.d.ts
|
|
146
|
+
/**
|
|
147
|
+
* Everything the core is allowed to reach: assembled at the entry point, then
|
|
148
|
+
* passed inward. The core receives this and imports nothing else.
|
|
149
|
+
*
|
|
150
|
+
* Three assemblers build one: `createHost.worker`, `createHost.test`, and
|
|
151
|
+
* `createNodeHost` from `@venn-lang/contracts/node`.
|
|
152
|
+
*/
|
|
153
|
+
interface Host {
|
|
154
|
+
readonly fs: FileSystem;
|
|
155
|
+
readonly proc: ProcessProvider;
|
|
156
|
+
readonly clock: Clock;
|
|
157
|
+
readonly random: Random;
|
|
158
|
+
readonly secrets: SecretProvider;
|
|
159
|
+
readonly log: Logger;
|
|
160
|
+
readonly lock: LockProvider;
|
|
161
|
+
readonly caps: readonly HostCapability[];
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/host/create-node-host.d.ts
|
|
165
|
+
/**
|
|
166
|
+
* Host for the CLI: the real file system, secrets from the environment, and
|
|
167
|
+
* every capability.
|
|
168
|
+
*
|
|
169
|
+
* @param args.root - where relative paths resolve. Defaults to the process's
|
|
170
|
+
* current directory.
|
|
171
|
+
*/
|
|
172
|
+
declare function createNodeHost(args?: {
|
|
173
|
+
root?: string;
|
|
174
|
+
}): Host;
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/ports/console/console.types.d.ts
|
|
177
|
+
/**
|
|
178
|
+
* The program's console: standard streams and process arguments.
|
|
179
|
+
*
|
|
180
|
+
* Everything a script needs to talk to the outside world without knowing
|
|
181
|
+
* whether it runs on Node, in a test, or in a browser worker. The host supplies
|
|
182
|
+
* the wiring.
|
|
183
|
+
*/
|
|
184
|
+
interface Console {
|
|
185
|
+
/** Write to standard output, exactly as given (no trailing newline). */
|
|
186
|
+
write(text: string): void;
|
|
187
|
+
/** Write to standard error. */
|
|
188
|
+
writeError(text: string): void;
|
|
189
|
+
/** Read the next line from standard input, or null at end of input. */
|
|
190
|
+
readLine(): Promise<string | null>;
|
|
191
|
+
/** The command-line arguments passed after the script path. */
|
|
192
|
+
args(): readonly string[];
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/ports/console/node-console.d.ts
|
|
196
|
+
/**
|
|
197
|
+
* Where a node console reads and writes. Injectable, so a test can drive the
|
|
198
|
+
* real implementation and read back what a script printed.
|
|
199
|
+
*/
|
|
200
|
+
interface ConsoleStreams {
|
|
201
|
+
argv?: readonly string[];
|
|
202
|
+
stdout?: {
|
|
203
|
+
write(text: string): unknown;
|
|
204
|
+
};
|
|
205
|
+
stderr?: {
|
|
206
|
+
write(text: string): unknown;
|
|
207
|
+
};
|
|
208
|
+
/** Where lines are read from. Defaults to the process's own standard input. */
|
|
209
|
+
stdin?: NodeJS.ReadableStream & {
|
|
210
|
+
isTTY?: boolean;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The real console: Node's own streams.
|
|
215
|
+
*
|
|
216
|
+
* stdin is opened lazily, on the first `readLine`. A script that never reads
|
|
217
|
+
* input must not hold the process open waiting for a line that never comes.
|
|
218
|
+
*
|
|
219
|
+
* @param streams - overrides for stdin, stdout, stderr and argv. Each defaults
|
|
220
|
+
* to the process's own.
|
|
221
|
+
*/
|
|
222
|
+
declare function createNodeConsole(streams?: ConsoleStreams): Console;
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/ports/file-system/node-fs.d.ts
|
|
225
|
+
/**
|
|
226
|
+
* The real file system, rooted at `root`.
|
|
227
|
+
*
|
|
228
|
+
* @param args.root - where relative paths resolve. Defaults to ".".
|
|
229
|
+
* @returns a {@link FileSystem} that reports a missing path as VN8010 and any
|
|
230
|
+
* other failure as VN8019.
|
|
231
|
+
*/
|
|
232
|
+
declare function createNodeFs(args?: {
|
|
233
|
+
root?: string;
|
|
234
|
+
}): FileSystem;
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/ports/process-provider/node-spawn.d.ts
|
|
237
|
+
/**
|
|
238
|
+
* The real one, on `node:child_process`.
|
|
239
|
+
*
|
|
240
|
+
* Output is streamed to whoever asked and kept at the same time: a package
|
|
241
|
+
* manager needs watching while it works and reading once it is done, and only
|
|
242
|
+
* one of the two would leave either a command that looks hung or a result
|
|
243
|
+
* nobody can inspect.
|
|
244
|
+
*/
|
|
245
|
+
declare function createNodeSpawn(): ProcessProvider;
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/ports/signal-source/signal-source.types.d.ts
|
|
248
|
+
/**
|
|
249
|
+
* The ways a system asks a program to stop. `SIGBREAK` is Windows' Ctrl+Break,
|
|
250
|
+
* `SIGHUP` is the terminal itself going away.
|
|
251
|
+
*/
|
|
252
|
+
declare const ALL_SIGNALS: readonly ["SIGINT", "SIGTERM", "SIGBREAK", "SIGHUP"];
|
|
253
|
+
/** One signal name, drawn from {@link ALL_SIGNALS}. */
|
|
254
|
+
type SystemSignal = (typeof ALL_SIGNALS)[number];
|
|
255
|
+
/** Called on every delivery of the signal it was registered for. */
|
|
256
|
+
type SignalHandler = (signal: SystemSignal) => void;
|
|
257
|
+
/** Drops a subscription. Calling it more than once is harmless. */
|
|
258
|
+
type Unsubscribe = () => void;
|
|
259
|
+
/**
|
|
260
|
+
* Where a program hears the system asking it to stop.
|
|
261
|
+
*
|
|
262
|
+
* The double matters more than usual here: raising a true SIGINT inside a test
|
|
263
|
+
* run stops the test runner, not the code under test.
|
|
264
|
+
*/
|
|
265
|
+
interface SignalSource {
|
|
266
|
+
on(signal: SystemSignal, handler: SignalHandler): Unsubscribe;
|
|
267
|
+
}
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/ports/signal-source/node-signals.d.ts
|
|
270
|
+
/**
|
|
271
|
+
* Whether this platform knows the signal.
|
|
272
|
+
*
|
|
273
|
+
* Not every name exists everywhere: `SIGBREAK` is Windows only, and subscribing
|
|
274
|
+
* to an unknown one throws. Asking first turns a crash at start up into a
|
|
275
|
+
* subscription that never fires.
|
|
276
|
+
*/
|
|
277
|
+
declare function isKnownSignal(signal: SystemSignal): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* The real one: the signals this process receives.
|
|
280
|
+
*
|
|
281
|
+
* Lives behind `@venn-lang/contracts/node` because it touches `node:process`, so the
|
|
282
|
+
* main entry stays neutral and still runs in the editor's worker.
|
|
283
|
+
*/
|
|
284
|
+
declare function createNodeSignals(): SignalSource;
|
|
285
|
+
//#endregion
|
|
286
|
+
export { type ConsoleStreams, createNodeConsole, createNodeFs, createNodeHost, createNodeSignals, createNodeSpawn, isKnownSignal };
|
|
287
|
+
//# sourceMappingURL=node.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.mts","names":[],"sources":["../src/capabilities/host-capability.ts","../src/logger/logger.types.ts","../src/ports/clock/clock.types.ts","../src/ports/file-system/file-system.types.ts","../src/ports/lock-provider/lock-provider.types.ts","../src/ports/process-provider/process-provider.types.ts","../src/ports/random/random.types.ts","../src/ports/secret-provider/secret-provider.types.ts","../src/host/host.types.ts","../src/host/create-node-host.ts","../src/ports/console/console.types.ts","../src/ports/console/node-console.ts","../src/ports/file-system/node-fs.ts","../src/ports/process-provider/node-spawn.ts","../src/ports/signal-source/signal-source.types.ts","../src/ports/signal-source/node-signals.ts"],"mappings":";;;;;;cAKa;;KAYD,yBAAyB;;;;KChBzB;;UAGK;WACN,OAAO;WACP;;;UAIM;EACf,IAAI,OAAO;;;;;UCVI;;EAEf;EACA,MAAM,aAAa;;;;;;;;;;;UCGJ;;EAEf,KAAK,eAAe,QAAQ;EAC5B,MAAM,cAAc,OAAO,aAAa;EACxC,OAAO,eAAe;;EAEtB,OAAO,eAAe;;;;;;EAMtB,KAAK,eAAe,iBAAiB;;;UAItB;EACf;EACA;;;;;KCxBU;;UAGK;;EAEf,QAAQ,eAAe,QAAQ;;;;;UCLhB;EACf;EACA;;EAEA;;EAEA,MAAM;;;;;;;;;;EAUN;;;;;;;;EAQA,YAAY;;;UAIG;EACf;;EAEA;;;UAIe;WACN;;EAET,QAAQ,QAAQ;EAChB;;;UAIe;EACf,MAAM,MAAM,YAAY;;;;;;;;UCzCT;;EAEf;;EAEA,IAAI,aAAa;;;;;;;;;UCHF;;EAEf;EACA;EACA;;;UAIe;EACf,IAAI,eAAe;EACnB,IAAI;;;;;;;;;;;UCCW;WACN,IAAI;WACJ,MAAM;WACN,OAAO;WACP,QAAQ;WACR,SAAS;WACT,KAAK;WACL,MAAM;WACN,eAAe;;;;;;;;;;;iBCPV,eAAe;EAAQ;IAAuB;;;;;;;;;;UCV7C;;EAEf,MAAM;;EAEN,WAAW;;EAEX,YAAY;;EAEZ;;;;;;;;UCRe;EACf;EACA;IAAW,MAAM;;EACjB;IAAW,MAAM;;;EAEjB,QAAQ,OAAO;IAAmB;;;;;;;;;;;;iBAYpB,kBAAkB,UAAS,iBAAsB;;;;;;;;;;iBCXjD,aAAa;EAAQ;IAAuB;;;;;;;;;;;iBCG5C,mBAAmB;;;;;;;cCZtB;;KAGD,uBAAuB;;KAGvB,iBAAiB,QAAQ;;KAGzB;;;;;;;UAQK;EACf,GAAG,QAAQ,cAAc,SAAS,gBAAgB;;;;;;;;;;;iBCXpC,cAAc,QAAQ;;;;;;;iBAUtB,qBAAqB"}
|