FileSystem

Description

FileSystem is a model object representing a complete file system. This object creates and manages File and Directory instances, dispatches events when the file system changes, and provides methods for showing 'open' and 'save' dialogs.

FileSystem automatically initializes when loaded. It depends on a pluggable "impl" layer, which it loads itself but must be designated in the require.config() that loads FileSystem.

There are three ways to get File or Directory instances:

  • Use FileSystem.resolve() to convert a path to a File/Directory object. This will only succeed if the file/directory already exists.
  • Use FileSystem.getFileForPath()/FileSystem.getDirectoryForPath() if you know the file/directory already exists, or if you want to create a new entry.
  • Use Directory.getContents() to return all entries for the specified Directory.

All paths passed to FileSystem APIs must be in the following format:

  • The path separator is "/" regardless of platform
  • Paths begin with "/" on Mac/Linux and "c:/" (or some other drive letter) on Windows

All paths returned from FileSystem APIs additionally meet the following guarantees:

  • No ".." segments
  • No consecutive "/"s
  • Paths to a directory always end with a trailing "/" (Because FileSystem normalizes paths automatically, paths passed to FileSystem do not need to meet these requirements)

FileSystem dispatches the following events: change - Sent whenever there is a change in the file system. The handler is passed up to three arguments: the changed entry and, if that changed entry is a Directory, a list of entries added to the directory and a list of entries removed from the Directory. The entry argument can be:

     *  a File - the contents of the file have changed, and should be reloaded.
     *  a Directory - an immediate child of the directory has been added, removed,
        or renamed/moved. Not triggered for "grandchildren".
          - If the added & removed arguments are null, we don't know what was added/removed:
            clients should assume the whole subtree may have changed.
          - If the added & removed arguments are 0-length, there's no net change in the set
            of files but a file may have been replaced: clients should assume the contents
            of any immediate child file may have changed.
     *  null - a 'wholesale' change happened, and you should assume everything may
        have changed.
     For changes made externally, there may be a significant delay before a "change" event
     is dispatched.

rename - Sent whenever a File or Directory is renamed. All affected File and Directory objects have been updated to reflect the new path by the time this event is dispatched. This event should be used to trigger any UI updates that may need to occur when a path has changed. Note that these events will only be sent for rename operations that happen within the filesystem. If a file is renamed externally, a change event on the parent directory will be sent instead.

FileSystem may perform caching. But it guarantees:

  • File contents & metadata - reads are guaranteed to be up to date (cached data is not used without first veryifying it is up to date).
  • Directory structure / file listing - reads may return cached data immediately, which may not reflect external changes made recently. (However, changes made via FileSystem itself are always reflected immediately, as soon as the change operation's callback signals success).

The FileSystem doesn't directly read or write contents--this work is done by a low-level implementation object. This allows client code to use the FileSystem API without having to worry about the underlying storage, which could be a local filesystem or a remote server.

Variables Summary

Classes Summary

Variables

Public API

USER_CANCELED

Unique token used to indicate user-driven cancellation of Save As (as opposed to file IO error)

_DUPLICATED_SLASH_RE

Matches continguous groups of forward slashes

Classes

Properties

_activeChangeCount

Refcount of any pending filesystem mutation operations (e.g., writes, unlinks, etc.). Used to ensure that external change events aren't processed until after index fixups, operation-specific callbacks, and internal change events are complete. (This is important for distinguishing rename from an unrelated delete-add pair).

_externalChanges

Queue of arguments with which to invoke _handleExternalChanges(); triggered once _activeChangeCount drops to zero.

_impl

The low-level file system implementation used by this object. This is set in the init() function and cannot be changed.

_index

The FileIndex used by this object. This is initialized in the constructor.

_watchRequests

The queue of pending watch/unwatch requests.

_watchedRoots

The set of watched roots, encoded as a mapping from full paths to WatchedRoot objects which contain a file entry, filter function, and an indication of whether the watched root is inactive, starting up or fully active.

type{Object.<string,
WatchedRoot>}

Methods

_beginChange

Indicates that a filesystem-mutating operation has begun. As long as there are changes taking place, change events from the external watchers are blocked and queued, to be handled once changes have finished. This is done because for mutating operations that originate from within the filesystem, synthetic change events are fired that do not depend on external file watchers, and we prefer the former over the latter for the following reasons: 1) there is no delay; and 2) they may have higher fidelity --- e.g., a rename operation can be detected as such, instead of as a nearly simultaneous addition and deletion.

