@ai-ecoverse/slicc-kernel 1.13.0 → 1.15.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.
@@ -177,6 +177,37 @@ function openMeta(name2, factory) {
177
177
  });
178
178
  }
179
179
 
180
+ // src/mount/media.ts
181
+ var MEDIA_STORE = "handles";
182
+ function memoryMedia() {
183
+ const handles = /* @__PURE__ */ new Map();
184
+ return {
185
+ get: async (id) => handles.get(id),
186
+ put: async (id, handle) => void handles.set(id, handle)
187
+ };
188
+ }
189
+ function settle2(request2, value) {
190
+ return new Promise((resolve, reject) => {
191
+ request2.onsuccess = () => resolve(value());
192
+ request2.onerror = () => reject(request2.error);
193
+ });
194
+ }
195
+ function openMedia(name2, factory) {
196
+ const request2 = factory.open(name2, 1);
197
+ request2.onupgradeneeded = () => request2.result.createObjectStore(MEDIA_STORE);
198
+ return settle2(request2, () => {
199
+ const db = request2.result;
200
+ const store = (mode) => db.transaction(MEDIA_STORE, mode).objectStore(MEDIA_STORE);
201
+ return {
202
+ get: (id) => {
203
+ const got = store("readonly").get(id);
204
+ return settle2(got, () => got.result);
205
+ },
206
+ put: (id, handle) => settle2(store("readwrite").put(handle, id), () => void 0)
207
+ };
208
+ });
209
+ }
210
+
180
211
  // src/pin.ts
