Skip to content

Commit

Permalink
feat: allow passing default driver to factory fn
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Mar 13, 2021
1 parent 6a71c48 commit bbca3c3
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 32 deletions.
43 changes: 28 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,15 @@ npm i unistorage
```js
import { createStorage } from 'unistorage'

// Create a storage container with default memory storage
const storage = createStorage()
const storage = createStorage(/* opts */)

await storage.getItem('foo:bar')
// or
await storage.getItem('/foo/bar')
await storage.getItem('foo:bar') // or storage.getItem('/foo/bar')
```

**Options:**

- `driver`: Default driver (using memory if not provided)

## Storage Interface

### `storage.hasItem(key)`
Expand Down Expand Up @@ -239,9 +240,12 @@ npx unstorage .
Maps data to real filesystem using directory structure for nested keys. Supports watching using [chokidar](https://github.com/paulmillr/chokidar).

```js
import { createStorage } from 'unstorage'
import fsDriver from 'unstorage/drivers/memory'

storage.mount('/tmp', fsDriver({ base: './tmp' }))
const storage = createStorage({
driver: fsDriver({ base: './tmp' })
})
```

**Options:**
Expand All @@ -255,9 +259,12 @@ storage.mount('/tmp', fsDriver({ base: './tmp' }))
Store data in [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).

```js
import lsDriver from 'unstorage/drivers/memory'
import { createStorage } from 'unstorage'
import localStorageDriver from 'unstorage/drivers/memory'

storage.mount('local', lsDriver({ base: 'myapp' }))
const storage = createStorage({
driver: localStorageDriver({ base: 'app:' })
})
```

**Options:**
Expand All @@ -273,19 +280,25 @@ Keeps data in memory using [Set](https://developer.mozilla.org/en-US/docs/Web/Ja
By default it is mounted to top level so it is unlikely you need to mount it again.

```js
import { createStorage } from 'unstorage'
import memoryDriver from 'unstorage/drivers/memory'

storage.mount('/tmp', memory())
const storage = createStorage({
driver: memoryDriver()
})
```

### `http` (universal)

Use a remote HTTP/HTTPS endpoint as data storage. Supports built-in [http server](#storage-server) methods.

```js
import { createStorage } from 'unstorage'
import httpDriver from 'unstorage/drivers/http'

storage.mount('local', lsDriver({ base: 'http://myapp.com' }))
const storage = createStorage({
driver: httpDriver({ base: 'http://cdn.com' })
})
```

**Options:**
Expand All @@ -300,9 +313,9 @@ storage.mount('local', lsDriver({ base: 'http://myapp.com' }))
- `removeIterm`: Maps to `DELETE`
- `clear`: Not supported

## Custom drivers
## Making custom drivers

It is possible to extend unstorage by creating custom driver and mounting it.
It is possible to extend unstorage by creating custom drives.

- Keys are always normalized in `foo:bar` convention
- Mount base is removed
Expand All @@ -318,8 +331,6 @@ See [src/drivers](./src/drivers) to inspire how to implement them. Methods can
```js
import { createStorage, defineDriver } from 'unstorage'

const storage = createStorage()

const myStorageDriver = defineDriver((_opts) => {
return {
async hasItem (key) {},
Expand All @@ -333,7 +344,9 @@ const myStorageDriver = defineDriver((_opts) => {
}
})

storage.mount('/custom', myStorageDriver())
const storage = createStorage({
driver: myStorageDriver()
})
```

## Contribution
Expand Down
5 changes: 3 additions & 2 deletions demo/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import httpDriver from '../src/drivers/http'
import App from './App.vue'

function main () {
const storage = createStorage()
.mount('/', httpDriver({ base: location.origin + '/storage' }))
const storage = createStorage({
driver: httpDriver({ base: location.origin + '/storage' })
})
const app = createApp(App)
app.provide('storage', storage)
app.mount('#app')
Expand Down
10 changes: 6 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ async function main () {
process.exit(0)
}

const storage = createStorage()
const storageServer = createStorageServer(storage)

const rootDir = resolve(args._[0] || '.')
storage.mount('/', fsDriver({ base: rootDir }))

const storage = createStorage({
driver: fsDriver({ base: rootDir })
})

const storageServer = createStorageServer(storage)

await listen(storageServer.handle, {
name: 'Storage server',
Expand Down
24 changes: 14 additions & 10 deletions src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ interface StorageCTX {
watchListeners: Function[]
}

export function createStorage (): Storage {
export interface CreateStorageOptions {
driver?: Driver
}

export function createStorage (opts: CreateStorageOptions = {}): Storage {
const ctx: StorageCTX = {
mounts: { '': memory() },
mounts: { '': opts.driver || memory() },
mountpoints: [''],
watching: false,
watchListeners: []
Expand Down Expand Up @@ -151,19 +155,19 @@ export async function snapshot (storage: Storage, base: string): Promise<Snapsho
return snapshot
}

export async function restoreSnapshot (storage: Storage, snapshot: Snapshot<StorageValue>, base: string = '') {
export async function restoreSnapshot (driver: Storage, snapshot: Snapshot<StorageValue>, base: string = '') {
base = normalizeBase(base)
await Promise.all(Object.entries(snapshot).map(e => storage.setItem(base + e[0], e[1])))
await Promise.all(Object.entries(snapshot).map(e => driver.setItem(base + e[0], e[1])))
}

function watch (storage: Driver, onChange: WatchCallback, base: string) {
if (storage.watch) {
return storage.watch((event, key) => onChange(event, base + key))
function watch (driver: Driver, onChange: WatchCallback, base: string) {
if (driver.watch) {
return driver.watch((event, key) => onChange(event, base + key))
}
}

async function dispose (storage: Driver) {
if (typeof storage.dispose === 'function') {
await asyncCall(storage.dispose)
async function dispose (driver: Driver) {
if (typeof driver.dispose === 'function') {
await asyncCall(driver.dispose)
}
}
2 changes: 1 addition & 1 deletion test/drivers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function testDriver (opts: TestOptions) {
}

it('init', async () => {
await ctx.storage.mount('/', ctx.driver)
ctx.storage = createStorage({ driver: opts.driver })
await restoreSnapshot(ctx.storage, { initial: 'works' })
expect(await ctx.storage.getItem('initial')).toBe('works')
await ctx.storage.clear()
Expand Down

0 comments on commit bbca3c3

Please sign in to comment.