All operations that mutate the file system MUST begin with a call to _beginChange and must end with a call to _endChange.

_dequeueWatchRequest

Dequeue and process all pending watch/unwatch requests

_endChange

Indicates that a filesystem-mutating operation has completed. See FileSystem._beginChange above.

_enqueueExternalChange

Receives a result from the impl's watcher callback, and either processes it immediately (if _activeChangeCount is 0) or otherwise stores it for later processing.

path nullable string
The fullPath of the changed entry
stat optional FileSystemStats
An optional stat object for the changed entry

_enqueueWatchRequest

Enqueue a new watch/unwatch request.

fn function()
- The watch/unwatch request function.
cb callback()
- The callback for the provided watch/unwatch request function.

_findWatchedRootForPath

Finds a parent watched root for a given path, or returns null if a parent watched root does not exist.

param{string}
fullPath The child path for which a parent watched root is to be found
return{?{entry:
FileSystemEntry, filter: function(string) boolean}} The parent watched root, if it exists, or null.

_fireChangeEvent

Fire a change event. Clients listen for these events using FileSystem.on.

entry File,Directory
The entry that has changed
added optional Array<File, Directory>
If the entry is a directory, this is a set of new entries in the directory.
removed optional Array<File, Directory>
If the entry is a directory, this is a set of removed entries from the directory.

_fireRenameEvent

Fire a rename event. Clients listen for these events using FileSystem.on.

oldPath string
The entry's previous fullPath
newPath string
The entry's current fullPath
Private

_getEntryForPath

Return a (strict subclass of a) FileSystemEntry object for the specified path using the provided constuctor. For now, the provided constructor should be either File or Directory.

EntryConstructor function(string,FileSystem)
Constructor with which to initialize new FileSystemEntry objects.
path string
Absolute path of file.
Returns: File,Directory
The File or Directory object. This file may not yet exist on disk.

_handleDirectoryChange

Notify the filesystem that the given directory has changed. Updates the filesystem's internal state as a result of the change, and calls back with the set of added and removed entries. Mutating FileSystemEntry operations should call this method before applying the operation's callback, and pass along the resulting change sets in the internal change event.

directory Directory
The directory that has changed.
callback function(Array<File,Directory>=,Array<File,Directory>=)
The callback that will be applied to a set of added and a set of removed FileSystemEntry objects.
Private

_handleExternalChange

path string
The path that changed. This could be a file or a directory.
stat optional FileSystemStats
Optional stat for the item that changed. This param is not always passed.
Private

_handleRename

oldFullPath string
newFullPath string
isDirectory boolean

_indexFilter

Returns true if the given path should be automatically added to the index & watch list when one of its ancestors is a watch-root. (Files are added automatically when the watch-root is first established, or later when a new directory is created and its children enumerated).

Entries explicitly created via FileSystem.getFile/DirectoryForPath() are always added to the index regardless of this filtering - but they will not be watched if the watch-root's filter excludes them.

path string
Full path
name string
Name portion of the path

_normalizePath

Returns a canonical version of the path: no duplicated "/"es, no ".."s, and directories guaranteed to end in a trailing "/"

path non-nullable string
Absolute path, using "/" as path separator
isDirectory optional boolean
Returns: !string

_triggerExternalChangesNow

Process all queued watcher results, by calling _handleExternalChange() on each

Private

_unwatchAll

Unwatch all watched roots. Calls unwatch on the underlying impl for each watched root and ignores errors.

Private

_unwatchEntry

Unwatch a filesystem entry beneath a given watchedRoot.

