Skip to content
File

Blob: src/pyodide/internal/tarfs.ts

typescript57 lines
1// Copyright (c) 2026 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5import { createReadonlyFS } from 'pyodide-internal:readOnlyFS';
6import { PythonWorkersInternalError } from 'pyodide-internal:util';
7 
8const FSOps: FSOps<TarFSInfo> = {
9 getNodeMode(_parent, _name, info) {
10 return {
11 permissions: info.mode,
12 isDir: info.children !== undefined,
13 };
14 },
15 setNodeAttributes(node, info, isDir) {
16 node.info = info!;
17 node.modtime = node.info.modtime;
18 node.usedBytes = 0;
19 if (!isDir) {
20 node.contentsOffset = node.info.contentsOffset;
21 node.usedBytes = node.info.size;
22 }
23 },
24 readdir(node) {
25 if (!node.info.children) {
26 throw new PythonWorkersInternalError(
27 'Trying to readdir from a non-dir node'
28 );
29 }
30 return Array.from(node.info.children.keys());
31 },
32 lookup(parent, name) {
33 if (!parent.info.children) {
34 throw new PythonWorkersInternalError(
35 'Trying to lookup from a non-dir node'
36 );
37 }
38 return parent.info.children.get(name)!;
39 },
40 read(stream, position, buffer) {
41 if (stream.node.contentsOffset == undefined) {
42 throw new PythonWorkersInternalError('contentsOffset is undefined');
43 }
44 if (!stream.node.info.reader) {
45 throw new PythonWorkersInternalError('reader is undefined');
46 }
47 return stream.node.info.reader.read(
48 stream.node.contentsOffset + position,
49 buffer
50 );
51 },
52};
53 
54export function createTarFS(Module: Module): EmscriptenFS<TarFSInfo> {
55 return createReadonlyFS(FSOps, Module);
56}