### Install Dependencies Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/contributing/building.md Run this command to install all necessary project dependencies before building. ```sh $ npm install ``` -------------------------------- ### Start Local Docs Preview Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/contributing/docs.md Run this command to start a local development server for previewing the documentation with live reloading. ```sh npm run docs:dev ``` -------------------------------- ### Run All Tests and Linting Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/contributing/testing.md Execute the full test suite and code linting using npm. Ensure you have installed dependencies with `npm install` first. ```sh $ npm run test ``` -------------------------------- ### Install remotestoragejs Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Install the remotestoragejs package using npm, pnpm, yarn, or bun. ```sh npm add remotestoragejs # or: pnpm add remotestoragejs | yarn add remotestoragejs | bun add remotestoragejs ``` -------------------------------- ### Install remotestoragejs with deno Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Use deno to add remotestoragejs from npm. ```sh $ deno add npm:remotestoragejs ``` -------------------------------- ### Create a Scoped Client and List Items Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/read-and-write-data.md Use the `scope()` method to create a BaseClient instance for a specific path. This example shows how to list all items within the 'foo/' category. ```javascript const client = remoteStorage.scope('/foo/'); // List all items in the "foo/" category/folder client.getListing('').then(listing => console.log(listing)); ``` -------------------------------- ### Install remotestoragejs with bun Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Use bun to add remotestoragejs as a development dependency. ```sh $ bun add -D remotestoragejs ``` -------------------------------- ### Initialize RemoteStorage Instance Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Create a new RemoteStorage instance with optional configuration for caching, logging, and change event behavior. A minimal setup for an offline-first app is also shown. ```javascript // All options with their defaults shown const remoteStorage = new RemoteStorage({ cache: true, // set false to skip local caching entirely logging: false, // set true to enable verbose debug output cordovaRedirectUri: undefined, changeEvents: { local: true, // fire on page load from local cache window: false, // fire when this tab writes (opt-in) remote: true, // fire when remote changes arrive conflict: true // fire on sync conflicts }, modules: [] // pre-load data modules (see addModule) }); // Minimal setup for an offline-first app const rs = new RemoteStorage({ logging: true }); ``` -------------------------------- ### Install remotestoragejs with npm Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Use npm to add remotestoragejs as a development dependency. ```sh $ npm add -D remotestoragejs ``` -------------------------------- ### Start Synchronization Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Initiate synchronization with remote storage to upload local changes and download remote updates. This is often used for manual sync actions. ```typescript remoteStorage.startSync(); ``` -------------------------------- ### Install remotestoragejs with pnpm Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Use pnpm to add remotestoragejs as a development dependency. ```sh $ pnpm add -D remotestoragejs ``` -------------------------------- ### Install remotestoragejs with yarn Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Use yarn to add remotestoragejs as a development dependency. ```sh $ yarn add -D remotestoragejs ``` -------------------------------- ### Local Change Event Example Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md An example of a 'change' event with the origin set to 'local'. This typically occurs during page load to populate views with existing data. ```json { path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'local', oldValue: undefined, newValue: 'white', oldContentType: undefined, newContentType: 'text/plain' } ``` -------------------------------- ### addEventListener() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remote/classes/RemoteBase.md Installs an event handler for a given event name. This method is usually called via the `on()` method. ```APIDOC ## addEventListener(eventName, handler) ### Description Installs an event handler for the given event name. ### Parameters #### eventName - `string` #### handler - `EventHandler` - Function to handle the event ### Returns - `void` ``` -------------------------------- ### Example of 'window' origin event Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md This event is fired when a value is changed by calling a method on the BaseClient. It is disabled by default and can be enabled via remoteStorage configuration. ```javascript { path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'window', oldValue: 'white', newValue: 'blue', oldContentType: 'text/plain', newContentType: 'text/plain' } ``` -------------------------------- ### Registering Event Handlers with RemoteStorage.js Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/events.md Use the `.on()` method to register callback functions for specific events. This example shows how to log when a user connects, or when the network status changes. ```javascript remoteStorage.on('connected', () => { const userAddress = remoteStorage.remote.userAddress; console.debug(`${userAddress} connected their remote storage.`); }) remoteStorage.on('network-offline', () => { console.debug(`We're offline now.`); }) remoteStorage.on('network-online', () => { console.debug(`Hooray, we're back online.`); }) ``` -------------------------------- ### Get Directory Listing with BaseClient Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Use getListing to retrieve a list of child nodes within a given path. Caching can be controlled with maxAge. ```javascript client.getListing('path/') ``` -------------------------------- ### Get Request Timeout Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Retrieves the current network request timeout duration in milliseconds. Example shows a typical return value. ```typescript remoteStorage.getRequestTimeout(); // 30000 ``` -------------------------------- ### Get Foreground Sync Interval Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Retrieves the sync interval duration in milliseconds when the application is in the foreground. Example shows a typical return value. ```typescript remoteStorage.getSyncInterval(); // 10000 ``` -------------------------------- ### startSync() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Initiates synchronization with remote storage, handling both uploads and downloads. ```APIDOC ## startSync() ### Description Start synchronization with remote storage, downloading and uploading any changes within the cached paths. Please consider: local changes will attempt sync immediately, and remote changes should also be synced timely when using library defaults. So this is mostly useful for letting users sync manually, when pressing a sync button for example. This might feel safer to them sometimes, esp. when shifting between offline and online a lot. ### Returns - `Promise` - A Promise which resolves when the sync has finished. ``` -------------------------------- ### Get Background Sync Interval Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Retrieves the sync interval duration in milliseconds when the application is in the background. Example shows a typical return value. ```typescript remoteStorage.getBackgroundSyncInterval(); // 60000 ``` -------------------------------- ### Get Current Sync Interval Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Retrieves the current sync interval duration in milliseconds. This can be the background, foreground, custom, or default interval. Example shows a typical return value. ```typescript remoteStorage.getCurrentSyncInterval(); // 15000 ``` -------------------------------- ### Handle Change Events on Startup Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/loading-data.md Use this to display items loaded from the local cache during startup and also items synchronized from remote storage afterwards. It listens for 'change' events with any origin. ```javascript remoteStorage.myfavoritedrinks.on('change', function(event) { if (event.newValue && (! event.oldValue)) { console.log('Change from '+event.origin+' (add)', event); displayDrink(event.relativePath, event.newValue.name); } }); ``` -------------------------------- ### Load All Items with getAll() and Update via Events Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/loading-data.md Use this to load all relevant documents on startup and then use only 'remote' change events for updates. This allows rendering all items at once. Ensure the event listener is registered after loading items if only remote changes are desired. ```javascript const items = await client.getAll("/my-sub-folder"); for (const path in items) { renderItem(path, items[path]); } client.on('change', event => { if (event.newValue) { renderItem(path, items[path]); } }); ``` -------------------------------- ### removeEventListener() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remote/classes/RemoteBase.md Removes a previously installed event handler. ```APIDOC ## removeEventListener(eventName, handler) ### Description Removes a previously installed event handler. ### Parameters #### eventName - `string` #### handler - `EventHandler` - Function to handle the event ### Returns - `void` ``` -------------------------------- ### Instantiating RemoteStorage Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md You can create a new instance of the RemoteStorage class. The constructor can optionally accept a configuration object to customize its behavior. ```APIDOC ## Instantiating RemoteStorage ### Description Create a `remoteStorage` class instance. ### Constructor ```javascript const remoteStorage = new RemoteStorage(); ``` ### Constructor with Configuration ### Description The constructor can optionally be called with a configuration object. ### Parameters #### Configuration Object - **cache** (boolean) - Optional - Whether to enable caching. - **changeEvents** (object) - Optional - Configuration for change event listeners. - **local** (boolean) - Optional - Enable local change events. - **window** (boolean) - Optional - Enable window change events. - **remote** (boolean) - Optional - Enable remote change events. - **conflict** (boolean) - Optional - Enable conflict change events. - **cordovaRedirectUri** (string) - Optional - The redirect URI for Cordova environments. - **logging** (boolean) - Optional - Whether to enable logging. - **modules** (array) - Optional - An array of module configurations. ### Example ```javascript const remoteStorage = new RemoteStorage({ cache: true, changeEvents: { local: true, window: false, remote: true, conflict: true }, cordovaRedirectUri: undefined, logging: false, modules: [] }); ``` ``` -------------------------------- ### Defining and Using Data Modules Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Demonstrates how to define a reusable data module for bookmarks, including type declarations and basic CRUD operations. It also shows how to register and use this module with a RemoteStorage instance. ```APIDOC ## Data Modules — Defining Reusable Storage Modules Data modules encapsulate storage logic with declared types, exposing a clean API that can be shared or published as npm packages. Modules receive private and public `BaseClient` instances automatically. ```javascript // Define a bookmarks module const BookmarksModule = { name: 'bookmarks', builder: function(privateClient, publicClient) { privateClient.declareType('archive-bookmark', { type: 'object', properties: { id: { type: 'string' }, url: { type: 'string', format: 'uri' }, title: { type: 'string' }, description: { type: 'string' }, tags: { type: 'array', default: [] }, createdAt: { type: 'string', format: 'date-time' } }, required: ['url', 'title'] }); return { exports: { add(bookmark) { bookmark.id = Math.random().toString(36).slice(2); bookmark.createdAt = new Date().toISOString(); return privateClient.storeObject('archive-bookmark', `archive/${bookmark.id}`, bookmark); }, getAll() { return privateClient.getAll('archive/', false); }, remove(id) { return privateClient.remove(`archive/${id}`); }, on(event, handler) { privateClient.on(event, handler); } } }; } }; // Register and use the module const remoteStorage = new RemoteStorage({ modules: [BookmarksModule] }); remoteStorage.access.claim('bookmarks', 'rw'); remoteStorage.caching.enable('/bookmarks/'); remoteStorage.on('ready', async () => { // Use the module's exported API await remoteStorage.bookmarks.add({ url: 'https://remotestorage.io', title: 'remoteStorage', tags: ['storage', 'offline-first'] }); const all = await remoteStorage.bookmarks.getAll(); console.log('All bookmarks:', all); remoteStorage.bookmarks.on('change', event => { console.log('Bookmarks changed:', event.relativePath, event.origin); }); }); ``` ``` -------------------------------- ### Initialize Connect Widget Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/connect-widget.md Create a new instance of the Connect Widget using your initialized remoteStorage instance. This widget simplifies the process of letting users connect their storage. ```javascript const widget = new Widget(remoteStorage); ``` -------------------------------- ### new RemoteStorage(config?) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Creates the main library instance. Accepts an optional configuration object to control caching, logging, supported backends, and change event behavior. ```APIDOC ## new RemoteStorage(config?) ### Description Creates the main library instance. Accepts an optional configuration object to control caching, logging, supported backends, and change event behavior. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript // All options with their defaults shown const remoteStorage = new RemoteStorage({ cache: true, // set false to skip local caching entirely logging: false, // set true to enable verbose debug output cordovaRedirectUri: undefined, changeEvents: { local: true, // fire on page load from local cache window: false, // fire when this tab writes (opt-in) remote: true, // fire when remote changes arrive conflict: true // fire on sync conflicts }, modules: [] // pre-load data modules (see addModule) }); // Minimal setup for an offline-first app const rs = new RemoteStorage({ logging: true }); ``` ### Response None ### Response Example None ``` -------------------------------- ### Version and Publish with npm Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/contributing/release-checklist.md This command automates several release tasks including running tests, updating package.json, creating a release build, committing changes, and tagging the release. ```sh $ npm version patch|minor|major|x.x.x-rc1 ``` -------------------------------- ### removeEventListener(eventName, handler) Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Removes a previously installed event handler for a specific event. ```APIDOC ## removeEventListener(eventName, handler) ### Description Remove a previously installed event handler. ### Parameters #### eventName - `eventName` (string) - The name of the event to remove the handler for. #### handler - `handler` (EventHandler) - The event handler function to remove. ### Returns - `void` ``` -------------------------------- ### Sync Control Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Provides methods to manually control the synchronization process, including starting, stopping, and configuring the sync interval and request timeouts. ```APIDOC ## Sync Control — `startSync()`, `stopSync()`, `setSyncInterval(ms)` Manually trigger, stop, or tune the automatic background sync behavior. ```javascript // Set foreground sync every 20 seconds (default: 10000ms) remoteStorage.setSyncInterval(20000); // Set background sync to every 2 minutes (default: 60000ms) remoteStorage.setBackgroundSyncInterval(120000); // Set network request timeout (default: 30000ms) remoteStorage.setRequestTimeout(15000); // Check current intervals console.log(remoteStorage.getSyncInterval()); // 20000 console.log(remoteStorage.getBackgroundSyncInterval()); // 120000 console.log(remoteStorage.getCurrentSyncInterval()); // active interval console.log(remoteStorage.getRequestTimeout()); // 15000 // Manually trigger a full sync (e.g., on a "Sync now" button) document.querySelector('#sync-btn').addEventListener('click', async () => { await remoteStorage.startSync(); console.log('Manual sync complete'); }); // Stop background sync entirely (e.g., when app is backgrounded) remoteStorage.stopSync(); ``` ``` -------------------------------- ### Connect Widget Integration Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Details on how to integrate the optional `remotestorage-widget` for a user-friendly UI to connect to remote storage services. ```APIDOC ## Connect Widget — Add-on UI The optional `remotestorage-widget` npm package provides a ready-made UI button for storage connection, rendering seamlessly in any web app. ```javascript import RemoteStorage from 'remotestoragejs'; import Widget from 'remotestorage-widget'; const remoteStorage = new RemoteStorage(); remoteStorage.access.claim('notes', 'rw'); remoteStorage.caching.enable('/notes/'); // Enable Dropbox and Google Drive options remoteStorage.setApiKeys({ dropbox: 'your-dropbox-app-key', googledrive: 'your-google-client-id' }); // Attach widget to document body const widget = new Widget(remoteStorage); widget.attach(); // Or attach to a specific container element widget.attach('my-toolbar-element-id'); ``` ``` -------------------------------- ### Instantiate RemoteStorage with Configuration Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Instantiate RemoteStorage with a configuration object. All default values are shown here. Note that change events must be explicitly set. ```javascript const remoteStorage = new RemoteStorage({ cache: true, changeEvents: { local: true, window: false, remote: true, conflict: true }, cordovaRedirectUri: undefined, logging: false, modules: [] }); ``` -------------------------------- ### Write Text File using Scoped Client Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/read-and-write-data.md Demonstrates how to use a scoped BaseClient to store a plain text file. The `storeFile()` method takes the content type, filename, and content as arguments. ```javascript // Write some text to "foo/bar.txt" const content = 'The most simple things can bring the most happiness.'; client.storeFile('text/plain', 'bar.txt', content) .then(() => console.log("data has been saved")); ``` -------------------------------- ### Initialize RemoteStorage Instance Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/initialize-and-configure.md Instantiate the RemoteStorage class to begin using its features. This is the first step in integrating RemoteStorage.js into your project. ```javascript const remoteStorage = new RemoteStorage(); ``` -------------------------------- ### Create a Scoped Client Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Instantiate a BaseClient for a specific path in your remote storage. Useful for debugging and development. ```typescript remoteStorage.scope('/pictures/').getListing(''); remoteStorage.scope('/public/pictures/').getListing(''); ``` -------------------------------- ### Get Public URL with BaseClient.getItemURL(path) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Retrieve the full, shareable URL for a document stored under the '/public/' folder. This method is only supported by remoteStorage backends and is useful for sharing files. ```javascript const publicClient = remoteStorage.scope('/public/portfolio/'); publicClient.storeFile('image/png', 'avatar.png', imageArrayBuffer) .then(() => { const url = publicClient.getItemURL('avatar.png'); console.log('Shareable URL:', url); // e.g. https://storage.example.com/alice/public/portfolio/avatar.png document.querySelector('#share-link').href = url; }); ``` -------------------------------- ### Configure and use RemoteStorage with AMD module Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Configure RequireJS to load RemoteStorage and then use it. Ensure the script is placed in the correct path. ```javascript requirejs.config({ paths: { RemoteStorage: './lib/remotestorage' } }); requirejs(['RemoteStorage'], function(RemoteStorage) { // Here goes my app }); ``` -------------------------------- ### Get Object from Remote Storage - TypeScript Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Fetches a JSON object from a specified path in remote storage. Optionally, you can specify the maximum age of the cached object in milliseconds or disable caching by setting it to false. ```typescript client.getObject('/path/to/object').then(obj => console.log(obj)); ``` -------------------------------- ### enable() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/caching/classes/Caching.md Enable caching for a given path using the 'ALL' strategy. This ensures all data within the specified path is proactively cached. ```APIDOC ## enable(path) ### Description Enable caching for a given path. Uses caching strategy ``ALL``. ### Parameters #### path `string` - Path to enable caching for ### Returns `void` ### Example ```js remoteStorage.caching.enable('/bookmarks/'); ``` ``` -------------------------------- ### Get Item URL with BaseClient Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Use getItemURL to obtain the full public URL for an item, which is particularly useful for sharing resources stored in the '/public' directory. This method currently only supports remoteStorage backends. ```javascript client.getItemURL('path') ``` -------------------------------- ### Configure Caching Strategies Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Control local sync strategies per path using 'ALL' (proactive sync), 'SEEN' (sync accessed items, default), or 'FLUSH' (write-through only). ```javascript // Enable full caching for a folder (uses ALL strategy) remoteStorage.caching.enable('/bookmarks/'); ``` ```javascript // Disable caching for a path (uses FLUSH — changes pushed but not retained locally) remoteStorage.caching.disable('/large-files/'); ``` ```javascript // Fine-grained strategy assignment remoteStorage.caching.set('/bookmarks/archive/', 'SEEN'); // cache only accessed items remoteStorage.caching.set('/notes/', 'ALL'); // cache everything proactively remoteStorage.caching.set('/temp/', 'FLUSH'); // write-through, no local store ``` ```javascript // Check which strategy applies to a path remoteStorage.caching.checkPath('documents/').then(strategy => { console.log(`caching strategy: ${strategy}`); // e.g. "SEEN" }); ``` ```javascript // Reset all caching configuration remoteStorage.caching.reset(); ``` -------------------------------- ### Get Folder Listing - JavaScript Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Retrieves a listing of items within a remote storage folder. The listing is returned as a JSON object where keys represent paths. Folder nodes end with a forward slash, and data nodes include ETag, Content-Length, and Content-Type. ```javascript client.getListing().then(listing => console.log(listing)); ``` ```json { "@context": "http://remotestorage.io/spec/folder-description", "items": { "thumbnails/": true, "screenshot-20170902-1913.png": { "ETag": "6749fcb9eef3f9e46bb537ed020aeece", "Content-Length": 53698, "Content-Type": "image/png;charset=binary" }, "screenshot-20170823-0142.png": { "ETag": "92ab84792ef3f9e46bb537edac9bc3a1", "Content-Length": 412401, "Content-Type": "image/png;charset=binary" } } } ``` -------------------------------- ### Include RemoteStorage script globally Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/how-to-add.md Link the remotestorage.js build directly in HTML to make RemoteStorage available as a global variable on the window object. ```html ``` -------------------------------- ### Example of 'conflict' origin event Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md This event is fired when a conflict occurs during the sync process, typically when a local change is pushed to the remote store and the remote version has changed in the meantime. It includes information about the local and remote versions, as well as the last known common ancestor. ```javascript { path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'conflict', oldValue: 'blue', newValue: 'red', oldContentType: 'text/plain', newContentType: 'text/plain', // Most recent known common ancestor body of local and remote lastCommonValue: 'white', // Most recent known common ancestor contentType of local and remote lastCommonContentType: 'text/plain' } ``` -------------------------------- ### BaseClient.getListing(path?, maxAge?) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Returns a mapping of all child nodes (files and sub-folders) under the given path. Folder entries end with `/`; file entries contain ETag and content metadata. ```APIDOC ## `BaseClient.getListing(path?, maxAge?)` — List Folder Contents Returns a mapping of all child nodes (files and sub-folders) under the given path. Folder entries end with `/`; file entries contain ETag and content metadata (when caching is off). ### Parameters #### Path Parameters - **path** (string) - Optional - The path to list contents from. Defaults to the client's root. - **maxAge** (number | false) - Optional - Maximum age in milliseconds for cached entries, or `false` to force a remote read. ### Request Example ```javascript const client = remoteStorage.scope('/bookmarks/'); // List root of this client's scope client.getListing('').then(listing => { Object.keys(listing).forEach(name => { if (name.endsWith('/')) { console.log('Folder:', name); } else { console.log('File:', name, listing[name]); } }); }); // List a subfolder with a freshness constraint (max 5 seconds old) client.getListing('archive/', 5000).then(listing => console.log(listing)); // Force read from local cache only (skip remote check) client.getListing('archive/', false).then(listing => console.log(listing)); ``` ### Response #### Success Response - **listing** (object) - A mapping of child node names to their metadata. ``` -------------------------------- ### Integrate RemoteStorage Connect Widget Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Integrate the `remotestorage-widget` for a UI button to manage storage connections. Configure API keys for services like Dropbox and Google Drive, then attach the widget to the document body or a specific element. ```javascript import RemoteStorage from 'remotestoragejs'; import Widget from 'remotestorage-widget'; const remoteStorage = new RemoteStorage(); remoteStorage.access.claim('notes', 'rw'); remoteStorage.caching.enable('/notes/'); // Enable Dropbox and Google Drive options remoteStorage.setApiKeys({ dropbox: 'your-dropbox-app-key', googledrive: 'your-google-client-id' }); // Attach widget to document body const widget = new Widget(remoteStorage); widget.attach(); // Or attach to a specific container element widget.attach('my-toolbar-element-id'); ``` -------------------------------- ### Configure Dropbox and Google Drive API Keys Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/dropbox-and-google-drive.md Set your Dropbox app key and Google Drive client ID to enable these backends. The Connect widget will automatically display available options based on these configurations. ```javascript remoteStorage.setApiKeys({ dropbox: 'your-app-key', googledrive: 'your-client-id' }); ``` -------------------------------- ### List Folder Contents with BaseClient.getListing Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Lists child nodes under a given path. Folder entries end with '/', file entries include ETag and content metadata. Supports freshness constraints and cache-only reads. ```javascript const client = remoteStorage.scope('/bookmarks/'); // List root of this client's scope client.getListing('').then(listing => { Object.keys(listing).forEach(name => { if (name.endsWith('/')) { console.log('Folder:', name); } else { console.log('File:', name, listing[name]); } }); }); // List a subfolder with a freshness constraint (max 5 seconds old) client.getListing('archive/', 5000).then(listing => console.log(listing)); // Force read from local cache only (skip remote check) client.getListing('archive/', false).then(listing => console.log(listing)); ``` -------------------------------- ### Connecting to RemoteStorage Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Details the process of connecting to a remoteStorage server, including user address discovery and token handling. ```APIDOC ### connect() > **connect**(`userAddress`, `token?`): `void` Connect to a remoteStorage server. Discovers the WebFinger profile of the given user address and initiates the OAuth dance. This method must be called *after* all required access has been claimed. When using the connect widget, it will call this method when the user clicks/taps the "connect" button. Special cases: 1. If a bearer token is supplied as second argument, the OAuth dance will be skipped and the supplied token be used instead. This is useful outside of browser environments, where the token has been acquired in a different way. 2. If the Webfinger profile for the given user address doesn't contain an auth URL, the library will assume that client and server have established authorization among themselves, which will omit bearer tokens in all requests later on. This is useful for example when using Kerberos and similar protocols. #### Parameters ##### userAddress `string` The user address (user@host) or URL to connect to. ##### token? `string` (optional) A bearer token acquired beforehand #### Returns `void` #### Example ```ts remoteStorage.connect('user@example.com'); ``` ``` -------------------------------- ### Define and Use a Bookmarks Data Module Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Defines a reusable 'bookmarks' data module with custom type declarations and exportable functions. Register the module with RemoteStorage and access its API after the remoteStorage instance is ready. ```javascript // Define a bookmarks module const BookmarksModule = { name: 'bookmarks', builder: function(privateClient, publicClient) { privateClient.declareType('archive-bookmark', { type: 'object', properties: { id: { type: 'string' }, url: { type: 'string', format: 'uri' }, title: { type: 'string' }, description: { type: 'string' }, tags: { type: 'array', default: [] }, createdAt: { type: 'string', format: 'date-time' } }, required: ['url', 'title'] }); return { exports: { add(bookmark) { bookmark.id = Math.random().toString(36).slice(2); bookmark.createdAt = new Date().toISOString(); return privateClient.storeObject('archive-bookmark', `archive/${bookmark.id}`, bookmark); }, getAll() { return privateClient.getAll('archive/', false); }, remove(id) { return privateClient.remove(`archive/${id}`); }, on(event, handler) { privateClient.on(event, handler); } } }; } }; // Register and use the module const remoteStorage = new RemoteStorage({ modules: [BookmarksModule] }); remoteStorage.access.claim('bookmarks', 'rw'); remoteStorage.caching.enable('/bookmarks/'); remoteStorage.on('ready', async () => { // Use the module's exported API await remoteStorage.bookmarks.add({ url: 'https://remotestorage.io', title: 'remoteStorage', tags: ['storage', 'offline-first'] }); const all = await remoteStorage.bookmarks.getAll(); console.log('All bookmarks:', all); remoteStorage.bookmarks.on('change', event => { console.log('Bookmarks changed:', event.relativePath, event.origin); }); }); ``` -------------------------------- ### Retrieve All Objects Below a Path with BaseClient Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Use getAll to fetch all items directly under a specified path. It can optionally use cached data if maxAge is provided. ```javascript client.getAll('example-subdirectory/').then(objects => { for (var path in objects) { console.log(path, objects[path]); } }); ``` -------------------------------- ### BaseClient.getAll(path?, maxAge?) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Returns all objects (or files) directly under the given folder path as a keyed object. Non-JSON-stored items appear with value `true`. ```APIDOC ## `BaseClient.getAll(path?, maxAge?)` — Read All Objects in a Folder Returns all objects (or files) directly under the given folder path as a keyed object. Non-JSON-stored items appear with value `true`. ### Parameters #### Path Parameters - **path** (string) - Optional - The folder path to retrieve items from. Defaults to the client's root. - **maxAge** (number | false) - Optional - Maximum age in milliseconds for cached entries, or `false` to force a remote read. ### Request Example ```javascript const client = remoteStorage.scope('/bookmarks/'); // Get all items; allow up to 10s old (default) client.getAll('archive/').then(items => { for (const [path, obj] of Object.entries(items)) { console.log(path, obj); } }); // Get immediately from local cache without waiting for remote client.getAll('archive/', false).then(items => { renderItemList(Object.values(items)); }); ``` ### Response #### Success Response - **items** (object) - A keyed object where keys are item paths and values are the item content (or `true` for non-JSON files). ``` -------------------------------- ### Set Caching Strategy with BaseClient.cache(path, strategy) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Configure caching strategies for sub-paths on a client, supporting method chaining. Strategies include 'ALL' for full caching, 'SEEN' for caching accessed items, and 'FLUSH' for write-through caching. ```javascript const client = remoteStorage.scope('/bookmarks/'); // Chain cache configuration client .cache('archive/', 'ALL') // full caching for archive .cache('drafts/', 'SEEN') // cache only what's been accessed .cache('temp/', 'FLUSH'); // write-through only // Then store an object — cache behavior applies immediately client.storeObject('bookmark', 'archive/my-link', { url: 'https://example.com', title: 'Example' }); ``` -------------------------------- ### Node.js Usage Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Explains how to use RemoteStorage.js in a Node.js environment, including its in-memory storage behavior and external OAuth handling. ```APIDOC ## Node.js Usage In Node.js, the library uses in-memory storage (no IndexedDB/localStorage), and OAuth must be handled externally. Pass the token directly to `connect()`. ```javascript import RemoteStorage from 'remotestoragejs'; // Node 18+ has fetch built-in; for older versions: // import fetch from 'node-fetch'; global.fetch = fetch; const remoteStorage = new RemoteStorage({ logging: true }); remoteStorage.access.claim('messages', 'rw'); remoteStorage.on('connected', async () => { const client = remoteStorage.scope('/messages/'); await client.storeObject('message', 'hello.json', { text: 'Hello from Node.js', ts: Date.now() }); const msg = await client.getObject('hello.json'); console.log('Retrieved:', msg); }); remoteStorage.on('error', err => console.error('Error:', err)); // Token acquired out-of-band (e.g. from env var, manual OAuth flow, etc.) remoteStorage.connect('user@storage.example.com', process.env.RS_TOKEN); ``` ``` -------------------------------- ### Create Ad-hoc Scoped Client Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Creates a `BaseClient` instance rooted at a specified path for direct reads and writes without defining formal data modules. This is primarily useful for development and debugging purposes. ```javascript const client = remoteStorage.scope('/notes/'); // List all items in the scoped folder client.getListing('').then(listing => { console.log(listing); // { // "note-1.json": { "ETag": "abc123", "Content-Length": 256, "Content-Type": "application/json" }, // "drafts/": true // } }); ``` ```javascript // Scope into a public path const publicClient = remoteStorage.scope('/public/portfolio/'); ``` -------------------------------- ### Connect Storage Manually Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/getting-started/connect-widget.md Connect a user's storage by calling the `connect()` method on the remoteStorage instance with the user's address. This is used when building a custom connection UI. ```javascript remoteStorage.connect('user@example.com'); ``` -------------------------------- ### Adding Modules Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Explains how to add custom or third-party modules to RemoteStorage to extend its functionality. ```APIDOC ### addModule() > **addModule**(`module`): `void` Add remoteStorage data module #### Parameters ##### module [`RSModule`](../interfaces/RSModule.md) A data module object #### Returns `void` #### Example Usually, you will import your data module from either a package or a local path. Let's say you want to use the [bookmarks module](https://github.com/raucao/remotestorage-module-bookmarks) in order to load data stored from [Webmarks](https://webmarks.5apps.com) for example: ```js import Bookmarks from 'remotestorage-module-bookmarks'; remoteStorage.addModule(Bookmarks); ``` You can also forgo this function entirely and add modules when creating your remoteStorage instance: ```js const remoteStorage = new RemoteStorage({ modules: [ Bookmarks ] }); ``` After the module has been added, it can be used like so: ```js remoteStorage.bookmarks.archive.getAll(false) .then(bookmarks => console.log(bookmarks)); ``` ``` -------------------------------- ### Write Raw File with BaseClient.storeFile Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Stores raw data (text or binary) with a specified MIME type. Returns a promise resolving to the new ETag. Handles both direct string input and binary data from file inputs. ```javascript const client = remoteStorage.scope('/documents/'); // Store a text file client.storeFile('text/html', 'index.html', '