entry FileSystemEntry
- The FileSystemEntry to watch. Must be a non-strict descendent of watchedRoot.entry.
watchedRoot WatchedRoot
- See FileSystem._watchedRoots.
callback function(?string)
- A function that is called once the watch is complete, possibly with a FileSystemError string.
Private

_watchEntry

Watch a filesystem entry beneath a given watchedRoot.

entry FileSystemEntry
- The FileSystemEntry to watch. Must be a non-strict descendent of watchedRoot.entry.
watchedRoot WatchedRoot
- See FileSystem._watchedRoots.
callback function(?string)
- A function that is called once the watch is complete, possibly with a FileSystemError string.
Private

_watchOrUnwatchEntry

Helper function to watch or unwatch a filesystem entry beneath a given watchedRoot.

entry FileSystemEntry
- The FileSystemEntry to watch. Must be a non-strict descendent of watchedRoot.entry.
watchedRoot WatchedRoot
- See FileSystem._watchedRoots.
callback function(?string)
- A function that is called once the watch is complete, possibly with a FileSystemError string.
shouldWatch boolean
- Whether the entry should be watched (true) or unwatched (false).
Public API

close

Close a file system. Clear all caches, indexes, and file watchers.

Public API

getDirectoryForPath

Return a Directory object for the specified path.

path string
Absolute path of directory.
Returns: Directory
The Directory object. This directory may not yet exist on disk.
Public API

getFileForPath

Return a File object for the specified path.

path string
Absolute path of file.
Returns: File
The File object. This file may not yet exist on disk.
Public API

init

Initialize this FileSystem instance.

impl FileSystemImpl
The back-end implementation for this FileSystem instance.
Public API

isAbsolutePath STATIC

Determines whether or not the supplied path is absolute, as opposed to relative.

fullPath non-nullable string
Returns: boolean
True if the fullPath is absolute and false otherwise.
Public API

resolve

Resolve a path.

path string
The path to resolve
callback function (?string,FileSystemEntry=,FileSystemStats=)
Callback resolved with a FileSystemError string or with the entry for the provided path.
Public API

showOpenDialog

Show an "Open" dialog and return the file(s)/directories selected by the user.

allowMultipleSelection boolean
Allows selecting more than one file at a time
chooseDirectories boolean
Allows directories to be opened
title string
The title of the dialog
initialPath string
The folder opened inside the window initially. If initialPath is not set, or it doesn't exist, the window would show the last browsed folder depending on the OS preferences
fileTypes nullable Array.<string>
(Currently *ignored* except on Mac - https://trello.com/c/430aXkpq) List of extensions that are allowed to be opened, without leading ".". Null or empty array allows all files to be selected. Not applicable when chooseDirectories = true.
callback function (?string,Array.<string>=)
Callback resolved with a FileSystemError string or the selected file(s)/directories. If the user cancels the open dialog, the error will be falsy and the file/directory array will be empty.
Public API

showSaveDialog

Show a "Save" dialog and return the path of the file to save.

title string
The title of the dialog.
initialPath string
The folder opened inside the window initially. If initialPath is not set, or it doesn't exist, the window would show the last browsed folder depending on the OS preferences.
proposedNewFilename string
Provide a new file name for the user. This could be based on on the current file name plus an additional suffix
callback function (?string,string=)
Callback that is resolved with a FileSystemError string or the name of the file to save. If the user cancels the save, the error will be falsy and the name will be empty.
Public API

unwatch

Stop watching a filesystem root entry.

entry FileSystemEntry
- The root entry to stop watching. The unwatch will if the entry is not currently being watched.
callback optional function(?string)
- A function that is called when the unwatch has completed. If the unwatch fails, the function will have a non-null FileSystemError string parameter.
Public API

watch

Start watching a filesystem root entry.

entry FileSystemEntry
- The root entry to watch. If entry is a directory, all subdirectories that aren't explicitly filtered will also be watched.
filter function(string): boolean
- Returns true if a particular item should be watched, given its name (not full path). Items that are ignored are also filtered from Directory.getContents() results within this subtree.
callback optional function(?string)
- A function that is called when the watch has completed. If the watch fails, the function will have a non-null FileSystemError string parametr.