@ai-ecoverse/slicc-kernel 1.124.13 → 1.125.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.
@@ -4,12 +4,27 @@ export type WatchChange = {
4
4
  } | {
5
5
  overflow: true;
6
6
  };
7
+ export type WatchEventType = 'rename' | 'change';
8
+ export type WatchNote = {
9
+ type: WatchEventType;
10
+ filename: string;
11
+ } | {
12
+ overflow: true;
13
+ } | {
14
+ ended: true;
15
+ };
16
+ export interface TypedWatch {
17
+ next(signal: AbortSignal): Promise<WatchNote[]>;
18
+ close(): void;
19
+ }
20
+ export declare const WATCH_NOTES_LIMIT = 1000;
7
21
  export interface WatchOptions {
8
22
  recursive?: boolean;
9
23
  }
10
24
  export declare const WATCH_BATCH_LIMIT = 1000;
11
25
  export declare class FsWatchers {
12
26
  private readonly watchers;
27
+ private readonly typed;
13
28
  private readonly taps;
14
29
  private readonly reals;
15
30
  private readonly reshapes;
@@ -17,7 +32,11 @@ export declare class FsWatchers {
17
32
  reshaped(): void;
18
33
  tap(listener: (paths: string[]) => void): void;
19
34
  watch(paths: string[], options: WatchOptions, notify: (change: WatchChange) => void): () => void;
35
+ typedWatch(root: string, recursive: boolean, alias?: string): TypedWatch;
36
+ private covers;
37
+ private emit;
20
38
  changed(...paths: string[]): void;
39
+ private report;
21
40
  private flush;
22
41
  wrap(fs: KernelFs): KernelFs;
23
42
  }
@@ -12,6 +12,7 @@ export interface PollState {
12
12
  readable: boolean;
13
13
  writable: boolean;
14
14
  hangup: boolean;
15
+ nread?: number;
15
16
  rdhup?: boolean;
16
17
  error?: boolean;
17
18
  }
@@ -90,6 +90,7 @@ export interface SpawnWasmOptions {
90
90
  locks?: KernelLocks;
91
91
  fifos?: FifoTable;
92
92
  sems?: SemTable;
93
+ watches?: WasmProcessOptions['watches'];
93
94
  onReap?: (pid: number) => void;
94
95
  resolver?: Resolver;
95
96
  }
@@ -29,6 +29,7 @@ import { LoopbackNet } from './socket.js';
29
29
  import { type SocketSyscall } from './socket-syscalls.js';
30
30
  import type { Termios } from './tty.js';
31
31
  import { type VersionPin, type VfsFileFs, VfsNodes } from './vfs-file.js';
32
+ import { type WatchSource, type WatchSyscall } from './watch-ops.js';
32
33
  export type WasmSyscall = {
33
34
  op: 'fd-read';
34
35
  fd: number;
@@ -334,7 +335,7 @@ export type WasmSyscall = {
334
335
  tid?: number;
335
336
  } | {
336
337
  op: 'sig-pause';
337
- } | SocketSyscall | EpollSyscall | SemSyscall | HttpSyscall | PtySyscall | HostSyscall;
338
+ } | SocketSyscall | EpollSyscall | SemSyscall | HttpSyscall | PtySyscall | HostSyscall | WatchSyscall;
338
339
  export interface FdInfo {
339
340
  tty: boolean;
340
341
  kind: KernelFdKind;
@@ -397,6 +398,7 @@ export interface WasmProcessOptions {
397
398
  dl?: DlState;
398
399
  raise?: (sig: number, info?: SigInfo) => void;
399
400
  exitNow?: (status: number) => void;
401
+ watches?: WatchSource | undefined;
400
402
  exitSignal?: (sig: number) => void;
401
403
  onReap?: (pid: number) => void;
402
404
  jobs?: JobTable;
@@ -412,6 +414,7 @@ export type StateListener = (state: 'stopped' | 'continued', sig: number) => voi
412
414
  export type SignalOutcome = DefaultAction | 'deliver' | 'forward';
413
415
  export declare class WasmProcess {
414
416
  private exited;
417
+ private readonly watches;
415
418
  private readonly children;
416
419
  private readonly deathSignals;
417
420
  private caught;
@@ -3,5 +3,6 @@ export interface SelectResult {
3
3
  read: number[];
4
4
  write: number[];
5
5
  hangup?: number[];
6
+ nread?: Record<number, number>;
6
7
  }
7
8
  export declare function selectFds(fds: FdTable, read: readonly number[], write: readonly number[], timeoutMs: number, interrupt: AbortSignal): Promise<SelectResult>;
@@ -0,0 +1,30 @@
1
+ import type { TypedWatch } from '../fs/watch.js';
2
+ import type { SyncFsResult } from '../realm/sync-fs-wire.js';
3
+ export type WatchSyscall = {
4
+ op: 'watch-open';
5
+ path: string;
6
+ recursive?: boolean;
7
+ } | {
8
+ op: 'watch-next';
9
+ id: number;
10
+ } | {
11
+ op: 'watch-close';
12
+ id: number;
13
+ };
14
+ export declare const WATCH_OPS: readonly ['watch-open', 'watch-next', 'watch-close'];
15
+ export declare function isWatchSyscall(req: {
16
+ op: string;
17
+ }): req is WatchSyscall;
18
+ export declare const WATCHES_MAX = 8192;
19
+ export declare function visibleTo(watch: TypedWatch, root: string, visible: (dir: string) => Promise<boolean>): TypedWatch;
20
+ export interface WatchSource {
21
+ open(path: string, recursive: boolean): Promise<TypedWatch>;
22
+ }
23
+ export declare class ProcessWatches {
24
+ private readonly open;
25
+ private nextId;
26
+ private readonly source;
27
+ constructor(source: WatchSource | undefined);
28
+ syscall(req: WatchSyscall, cancelled: AbortSignal): Promise<SyncFsResult>;
29
+ closeAll(): void;
30
+ }
@@ -360,6 +360,7 @@ export declare class Launcher {
360
360
  private fsaDriver;
361
361
  revokeIntegrity(path?: string): Promise<void>;
362
362
  attest(path: string): Promise<Attestation>;
363
+ private watchSource;
363
364
  watchFiles(paths: readonly string[], notify: (path: string) => void): Promise<() => void>;
364
365
  mount(spec: MountSpec): Promise<MountEntry>;
365
366
  private mountShm;
@@ -5,6 +5,7 @@ import { type JsKernel } from './js-kernel.js';
5
5
  import { type JsNet } from './js-net.js';
6
6
  import { type JsSyncContext, type SyncCall } from './js-sync.js';
7
7
  import { type JsTty } from './js-tty.js';
8
+ import { type JsWatcher, type JsWatchListener, type JsWatchOptions } from './js-watch.js';
8
9
  import { type JsWebSocket, type JsWebSocketOptions } from './js-websocket.js';
9
10
  export type { JsFdType, JsOpenOptions } from './js-io.js';
10
11
  export interface JsFile {
@@ -65,6 +66,7 @@ export interface JsProgramContext {
65
66
  writeFile(path: string, data: Uint8Array | string, options?: {
66
67
  mode?: number;
67
68
  }): Promise<void>;
69
+ watch(path: string, options: JsWatchOptions | JsWatchListener, listener?: JsWatchListener): Promise<JsWatcher>;
68
70
  };
69
71
  signals: {
70
72
  on(signal: JsSignal, handler: (signal: number) => void): Promise<void>;
@@ -5,6 +5,7 @@ import type { JsChild, JsSpawnOptions } from './js-children.js';
5
5
  import { type FdInfo, type JsOpenOptions, type JsStatFs } from './js-io.js';
6
6
  import { type JsKernel } from './js-kernel.js';
7
7
  import type { JsRunOptions, JsRunResult } from './js-run.js';
8
+ import type { JsWatcher, JsWatchListener, JsWatchOptions } from './js-watch.js';
8
9
  export type SyncCall = (req: SyncSabRequestBody) => SyncFsResult;
9
10
  export interface JsSyncFile {
10
11
  readonly fd: number;
@@ -61,6 +62,7 @@ export interface JsSyncContext {
61
62
  writeFile(path: string, data: Uint8Array | string, options?: {
62
63
  mode?: number;
63
64
  }): void;
65
+ watch(path: string, options: JsWatchOptions | JsWatchListener, listener?: JsWatchListener): JsWatcher;
64
66
  };
65
67
  }
66
68
  export interface SyncShared {
@@ -83,4 +85,6 @@ export declare class JsSyncKernel {
83
85
  bytes(req: SyncSabRequestBody): Uint8Array;
84
86
  blocking(req: SyncSabRequestBody): SyncFsResult;
85
87
  }
86
- export declare function syncOps(kernel: JsSyncKernel, shared: SyncShared): Omit<JsSyncContext, 'run' | 'spawn' | 'exit' | 'kill' | 'cred' | 'setcred' | 'kernel' | 'umask'>;
88
+ export declare function syncOps(kernel: JsSyncKernel, shared: SyncShared): Omit<JsSyncContext, 'run' | 'spawn' | 'exit' | 'kill' | 'cred' | 'setcred' | 'kernel' | 'umask' | 'fs'> & {
89
+ fs: Omit<JsSyncContext['fs'], 'watch'>;
90
+ };
@@ -0,0 +1,17 @@
1
+ import type { WatchNote } from '../../fs/watch.js';
2
+ import type { JsKernel } from './js-kernel.js';
3
+ export type JsWatchNote = WatchNote;
4
+ export interface JsWatchOptions {
5
+ recursive?: boolean;
6
+ }
7
+ export interface JsWatcher {
8
+ close(): void;
9
+ }
10
+ export type JsWatchListener = (note: JsWatchNote) => void;
11
+ export declare function watchRequest(path: string, options: JsWatchOptions | undefined): {
12
+ op: 'watch-open';
13
+ path: string;
14
+ recursive?: boolean | undefined;
15
+ };
16
+ export declare function watchArgs(options: JsWatchOptions | JsWatchListener | undefined, listener: JsWatchListener | undefined): [JsWatchOptions, JsWatchListener];
17
+ export declare function follow(kernel: Pick<JsKernel, 'blocking' | 'call'>, id: number, onNote: JsWatchListener): JsWatcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-kernel",
3
- "version": "1.124.13",
3
+ "version": "1.125.0",
4
4
  "description": "SLICC's wasm-realm kernel: run Emscripten programs in the browser against OPFS, with fork, spawn, pipes and waitpid",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -66,7 +66,7 @@
66
66
  "@ai-ecoverse/py-numpy": "2.3.2-11",
67
67
  "@ai-ecoverse/slicc-node": "2.5.1",
68
68
  "@ai-ecoverse/slicc-scrub": "1.0.0",
69
- "@ai-ecoverse/slicc-shared-web": "1.23.3",
69
+ "@ai-ecoverse/slicc-shared-web": "1.24.0",
70
70
  "@ai-ecoverse/wasi-cargo": "0.99.0-3",
71
71
  "@ai-ecoverse/wasi-pnpm": "12.9.1-10",
72
72
  "@ai-ecoverse/wasi-ripgrep": "15.2.0-5",
@@ -81,7 +81,7 @@
81
81
  "@ai-ecoverse/wasm-procps": "4.0.7-3",
82
82
  "@ai-ecoverse/wasm-sqlite3": "3.54.0-5",
83
83
  "@ai-ecoverse/wasm-tar": "1.35.0-7",
84
- "@ai-ecoverse/wasm-tls-engine": "4.2.0-3",
84
+ "@ai-ecoverse/wasm-tls-engine": "4.2.0-4",
85
85
  "@ai-ecoverse/wasm-tree": "2.3.2-4",
86
86
  "@ai-ecoverse/wasm-util-linux": "2.42.4-3",
87
87
  "@biomejs/biome": "2.5.15",