Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unstorage

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unstorage - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

drivers/http.js

14

CHANGELOG.md

@@ -5,2 +5,16 @@ # Changelog

### [0.0.2](https://github.com/unjsio/unstorage/compare/v0.0.1...v0.0.2) (2021-03-11)
### Features
* http driver ([438db64](https://github.com/unjsio/unstorage/commit/438db6427602a08343c8836a3386b9d712ca6ee9))
* support base for drivers ([6844cd1](https://github.com/unjsio/unstorage/commit/6844cd11373c7aeee49780322d4c23c48342eb8a))
* watcher ([ebcf1f1](https://github.com/unjsio/unstorage/commit/ebcf1f1a742756b78adaa955bdc90615554404cf))
### Bug Fixes
* add mount prefix to watch key ([0bb634d](https://github.com/unjsio/unstorage/commit/0bb634dcc51de2f32f2b2b892efa9090ef2c6885))
### 0.0.1 (2021-03-11)

@@ -7,0 +21,0 @@

8

dist/index.d.ts
declare type StorageValue = null | string | String | number | Number | boolean | Boolean | object;
declare type WatchEvent = 'update' | 'remove';
declare type WatchCallback = (event: WatchEvent, key: string) => any;
interface Driver {

@@ -10,2 +12,3 @@ hasItem: (key: string) => boolean | Promise<boolean>;

dispose?: () => void | Promise<void>;
watch?: (callback: WatchCallback) => void | Promise<void>;
}

@@ -21,5 +24,6 @@ declare type DriverFactory<OptsT = any> = (opts?: OptsT) => Driver;

clear: (base?: string) => Promise<void>;
mount: (base: string, driver: Driver, initialState?: Record<string, string>) => Promise<void>;
mount: (base: string, driver: Driver, initialState?: Record<string, StorageValue>) => Promise<void>;
unmount: (base: string, dispose?: boolean) => Promise<void>;
dispose: () => Promise<void>;
watch: (callback: WatchCallback) => Promise<void>;
}

@@ -30,2 +34,2 @@

export { Driver, DriverFactory, Storage, StorageValue, createStorage, snapshot };
export { Driver, DriverFactory, Storage, StorageValue, WatchCallback, WatchEvent, createStorage, snapshot };

@@ -111,6 +111,7 @@ 'use strict';

mounts: {"": memory()},
mountpoints: [""]
mountpoints: [""],
watching: false,
watchListeners: []
};
const getMount = (key) => {
key = normalizeKey(key);
for (const base of ctx.mountpoints) {

@@ -130,3 +131,2 @@ if (key.startsWith(base)) {

const getMounts = (base) => {
base = normalizeBase(base);
return ctx.mountpoints.filter((mountpoint) => base.startsWith(mountpoint)).map((mountpoint) => ({

@@ -137,4 +137,23 @@ mountpoint,

};
const onChange = (event, key) => {
if (!ctx.watching) {
return;
}
key = normalizeKey(key);
for (const listener of ctx.watchListeners) {
listener(event, key);
}
};
const startWatch = async () => {
if (ctx.watching) {
return;
}
ctx.watching = true;
for (const mountpoint in ctx.mounts) {
await watch(ctx.mounts[mountpoint], onChange, mountpoint);
}
};
const storage = {
hasItem(key) {
key = normalizeKey(key);
const {relativeKey, driver} = getMount(key);

@@ -144,11 +163,16 @@ return asyncCall(driver.hasItem, relativeKey);

getItem(key) {
key = normalizeKey(key);
const {relativeKey, driver} = getMount(key);
return asyncCall(driver.getItem, relativeKey).then((val) => destr(val));
},
setItem(key, value) {
async setItem(key, value) {
if (value === void 0) {
return storage.removeItem(key);
}
key = normalizeKey(key);
const {relativeKey, driver} = getMount(key);
return asyncCall(driver.setItem, relativeKey, stringify(value));
await asyncCall(driver.setItem, relativeKey, stringify(value));
if (!driver.watch) {
onChange("update", key);
}
},

@@ -159,5 +183,9 @@ async setItems(base, items) {

},
removeItem(key) {
async removeItem(key) {
key = normalizeKey(key);
const {relativeKey, driver} = getMount(key);
return asyncCall(driver.removeItem, relativeKey);
await asyncCall(driver.removeItem, relativeKey);
if (!driver.watch) {
onChange("remove", key);
}
},

@@ -174,2 +202,3 @@ async getKeys(base) {

async clear(base) {
base = normalizeBase(base);
await Promise.all(getMounts(base).map((m) => asyncCall(m.driver.clear)));

@@ -193,2 +222,5 @@ },

ctx.mounts[base] = driver;
if (ctx.watching) {
await watch(driver, onChange, base);
}
if (initialState) {

@@ -208,2 +240,6 @@ await storage.setItems(base, initialState);

delete ctx.mounts[base];
},
async watch(callback) {
await startWatch();
ctx.watchListeners.push(callback);
}

@@ -222,2 +258,7 @@ };

}
function watch(storage, onChange, base) {
if (storage.watch) {
return storage.watch((event, key) => onChange(event, base + key));
}
}
async function dispose(storage) {

@@ -224,0 +265,0 @@ if (typeof storage.dispose === "function") {

import {existsSync} from "fs";
import {resolve} from "path";
import {resolve, relative, join} from "path";
import {watch} from "chokidar";
import {readFile, writeFile, readdirRecursive, rmRecursive, unlink} from "./utils/node-fs";
export default (function(opts) {
if (!opts.dir) {
if (!opts.base) {
throw new Error("dir is required");
}
const r = (key) => resolve(opts.dir, key.replace(/:/g, "/"));
if (!opts.ingore) {
opts.ingore = [
"node_modules"
];
}
opts.base = resolve(opts.base);
const r = (key) => join(opts.base, key.replace(/:/g, "/"));
let _watcher;
return {

@@ -28,5 +36,27 @@ hasItem(key) {

},
dispose() {
async dispose() {
if (_watcher) {
await _watcher.close();
}
},
watch(callback) {
if (_watcher) {
return;
}
return new Promise((resolve2, reject) => {
_watcher = watch(opts.base, {
ignoreInitial: true,
ignored: opts.ingore,
...opts.watchOptions
}).on("ready", resolve2).on("error", reject).on("all", (eventName, path) => {
path = relative(opts.base, path);
if (eventName === "change" || eventName === "add") {
callback("update", path);
} else if (eventName === "unlink") {
callback("remove", path);
}
});
});
}
};
});

@@ -1,26 +0,52 @@

export default (function(opts) {
const _localStorage = opts?.localStorage || globalThis.localStorage;
if (!_localStorage) {
export default (function(opts = {}) {
if (!opts.window) {
opts.window = typeof window !== "undefined" ? window : void 0;
}
if (!opts.localStorage) {
opts.localStorage = opts.window?.localStorage;
}
if (!opts.localStorage) {
throw new Error("localStorage not available");
}
const r = (key) => (opts.base ? opts.base + ":" : "") + key;
let _storageListener;
return {
hasItem(key) {
return Object.prototype.hasOwnProperty.call(_localStorage, key);
return Object.prototype.hasOwnProperty.call(opts.localStorage, r(key));
},
getItem(key) {
return _localStorage.getItem(key);
return opts.localStorage.getItem(r(key));
},
setItem(key, value) {
return _localStorage.setItem(key, value);
return opts.localStorage.setItem(r(key), value);
},
removeItem(key) {
return _localStorage.removeItem(key);
return opts.localStorage.removeItem(r(key));
},
getKeys() {
return Object.keys(_localStorage);
return Object.keys(opts.localStorage);
},
clear() {
_localStorage.clear();
if (!opts.base) {
opts.localStorage.clear();
} else {
for (const key of Object.keys(opts.localStorage)) {
opts.localStorage?.removeItem(key);
}
}
if (opts.window && _storageListener) {
opts.window.removeEventListener("storage", _storageListener);
}
},
watch(callback) {
if (opts.window) {
_storageListener = (ev) => {
if (ev.key) {
callback(ev.newValue ? "update" : "remove", ev.key);
}
};
opts.window.addEventListener("storage", _storageListener);
}
}
};
});
{
"name": "unstorage",
"version": "0.0.1",
"version": "0.0.2",
"description": "",

@@ -21,4 +21,10 @@ "repository": "unjsio/unstorage",

"release": "yarn test && standard-version && git push --follow-tags && npm publish",
"test": "yarn lint && jest"
"test": "yarn lint && jest",
"doctoc": "doctoc README.md --notitle"
},
"dependencies": {
"chokidar": "^3.5.1",
"ohmyfetch": "^0.1.8",
"ufo": "^0.6.10"
},
"devDependencies": {

@@ -30,2 +36,3 @@ "@nuxtjs/eslint-config-typescript": "latest",

"destr": "^1.1.0",
"doctoc": "^2.0.0",
"eslint": "latest",

@@ -35,2 +42,3 @@ "jest": "latest",

"jsdom": "^16.4.0",
"listhen": "^0.1.4",
"mkdist": "^0.1.2",

@@ -37,0 +45,0 @@ "siroc": "latest",

@@ -21,9 +21,38 @@ # unstorage

- State snapshot
- Abstract watcher
WIP:
- State watching
- Key expiration
- Storage server
**Table of Contents**
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Drivers](#drivers)
- [Usage](#usage)
- [Storage Interface](#storage-interface)
- [`storage.hasItem(key)`](#storagehasitemkey)
- [`storage.getItem(key)`](#storagegetitemkey)
- [`storage.setItem(key, value)`](#storagesetitemkey-value)
- [`storage.setItems(base, items)`](#storagesetitemsbase-items)
- [`storage.removeItem(key)`](#storageremoveitemkey)
- [`storage.getKeys(base?)`](#storagegetkeysbase)
- [`storage.clear(base?)`](#storageclearbase)
- [`storage.dispose()`](#storagedispose)
- [`storage.mount(mountpoint, driver, initialState?)`](#storagemountmountpoint-driver-initialstate)
- [`storage.unmount(mountpoint, dispose = true)`](#storageunmountmountpoint-dispose--true)
- [`storage.watch(callback)`](#storagewatchcallback)
- [Utils](#utils)
- [`snapshot(storage, base?)`](#snapshotstorage-base)
- [Drivers](#drivers-1)
- [`fs` (node)](#fs-node)
- [`localStorage` (browser)](#localstorage-browser)
- [`memory` (universal)](#memory-universal)
- [Contribution](#contribution)
- [License](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Drivers

@@ -34,5 +63,5 @@

- [x] LocalStorage (Browser)
- [x] HTTP (Universal)
- [ ] Cookies (Browser)
- [ ] Location params (Browser)
- [ ] HTTP (Universal)
- [ ] S3 (Universal)

@@ -63,2 +92,4 @@ - [ ] Cloudflare KV (Workers and Universal)

## Storage Interface
### `storage.hasItem(key)`

@@ -136,3 +167,3 @@

### `storage.mount(mountpoint, driver, items?)`
### `storage.mount(mountpoint, driver, initialState?)`

@@ -143,3 +174,3 @@ By default, everything is stored in memory. We can mount additional storage space in a Unix-like fashion.

If `items` argument is provided, restores/hydrates state of mountpoint using `setItems`.
If `initialState` argument is provided, restores/hydrates state of mountpoint using `setItems`.

@@ -168,2 +199,16 @@ <!-- TODO: Explain mountpoint hiding -->

```js
await storage.unmount('/output')
```
### `storage.watch(callback)`
Starts watching on all mountpoints. If driver does not supports watching, only emits even when `storage.*` methods are called.
```js
await storage.watch((event, key) => { })
```
## Utils
### `snapshot(storage, base?)`

@@ -178,2 +223,50 @@

## Drivers
### `fs` (node)
Maps data to real filesystem using directory structure for nested keys. Supports watching using [chokidar](https://github.com/paulmillr/chokidar).
```js
import fsDriver from 'unstorage/drivers/memory'
await storage.mount('/tmp', fsDriver({ base: './tmp' }))
```
**Options:**
- `base`: Base directory to isolate operations on this directory
- `ignore`: Ignore patterns for watch <!-- and key listing -->
- `watchOptions`: Additional [chokidar](https://github.com/paulmillr/chokidar) options.
### `localStorage` (browser)
Store data in [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
```js
import lsDriver from 'unstorage/drivers/memory'
await storage.mount('local', lsDriver({ base: 'myapp' }))
```
**Options:**
- `base`: Add `${base}:` to all keys to avoid collision
- `localStorage`: Optionally provide `localStorage` object
- `window`: Optionally provide `window` object
### `memory` (universal)
Keeps data in memory using [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
By default it is mounted to top level so it is unlikely you need to mount it again.
```js
import memoryDriver from 'unstorage/drivers/memory'
storage.mount('/tmp', memory())
```
## Contribution

@@ -180,0 +273,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc