@polyengine/wasi 0.4.0-pre.gebdce7f → 0.5.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.
- package/esm/cli_stdio.js +2 -2
- package/esm/http.js +1 -1
- package/esm/internal/fs_provider.js +120 -40
- package/esm/internal/sockets_02.js +1 -1
- package/esm/internal/sockets_03.js +2 -2
- package/esm/internal/sockets_shared.js +1 -1
- package/esm/io.js +6 -2
- package/esm/mod.js +2 -1
- package/package.json +2 -3
- package/types/http.d.ts +1 -1
- package/types/internal/cli_shared.d.ts +1 -1
- package/types/internal/fs_provider.d.ts +1 -1
- package/types/internal/sockets_shared.d.ts +1 -1
package/esm/cli_stdio.js
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
// error.
|
|
47
47
|
// * terminals: reported from the real streams' `isTTY` (injectable).
|
|
48
48
|
// * environment/arguments/cwd: the host process's, overridable.
|
|
49
|
-
import {
|
|
49
|
+
import { isStream } from "@polyengine/protocol";
|
|
50
50
|
import { ExitError, TerminalInput, TerminalOutput, } from "./internal/cli_shared.js";
|
|
51
51
|
import { FedInputStream, SinkOutputStream } from "./io.js";
|
|
52
52
|
const OK = { kind: "ok" };
|
|
@@ -119,7 +119,7 @@ export function cliStdio(options = {}) {
|
|
|
119
119
|
return OK;
|
|
120
120
|
}
|
|
121
121
|
catch (e) {
|
|
122
|
-
if (data
|
|
122
|
+
if (isStream(data))
|
|
123
123
|
data.drop(); // the guest's writer must not hang
|
|
124
124
|
return { kind: "err", value: ioErrorCode(e) };
|
|
125
125
|
}
|
package/esm/http.js
CHANGED
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
// A10: case names are data, kebab-case as written, including capitals).
|
|
66
66
|
// Fetch failures are TypeErrors with prose; a small sniff table maps the
|
|
67
67
|
// recognizable ones and everything else is `internal-error(message)`.
|
|
68
|
-
import { ComponentException, isComponentException } from "@polyengine/
|
|
68
|
+
import { ComponentException, isComponentException } from "@polyengine/protocol";
|
|
69
69
|
/**
|
|
70
70
|
* The compatibility track the fragment registers on by default.
|
|
71
71
|
*
|
|
@@ -46,13 +46,31 @@
|
|
|
46
46
|
// from one site. Refusals use the WIT `read-only` error code.
|
|
47
47
|
//
|
|
48
48
|
// Two DISTINCT concerns, deliberately not merged:
|
|
49
|
-
// * per-descriptor flags (`requireWrite`) -> `bad-descriptor`: this
|
|
50
|
-
// descriptor was not opened for writing / directory mutation;
|
|
51
49
|
// * the global grant (`requireWritable`) -> `read-only`: this
|
|
52
|
-
// filesystem is read-only, whatever the descriptor says.
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
50
|
+
// filesystem is read-only, whatever the descriptor says. It runs
|
|
51
|
+
// FIRST on every mutating leaf, so a read-only package answers
|
|
52
|
+
// `read-only` uniformly rather than leaking descriptor bookkeeping.
|
|
53
|
+
// * per-descriptor flags, which SPLIT by descriptor kind because the
|
|
54
|
+
// WIT dictates one half and is silent on the other:
|
|
55
|
+
// - directories (`requireDirMutate`) -> `read-only`. WIT-mandated:
|
|
56
|
+
// of `mutate-directory`, "When this flag is unset on a
|
|
57
|
+
// descriptor, operations using the descriptor which would
|
|
58
|
+
// create, rename, delete, modify the data or metadata of
|
|
59
|
+
// filesystem objects, or obtain another handle which would
|
|
60
|
+
// permit any of those, shall fail with `error-code::read-only`".
|
|
61
|
+
// - files (`requireFileWrite`) -> `bad-descriptor`. The WIT says
|
|
62
|
+
// nothing about a file descriptor opened without `write`; POSIX
|
|
63
|
+
// answers EBADF for a write on a handle not opened for writing,
|
|
64
|
+
// so we do. `mutate-directory` is NOT accepted here: the WIT
|
|
65
|
+
// says it "may only be set on directories".
|
|
66
|
+
// The "obtain another handle" fragment is why `open-at` carries an
|
|
67
|
+
// ESCALATION clause: through a directory descriptor without
|
|
68
|
+
// `mutate-directory`, an open asking for `write`/`mutate-directory` (or
|
|
69
|
+
// `create`/`truncate`/`exclusive`) is refused `read-only` — otherwise
|
|
70
|
+
// the handle it mints would launder the missing permission.
|
|
71
|
+
// Path-ops check kind before permission (`requireDir` first), so a
|
|
72
|
+
// path-op through a FILE descriptor reports `not-directory` rather than
|
|
73
|
+
// a bogus `read-only` — wasmtime's `Descriptor::dir()` ordering.
|
|
56
74
|
//
|
|
57
75
|
// PATHS. Guest paths are resolved TEXTUALLY: split on "/", drop "." and
|
|
58
76
|
// empty segments, ".." pops (underflow = `not-permitted`), absolute
|
|
@@ -66,7 +84,7 @@
|
|
|
66
84
|
// (filesystem_node.ts header, issue #177), so guest-created and
|
|
67
85
|
// pre-existing escaping symlinks alike are refused with `not-permitted`;
|
|
68
86
|
// OPFS has no symlinks, so the web backend is immune by construction.
|
|
69
|
-
import { ComponentException,
|
|
87
|
+
import { ComponentException, isStream, suspending } from "@polyengine/protocol";
|
|
70
88
|
import { FedInputStream, IoError, OutputStream, Pollable, SinkOutputStream } from "../io.js";
|
|
71
89
|
const OK03 = { kind: "ok" };
|
|
72
90
|
// --- errors ----------------------------------------------------------------------
|
|
@@ -258,8 +276,9 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
258
276
|
});
|
|
259
277
|
const PREOPEN_FLAGS = flagsValue({ read: true, write: true, mutateDirectory: true });
|
|
260
278
|
/** The package-level grant. Refuses with the WIT `read-only` code —
|
|
261
|
-
* distinct from
|
|
262
|
-
*
|
|
279
|
+
* distinct from the per-descriptor checks (`requireDirMutate`,
|
|
280
|
+
* `requireFileWrite`; module header). Called FIRST by every mutating
|
|
281
|
+
* leaf. */
|
|
263
282
|
const requireWritable = (shape) => {
|
|
264
283
|
if (!writable)
|
|
265
284
|
throw shape("read-only");
|
|
@@ -366,10 +385,21 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
366
385
|
if (!c.flags.read)
|
|
367
386
|
throw shape("bad-descriptor");
|
|
368
387
|
};
|
|
369
|
-
|
|
370
|
-
|
|
388
|
+
/** Per-descriptor write permission on a FILE. WIT-silent; POSIX EBADF
|
|
389
|
+
* (module header). `mutate-directory` deliberately does NOT satisfy
|
|
390
|
+
* it: the WIT says that flag "may only be set on directories". */
|
|
391
|
+
const requireFileWrite = (c, shape) => {
|
|
392
|
+
if (!c.flags.write)
|
|
371
393
|
throw shape("bad-descriptor");
|
|
372
394
|
};
|
|
395
|
+
/** Per-descriptor mutation permission on a DIRECTORY. The WIT's
|
|
396
|
+
* `mutate-directory` doc mandates the code: operations that would
|
|
397
|
+
* create/rename/delete/modify "shall fail with
|
|
398
|
+
* `error-code::read-only`". */
|
|
399
|
+
const requireDirMutate = (c, shape) => {
|
|
400
|
+
if (!c.flags.mutateDirectory)
|
|
401
|
+
throw shape("read-only");
|
|
402
|
+
};
|
|
373
403
|
// --- the 0.2 track ---------------------------------------------------------
|
|
374
404
|
class DirectoryEntryStream02 {
|
|
375
405
|
#entries;
|
|
@@ -402,7 +432,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
402
432
|
return g02(() => {
|
|
403
433
|
requireWritable(err02);
|
|
404
434
|
requireFile(this.core, err02);
|
|
405
|
-
|
|
435
|
+
requireFileWrite(this.core, err02);
|
|
406
436
|
let cursor = Number(offset);
|
|
407
437
|
if (backend.isSync) {
|
|
408
438
|
return syncWriteStream((chunk) => {
|
|
@@ -418,7 +448,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
418
448
|
return g02(() => {
|
|
419
449
|
requireWritable(err02);
|
|
420
450
|
requireFile(this.core, err02);
|
|
421
|
-
|
|
451
|
+
requireFileWrite(this.core, err02);
|
|
422
452
|
if (backend.isSync) {
|
|
423
453
|
return syncWriteStream((chunk) => void backend.append(this.core.h, chunk));
|
|
424
454
|
}
|
|
@@ -442,14 +472,19 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
442
472
|
setSize(size) {
|
|
443
473
|
return g02(() => {
|
|
444
474
|
requireWritable(err02);
|
|
445
|
-
|
|
475
|
+
requireFileWrite(this.core, err02);
|
|
446
476
|
return backend.setSize(this.core.h, Number(size));
|
|
447
477
|
});
|
|
448
478
|
}
|
|
449
479
|
setTimes(atime, mtime) {
|
|
450
480
|
return g02(() => {
|
|
451
481
|
requireWritable(err02);
|
|
452
|
-
|
|
482
|
+
// The descriptor's OWN times: which half of the per-descriptor
|
|
483
|
+
// rule applies depends on what this descriptor IS (module header).
|
|
484
|
+
if (this.core.type === "directory")
|
|
485
|
+
requireDirMutate(this.core, err02);
|
|
486
|
+
else
|
|
487
|
+
requireFileWrite(this.core, err02);
|
|
453
488
|
return backend.setTimes(this.core.h, newTimestampToSpec(atime), newTimestampToSpec(mtime));
|
|
454
489
|
});
|
|
455
490
|
}
|
|
@@ -465,7 +500,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
465
500
|
return g02(() => {
|
|
466
501
|
requireWritable(err02);
|
|
467
502
|
requireFile(this.core, err02);
|
|
468
|
-
|
|
503
|
+
requireFileWrite(this.core, err02);
|
|
469
504
|
return chain(backend.write(this.core.h, buffer, Number(offset)), BigInt);
|
|
470
505
|
});
|
|
471
506
|
}
|
|
@@ -481,7 +516,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
481
516
|
createDirectoryAt(path) {
|
|
482
517
|
return g02(() => {
|
|
483
518
|
requireWritable(err02);
|
|
484
|
-
|
|
519
|
+
requireDir(this.core, err02);
|
|
520
|
+
requireDirMutate(this.core, err02);
|
|
485
521
|
return backend.createDirectoryAt(this.core.h, requireFinal(parsePath(path, err02), err02));
|
|
486
522
|
});
|
|
487
523
|
}
|
|
@@ -494,7 +530,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
494
530
|
setTimesAt(pathFlags, path, atime, mtime) {
|
|
495
531
|
return g02(() => {
|
|
496
532
|
requireWritable(err02);
|
|
497
|
-
|
|
533
|
+
requireDir(this.core, err02);
|
|
534
|
+
requireDirMutate(this.core, err02);
|
|
498
535
|
return backend.setTimesAt(this.core.h, parsePath(path, err02), pathFlags.symlinkFollow === true, newTimestampToSpec(atime), newTimestampToSpec(mtime));
|
|
499
536
|
});
|
|
500
537
|
}
|
|
@@ -505,14 +542,27 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
505
542
|
throw err02("unsupported");
|
|
506
543
|
// Both ends: a two-descriptor op checked on one side only is the
|
|
507
544
|
// classic bridge bug (module header).
|
|
508
|
-
|
|
509
|
-
|
|
545
|
+
requireDir(this.core, err02);
|
|
546
|
+
requireDirMutate(this.core, err02);
|
|
547
|
+
requireDir(newDescriptor.core, err02);
|
|
548
|
+
requireDirMutate(newDescriptor.core, err02);
|
|
510
549
|
return backend.linkAt(this.core.h, requireFinal(parsePath(oldPath, err02), err02), oldPathFlags.symlinkFollow === true, newDescriptor.core.h, requireFinal(parsePath(newPath, err02), err02));
|
|
511
550
|
});
|
|
512
551
|
}
|
|
513
552
|
openAt(pathFlags, path, openFlags, flags) {
|
|
514
553
|
return g02(() => {
|
|
515
554
|
requireOpenAllowed(openFlags, flags, err02);
|
|
555
|
+
requireDir(this.core, err02);
|
|
556
|
+
// "obtain another handle which would permit any of those" (WIT,
|
|
557
|
+
// mutate-directory): a base directory without mutate-directory
|
|
558
|
+
// cannot mint a handle that escalates. `exclusive` is included
|
|
559
|
+
// beyond the WIT's literal create/truncate to mirror the
|
|
560
|
+
// package-level `requireOpenAllowed` enumeration.
|
|
561
|
+
if (flags.write === true || flags.mutateDirectory === true ||
|
|
562
|
+
openFlags.create === true || openFlags.truncate === true ||
|
|
563
|
+
openFlags.exclusive === true) {
|
|
564
|
+
requireDirMutate(this.core, err02);
|
|
565
|
+
}
|
|
516
566
|
return chain(backend.openAt(this.core.h, parsePath(path, err02), decodeOpen(pathFlags, openFlags, flags)), ({ handle, type }) => new Descriptor02(handle, type, flagsValue(flags)));
|
|
517
567
|
});
|
|
518
568
|
}
|
|
@@ -526,7 +576,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
526
576
|
removeDirectoryAt(path) {
|
|
527
577
|
return g02(() => {
|
|
528
578
|
requireWritable(err02);
|
|
529
|
-
|
|
579
|
+
requireDir(this.core, err02);
|
|
580
|
+
requireDirMutate(this.core, err02);
|
|
530
581
|
return backend.removeDirectoryAt(this.core.h, requireFinal(parsePath(path, err02), err02));
|
|
531
582
|
});
|
|
532
583
|
}
|
|
@@ -534,8 +585,10 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
534
585
|
return g02(() => {
|
|
535
586
|
requireWritable(err02);
|
|
536
587
|
// Both ends (see link-at).
|
|
537
|
-
|
|
538
|
-
|
|
588
|
+
requireDir(this.core, err02);
|
|
589
|
+
requireDirMutate(this.core, err02);
|
|
590
|
+
requireDir(newDescriptor.core, err02);
|
|
591
|
+
requireDirMutate(newDescriptor.core, err02);
|
|
539
592
|
return backend.renameAt(this.core.h, requireFinal(parsePath(oldPath, err02), err02), newDescriptor.core.h, requireFinal(parsePath(newPath, err02), err02));
|
|
540
593
|
});
|
|
541
594
|
}
|
|
@@ -544,7 +597,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
544
597
|
requireWritable(err02);
|
|
545
598
|
if (backend.symlinkAt === undefined)
|
|
546
599
|
throw err02("unsupported");
|
|
547
|
-
|
|
600
|
+
requireDir(this.core, err02);
|
|
601
|
+
requireDirMutate(this.core, err02);
|
|
548
602
|
// old-path is the link CONTENTS (never validated as a lookup path).
|
|
549
603
|
return backend.symlinkAt(oldPath, this.core.h, requireFinal(parsePath(newPath, err02), err02));
|
|
550
604
|
});
|
|
@@ -552,7 +606,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
552
606
|
unlinkFileAt(path) {
|
|
553
607
|
return g02(() => {
|
|
554
608
|
requireWritable(err02);
|
|
555
|
-
|
|
609
|
+
requireDir(this.core, err02);
|
|
610
|
+
requireDirMutate(this.core, err02);
|
|
556
611
|
return backend.unlinkFileAt(this.core.h, requireFinal(parsePath(path, err02), err02));
|
|
557
612
|
});
|
|
558
613
|
}
|
|
@@ -602,7 +657,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
602
657
|
try {
|
|
603
658
|
requireWritable(err03);
|
|
604
659
|
requireFile(this.core, err03);
|
|
605
|
-
|
|
660
|
+
requireFileWrite(this.core, err03);
|
|
606
661
|
let cursor = Number(offset);
|
|
607
662
|
for await (const chunk of data) {
|
|
608
663
|
const bytes = chunk instanceof Uint8Array ? chunk : Uint8Array.from(chunk);
|
|
@@ -611,7 +666,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
611
666
|
return OK03;
|
|
612
667
|
}
|
|
613
668
|
catch (e) {
|
|
614
|
-
if (data
|
|
669
|
+
if (isStream(data))
|
|
615
670
|
data.drop(); // the guest's writer must not hang
|
|
616
671
|
return {
|
|
617
672
|
kind: "err",
|
|
@@ -623,7 +678,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
623
678
|
try {
|
|
624
679
|
requireWritable(err03);
|
|
625
680
|
requireFile(this.core, err03);
|
|
626
|
-
|
|
681
|
+
requireFileWrite(this.core, err03);
|
|
627
682
|
for await (const chunk of data) {
|
|
628
683
|
const bytes = chunk instanceof Uint8Array ? chunk : Uint8Array.from(chunk);
|
|
629
684
|
await backend.append(this.core.h, bytes);
|
|
@@ -631,7 +686,7 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
631
686
|
return OK03;
|
|
632
687
|
}
|
|
633
688
|
catch (e) {
|
|
634
|
-
if (data
|
|
689
|
+
if (isStream(data))
|
|
635
690
|
data.drop();
|
|
636
691
|
return {
|
|
637
692
|
kind: "err",
|
|
@@ -654,14 +709,19 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
654
709
|
setSize(size) {
|
|
655
710
|
return g03(() => {
|
|
656
711
|
requireWritable(err03);
|
|
657
|
-
|
|
712
|
+
requireFileWrite(this.core, err03);
|
|
658
713
|
return backend.setSize(this.core.h, Number(size));
|
|
659
714
|
});
|
|
660
715
|
}
|
|
661
716
|
setTimes(atime, mtime) {
|
|
662
717
|
return g03(() => {
|
|
663
718
|
requireWritable(err03);
|
|
664
|
-
|
|
719
|
+
// The descriptor's OWN times: which half of the per-descriptor
|
|
720
|
+
// rule applies depends on what this descriptor IS (module header).
|
|
721
|
+
if (this.core.type === "directory")
|
|
722
|
+
requireDirMutate(this.core, err03);
|
|
723
|
+
else
|
|
724
|
+
requireFileWrite(this.core, err03);
|
|
665
725
|
return backend.setTimes(this.core.h, newTimestampToSpec(atime), newTimestampToSpec(mtime));
|
|
666
726
|
});
|
|
667
727
|
}
|
|
@@ -681,7 +741,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
681
741
|
createDirectoryAt(path) {
|
|
682
742
|
return g03(() => {
|
|
683
743
|
requireWritable(err03);
|
|
684
|
-
|
|
744
|
+
requireDir(this.core, err03);
|
|
745
|
+
requireDirMutate(this.core, err03);
|
|
685
746
|
return backend.createDirectoryAt(this.core.h, requireFinal(parsePath(path, err03), err03));
|
|
686
747
|
});
|
|
687
748
|
}
|
|
@@ -694,7 +755,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
694
755
|
setTimesAt(pathFlags, path, atime, mtime) {
|
|
695
756
|
return g03(() => {
|
|
696
757
|
requireWritable(err03);
|
|
697
|
-
|
|
758
|
+
requireDir(this.core, err03);
|
|
759
|
+
requireDirMutate(this.core, err03);
|
|
698
760
|
return backend.setTimesAt(this.core.h, parsePath(path, err03), pathFlags.symlinkFollow === true, newTimestampToSpec(atime), newTimestampToSpec(mtime));
|
|
699
761
|
});
|
|
700
762
|
}
|
|
@@ -705,14 +767,27 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
705
767
|
throw err03("unsupported");
|
|
706
768
|
// Both ends: a two-descriptor op checked on one side only is the
|
|
707
769
|
// classic bridge bug (module header).
|
|
708
|
-
|
|
709
|
-
|
|
770
|
+
requireDir(this.core, err03);
|
|
771
|
+
requireDirMutate(this.core, err03);
|
|
772
|
+
requireDir(newDescriptor.core, err03);
|
|
773
|
+
requireDirMutate(newDescriptor.core, err03);
|
|
710
774
|
return backend.linkAt(this.core.h, requireFinal(parsePath(oldPath, err03), err03), oldPathFlags.symlinkFollow === true, newDescriptor.core.h, requireFinal(parsePath(newPath, err03), err03));
|
|
711
775
|
});
|
|
712
776
|
}
|
|
713
777
|
openAt(pathFlags, path, openFlags, flags) {
|
|
714
778
|
return g03(() => {
|
|
715
779
|
requireOpenAllowed(openFlags, flags, err03);
|
|
780
|
+
requireDir(this.core, err03);
|
|
781
|
+
// "obtain another handle which would permit any of those" (WIT,
|
|
782
|
+
// mutate-directory): a base directory without mutate-directory
|
|
783
|
+
// cannot mint a handle that escalates. `exclusive` is included
|
|
784
|
+
// beyond the WIT's literal create/truncate to mirror the
|
|
785
|
+
// package-level `requireOpenAllowed` enumeration.
|
|
786
|
+
if (flags.write === true || flags.mutateDirectory === true ||
|
|
787
|
+
openFlags.create === true || openFlags.truncate === true ||
|
|
788
|
+
openFlags.exclusive === true) {
|
|
789
|
+
requireDirMutate(this.core, err03);
|
|
790
|
+
}
|
|
716
791
|
return chain(backend.openAt(this.core.h, parsePath(path, err03), decodeOpen(pathFlags, openFlags, flags)), ({ handle, type }) => new Descriptor03(handle, type, flagsValue(flags)));
|
|
717
792
|
});
|
|
718
793
|
}
|
|
@@ -726,7 +801,8 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
726
801
|
removeDirectoryAt(path) {
|
|
727
802
|
return g03(() => {
|
|
728
803
|
requireWritable(err03);
|
|
729
|
-
|
|
804
|
+
requireDir(this.core, err03);
|
|
805
|
+
requireDirMutate(this.core, err03);
|
|
730
806
|
return backend.removeDirectoryAt(this.core.h, requireFinal(parsePath(path, err03), err03));
|
|
731
807
|
});
|
|
732
808
|
}
|
|
@@ -734,8 +810,10 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
734
810
|
return g03(() => {
|
|
735
811
|
requireWritable(err03);
|
|
736
812
|
// Both ends (see link-at).
|
|
737
|
-
|
|
738
|
-
|
|
813
|
+
requireDir(this.core, err03);
|
|
814
|
+
requireDirMutate(this.core, err03);
|
|
815
|
+
requireDir(newDescriptor.core, err03);
|
|
816
|
+
requireDirMutate(newDescriptor.core, err03);
|
|
739
817
|
return backend.renameAt(this.core.h, requireFinal(parsePath(oldPath, err03), err03), newDescriptor.core.h, requireFinal(parsePath(newPath, err03), err03));
|
|
740
818
|
});
|
|
741
819
|
}
|
|
@@ -744,14 +822,16 @@ export function makeFilesystem(backend, preopens, access = {}) {
|
|
|
744
822
|
requireWritable(err03);
|
|
745
823
|
if (backend.symlinkAt === undefined)
|
|
746
824
|
throw err03("unsupported");
|
|
747
|
-
|
|
825
|
+
requireDir(this.core, err03);
|
|
826
|
+
requireDirMutate(this.core, err03);
|
|
748
827
|
return backend.symlinkAt(oldPath, this.core.h, requireFinal(parsePath(newPath, err03), err03));
|
|
749
828
|
});
|
|
750
829
|
}
|
|
751
830
|
unlinkFileAt(path) {
|
|
752
831
|
return g03(() => {
|
|
753
832
|
requireWritable(err03);
|
|
754
|
-
|
|
833
|
+
requireDir(this.core, err03);
|
|
834
|
+
requireDirMutate(this.core, err03);
|
|
755
835
|
return backend.unlinkFileAt(this.core.h, requireFinal(parsePath(path, err03), err03));
|
|
756
836
|
});
|
|
757
837
|
}
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
// of sockets.ts) — tcp keep-alive enabled/idle-time and udp
|
|
48
48
|
// hop-limit/buffer-sizes are real where node has API, cached-getter
|
|
49
49
|
// where it has only a setter, `not-supported` where it has neither.
|
|
50
|
-
import { ComponentException } from "@polyengine/
|
|
50
|
+
import { ComponentException } from "@polyengine/protocol";
|
|
51
51
|
import { FedInputStream, IoError, Pollable, SinkOutputStream } from "../io.js";
|
|
52
52
|
import { dnsLookup, listenDatagram, tcpConnect, tcpListen, } from "./sockets_platform.js";
|
|
53
53
|
import { ipHostname, isUnspecified, isValidAddressFamily, mapPlatformError, MAX_UDP_DATAGRAM_SIZE, parseNetAddr, sameSocketAddress, } from "./sockets_shared.js";
|
|
@@ -37,7 +37,7 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
37
37
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
38
38
|
done = true;
|
|
39
39
|
};
|
|
40
|
-
import { ComponentException,
|
|
40
|
+
import { ComponentException, isStream, suspending } from "@polyengine/protocol";
|
|
41
41
|
import { dnsLookup, listenDatagram, tcpConnect, tcpListen, } from "./sockets_platform.js";
|
|
42
42
|
import { componentError, ipHostname, isDenoError, isUnspecified, isValidAddressFamily, mapPlatformError, MAX_UDP_DATAGRAM_SIZE, parseNetAddr, RESULT_INVALID_STATE, RESULT_OK, resultErrOf, sameSocketAddress, wildcardAddress, } from "./sockets_shared.js";
|
|
43
43
|
/**
|
|
@@ -964,6 +964,6 @@ const TRANSIENT_ACCEPT_FAILURES = new Set([
|
|
|
964
964
|
* iteration protocol itself (`for await`'s abrupt-exit `return()`).
|
|
965
965
|
*/
|
|
966
966
|
function dropSendSource(data) {
|
|
967
|
-
if (data
|
|
967
|
+
if (isStream(data))
|
|
968
968
|
data.drop();
|
|
969
969
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// (sockets_03.ts, sockets_02.ts) — not a package export; the public home
|
|
3
3
|
// of these names is `@polyengine/wasi/sockets`. Address codec, wasmtime-parity
|
|
4
4
|
// validation, platform error mapping, and the WIT-facing type shapes.
|
|
5
|
-
import { ComponentException } from "@polyengine/
|
|
5
|
+
import { ComponentException } from "@polyengine/protocol";
|
|
6
6
|
/**
|
|
7
7
|
* The datagram payload ceiling, matching wasmtime-wasi's
|
|
8
8
|
* `MAX_UDP_DATAGRAM_SIZE` (`u16::MAX`). Larger sends fail
|
package/esm/io.js
CHANGED
|
@@ -79,8 +79,8 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
79
79
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
80
80
|
done = true;
|
|
81
81
|
};
|
|
82
|
-
import { defineBrand, POLLABLE } from "@polyengine/protocol";
|
|
83
|
-
import { suspending, ComponentException } from "@polyengine/
|
|
82
|
+
import { defineBrand, defineRealmLocal, POLLABLE } from "@polyengine/protocol";
|
|
83
|
+
import { suspending, ComponentException } from "@polyengine/protocol";
|
|
84
84
|
/** The engine setTimeout ceiling: delays above 2^31-1 ms are clamped to
|
|
85
85
|
* ~0 (node/Deno warn and fire at 1 ms). `Pollable.timer` sleeps in
|
|
86
86
|
* chunks of at most this and re-checks the clock at each chunk end. */
|
|
@@ -135,6 +135,10 @@ let Pollable = (() => {
|
|
|
135
135
|
constructor(ready = () => true, wait = () => Promise.resolve()) {
|
|
136
136
|
this.#ready = ready;
|
|
137
137
|
this.#wait = wait;
|
|
138
|
+
// A20 realm-local pill (contracts/embedder-api.md §"Realm boundaries
|
|
139
|
+
// and structured-clone-safe forms"; issue #131): stateful handles fail
|
|
140
|
+
// loud at a raw structuredClone/postMessage instead of husking.
|
|
141
|
+
defineRealmLocal(this);
|
|
138
142
|
}
|
|
139
143
|
/**
|
|
140
144
|
* A pollable that becomes ready at `deadline` (nanoseconds on the
|
package/esm/mod.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// `@polyengine/wasi` — the WASI providers for polyengine hosts, and the
|
|
2
2
|
// executable check that the embedder conventions
|
|
3
|
-
// (`@polyengine/
|
|
3
|
+
// (`@polyengine/protocol`, amendment A22 — this package is protocol-only)
|
|
4
|
+
// serve WASI (contracts/embedder-api.md C2
|
|
4
5
|
// checklist item 7; docs/architecture.md §2 keeps implementations out of
|
|
5
6
|
// the RUNTIME — this package is where they live). Scope: p2
|
|
6
7
|
// baseline + p3 clocks + à la carte sockets on BOTH tracks (the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polyengine/wasi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "WASI providers for polyengine hosts: the p2 baseline and p3 clocks, one module per semver track.",
|
|
5
5
|
"homepage": "https://github.com/polymorph-components/polyengine#readme",
|
|
6
6
|
"repository": {
|
|
@@ -91,8 +91,7 @@
|
|
|
91
91
|
"access": "public"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"@polyengine/protocol": "^0.2.
|
|
95
|
-
"@polyengine/runtime": "0.4.0-pre.gebdce7f"
|
|
94
|
+
"@polyengine/protocol": "^0.2.2"
|
|
96
95
|
},
|
|
97
96
|
"_generatedBy": "dnt@0.43.2"
|
|
98
97
|
}
|
package/types/http.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Stream } from "@polyengine/
|
|
1
|
+
import type { Stream } from "@polyengine/protocol";
|
|
2
2
|
/** `wasi:cli/types@0.3`'s `error-code` ENUM: bare kebab-case strings (the
|
|
3
3
|
* A10 value table — enums are data strings, not `{kind}` variants; this
|
|
4
4
|
* type carried a `{kind}` wrapper until 2026-08-14, a latent bug no err
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentException, Stream } from "@polyengine/
|
|
1
|
+
import { ComponentException, type Stream } from "@polyengine/protocol";
|
|
2
2
|
import { IoError } from "../io.js";
|
|
3
3
|
/** `wasi:filesystem/types.error-code` labels. 0.2 (enum): all of these,
|
|
4
4
|
* bare. 0.3 (variant): all but `would-block`, as `{kind}` — this package
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentException, Stream } from "@polyengine/
|
|
1
|
+
import { ComponentException, type Stream } from "@polyengine/protocol";
|
|
2
2
|
import type { NetAddr } from "./sockets_platform.js";
|
|
3
3
|
export type { NetAddr };
|
|
4
4
|
/** `wasi:sockets/types@0.3`'s `ip-address-family` enum. */
|