@@ -125,7 +125,8 @@ never be allowed using this API, rather than leaving it entirely up to underlyin
125
125
systems.
126
126
127
127
A <dfn>lock type</dfn> is a [=string=] that may exclusively be "`open`",
128
- "`exclusive`", or "`shared`".
128
+ "`exclusive`", "`writable-siloed`", "`sync-access-handle-read-only`",
129
+ "`sync-access-handle-read-write-unsafe`".
129
130
130
131
A <dfn export id=file>file entry</dfn> additionally consists of
131
132
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=] ), a
@@ -170,8 +171,7 @@ Note: These steps have to be run on the [=file system queue=].
170
171
171
172
</div>
172
173
173
- Note: Locks help prevent concurrent modifications to a file. A {{FileSystemWritableFileStream}}
174
- requires a shared lock, while a {{FileSystemSyncAccessHandle}} requires an exclusive one.
174
+ Note: Locks help prevent concurrent modifications to a file that are incompatible.
175
175
176
176
A <dfn export id=directory>directory entry</dfn> additionally consists of a [=/set=] of
177
177
<dfn for="directory entry">children</dfn> , which are themselves [=/file system entries=] .
@@ -417,16 +417,32 @@ The <dfn method for=FileSystemHandle>isSameEntry(|other|)</dfn> method steps are
417
417
## The {{FileSystemFileHandle}} interface ## {#api-filesystemfilehandle}
418
418
419
419
<xmp class=idl>
420
+ enum FileSystemWritableFileStreamMode {
421
+ "exclusive",
422
+ "siloed",
423
+ };
424
+
420
425
dictionary FileSystemCreateWritableOptions {
421
426
boolean keepExistingData = false;
427
+ FileSystemWritableFileStreamMode mode = "siloed";
428
+ };
429
+
430
+ enum FileSystemSyncAccessHandleMode {
431
+ "readwrite",
432
+ "read-only",
433
+ "readwrite-unsafe",
434
+ };
435
+
436
+ dictionary FileSystemCreateSyncAccessHandleOptions {
437
+ FileSystemSyncAccessHandleMode mode = "readwrite";
422
438
};
423
439
424
440
[Exposed=(Window,Worker), SecureContext, Serializable]
425
441
interface FileSystemFileHandle : FileSystemHandle {
426
442
Promise<File> getFile();
427
443
Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWritableOptions options = {});
428
444
[Exposed=DedicatedWorker]
429
- Promise<FileSystemSyncAccessHandle> createSyncAccessHandle();
445
+ Promise<FileSystemSyncAccessHandle> createSyncAccessHandle(optional FileSystemCreateSyncAccessHandleOptions options = {} );
430
446
};
431
447
</xmp>
432
448
@@ -535,10 +551,12 @@ The <dfn method for=FileSystemFileHandle>getFile()</dfn> method steps are:
535
551
the temporary file starts out empty,
536
552
otherwise the existing file is first copied to this temporary file.
537
553
538
- Creating a {{FileSystemWritableFileStream}} [=file entry/take a lock|takes a shared lock=] on the
539
- [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=] .
540
- This prevents the creation of {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
541
- for the entry, until the stream is closed.
554
+ Creating a {{FileSystemWritableFileStream}} [=file entry/take a lock|takes a lock=] on the
555
+ [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=]
556
+ and a |lockType| determined by {{FileSystemCreateWritableOptions/mode}} . Until the stream is
557
+ closed, both {{FileSystemCreateWritableOptions/mode|modes}} prevent any file operation or the
558
+ creation of a file primitive on the [=file entry=] , but "`siloed`" will allow the creation of other
559
+ {{FileSystemWritableFileStream}} in "`siloed`" {{FileSystemCreateWritableOptions/mode}} .
542
560
</div>
543
561
544
562
<p class=XXX> See <a href=https://github.com/WICG/file-system-access/issues/67>WICG/file-system-access issue #67</a>
@@ -572,8 +590,15 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
572
590
|result| with a "{{NotFoundError}} " {{DOMException}} and abort these steps.
573
591
1. [=Assert=] : |entry| is a [=file entry=] .
574
592
593
+ 1. Let |lockType| be the empty string.
594
+ 1. Let |mode| be |options|["{{FileSystemCreateWritableOptions/mode}}"] .
595
+ 1. If |mode| is "`exclusive`":
596
+ 1. Set |lockType| to "`exclusive`".
597
+ 1. Otherwise:
598
+ 1. [=Assert=] : |mode| is "`siloed`".
599
+ 1. Set |lockType| to "`writable-siloed`".
575
600
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
576
- with "`shared`" on |entry|.
601
+ with |lockType| on |entry|.
577
602
578
603
1. [=Queue a storage task=] with |global| to run these steps:
579
604
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
@@ -600,11 +625,12 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
600
625
[=file entry=] [=locate an entry|locatable=] by |fileHandle|'s [=FileSystemHandle/locator=] .
601
626
To ensure the changes are reflected in this file, the handle can be flushed.
602
627
603
- Creating a {{FileSystemSyncAccessHandle}} [=file entry/take a lock|takes an exclusive lock=] on the
604
- [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=] .
605
- This prevents the creation of further {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
606
- or {{FileSystemWritableFileStream|FileSystemWritableFileStreams}}
607
- for the entry, until the access handle is closed.
628
+ Creating a {{FileSystemSyncAccessHandle}} [=file entry/take a lock|takes a lock=] on the
629
+ [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=]
630
+ and a |lockType| determined by {{FileSystemCreateSyncAccessHandleOptions/mode}} . Until the access handle is
631
+ closed, all {{FileSystemCreateSyncAccessHandleOptions/mode|modes}} prevent any file operation or the
632
+ creation of a file primitive on the [=file entry=] , but "`read-only`" and "`readwrite-unsafe`" will allow the creation of other
633
+ {{FileSystemSyncAccessHandle}} in their respective {{FileSystemCreateSyncAccessHandleOptions/mode|modes}} .
608
634
609
635
The returned {{FileSystemSyncAccessHandle}} offers synchronous methods. This allows for higher performance
610
636
on contexts where asynchronous operations come with high overhead, e.g., WebAssembly.
@@ -614,7 +640,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
614
640
</div>
615
641
616
642
<div algorithm>
617
- The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method steps are:
643
+ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle(|options| )</dfn> method steps are:
618
644
619
645
1. Let |result| be [=a new promise=] .
620
646
1. Let |locator| be [=this=] 's [=FileSystemHandle/locator=] .
@@ -642,15 +668,28 @@ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method s
642
668
|result| with a "{{NotFoundError}} " {{DOMException}} and abort these steps.
643
669
1. [=Assert=] : |entry| is a [=file entry=] .
644
670
671
+ 1. Let |lockType| be the empty string.
672
+ 1. Let |writeAccess| be the empty string.
673
+ 1. Let |mode| be |options|["{{FileSystemCreateSyncAccessHandleOptions/mode}}"] .
674
+ 1. If |mode| is "`readwrite`":
675
+ 1. Set |lockType| to "`exclusive`".
676
+ 1. Set |writeAccess| to "`writable`".
677
+ 1. Otherwise, if |mode| is "`read-only`":
678
+ 1. Set |lockType| to "`sync-access-handle-read-only`".
679
+ 1. Set |writeAccess| to "`not-writable`".
680
+ 1. Otherwise:
681
+ 1. [=Assert=] : |mode| is "`readwrite-unsafe`".
682
+ 1. Set |lockType| to "`sync-access-handle-read-write-unsafe`".
683
+ 1. Set |writeAccess| to "`writable`".
645
684
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
646
- with "`exclusive`" on |entry|.
685
+ with |lockType| on |entry|.
647
686
648
687
1. [=Queue a storage task=] with |global| to run these steps:
649
688
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
650
689
"{{NoModificationAllowedError}} " {{DOMException}} and abort these steps.
651
690
652
691
1. Let |handle| be the result of <a>creating a new `FileSystemSyncAccessHandle`</a>
653
- for |entry| in |realm|.
692
+ with |entry| and |writeAccess | in |realm|.
654
693
1. [=/Resolve=] |result| with |handle|.
655
694
656
695
1. Return |result|.
@@ -1437,6 +1476,9 @@ A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccess
1437
1476
A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[state]]</dfn> ,
1438
1477
a string that may exclusively be "`open`" or "`closed`".
1439
1478
1479
+ A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[writeAccess]]</dfn> ,
1480
+ a [=string=] that may exclusively be "`writable`" or "`not-writable`".
1481
+
1440
1482
A {{FileSystemSyncAccessHandle}} is an object that is capable of reading from/writing to,
1441
1483
as well as obtaining and changing the size of, a single file.
1442
1484
@@ -1448,11 +1490,13 @@ A {{FileSystemSyncAccessHandle}} has a <dfn for="FileSystemSyncAccessHandle">fil
1448
1490
<div algorithm>
1449
1491
To
1450
1492
<dfn local-lt="creating a new FileSystemSyncAccessHandle">create a new `FileSystemSyncAccessHandle`</dfn>
1451
- given a [=file entry=] |file| in a [=/Realm=] |realm|:
1493
+ given a [=file entry=] |file| and a [=string=] |writeAccess| in a [=/Realm=] |realm|:
1452
1494
1495
+ 1. [=Assert=] : |writeAccess| is "`writable`" or "`not-writable`".
1453
1496
1. Let |handle| be a [=new=] {{FileSystemSyncAccessHandle}} in |realm|.
1454
1497
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[file]]=] to |file|.
1455
1498
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[state]]=] to "`open`".
1499
+ 1. Set |handle|'s [=FileSystemSyncAccessHandle/[[writeAccess]]=] to |writeAccess|.
1456
1500
1. Return |handle|.
1457
1501
1458
1502
</div>
@@ -1515,6 +1559,8 @@ The <dfn method for=FileSystemSyncAccessHandle>write(|buffer|, {{FileSystemReadW
1515
1559
1516
1560
1. If [=this=] 's [=[[state]]=] is "`closed`",
1517
1561
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1562
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1563
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1518
1564
1. Let |writePosition| be |options|["{{FileSystemReadWriteOptions/at}}"] if
1519
1565
|options|["{{FileSystemReadWriteOptions/at}}"] [=map/exists=] ; otherwise
1520
1566
[=this=] 's [=FileSystemSyncAccessHandle/file position cursor=] .
@@ -1575,6 +1621,8 @@ The <dfn method for=FileSystemSyncAccessHandle>truncate(|newSize|)</dfn> method
1575
1621
1576
1622
1. If [=this=] 's [=[[state]]=] is "`closed`",
1577
1623
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1624
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1625
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1578
1626
1. Let |fileContents| be a copy of [=this=] 's
1579
1627
[=FileSystemSyncAccessHandle/[[file]]=] 's [=file entry/binary data=] .
1580
1628
1. Let |oldSize| be the [=byte sequence/length=] of [=this=] 's
@@ -1631,6 +1679,8 @@ The <dfn method for=FileSystemSyncAccessHandle>flush()</dfn> method steps are:
1631
1679
1632
1680
1. If [=this=] 's [=[[state]]=] is "`closed`",
1633
1681
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1682
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1683
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1634
1684
1. Attempt to transfer all cached modifications of the file's content to the
1635
1685
file system's underlying storage device.
1636
1686
0 commit comments