@@ -127,31 +127,29 @@ systems.
127
127
A <dfn export id=file>file entry</dfn> additionally consists of
128
128
<dfn for="file entry" export>binary data</dfn> (a [=byte sequence=] ), a
129
129
<dfn for="file entry">modification timestamp</dfn> (a number representing the number of milliseconds since the <a spec=FileAPI>Unix Epoch</a> ),
130
- a <dfn for="file entry">lock</dfn> (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`")
130
+ a <dfn for="file entry">lock</dfn> (a [=string=] that may exclusively be "`open`", "`exclusive`", "`writableSiloed`",
131
+ "`syncAccessHandleReadOnly`", "`syncAccessHandleReadWriteUnsafe`")
131
132
and a <dfn for="file entry">shared lock count</dfn> (a number representing the number of shared locks that are taken at a given point in time).
132
133
133
134
A user agent has an associated <dfn>file system queue</dfn> which is the
134
135
result of [=starting a new parallel queue=] . This queue is to be used for all
135
136
file system operations.
136
137
137
138
<div algorithm>
138
- To <dfn for="file entry" id=file-entry-lock-take>take a lock</dfn> with a |value| of
139
- "`exclusive`" or "`shared`" on a given [=file entry=] |file|:
139
+ To <dfn for="file entry" id=file-entry-lock-take>take a lock</dfn> with a |lockType| (a [=string=] )
140
+ on a given [=file entry=] |file|:
140
141
142
+ 1. [=Assert=] : |lockType| is "`exclusive`", "`writableSiloed`", "`syncAccessHandleReadOnly`", or "`syncAccessHandleReadWriteUnsafe`".
141
143
1. Let |lock| be the |file|'s [=file entry/lock=] .
142
144
1. Let |count| be the |file|'s [=file entry/shared lock count=] .
143
- 1. If |value| is "`exclusive`":
144
- 1. If |lock| is "`open`":
145
- 1. Set lock to "`taken-exclusive`".
146
- 1. Return "`success`".
147
- 1. If |value| is "`shared`":
148
- 1. If |lock| is "`open`":
149
- 1. Set |lock| to "`taken-shared`".
150
- 1. Set |count| to 1.
151
- 1. Return "`success`".
152
- 1. Otherwise, if |lock| is "`taken-shared`":
153
- 1. Increase |count| by 1.
154
- 1. Return "`success`".
145
+ 1. If |lock| is null:
146
+ 1. Set |lock| to |lockType|.
147
+ 1. Set |count| to 1.
148
+ 1. Return "`success`".
149
+ 1. If |lock| is not "`exclusive`":
150
+ 1. If |lock| equals |lockType|:
151
+ 1. Increase |count| by 1.
152
+ 1. Return "`success`".
155
153
1. Return "`failure`".
156
154
157
155
Note: These steps have to be run on the [=file system queue=] .
@@ -164,10 +162,9 @@ To <dfn for="file entry/lock">release</dfn> a [=file entry/lock=] on a given
164
162
165
163
1. Let |lock| be the |file|'s associated [=file entry/lock=] .
166
164
1. Let |count| be the |file|'s [=file entry/shared lock count=] .
167
- 1. If |lock| is "`taken-shared`":
168
- 1. Decrease |count| by 1.
169
- 1. If |count| is 0, set |lock| to "`open`".
170
- 1. Otherwise, set |lock| to "`open`".
165
+ 1. [=Assert=] : |count| is greater than 0.
166
+ 1. Decrease |count| by 1.
167
+ 1. If |count| is 0, set |lock| to null.
171
168
172
169
Note: These steps have to be run on the [=file system queue=] .
173
170
@@ -420,16 +417,32 @@ The <dfn method for=FileSystemHandle>isSameEntry(|other|)</dfn> method steps are
420
417
## The {{FileSystemFileHandle}} interface ## {#api-filesystemfilehandle}
421
418
422
419
<xmp class=idl>
420
+ enum FileSystemWritableFileStreamMode {
421
+ "exclusive",
422
+ "siloed",
423
+ };
424
+
423
425
dictionary FileSystemCreateWritableOptions {
424
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";
425
438
};
426
439
427
440
[Exposed=(Window,Worker), SecureContext, Serializable]
428
441
interface FileSystemFileHandle : FileSystemHandle {
429
442
Promise<File> getFile();
430
443
Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWritableOptions options = {});
431
444
[Exposed=DedicatedWorker]
432
- Promise<FileSystemSyncAccessHandle> createSyncAccessHandle();
445
+ Promise<FileSystemSyncAccessHandle> createSyncAccessHandle(optional FileSystemCreateSyncAccessHandleOptions options = {} );
433
446
};
434
447
</xmp>
435
448
@@ -538,10 +551,13 @@ The <dfn method for=FileSystemFileHandle>getFile()</dfn> method steps are:
538
551
the temporary file starts out empty,
539
552
otherwise the existing file is first copied to this temporary file.
540
553
541
- Creating a {{FileSystemWritableFileStream}} [=file entry/take a lock|takes a shared lock=] on the
542
- [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=] .
543
- This prevents the creation of {{FileSystemSyncAccessHandle|FileSystemSyncAccessHandles}}
544
- 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 the creation on the entry
558
+ of a {{FileSystemWritableFileStream}} in a different {{FileSystemCreateWritableOptions/mode}}
559
+ or a {{FileSystemSyncAccessHandle}} , but "`exclusive`" will also prevent the creation of
560
+ {{FileSystemWritableFileStream}} in "`exclusive`" {{FileSystemCreateWritableOptions/mode}} .
545
561
</div>
546
562
547
563
<p class=XXX> See <a href=https://github.com/WICG/file-system-access/issues/67>WICG/file-system-access issue #67</a>
@@ -575,8 +591,15 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
575
591
|result| with a "{{NotFoundError}} " {{DOMException}} and abort these steps.
576
592
1. [=Assert=] : |entry| is a [=file entry=] .
577
593
594
+ 1. Let |lockType| be the empty string.
595
+ 1. Let |mode| be |options|["{{FileSystemCreateWritableOptions/mode}}"] .
596
+ 1. If |mode| is "`exclusive`":
597
+ 1. Set |lockType| to "`exclusive`".
598
+ 1. Otherwise:
599
+ 1. [=Assert=] : |mode| is "`siloed`".
600
+ 1. Set |lockType| to "`writableSiloed`".
578
601
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
579
- with "`shared`" on |entry|.
602
+ with |lockType| on |entry|.
580
603
581
604
1. [=Queue a storage task=] with |global| to run these steps:
582
605
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
@@ -609,6 +632,14 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
609
632
or {{FileSystemWritableFileStream|FileSystemWritableFileStreams}}
610
633
for the entry, until the access handle is closed.
611
634
635
+ Creating a {{FileSystemSyncAccessHandle}} [=file entry/take a lock|takes a lock=] on the
636
+ [=file entry=] [=locate an entry|locatable=] with |fileHandle|'s [=FileSystemHandle/locator=]
637
+ and a |lockType| determined by {{FileSystemCreateSyncAccessHandleOptions/mode}} . Until the access handle is
638
+ closed, all {{FileSystemCreateSyncAccessHandleOptions/mode|modes}} prevent the creation on the entry
639
+ of a {{FileSystemSyncAccessHandle}} in a different {{FileSystemCreateSyncAccessHandleOptions/mode}}
640
+ or a {{FileSystemWritableFileStream}} , but "`read-write`" will also prevent the creation of
641
+ {{FileSystemSyncAccessHandle}} in "`read-write`" {{FileSystemCreateSyncAccessHandleOptions/mode}} .
642
+
612
643
The returned {{FileSystemSyncAccessHandle}} offers synchronous methods. This allows for higher performance
613
644
on contexts where asynchronous operations come with high overhead, e.g., WebAssembly.
614
645
@@ -617,7 +648,7 @@ The <dfn method for=FileSystemFileHandle>createWritable(|options|)</dfn> method
617
648
</div>
618
649
619
650
<div algorithm>
620
- The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method steps are:
651
+ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle(|options| )</dfn> method steps are:
621
652
622
653
1. Let |result| be [=a new promise=] .
623
654
1. Let |locator| be [=this=] 's [=FileSystemHandle/locator=] .
@@ -645,15 +676,28 @@ The <dfn method for=FileSystemFileHandle>createSyncAccessHandle()</dfn> method s
645
676
|result| with a "{{NotFoundError}} " {{DOMException}} and abort these steps.
646
677
1. [=Assert=] : |entry| is a [=file entry=] .
647
678
679
+ 1. Let |lockType| be the empty string.
680
+ 1. Let |writeAccess| be the empty string.
681
+ 1. Let |mode| be |options|["{{FileSystemCreateSyncAccessHandleOptions/mode}}"] .
682
+ 1. If |mode| is "`readwrite`":
683
+ 1. Set |lockType| to "`exclusive`".
684
+ 1. Set |writeAccess| to "`writable`".
685
+ 1. Otherwise, if |mode| is "`read-only`":
686
+ 1. Set |lockType| to "`syncAccessHandleReadOnly`".
687
+ 1. Set |writeAccess| to "`not-writable`".
688
+ 1. Otherwise:
689
+ 1. [=Assert=] : |mode| is "`readwrite-unsafe`".
690
+ 1. Set |lockType| to "`syncAccessHandleReadWriteUnsafe`".
691
+ 1. Set |writeAccess| to "`writable`".
648
692
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
649
- with "`exclusive`" on |entry|.
693
+ with |lockType| on |entry|.
650
694
651
695
1. [=Queue a storage task=] with |global| to run these steps:
652
696
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
653
697
"{{NoModificationAllowedError}} " {{DOMException}} and abort these steps.
654
698
655
699
1. Let |handle| be the result of <a>creating a new `FileSystemSyncAccessHandle`</a>
656
- for |entry| in |realm|.
700
+ with |entry| and |writeAccess | in |realm|.
657
701
1. [=/Resolve=] |result| with |handle|.
658
702
659
703
1. Return |result|.
@@ -1440,6 +1484,9 @@ A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccess
1440
1484
A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[state]]</dfn> ,
1441
1485
a string that may exclusively be "`open`" or "`closed`".
1442
1486
1487
+ A {{FileSystemSyncAccessHandle}} has an associated <dfn for=FileSystemSyncAccessHandle>\[[writeAccess]]</dfn> ,
1488
+ a string that may exclusively be "`writable`" or "`not-writable`".
1489
+
1443
1490
A {{FileSystemSyncAccessHandle}} is an object that is capable of reading from/writing to,
1444
1491
as well as obtaining and changing the size of, a single file.
1445
1492
@@ -1451,11 +1498,13 @@ A {{FileSystemSyncAccessHandle}} has a <dfn for="FileSystemSyncAccessHandle">fil
1451
1498
<div algorithm>
1452
1499
To
1453
1500
<dfn local-lt="creating a new FileSystemSyncAccessHandle">create a new `FileSystemSyncAccessHandle`</dfn>
1454
- given a [=file entry=] |file| in a [=/Realm=] |realm|:
1501
+ given a [=file entry=] |file| and a [=string=] |writeAccess| in a [=/Realm=] |realm|:
1455
1502
1503
+ 1. [=Assert=] : |writeAccess| is "`writable`" or "`notWritable`".
1456
1504
1. Let |handle| be a [=new=] {{FileSystemSyncAccessHandle}} in |realm|.
1457
1505
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[file]]=] to |file|.
1458
1506
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[state]]=] to "`open`".
1507
+ 1. Set |handle|'s [=FileSystemSyncAccessHandle/[[writeAccess]]=] to |writeAccess|.
1459
1508
1. Return |handle|.
1460
1509
1461
1510
</div>
@@ -1518,6 +1567,8 @@ The <dfn method for=FileSystemSyncAccessHandle>write(|buffer|, {{FileSystemReadW
1518
1567
1519
1568
1. If [=this=] 's [=[[state]]=] is "`closed`",
1520
1569
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1570
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1571
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1521
1572
1. Let |writePosition| be |options|["{{FileSystemReadWriteOptions/at}}"] if
1522
1573
|options|["{{FileSystemReadWriteOptions/at}}"] [=map/exists=] ; otherwise
1523
1574
[=this=] 's [=FileSystemSyncAccessHandle/file position cursor=] .
@@ -1578,6 +1629,8 @@ The <dfn method for=FileSystemSyncAccessHandle>truncate(|newSize|)</dfn> method
1578
1629
1579
1630
1. If [=this=] 's [=[[state]]=] is "`closed`",
1580
1631
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1632
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1633
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1581
1634
1. Let |fileContents| be a copy of [=this=] 's
1582
1635
[=FileSystemSyncAccessHandle/[[file]]=] 's [=file entry/binary data=] .
1583
1636
1. Let |oldSize| be the [=byte sequence/length=] of [=this=] 's
@@ -1634,6 +1687,8 @@ The <dfn method for=FileSystemSyncAccessHandle>flush()</dfn> method steps are:
1634
1687
1635
1688
1. If [=this=] 's [=[[state]]=] is "`closed`",
1636
1689
[=throw=] an "{{InvalidStateError}} " {{DOMException}} .
1690
+ 1. If [=this=] 's [=[[writeAccess]]=]' is "`not-writable`",
1691
+ [=throw=] a "{{NoModificationAllowedError}} " {{DOMException}} .
1637
1692
1. Attempt to transfer all cached modifications of the file's content to the
1638
1693
file system's underlying storage device.
1639
1694
0 commit comments