@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
159 lines • 7.08 kB
JavaScript
// ========= 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