diff --git a/index.bs b/index.bs
index 43da40f..0fc72f2 100644
--- a/index.bs
+++ b/index.bs
@@ -127,7 +127,7 @@ systems.
A file entry additionally consists of
binary data (a [=byte sequence=]), a
modification timestamp (a number representing the number of milliseconds since the Unix Epoch),
-a lock (a string that may exclusively be "`open`", "`taken-exclusive`" or "`taken-shared`")
+a lock (a [=string=] or null)
and a shared lock count (a number representing the number of shared locks that are taken at a given point in time).
A user agent has an associated file system queue which is the
@@ -135,23 +135,19 @@ result of [=starting a new parallel queue=]. This queue is to be used for all
file system operations.
-To take a lock with a |value| of
-"`exclusive`" or "`shared`" on a given [=file entry=] |file|:
+To take a lock with a |lockType| (a [=string=])
+on a given [=file entry=] |file|:
1. Let |lock| be the |file|'s [=file entry/lock=].
1. Let |count| be the |file|'s [=file entry/shared lock count=].
-1. If |value| is "`exclusive`":
- 1. If |lock| is "`open`":
- 1. Set lock to "`taken-exclusive`".
- 1. Return "`success`".
-1. If |value| is "`shared`":
- 1. If |lock| is "`open`":
- 1. Set |lock| to "`taken-shared`".
- 1. Set |count| to 1.
- 1. Return "`success`".
- 1. Otherwise, if |lock| is "`taken-shared`":
- 1. Increase |count| by 1.
- 1. Return "`success`".
+1. If |lock| is null:
+ 1. Set |lock| to |lockType|.
+ 1. Set |count| to 1.
+ 1. Return "`success`".
+1. If |lock| is not "`exclusive`":
+ 1. If |lock| equals |lockType|:
+ 1. Increase |count| by 1.
+ 1. Return "`success`".
1. Return "`failure`".
Note: These steps have to be run on the [=file system queue=].
@@ -164,10 +160,9 @@ To release a [=file entry/lock=] on a given
1. Let |lock| be the |file|'s associated [=file entry/lock=].
1. Let |count| be the |file|'s [=file entry/shared lock count=].
-1. If |lock| is "`taken-shared`":
- 1. Decrease |count| by 1.
- 1. If |count| is 0, set |lock| to "`open`".
-1. Otherwise, set |lock| to "`open`".
+1. [=Assert=]: |count| greater than 0.
+1. Decrease |count| by 1.
+1. If |count| is 0, set |lock| to null.
Note: These steps have to be run on the [=file system queue=].
@@ -420,8 +415,24 @@ The isSameEntry(|other|) method steps are
## The {{FileSystemFileHandle}} interface ## {#api-filesystemfilehandle}
+enum FileSystemWritableFileStreamMode {
+ "exclusive",
+ "siloed",
+};
+
dictionary FileSystemCreateWritableOptions {
boolean keepExistingData = false;
+ FileSystemWritableFileStreamMode mode = "siloed";
+};
+
+enum FileSystemSyncAccessHandleMode {
+ "readwrite",
+ "read-only",
+ "readwrite-unsafe",
+};
+
+dictionary FileSystemCreateSyncAccessHandleOptions {
+ FileSystemSyncAccessHandleMode mode = "readwrite";
};
[Exposed=(Window,Worker), SecureContext, Serializable]
@@ -429,7 +440,7 @@ interface FileSystemFileHandle : FileSystemHandle {
Promise getFile();
Promise createWritable(optional FileSystemCreateWritableOptions options = {});
[Exposed=DedicatedWorker]
- Promise createSyncAccessHandle();
+ Promise createSyncAccessHandle(optional FileSystemCreateSyncAccessHandleOptions options = {});
};
@@ -575,8 +586,14 @@ The createWritable(|options|) method
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
1. [=Assert=]: |entry| is a [=file entry=].
+ 1. Let |lockType| be a [=string=].
+ 1. Let |mode| be |options|["{{FileSystemCreateWritableOptions/mode}}"].
+ 1. If |mode| is "`exclusive`":
+ 1. Set |lockType| to "`exclusive`".
+ 1. Otherwise, if |mode| is "`siloed`":
+ 1. Set |lockType| to "`writableSiloed`".
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
- with "`shared`" on |entry|.
+ with |lockType| on |entry|.
1. [=Queue a storage task=] with |global| to run these steps:
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
@@ -617,7 +634,7 @@ The createWritable(|options|) method
-The
createSyncAccessHandle() method steps are:
+The
createSyncAccessHandle(|options|) method steps are:
1. Let |result| be [=a new promise=].
1. Let |locator| be [=this=]'s [=FileSystemHandle/locator=].
@@ -645,15 +662,27 @@ The
createSyncAccessHandle() method s
|result| with a "{{NotFoundError}}" {{DOMException}} and abort these steps.
1. [=Assert=]: |entry| is a [=file entry=].
+ 1. Let |lockType| be a [=string=].
+ 1. Let |writePermission| be a [=string=].
+ 1. Let |mode| be |options|["{{FileSystemCreateSyncAccessHandleOptions/mode}}"].
+ 1. If |mode| is "`readwrite`":
+ 1. Set |lockType| to "`exclusive`".
+ 1. Set |writePermission| to "`writable`".
+ 1. Otherwise, if |mode| is "`read-only`":
+ 1. Set |lockType| to "`syncAccessHandleReadOnly`".
+ 1. Set |writePermission| to "`notWritable`".
+ 1. Otherwise, if |mode| is "`readwrite-unsafe`":
+ 1. Set |lockType| to "`syncAccessHandleReadWriteUnsafe`".
+ 1. Set |writePermission| to "`writable`".
1. Let |lockResult| be the result of [=file entry/take a lock|taking a lock=]
- with "`exclusive`" on |entry|.
+ with |lockType| on |entry|.
1. [=Queue a storage task=] with |global| to run these steps:
1. If |lockResult| is "`failure`", [=/reject=] |result| with a
"{{NoModificationAllowedError}}" {{DOMException}} and abort these steps.
1. Let |handle| be the result of
creating a new `FileSystemSyncAccessHandle`
- for |entry| in |realm|.
+ with |entry| and |writePermission| in |realm|.
1. [=/Resolve=] |result| with |handle|.
1. Return |result|.
@@ -1440,6 +1469,9 @@ A {{FileSystemSyncAccessHandle}} has an associated
\[[state]],
a string that may exclusively be "`open`" or "`closed`".
+A {{FileSystemSyncAccessHandle}} has an associated
\[[writePermission]],
+a string that may exclusively be "`writable`" or "`notWritable`".
+
A {{FileSystemSyncAccessHandle}} is an object that is capable of reading from/writing to,
as well as obtaining and changing the size of, a single file.
@@ -1451,11 +1483,12 @@ A {{FileSystemSyncAccessHandle}} has a
fil
To
create a new `FileSystemSyncAccessHandle`
-given a [=file entry=] |file| in a [=/Realm=] |realm|:
+given a [=file entry=] |file| and a |writePermission| of "`writable`" or "`notWritable`" in a [=/Realm=] |realm|:
1. Let |handle| be a [=new=] {{FileSystemSyncAccessHandle}} in |realm|.
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[file]]=] to |file|.
1. Set |handle|'s [=FileSystemSyncAccessHandle/[[state]]=] to "`open`".
+1. Set |handle|'s [=FileSystemSyncAccessHandle/[[writePermission]]=] to |writePermission|.
1. Return |handle|.
@@ -1518,6 +1551,8 @@ The write(|buffer|, {{FileSystemReadW
1. If [=this=]'s [=[[state]]=] is "`closed`",
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
+1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
+ [=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
1. Let |writePosition| be |options|["{{FileSystemReadWriteOptions/at}}"] if
|options|["{{FileSystemReadWriteOptions/at}}"] [=map/exists=]; otherwise
[=this=]'s [=FileSystemSyncAccessHandle/file position cursor=].
@@ -1578,6 +1613,8 @@ The truncate(|newSize|) method
1. If [=this=]'s [=[[state]]=] is "`closed`",
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
+1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
+ [=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
1. Let |fileContents| be a copy of [=this=]'s
[=FileSystemSyncAccessHandle/[[file]]=]'s [=file entry/binary data=].
1. Let |oldSize| be the [=byte sequence/length=] of [=this=]'s
@@ -1634,6 +1671,8 @@ The flush() method steps are:
1. If [=this=]'s [=[[state]]=] is "`closed`",
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
+1. If [=this=]'s [=[[writePermission]]=]' is "`notWritable`",
+ [=throw=] a "{{NoModificationAllowedError}}" {{DOMException}}.
1. Attempt to transfer all cached modifications of the file's content to the
file system's underlying storage device.