UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

108 lines • 4.43 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { enoent } from "../../errors/fs.js"; import { DirListing, FileStat, FileType } from "../../types.js"; import { makeReaddir } from "../hierarchy/readdir.js"; import { jsonBytes } from "../render/json.js"; import { fetchOperations, fetchServices, fetchTraces, isTraceId } from "./client.js"; import { OPERATIONS_FILE, TOP_LEVEL_DIRS, detectScope } from "./scope.js"; /** * Throw ENOENT unless the service is known to Jaeger. * * The operations endpoint answers 200 with an empty list for a service that * was never seen, so an unknown service would otherwise look like an empty * directory instead of a missing one. */ export async function assertService(accessor, service, virtual) { const services = await fetchServices(accessor.transport); if (!services.includes(service)) throw enoent(virtual); } export async function serviceGuard(accessor, match, virtual) { await assertService(accessor, match.slots.service ?? '', virtual); } function serviceExtra(match) { return { service: match.slots.service ?? '' }; } function traceExtra(match) { return { trace_id: match.slots.trace_id ?? '' }; } // What each kind's stat carries in `extra`, listed or not. export const EXTRAS = { service: serviceExtra, trace: traceExtra, }; async function listServices(accessor, _match) { const services = await fetchServices(accessor.transport); return services.map((service) => new FileStat({ name: service, type: FileType.DIRECTORY })); } async function listService(accessor, match) { const service = match.slots.service ?? ''; // One operations call per service directory actually entered: nothing in // the services listing carries operation names, so operations.json can only // be sized here, and only for services the caller opens. const operations = await fetchOperations(accessor.transport, service); return [ new FileStat({ name: OPERATIONS_FILE, type: FileType.FILE, size: jsonBytes(operations).byteLength, }), new FileStat({ name: 'traces', type: FileType.DIRECTORY }), ]; } async function listTraces(accessor, match) { const service = match.slots.service ?? ''; const opts = { limit: accessor.config.defaultTraceLimit ?? 100, }; const from = accessor.config.defaultFromTimestamp; if (from !== undefined && from !== '') opts.fromTimestamp = from; const to = accessor.config.defaultToTimestamp; if (to !== undefined && to !== '') opts.toTimestamp = to; const traces = await fetchTraces(accessor.transport, service, opts); const rows = []; for (const trace of traces) { const traceId = typeof trace.traceID === 'string' ? trace.traceID : ''; if (!isTraceId(traceId)) continue; // The search endpoint returns complete trace documents, so the rendered // size is free here. Span order may differ from the by-id fetch, but // reordering the same spans leaves the byte length equal. rows.push(new FileStat({ name: `${traceId}.json`, type: FileType.FILE, size: jsonBytes(trace).byteLength, })); } // The newest defaultTraceLimit traces: one that ages out of the page is // still in Jaeger, so the listing evicts nothing. return new DirListing({ entries: rows, window: true }); } export const readdir = makeReaddir(detectScope, { listers: { services: listServices, service: listService, traces: listTraces, }, staticRoot: TOP_LEVEL_DIRS, guards: { service: serviceGuard, traces: serviceGuard, }, extras: EXTRAS, }); //# sourceMappingURL=readdir.js.map