La plate-forme Web offre de plus en plus aux développeurs les outils dont ils ont besoin pour créer des applications hautes performances et affinées pour le Web. En particulier, WebAssembly (Wasm) a ouvert la voie à des applications Web rapides et puissantes, tandis que des technologies comme Emscripten permettent désormais aux développeurs de réutiliser du code éprouvé sur le Web. Pour exploiter pleinement ce potentiel, les développeurs doivent disposer de la même puissance et de la même flexibilité en matière de stockage.
C'est là que l'API Storage Foundation entre en jeu. L'API Storage Foundation est une nouvelle API de stockage rapide et neutre qui ouvre de nouveaux cas d'utilisation très demandés pour le Web, tels que l'implémentation de bases de données performantes et la gestion élégante de grands fichiers temporaires. Avec cette nouvelle interface, les développeurs peuvent "apporter leur propre stockage" sur le Web, ce qui réduit l'écart de fonctionnalités entre le code Web et le code spécifique à la plate-forme.
L'API Storage Foundation est conçue pour ressembler à un système de fichiers très basique. Elle offre ainsi aux développeurs une flexibilité en fournissant des primitives génériques, simples et performantes sur lesquelles ils peuvent créer des composants de niveau supérieur. Les applications peuvent tirer parti de l'outil le mieux adapté à leurs besoins, en trouvant le bon équilibre entre facilité d'utilisation, performances et fiabilité.
Pourquoi le Web a-t-il besoin d'une autre API de stockage ?
La plate-forme Web propose un certain nombre d'options de stockage aux développeurs, chacune étant conçue pour des cas d'utilisation spécifiques.
- Certaines de ces options ne coïncident clairement pas avec cette proposition, car elles ne permettent de stocker que de très faibles quantités de données, comme les cookies ou l'API Web Storage composée des mécanismes
sessionStorage
etlocalStorage
. - D'autres options sont déjà obsolètes pour diverses raisons, comme l'API File and Directory Entries ou WebSQL.
- L'API File System Access présente une surface d'API similaire, mais son utilisation consiste à interagir avec le système de fichiers du client et à fournir un accès aux données qui peuvent ne pas appartenir à l'origine ou même au navigateur. Cette approche différente implique des considérations de sécurité plus strictes et des coûts de performances plus élevés.
- L'API IndexedDB peut être utilisée comme backend pour certains des cas d'utilisation de l'API Storage Foundation. Par exemple, Emscripten inclut IDBFS, un système de fichiers persistant basé sur IndexedDB. Toutefois, comme IndexedDB est fondamentalement un magasin de clés-valeurs, il présente des limites de performances importantes. De plus, l'accès direct aux sous-sections d'un fichier est encore plus difficile et plus lent sous IndexedDB.
- Enfin, l'interface CacheStorage est largement acceptée et conçue pour stocker des données de grande taille telles que des ressources d'application Web, mais les valeurs sont immuables.
L'API Storage Foundation tente de combler toutes les lacunes des options de stockage précédentes en permettant le stockage performant de grands fichiers modifiables définis dans l'origine de l'application.
Cas d'utilisation suggérés pour l'API Storage Foundation
Voici quelques exemples de sites qui peuvent utiliser cette API:
- Applications de productivité ou de créativité qui fonctionnent sur de grandes quantités de données vidéo, audio ou imagées Ces applications peuvent décharger des segments sur le disque au lieu de les conserver en mémoire.
- Applications qui reposent sur un système de fichiers persistant accessible depuis Wasm et qui ont besoin de performances supérieures à celles que l'IDBFS peut garantir.
Qu'est-ce que l'API Storage Foundation ?
L'API se compose de deux parties principales:
- Appels du système de fichiers, qui fournissent des fonctionnalités de base pour interagir avec les fichiers et les chemins d'accès aux fichiers.
- Handles de fichier, qui fournissent un accès en lecture et en écriture à un fichier existant.
Appels au système de fichiers
L'API Storage Foundation introduit un nouvel objet, storageFoundation
, qui réside dans l'objet window
et qui inclut un certain nombre de fonctions:
storageFoundation.open(name)
: ouvre le fichier avec le nom donné s'il existe, sinon crée un fichier. Renvoie une promesse qui se résout avec le fichier ouvert.
storageFoundation.delete(name)
: supprime le fichier portant le nom indiqué. Renvoie une promesse qui se résout lorsque le fichier est supprimé.storageFoundation.rename(oldName, newName)
: renomme le fichier de l'ancien nom au nouveau nom de manière atomique. Renvoie une promesse qui se résout lorsque le fichier est renommé.storageFoundation.getAll()
: renvoie une promesse qui se résout avec un tableau de tous les noms de fichiers existants.storageFoundation.requestCapacity(requestedCapacity)
: demande une nouvelle capacité (en octets) à utiliser par le contexte d'exécution actuel. Renvoie une promesse résolue avec la quantité de capacité restante disponible.
storageFoundation.releaseCapacity(toBeReleasedCapacity)
: libère le nombre d'octets spécifié à partir du contexte d'exécution actuel et renvoie une promesse qui se résout avec la capacité restante.storageFoundation.getRemainingCapacity()
: renvoie une promesse qui se résout avec la capacité disponible pour le contexte d'exécution actuel.
Poignées de fichiers
L'utilisation des fichiers s'effectue via les fonctions suivantes:
NativeIOFile.close()
: ferme un fichier et renvoie une promesse qui se résout à la fin de l'opération.NativeIOFile.flush()
: synchronise (c'est-à-dire vide) l'état en mémoire d'un fichier avec le périphérique de stockage, et renvoie une promesse qui se résout à la fin de l'opération.
NativeIOFile.getLength()
: renvoie une promesse qui se résout avec la longueur du fichier en octets.NativeIOFile.setLength(length)
: définit la longueur du fichier en octets et renvoie une promesse qui se résout à la fin de l'opération. Si la nouvelle longueur est inférieure à la longueur actuelle, les octets sont supprimés à partir de la fin du fichier. Sinon, le fichier est étendu avec des octets à valeur nulle.NativeIOFile.read(buffer, offset)
: lit le contenu du fichier au décalage donné via un tampon résultant du transfert du tampon donné, qui est ensuite laissé détaché. Renvoie unNativeIOReadResult
avec le tampon transféré et le nombre d'octets lus avec succès.Un
NativeIOReadResult
est un objet composé de deux entrées:buffer
:ArrayBufferView
, qui résulte du transfert du tampon transmis àread()
. Il est du même type et de la même longueur que le tampon source.readBytes
: nombre d'octets lus dansbuffer
. Cette valeur peut être inférieure à la taille de la mémoire tampon si une erreur se produit ou si la plage de lecture s'étend au-delà de la fin du fichier. Elle est définie sur zéro si la plage de lecture se situe au-delà de la fin du fichier.
NativeIOFile.write(buffer, offset)
: écrit le contenu du tampon donné dans le fichier au décalage donné. Le tampon est transféré avant l'écriture de données et reste donc détaché. Renvoie unNativeIOWriteResult
avec le tampon transféré et le nombre d'octets écrits avec succès. Le fichier sera étendu si la plage d'écriture dépasse sa longueur.Un
NativeIOWriteResult
est un objet qui comprend deux entrées:buffer
:ArrayBufferView
résultant du transfert du tampon transmis àwrite()
. Il est du même type et de la même longueur que le tampon source.writtenBytes
: nombre d'octets écrits dansbuffer
. Elle peut être inférieure à la taille de la mémoire tampon en cas d'erreur.
Exemples complets
Pour clarifier les concepts présentés ci-dessus, voici deux exemples complets qui vous expliquent les différentes étapes du cycle de vie des fichiers Storage Foundation.
Ouverture, écriture, lecture, fermeture
// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
// Request 100 bytes of capacity for this context.
await storageFoundation.requestCapacity(100);
const writeBuffer = new Uint8Array([64, 65, 66]);
// Write the buffer at offset 0. After this operation, `result.buffer`
// contains the transferred buffer and `result.writtenBytes` is 3,
// the number of bytes written. `writeBuffer` is left detached.
let result = await file.write(writeBuffer, 0);
const readBuffer = new Uint8Array(3);
// Read at offset 1. `result.buffer` contains the transferred buffer,
// `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
// detached.
result = await file.read(readBuffer, 1);
// `Uint8Array(3) [65, 66, 0]`
console.log(result.buffer);
} finally {
file.close();
}
Ouverture, liste, suppression
// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();
Démo
Vous pouvez tester la démonstration de l'API Storage Foundation dans l'intégration ci-dessous. Créez, renommez, écrivez dans et lisez des fichiers, et consultez la capacité disponible que vous avez demandée à mettre à jour à mesure que vous apportez des modifications. Vous trouverez le code source de la démonstration sur Glitch.
Sécurité et autorisations
L'équipe Chromium a conçu et implémenté l'API Storage Foundation en suivant les principes de base définis dans Controlling Access to Powerful Web Platform Features (Contrôler l'accès aux fonctionnalités puissantes de la plate-forme Web), y compris le contrôle utilisateur, la transparence et l'ergonomie.
Selon le même modèle que les autres API de stockage modernes sur le Web, l'accès à l'API Storage Foundation est lié à l'origine, ce qui signifie qu'une origine ne peut accéder qu'aux données créées par l'utilisateur. Elle est également limitée aux contextes sécurisés.
Contrôle des utilisateurs
Le quota de stockage permet de distribuer l'accès à l'espace disque et d'éviter les abus. La mémoire que vous souhaitez occuper doit d'abord être demandée. Comme les autres API de stockage, les utilisateurs peuvent libérer l'espace occupé par l'API Storage Foundation via leur navigateur.
Liens utiles
- Explication publique
- Démonstration de l'API Storage Foundation | Source de la démonstration de l'API Storage Foundation
- Bug de suivi Chromium
- Enregistrement sur ChromeStatus.com
- Composant Blink:
Blink>Storage>NativeIO
- Examen du TAG
- Intent to Prototype
- Thread WebKit
- Thread Mozilla
Remerciements
L'API Storage Foundation a été spécifiée et mise en œuvre par Emanuel Krivoy et Richard Stotz. Cet article a été examiné par Pete LePage et Joe Medley.
Image Hero via Markus Spiske sur Unsplash.