UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

159 lines • 7.08 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 { DirListing, FileType } from "../../types.js"; import { GoogleApiError } from "../google/client.js"; import { FOLDER_MIME, MIME_TO_EXT } from "../google/drive.js"; import { compareCodePoints } from "../../utils/sort.js"; import { readdir, statFromItem } from "./readdir.js"; export const PARENTS_PER_QUERY = 40; // The rendered vfs filename for a Drive item. function vfsName(item) { const ext = MIME_TO_EXT[item.mimeType ?? '']; return ext !== undefined ? `${item.name}${ext}` : item.name; } // Walk the subtree of the folder `folderId` (in shared drive `driveId`) at // `path`, yielding [mount-relative path, item, isDir]. The walk goes a level // at a time, the level's folders listed together (`listLevel`). Children are // visited in vfs-name order so every traversal-based command (find, du) is // deterministic, mirroring the python iter_tree contract. export async function* iterTree(accessor, path, folderId, driveId) { let level = [[path.vfsPath, folderId, driveId]]; while (level.length > 0) { const children = await listLevel(accessor, level.map(([, fid, did]) => [fid, did])); const below = []; for (const [rel, fid, did] of level) { const items = [...(children.get(fid) ?? [])].sort((a, b) => compareCodePoints(vfsName(a), vfsName(b))); for (const item of items) { const name = vfsName(item); const childRel = rel !== '' ? `${rel}/${name}` : name; const isDir = item.mimeType === FOLDER_MIME; yield [childRel, item, isDir]; if (isDir) below.push([childRel, item.id, item.driveId ?? did]); } } level = below; } } /** * The children of each folder of one level of a walk, by folder id. * * One query asks for the children of up to `PARENTS_PER_QUERY` folders of one * corpus, where a walk lists each folder on its own, and each child is filed * under every folder asked about that its `parents` name. A folder asked about * alone takes every child, so `root`, the alias Drive names My Drive by, lists * too. Once `limit` items are in hand no page or query more is asked, so the * level is then short. Mirrors Python's `list_level`. */ export async function listLevel(accessor, folders, limit) { const drive = accessor.drive; const corpora = new Map(); const children = new Map(); for (const [folderId, driveId] of folders) { const ids = corpora.get(driveId) ?? []; ids.push(folderId); corpora.set(driveId, ids); children.set(folderId, []); } let got = 0; for (const [driveId, ids] of corpora) { for (let start = 0; start < ids.length; start += PARENTS_PER_QUERY) { if (limit !== undefined && got >= limit) return children; const asked = ids.slice(start, start + PARENTS_PER_QUERY); const items = await (limit === undefined ? drive.listChildren(asked, driveId) : drive.listChildren(asked, driveId, limit - got)); got += items.length; for (const item of items) { const filed = asked.length === 1 ? asked : (item.parents ?? []).filter((p) => asked.includes(p)); for (const parent of filed) children.get(parent)?.push(item); } } } return children; } /** * Every item under a folder, each as its folder's listing renders it, read a * level at a time (`listLevel`): a query per level and corpus where a walk * sends a listing per folder. * * The folder's own children are its listing, so the mount root keeps its * Shared Drives and a folder that is not there raises what a listing raises. * Of two items with one name in a folder, the one its listing keeps, the last, * stands. Null when that listing is short (Shared Drives it could not list), * or when a level below it fails, so the walk lists what is there and reports, * or skips, each folder on its own; null too once it holds more than `limit` * items, which no level is paged past. Mirrors Python's `tree`. */ export async function tree(accessor, path, entry, limit) { const listed = await readdir(accessor, path, entry); if (listed instanceof DirListing) return null; const found = new Map(); let level = placed(found, '', listed, null); while (level.size > 0) { if (limit !== undefined && found.size > limit) return null; const left = limit === undefined ? undefined : limit - found.size + 1; let children; try { children = await listLevel(accessor, [...level.values()], left); } catch (err) { const failed = err instanceof GoogleApiError || err instanceof TypeError || err instanceof DOMException; if (!failed) throw err; console.debug(`drive tree of ${path.virtual} left to the walk: ${String(err)}`); return null; } if (left !== undefined && [...children.values()].reduce((n, rows) => n + rows.length, 0) >= left) return null; const below = new Map(); for (const [rel, [folderId, driveId]] of level) { const rows = (children.get(folderId) ?? []) .map(statFromItem) .sort((a, b) => compareCodePoints(a.name, b.name)); for (const [key, folder] of placed(found, rel, rows, driveId)) below.set(key, folder); } level = below; } if (limit !== undefined && found.size > limit) return null; return found; } /** * Put a folder's rows into a tree read, and answer the folders among them by * path, each with its id and shared drive. Mirrors Python's `_placed`. */ function placed(found, rel, rows, driveId) { const folders = new Map(); for (const row of rows) { const key = rel !== '' ? `${rel}/${row.name}` : row.name; found.set(key, row); folders.delete(key); if (row.type === FileType.DIRECTORY) { const own = row.extra.drive_id; folders.set(key, [ row.extra.file_id, typeof own === 'string' && own !== '' ? own : driveId, ]); } } return folders; } //# sourceMappingURL=tree.js.map