181
212
  function pinScript(url) {
182
213
  try {
@@ -643,7 +674,8 @@ var ERRNO_BY_DOM_ERROR = {
643
674
  TypeMismatchError: "ENOTDIR",
644
675
  InvalidModificationError: "ENOTEMPTY",
645
676
  NoModificationAllowedError: "EBUSY",
646
- TypeError: "EINVAL"
677
+ TypeError: "EINVAL",
678
+ NotAllowedError: "EACCES"
647
679
  };
648
680
  function translate(err, path) {
649
681
  if (typeof err?.code === "string") return err;
@@ -3022,9 +3054,28 @@ async function packages(fs, modules) {
3022
3054
  }
3023
3055
  return dirs;
3024
3056
  }
3057
+ async function pnpmGlobalRoots(fs, home) {
3058
+ const roots = [];
3059
+ const global = `${home}/global`;
3060
+ for (const version of (await fs.readdir(global).catch(() => [])).sort()) {
3061
+ for (const group of (await fs.readdir(`${global}/${version}`).catch(() => [])).sort()) {
3062
+ const dir = `${global}/${version}/${group}`;
3063
+ const st = await fs.lstat(dir).catch(() => void 0);
3064
+ if (st?.isDirectory && await fs.exists(`${dir}/node_modules`))
3065
+ roots.push(`${dir}/node_modules`);
3066
+ }
3067
+ }
3068
+ return roots;
3069
+ }
3070
+ async function packagesIn(fs, roots) {
3071
+ const dirs = [];
3072
+ for (const root of typeof roots === "string" ? [roots] : roots)
3073
+ dirs.push(...await packages(fs, root));
3074
+ return dirs;
3075
+ }
3025
3076
  async function scanCommands(fs, modules) {
3026
3077
  const found = /* @__PURE__ */ new Map();
3027
- for (const pkg of await packages(fs, modules)) {
3078
+ for (const pkg of await packagesIn(fs, modules)) {
3028
3079
  let manifest;
3029
3080
  try {
3030
3081
  manifest = JSON.parse(await fs.readFile(`${pkg}/package.json`));
@@ -3043,7 +3094,7 @@ async function scanCommands(fs, modules) {
3043
3094
  }
3044
3095
  async function scanFilesystems(fs, modules) {
3045
3096
  const found = /* @__PURE__ */ new Map();
3046
- for (const pkg of await packages(fs, modules)) {
3097
+ for (const pkg of await packagesIn(fs, modules)) {
3047
3098
  let manifest;
3048
3099
  try {
3049
3100
  manifest = JSON.parse(await fs.readFile(`${pkg}/package.json`));
@@ -3642,7 +3693,7 @@ function attachSyncSabResponder(port, sab, token, opts) {
3642
3693
  Atomics.notify(header2, SAB_I_PUB);
3643
3694
  if (offset + chunk2 >= entry.payload.byteLength) drop(id);
3644
3695
  }
3645
- function settle2(id, result) {
3696
+ function settle3(id, result) {
3646
3697
  if (disposed) return;
3647
3698
  const { status, payload } = encodeSabResult(result);
3648
3699
  drop(id);
@@ -3661,7 +3712,7 @@ function attachSyncSabResponder(port, sab, token, opts) {
3661
3712
  const entry = pending.get(data.id);
3662
3713
  const offset = data.offset;
3663
3714
  if (!entry || typeof offset !== "number" || !Number.isInteger(offset) || offset < 0 || offset > entry.payload.byteLength) {
3664
- settle2(data.id, { ok: false, errno: "EIO", message: "sync-sab: bad continuation" });
3715
+ settle3(data.id, { ok: false, errno: "EIO", message: "sync-sab: bad continuation" });
3665
3716
  return;
3666
3717
  }
3667
3718
  publish(data.id, entry, offset);
@@ -3675,7 +3726,7 @@ function attachSyncSabResponder(port, sab, token, opts) {
3675
3726
  try {
3676
3727
  dispatched = dispatch2(req);
3677
3728
  } catch (err) {
3678
- settle2(id, {
3729
+ settle3(id, {
3679
3730
  ok: false,
3680
3731
  errno: "EIO",
3681
3732
  message: err instanceof Error ? err.message : String(err)
@@ -3683,8 +3734,8 @@ function attachSyncSabResponder(port, sab, token, opts) {
3683
3734
  return;
3684
3735
  }
3685
3736
  void dispatched.then(
3686
- (result) => settle2(id, result),
3687
- (err) => settle2(id, {
3737
+ (result) => settle3(id, result),
3738
+ (err) => settle3(id, {
3688
3739
  ok: false,
3689
3740
  errno: "EIO",
3690
3741
  message: err instanceof Error ? err.message : String(err)
@@ -5778,8 +5829,8 @@ function spawnWasmProcess(opts) {
5778
5829
  return dispatchSyncFs(req);
5779
5830
  };
5780
5831
  const responder = attachSyncSabResponder(worker, sab, token, { dispatch: dispatch2 });
5781
- let settle2;
5782
- const exited = new Promise((resolve) => settle2 = resolve);
5832
+ let settle3;
5833
+ const exited = new Promise((resolve) => settle3 = resolve);
5783
5834
  let done4 = false;
5784
5835
  let endedBy;
5785
5836
  const finish = (code, sig) => {
@@ -5794,8 +5845,8 @@ function spawnWasmProcess(opts) {
5794
5845
  opts.held?.delete(holds);
5795
5846
  worker.terminate();
5796
5847
  void process.exit().then(
5797
- () => settle2(code),
5798
- () => settle2(code)
5848
+ () => settle3(code),
5849
+ () => settle3(code)
5799
5850
  );
5800
5851
  };
5801
5852
  const handle = (data) => {
@@ -6108,6 +6159,148 @@ function serveFilesystem(port, handlers, capabilities = {}) {
6108
6159
  return { invalidate: (paths) => reply({ invalidate: paths }) };
6109
6160
  }
6110
6161
 
6162
+ // src/mount/fsa.ts
6163
+ var FSA_CAPABILITIES = { listingStats: true };
6164
+ var codeOf = (err) => err?.code;
6165
+ var denied = (err) => codeOf(err) === "EACCES" || err?.name === "NotAllowedError";
6166
+ function attrOf(st) {
6167
+ return {
6168
+ kind: st.isDirectory ? "directory" : st.isSymbolicLink ? "symlink" : "file",
6169
+ size: st.size,
6170
+ mtime: st.mtime.getTime(),
6171
+ mode: st.mode,
6172
+ ino: st.ino
6173
+ };
6174
+ }
6175
+ function kernelFsHandlers(fs) {
6176
+ const handles = /* @__PURE__ */ new Map();
6177
+ let nextFh = 0;
6178
+ const handle = (fh) => {
6179
+ const found = handles.get(fh);
6180
+ if (!found) throw fsError2("EBADF", `handle ${fh}`);
6181
+ return found;
6182
+ };
6183
+ async function existing(path) {
6184
+ try {
6185
+ return await fs.stat(path);
6186
+ } catch (err) {
6187
+ if (codeOf(err) === "ENOENT") return void 0;
6188
+ throw err;
6189
+ }
6190
+ }
6191
+ return {
6192
+ getattr: async (path) => attrOf(await fs.lstat(path)),
6193
+ readdir: async (path) => (await fs.readdirStat(path)).flatMap(([name2, st]) => {
6194
+ if (!st) return [];
6195
+ const attr = attrOf(st);
6196
+ return [{ name: name2, kind: attr.kind, attr }];
6197
+ }),
6198
+ async open(path, flags) {
6199
+ const st = await existing(path);
6200
+ if (st && flags.exclusive) throw fsError2("EEXIST", path);
6201
+ if (st?.isDirectory && flags.write) throw fsError2("EISDIR", path);
6202
+ if (!st && !flags.create) throw fsError2("ENOENT", path);
6203
+ const data = st && !flags.truncate ? await fs.readFileBuffer(path) : new Uint8Array(0);
6204
+ handles.set(++nextFh, { path, data, length: data.length, dirty: !st || flags.truncate });
6205
+ return nextFh;
6206
+ },
6207
+ async read(fh, offset, size) {
6208
+ const h = handle(fh);
6209
+ return h.data.slice(offset, Math.min(h.length, offset + size));
6210
+ },
6211
+ async write(fh, offset, bytes) {
6212
+ const h = handle(fh);
6213
+ const end = offset + bytes.length;
6214
+ if (end > h.data.length) {
6215
+ const grown = new Uint8Array(Math.max(end, h.data.length * 2));
6216
+ grown.set(h.data.subarray(0, h.length));
6217
+ h.data = grown;
6218
+ }
6219
+ h.data.set(bytes, offset);
6220
+ h.length = Math.max(h.length, end);
6221
+ h.dirty = true;
6222
+ },
6223
+ async release(fh) {
6224
+ const h = handle(fh);
6225
+ handles.delete(fh);
6226
+ if (h.dirty) await fs.writeFile(h.path, h.data.slice(0, h.length));
6227
+ },
6228
+ mkdir: (path) => fs.mkdir(path),
6229
+ async rmdir(path) {
6230
+ if (!(await fs.lstat(path)).isDirectory) throw fsError2("ENOTDIR", path);
6231
+ if ((await fs.readdir(path)).length > 0) throw fsError2("ENOTEMPTY", path);
6232
+ await fs.rm(path);
6233
+ },
6234
+ async unlink(path) {
6235
+ if ((await fs.lstat(path)).isDirectory) throw fsError2("EISDIR", path);
6236
+ await fs.rm(path);
6237
+ },
6238
+ rename: (from, to) => fs.rename(from, to),
6239
+ symlink: (target, path) => fs.symlink(target, path),
6240
+ readlink: (path) => fs.readlink(path),
6241
+ async setattr(path, change) {
6242
+ if (change.mode !== void 0) await fs.chmod(path, change.mode);
6243
+ if (change.mtime !== void 0) {
6244
+ await fs.utimes(path, new Date(change.mtime), new Date(change.mtime));
6245
+ }
6246
+ }
6247
+ };
6248
+ }
6249
+ var EMPTY_ROOT = { kind: "directory", size: 0, mtime: 0, mode: 16749 };
6250
+ function granted(handle) {
6251
+ if (!handle.queryPermission) return Promise.resolve(true);
6252
+ return handle.queryPermission({ mode: "readwrite" }).then(
6253
+ (state) => state === "granted",
6254
+ () => false
6255
+ );
6256
+ }
6257
+ function removableMedium(onLost, open = (handle) => new OpfsFs(handle)) {
6258
+ let current;
6259
+ const absent = () => fsError2("ENOMEDIUM", "No medium found");
6260
+ function wrap(pick) {
6261
+ return async (...args) => {
6262
+ const medium = current;
6263
+ if (!medium) throw absent();
6264
+ try {
6265
+ return await pick(medium.handlers)(...args);
6266
+ } catch (err) {
6267
+ if (!denied(err) || await granted(medium.handle)) throw err;
6268
+ if (current === medium) {
6269
+ current = void 0;
6270
+ onLost(medium.handle);
6271
+ }
6272
+ throw absent();
6273
+ }
6274
+ };
6275
+ }
6276
+ const getattr = wrap((h) => h.getattr);
6277
+ const readdir = wrap((h) => h.readdir);
6278
+ return {
6279
+ handlers: {
6280
+ getattr: (path) => current || path !== "/" ? getattr(path) : Promise.resolve(EMPTY_ROOT),
6281
+ readdir: (path) => current || path !== "/" ? readdir(path) : Promise.resolve([]),
6282
+ open: wrap((h) => h.open),
6283
+ read: wrap((h) => h.read),
6284
+ write: wrap((h) => h.write),
6285
+ release: wrap((h) => h.release),
6286
+ mkdir: wrap((h) => h.mkdir),
6287
+ rmdir: wrap((h) => h.rmdir),
6288
+ unlink: wrap((h) => h.unlink),
6289
+ rename: wrap((h) => h.rename),
6290
+ symlink: wrap((h) => h.symlink),
6291
+ readlink: wrap((h) => h.readlink),
6292
+ setattr: wrap((h) => h.setattr)
6293
+ },
6294
+ present: () => current !== void 0,
6295
+ insert(handle) {
6296
+ current = { handle, handlers: kernelFsHandlers(open(handle)) };
6297
+ },
6298
+ eject() {
6299
+ current = void 0;
6300
+ }
6301
+ };
6302
+ }
6303
+
6111
6304
  // src/mount/connection.ts
6112
6305
  var DRIVER_TIMEOUT_MS = 3e4;
6113
6306
  function unref(timer) {
@@ -6251,14 +6444,16 @@ var MountTable = class {
6251
6444
  this.deps = deps;
6252
6445
  }
6253
6446
  list() {
6254
- return [...this.mounts.values()].map(({ type, source, target, options, state, error }) => ({
6255
- type,
6256
- source,
6257
- target,
6258
- options: { ...options },
6259
- state,
6260
- ...error ? { error } : {}
6261
- }));
6447
+ return [...this.mounts.values()].map(
6448
+ ({ type, source, target, options, state, error, present }) => ({
6449
+ type,
6450
+ source,
6451
+ target,
6452
+ options: { ...options },
6453
+ state: state === "ok" && present?.() === false ? "nomedium" : state,
6454
+ ...error ? { error } : {}
6455
+ })
6456
+ );
6262
6457
  }
6263
6458
  locate(path) {
6264
6459
  let best;
@@ -6329,7 +6524,8 @@ var MountTable = class {
6329
6524
  maxFile: options.maxfile !== void 0 ? parseSize(options.maxfile) : caps.maxFile ?? 0,
6330
6525
  attrs: /* @__PURE__ */ new Map(),
6331
6526
  lists: /* @__PURE__ */ new Map(),
6332
- dispose: () => opened2.dispose()
6527
+ dispose: () => opened2.dispose(),
6528
+ ...opened2.present ? { present: opened2.present } : {}
6333
6529
  };
6334
6530
  mounted = mount;
6335
6531
  this.mounts.set(target, mount);
@@ -6966,6 +7162,7 @@ function foreignImports(bytes) {
6966
7162
  }
6967
7163
 
6968
7164
  // src/launcher.ts
7165
+ var PNPM_HOME = "/home/.local/share/pnpm";
6969
7166
  var COMMAND2 = /^\/(?:usr\/)?bin\/([^/]+)$/;
6970
7167
  var PACKAGE_ROOT = /^(.*\/node_modules\/(?:@[^/]+\/)?[^/]+)\//;
6971
7168
  var ENV_REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
@@ -7055,8 +7252,13 @@ var Launcher = class {
7055
7252
  ca;
7056
7253
  transport;
7057
7254
  watchers = new FsWatchers();
7255
+ pnpmHome;
7058
7256
  mounts;
7059
7257
  createDriverWorker;
7258
+ media;
7259
+ onMountPending;
7260
+ removable = /* @__PURE__ */ new Map();
7261
+ inserted = /* @__PURE__ */ new Map();
7060
7262
  openFiles = /* @__PURE__ */ new Set();
7061
7263
  held = /* @__PURE__ */ new Set();
7062
7264
  nextPid = 1e3;
@@ -7071,6 +7273,9 @@ var Launcher = class {
7071
7273
  this.base = this.watchers.wrap(this.mounts.wrap(options.fs));
7072
7274
  this.createWorker = options.createWorker;
7073
7275
  this.createDriverWorker = options.createDriverWorker;
7276
+ this.media = options.media ?? memoryMedia();
7277
+ this.onMountPending = options.onMountPending;
7278
+ this.pnpmHome = options.env?.PNPM_HOME ?? PNPM_HOME;
7074
7279
  this.modulesDir = options.modules ?? "/node_modules";
7075
7280
  this.env = { ...networkEnv(), ...options.env };
7076
7281
  this.ca = kernelCa(options.caStore ?? memoryCaStore());
@@ -7081,11 +7286,17 @@ var Launcher = class {
7081
7286
  ca: this.ca
7082
7287
  });
7083
7288
  this.fs = withCommandDirs(this.base, async () => new Set((await this.commands()).keys()));
7289
+ this.watchers.watch([this.modulesDir, this.pnpmHome], { recursive: true }, () => {
7290
+ this.catalog = void 0;
7291
+ });
7084
7292
  }
7085
7293
  commands() {
7086
- this.catalog ??= scanCommands(this.base, this.modulesDir);
7294
+ this.catalog ??= this.roots().then((roots) => scanCommands(this.base, roots));
7087
7295
  return this.catalog;
7088
7296
  }
7297
+ async roots() {
7298
+ return [this.modulesDir, ...await pnpmGlobalRoots(this.base, this.pnpmHome)];
7299
+ }
7089
7300
  async resolve(file, argv0, cwd) {
7090
7301
  const name2 = COMMAND2.exec(file)?.[1] ?? (file.includes("/") ? void 0 : file);
7091
7302
  if (name2 !== void 0) {
@@ -7327,7 +7538,8 @@ var Launcher = class {
7327
7538
  if (sig !== 0) handle.signal(sig);
7328
7539
  return true;
7329
7540
  }
7330
- async driver(type, _spec) {
7541
+ async driver(type, spec) {
7542
+ if (type === "fsa") return this.fsaDriver(spec);
7331
7543
  if (type === "tmpfs") {
7332
7544
  const { port1, port2 } = new MessageChannel();
7333
7545
  serveFilesystem(port2, tmpfs(), { symlinks: true, chmod: true, attrTtl: 0 });
@@ -7339,7 +7551,7 @@ var Launcher = class {
7339
7551
  }
7340
7552
  };
7341
7553
  }
7342
- const module = (await scanFilesystems(this.base, this.modulesDir)).get(type);
7554
+ const module = (await scanFilesystems(this.base, await this.roots())).get(type);
7343
7555
  if (!module) throw fsError("ENODEV", `unknown file system type ${type}`);
7344
7556
  if (!this.createDriverWorker)
7345
7557
  throw fsError("ENODEV", `this kernel cannot start ${type} drivers`);
@@ -7368,8 +7580,47 @@ var Launcher = class {
7368
7580
  })
7369
7581
  };
7370
7582
  }
7583
+ async fsaDriver(spec) {
7584
+ const { target, source } = spec;
7585
+ const ask = (handle) => this.onMountPending?.({ target, source, ...handle ? { handle } : {} });
7586
+ const { port1, port2 } = new MessageChannel();
7587
+ const medium = removableMedium((handle) => {
7588
+ served.invalidate(true);
7589
+ ask(handle);
7590
+ });
7591
+ const served = serveFilesystem(port2, medium.handlers, FSA_CAPABILITIES);
7592
+ const id = source.slice("fsa:".length);
7593
+ this.removable.set(target, { id, medium, served });
7594
+ const stored = this.inserted.get(id) ?? await this.media.get(id);
7595
+ if (stored && await granted(stored)) medium.insert(stored);
7596
+ else ask(stored);
7597
+ return {
7598
+ port: port1,
7599
+ present: () => medium.present(),
7600
+ dispose: () => {
7601
+ this.removable.delete(target);
7602
+ port1.close();
7603
+ port2.close();
7604
+ }
7605
+ };
7606
+ }
7371
7607
  mount(spec) {
7372
- return this.mounts.mount(spec, this.fs);
7608
+ if (spec.type !== "fsa" || spec.source.startsWith("fsa:"))
7609
+ return this.mounts.mount(spec, this.fs);
7610
+ return this.mounts.mount({ ...spec, source: `fsa:${crypto.randomUUID()}` }, this.fs);
7611
+ }
7612
+ async insert(target, handle, source) {
7613
+ const at = normalizePath(target);
7614
+ const slot = this.removable.get(at);
7615
+ if (!slot) throw fsError("EINVAL", `${at} is not a removable mount`);
7616
+ if (source !== void 0 && source !== `fsa:${slot.id}`) {
7617
+ throw fsError("EINVAL", `${at} is no longer the drive ${source}`);
7618
+ }
7619
+ if (!await granted(handle)) throw fsError("EACCES", `${at}: no permission for this folder`);
7620
+ this.inserted.set(slot.id, handle);
7621
+ await this.media.put(slot.id, handle);
7622
+ slot.medium.insert(handle);
7623
+ slot.served.invalidate(true);
7373
7624
  }
7374
7625
  umount(target) {
7375
7626
  this.mounts.umount(target);
@@ -7379,7 +7630,14 @@ var Launcher = class {
7379
7630
  await writeCaFile(this.base, this.ca).catch(() => void 0);
7380
7631
  }
7381
7632
  environment(cwd, extra) {
7382
- return { PATH: "/usr/bin:/bin", HOME: "/home", ...this.env, PWD: cwd, ...extra };
7633
+ return {
7634
+ PATH: `/usr/bin:/bin:${this.pnpmHome}/bin`,
7635
+ HOME: "/home",
7636
+ PNPM_HOME: this.pnpmHome,
7637
+ ...this.env,
7638
+ PWD: cwd,
7639
+ ...extra
7640
+ };
7383
7641
  }
7384
7642
  async starting(argv, dir) {
7385
7643
  this.catalog = void 0;
@@ -7470,6 +7728,10 @@ function act2(session, req) {
7470
7728
  function dirsChannel(name2) {
7471
7729
  return name2 === false ? void 0 : `slicc-kernel-dirs:${name2}`;
7472
7730
  }
7731
+ async function stores(deps, name2) {
7732
+ if (name2 === false) return {};
7733
+ return { meta: await deps.metadata?.(name2), media: await deps.media?.(`${name2}:media`) };
7734
+ }
7473
7735
  function serveKernel(port, deps) {
7474
7736
  let launcher;
7475
7737
  let remote;
@@ -7521,7 +7783,7 @@ function serveKernel(port, deps) {
7521
7783
  async function init(req) {
7522
7784
  launcher = (req.root ? Promise.resolve(req.root) : deps.storage()).then(async (root) => {
7523
7785
  const name2 = req.metadata ?? META_DB;
7524
- const meta = name2 === false ? void 0 : await deps.metadata?.(name2);
7786
+ const { meta, media } = await stores(deps, name2);
7525
7787
  remote = req.transport ? new RemoteTransport(port, req.transport) : void 0;
7526
7788
  const fs = new OpfsFs(root, meta, dirsChannel(name2));
7527
7789
  await fs.reconcile();
@@ -7532,6 +7794,8 @@ function serveKernel(port, deps) {
7532
7794
  ...req.modules ? { modules: req.modules } : {},
7533
7795
  ...req.env ? { env: req.env } : {},
7534
7796
  ...remote ? { transport: remote } : {},
7797
+ ...media ? { media } : {},
7798
+ onMountPending: (medium) => port.postMessage({ medium }),
7535
7799
  caStore: caStore(deps.metadata ? name2 : false)
7536
7800
  });
7537
7801
  await started.prepare();
@@ -7544,13 +7808,15 @@ function serveKernel(port, deps) {
7544
7808
  const l = await ready2();
7545
7809
  if (req.op === "mount") return l.mount(req.spec);
7546
7810
  if (req.op === "umount") return l.umount(req.target);
7811
+ if (req.op === "insert") return l.insert(req.target, req.handle, req.source);
7547
7812
  return l.mounts.list();
7548
7813
  }
7549
7814
  async function handle(req) {
7550
7815
  if (req.op === "init") return init(req);
7551
7816
  if (req.op === "open-terminal") return terminal(req);
7552
7817
  if (req.op === "connect") return connect();
7553
- if (req.op === "mount" || req.op === "umount" || req.op === "mounts") return mountOp(req);
7818
+ if (req.op === "mount" || req.op === "umount" || req.op === "mounts" || req.op === "insert")
7819
+ return mountOp(req);
7554
7820
  if (req.op === "terminal") {
7555
7821
  const session = terminals.get(req.terminal);
7556
7822
  if (!session) throw new Error(`no terminal ${req.terminal}`);
@@ -7583,6 +7849,7 @@ serveKernel(globalThis, {
7583
7849
  storage: () => navigator.storage.getDirectory(),
7584
7850
  createWorker: () => new Worker(processWorker, { type: "module" }),
7585
7851
  createDriverWorker: () => new Worker(driverWorker, { type: "module" }),
7586
- metadata: (name2) => openMeta(name2, indexedDB)
7852
+ metadata: (name2) => openMeta(name2, indexedDB),
7853
+ media: (name2) => openMedia(name2, indexedDB)
7587
7854
  });
7588
7855
  //# sourceMappingURL=kernel-worker.js.map