Hello World!

') .then(etag => console.log('Saved, revision:', etag)); // Store binary data from a file input const input = document.querySelector('input[type=file]'); const file = input.files[0]; const reader = new FileReader(); reader.onload = () => { client.storeFile(file.type, file.name, reader.result) .then(() => console.log('Binary file saved')) .catch(err => console.error('Upload failed:', err)); }; reader.readAsArrayBuffer(file); ``` -------------------------------- ### getListing() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Retrieves a list of child nodes (files and directories) located under a specified path. Caching can be controlled via the maxAge parameter. ```APIDOC ## getListing() ### Description Get a list of child nodes below a given path. ### Method GET (implied) ### Endpoint `/{path}` (implied) ### Parameters #### Path Parameters - **path?** (string) - Optional - The path to query. It must end with a forward slash. #### Query Parameters - **maxAge?** (number | false) - Optional - Either `false` or the maximum age of cached listing in milliseconds. ### Response #### Success Response (200) - **listing** (object) - An object where keys are the names of child nodes and values indicate their type (e.g., `true` for files, an object for directories). ### Request Example ```js client.getListing('my-folder/').then(listing => { console.log('Contents of my-folder:', listing); }); ``` ``` -------------------------------- ### scope() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Creates a new BaseClient instance scoped to a subpath of the current client's path. ```APIDOC ## scope(path) ### Description Instantiate a new client, scoped to a subpath of the current client's path. ### Method Client Scoping ### Parameters #### Path Parameters - **path** (string) - Required - The path to scope the new client to. ### Response #### Success Response (BaseClient) - **BaseClient** (BaseClient) - A new `BaseClient` operating on a subpath of the current base path. ### Request Example ```js const subClient = client.scope('/my-app-data'); ``` ``` -------------------------------- ### onActivate() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/caching/classes/Caching.md Set a callback function that will be executed when caching is activated for a specific path. ```APIDOC ## onActivate(cb) ### Description Set a callback for when caching is activated for a path. ### Parameters #### cb (`firstPending`) => `void` - Callback function ### Returns `void` ``` -------------------------------- ### Store Binary File with BaseClient Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Use this to store binary files. It requires reading the file content into an ArrayBuffer before storing. ```javascript const input = document.querySelector('form#upload input[type=file]'); const file = input.files[0]; const fileReader = new FileReader(); fileReader.onload = function () { client.storeFile(file.type, file.name, fileReader.result) .then(() => { console.log("File saved") }); }; fileReader.readAsArrayBuffer(file); ``` -------------------------------- ### Load a RemoteStorage Module Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/data-modules/defining-a-module.md Modules can be loaded into a RemoteStorage instance either during initialization or by calling `addModule()` later. ```javascript const remoteStorage = new RemoteStorage({ modules: [ Bookmarks ] }); ``` ```javascript remoteStorage.addModule(Bookmarks); ``` -------------------------------- ### remoteStorage.connect(userAddress, token?) Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Initiates a connection to a remoteStorage server. In browser environments, it triggers a WebFinger lookup and OAuth redirect. In Node.js or pre-authorized contexts, a bearer token can be provided to skip the OAuth flow. ```APIDOC ## `remoteStorage.connect(userAddress, token?)` — Connect Storage Initiates a connection to a remoteStorage server for the given user address. Performs a WebFinger lookup and redirects to the OAuth server. In Node.js or non-browser contexts, pass a pre-acquired bearer token to skip the OAuth flow. ### Parameters #### Path Parameters - **userAddress** (string) - Required - The user's storage address (e.g., 'user@storage.example.com'). - **token** (string) - Optional - A pre-acquired bearer token to skip the OAuth flow. ### Request Example ```javascript // Browser: triggers WebFinger + OAuth redirect flow remoteStorage.connect('user@storage.example.com'); // Node.js or pre-authorized environments: skip OAuth remoteStorage.connect('user@storage.example.com', 'my-bearer-token-abc123'); ``` ### Events - **connected**: Fired when the connection is successfully established. - **disconnected**: Fired when the session is terminated and the local cache is cleared. ### Event Example ```javascript remoteStorage.on('connected', () => { const { userAddress } = remoteStorage.remote; console.log(`Connected as ${userAddress}`); console.log(`Backend: ${remoteStorage.backend}`); // 'remotestorage' | 'dropbox' | 'googledrive' }); remoteStorage.on('disconnected', () => { console.log('Storage has been disconnected and local cache cleared.'); }); ``` ``` -------------------------------- ### Run Single Test File with Jaribu Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/contributing/testing.md Execute the Jaribu test runner for a specific test file. This is useful for focused testing during development. ```sh $ ./node_modules/.bin/jaribu test/unit/cachinglayer-suite.js ``` -------------------------------- ### Read All Folder Items with BaseClient.getAll Source: https://context7.com/remotestorage/remotestorage.js/llms.txt Retrieves all items (objects or files) directly under a folder path. Non-JSON items are represented by the value `true`. Supports freshness constraints and cache-only reads. ```javascript const client = remoteStorage.scope('/bookmarks/'); // Get all items; allow up to 10s old (default) client.getAll('archive/').then(items => { for (const [path, obj] of Object.entries(items)) { console.log(path, obj); } }); // Get immediately from local cache without waiting for remote client.getAll('archive/', false).then(items => { renderItemList(Object.values(items)); }); ``` -------------------------------- ### Accessing RemoteStorage Properties Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Demonstrates how to access key properties of the RemoteStorage instance, such as access control, caching settings, and remote connection details. ```APIDOC ## Accessors ### access > **access**: [`Access`](../../access/classes/Access.md) Managing claimed access scopes. ### caching > **caching**: [`Caching`](../../caching/classes/Caching.md) Managing cache settings. ### remote > **remote**: [`Remote`](../../remote/interfaces/Remote.md) Depending on the chosen backend, this is either an instance of `WireClient`, `Dropbox` or `GoogleDrive`. See [Remote](../../remote/interfaces/Remote.md) for public API. #### Example ```ts remoteStorage.remote.connected // false ``` ### connected #### Get Signature > **get** **connected**(): `boolean` Indicating if remoteStorage is currently connected. ##### Returns `boolean` ``` -------------------------------- ### Retrieve a File with BaseClient Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/baseclient/classes/BaseClient.md Use getFile to retrieve raw file data, such as images or other binary content. It returns the content type and the data itself. Caching can be controlled with maxAge. ```javascript client.getFile('path/to/some/image').then(file => { const blob = new Blob([file.data], { type: file.contentType }); const targetElement = document.findElementById('my-image-element'); targetElement.src = window.URL.createObjectURL(blob); }); ``` -------------------------------- ### set() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/caching/classes/Caching.md Configure caching for a given path explicitly with a specified strategy. This method is useful for fine-grained control over caching behavior. ```APIDOC ## set(path, strategy) ### Description Configure caching for a given path explicitly. Not needed when using ``enable``/``disable``. ### Parameters #### path `string` - Path to cache #### strategy `"ALL"` | `"SEEN"` | `"FLUSH"` - Caching strategy. One of 'ALL', 'SEEN', or 'FLUSH'. ### Returns `void` ### Example ```js remoteStorage.caching.set('/bookmarks/archive/', 'SEEN'); ``` ``` -------------------------------- ### enableLog() Source: https://github.com/remotestorage/remotestorage.js/blob/master/docs/api/remotestorage/classes/RemoteStorage.md Enables remoteStorage debug logging. This is typically configured during the instantiation of RemoteStorage. ```APIDOC ## enableLog() ### Description Enable remoteStorage debug logging. Usually done when instantiating remoteStorage: ```js const remoteStorage = new RemoteStorage({ logging: true }); ``` ### Method `void` ### Returns `void` ```