Fix actions/tour

This commit is contained in:
2025-02-13 23:19:32 +01:00
parent 47dd1adb30
commit fa21d30994
4543 changed files with 680810 additions and 0 deletions

5
node_modules/localforage/.huskyrc generated vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"hooks": {
"pre-commit": "lint-staged"
}
}

6
node_modules/localforage/.lintstagedrc generated vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"{src,test}/**/*.js": [
"prettier --write",
"git add"
]
}

161
node_modules/localforage/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,161 @@
# About this CHANGELOG
This file will include all API breakage, new features, and upgrade info in
localForage's lifetime.
### [1.10.0](https://github.com/localForage/localForage/releases/tag/1.10.0)
* Avoid uncaught error in `dropInstance`. You can now catch errors thrown by `dropInstance`, see #807.
### [1.9.0](https://github.com/mozilla/localForage/releases/tag/1.9.0)
* Fixed TypeScript definition for `getItem`. It now notes that `getItem` can return `null`, so this change may cause TypeScript code that didn't account for `null` values to fail. See #980.
### [1.8.1](https://github.com/mozilla/localForage/releases/tag/1.8.1)
* Reverted the ESM/`module` field change in #940, which broke many builds. See: #979. Sorry about that! 😓
### [1.8.0](https://github.com/mozilla/localForage/releases/tag/1.8.0)
* No changes to code, but added a `module` field in `package.json` for better ESM support. See: #940.
### [1.7.4](https://github.com/mozilla/localForage/releases/tag/1.7.4)
* Use `openKeyCursor` instead of `openCursor` for `key()` retrieval. Props to @MeMark2 for the fix, and thanks to @lincolnthree and @f for additional testing!
### [1.7.3](https://github.com/mozilla/localForage/releases/tag/1.7.3)
* Add `.npmignore` file to reduce package size when installed via npm.
### [1.6](https://github.com/mozilla/localForage/releases/tag/1.6.0)
* Add `dropInstance()` method to localforage.
* Improve IDB driver reliability when a connection gets closed.
### [1.5.7]
* Fix IE8 localStorage support detection.
### [1.5.6]
* Upgrade lie to 3.1.1 to work with yarn.
### [1.5.5]
* Roll back dropInstance breaking change.
### [1.5.4]
* Set `null` as `undefined` (for Edge).
### [1.5.3]
* Check whether localStorage is actually usable.
### [1.5.2]
* Prevent some unnecessary logs when calling `createInstance()`.
### [1.5.1]
* Try to re-establish IDB connection after an InvalidStateError.
* Added Generics to `iterate()` TS Typings.
* Define custom drivers syncronously when `_support` isn't a function.
* Use the custom driver API for internal drivers, which makes possible to override parts of their implementation.
### [1.5](https://github.com/mozilla/localForage/releases/tag/1.5.0)
* **Major storage engine change for Safari**: We now use IndexedDB as the storage engine for Safari v10.1 (and above). This means that **pre-existing Safari** `>= 10.1` users will experience "data loss" **after upgrading your site from a previous version of localForage to v1.5**. In fact no data is lost but the engine will change so localForage will seem empty.
* You can use the [localForage 1.4 compatibility plugin](https://github.com/localForage/localForage-compatibility-1-4) after the upgrade so that all your Safari users (both old & new) continue to use the WebSQL driver.
* Alternativelly you can force a connection to WebSQL using [localForage's config](https://localforage.github.io/localForage/#settings-api-setdriver) to either keep using your existing WebSQL database or migrate to IndexedDB.
### [1.4.2](https://github.com/mozilla/localForage/releases/tag/1.4.2)
* Fixes #562.
### [1.4.1](https://github.com/mozilla/localForage/releases/tag/1.4.1)
* Fixes #520; browserify builds work properly
### [1.4](https://github.com/mozilla/localForage/releases/tag/1.4.0)
* Fixes #516; this version should always load the correct driver without that bug.
### [1.3](https://github.com/mozilla/localForage/releases/tag/1.3.0)
* We now use ES6 for our source code and `webpack` to bundle the `dist/` files.
### [1.2](https://github.com/mozilla/localForage/releases/tag/1.2.0)
* Iterate through the entire database using `iterate()`. ([#283](https://github.com/mozilla/localForage/pull/283); fixes [#186](https://github.com/mozilla/localForage/pull/186))
### [1.1](https://github.com/mozilla/localForage/releases/tag/1.1.0)
* Custom drivers can be created using `defineDriver()`. ([#282](https://github.com/mozilla/localForage/pull/282); fixes [#267](https://github.com/mozilla/localForage/pull/267))
### [1.0.3](https://github.com/mozilla/localForage/releases/tag/1.0.3)
* `config()` accepts a new option: `driver`, so users can set the driver during config rather than using `setDriver()`. ([#273](https://github.com/mozilla/localForage/pull/273); fixes [#168](https://github.com/mozilla/localForage/pull/168))
### [1.0](https://github.com/mozilla/localForage/releases/tag/1.0.0)
* It is no longer necessary to queue commands using `ready()` when using RequireJS. ([723cc94e06](https://github.com/mozilla/localForage/commit/723cc94e06af4f5ba4c53fa65524ccd5f6c4432e))
* `setDriver` now accepts an array of drivers to be used, in order of preference, instead of simply a string. The string option is still supported. (eg. now one can use `setDriver(['WebSQL', 'localStorage'])` instead of `setDriver('WebSQL')`)
* node-style, error-first argument method signatures are used for callbacks. Promises don't use error-first method signatures; instead they supply an error to the promise's `reject()` function.
### [0.9](https://github.com/mozilla/localForage/releases/tag/0.9.1)
This release drops support for some legacy browsers, though not actually the
ones you might think. localForage's new policy is to support the current
version of all major browsers plus up to three versions back.
* Add built versions without the Promises polyfill to `dist/` directory. ([#172](https://github.com/mozilla/localForage/pull/172))
* **Drop support for Firefox 3.5. Minimum version is now Firefox 25.** (Technically, Firefox 4+ seems to work.)
* **Drop support for Chrome 31 and below. Minimum version is now Chrome 32.**
* Fix a **lot** of bugs. Especially in Internet Exploder.
* Switch to Mocha tests and test on [Sauce Labs](https://saucelabs.com/).
* Add a `keys()` method. ([#180](https://github.com/mozilla/localForage/pull/180))
* Check for localStorage instead of assuming it's available. ([#183](https://github.com/mozilla/localForage/pull/183))
### [Version 0.8](https://github.com/mozilla/localForage/releases/tag/0.8.1)
* Add support for web workers. ([#144](https://github.com/mozilla/localForage/pull/144), [#147](https://github.com/mozilla/localForage/pull/147)).
### [Version 0.6.1](https://github.com/mozilla/localForage/releases/tag/0.6.1)
* Put built versions back in `dist/` directory.
### [Version 0.6.0](https://github.com/mozilla/localForage/releases/tag/0.6.0)
* Add `localforage.config`. ([#40](https://github.com/mozilla/localForage/pull/140))
* Fix iFrame bug in WebKit. ([#78](https://github.com/mozilla/localForage/issues/78))
* Improve error handling. ([#60](https://github.com/mozilla/localForage/issues/60))
* Remove support for `window.localForageConfig`. ([#135](https://github.com/mozilla/localForage/issues/135))
### [Version 0.4](https://github.com/mozilla/localForage/releases/tag/0.4.0)
* Built versions of localForage are now in the top-level directory. ([2d11c90](https://github.com/mozilla/localForage/commit/2d11c90))
### [Version 0.3](https://github.com/mozilla/localForage/releases/tag/0.3.0)
* Check code quality in test suite ([#124](https://github.com/mozilla/localForage/pull/124))
* `_initDriver()` is called after first public API call ([#119](https://github.com/mozilla/localForage/pull/119))
### [Version 0.2.1](https://github.com/mozilla/localForage/releases/tag/0.2.1)
* Allow configuration of WebSQL DB size ([commit](https://github.com/mozilla/localForage/commit/6e78fff51a23e729206a03e5b750e959d8610f8c))
* Use bower for JS dependencies instead of `vendor/` folder ([#109](https://github.com/mozilla/localForage/pull/109))
### [Version 0.2.0](https://github.com/mozilla/localForage/releases/tag/0.2.0)
* Add support for ArrayBuffer, Blob, and TypedArrays ([#54](https://github.com/mozilla/localForage/pull/54), [#73](https://github.com/mozilla/localForage/pull/73))
### [Version 0.1.1](https://github.com/mozilla/localForage/releases/tag/0.1.1)
* Added config options to allow users to set their own database names, etc. ([#100](https://github.com/mozilla/localForage/pull/100))
---
### March 16th, 2014
* Moved Backbone adapter to its own repository ([b7987b3091855379d4908376b668b4b51a6fedfe](https://github.com/mozilla/localForage/commit/b7987b3091855379d4908376b668b4b51a6fedfe))
### March 13th, 2014
* Changed `localforage.driver` to a function instead of the string directly ([49415145021b0029d2521182de6e338e048fe5b1](https://github.com/mozilla/localForage/commit/49415145021b0029d2521182de6e338e048fe5b1))
### March 4th, 2014
* Changed the IndexedDB database name from `asyncStorage` to `localforage` ([f4e0156a29969a79005ac27b303d7e321a720fc6](https://github.com/mozilla/localForage/commit/f4e0156a29969a79005ac27b303d7e321a720fc6))

59
node_modules/localforage/CONTRIBUTING.md generated vendored Normal file
View File

@@ -0,0 +1,59 @@
# Filing issues
Please
[check the existing issues](https://github.com/mozilla/localForage/issues) to
make sure your issue hasn't already been filed.
If you have a bug to report, please file it.
You are also encouraged to create an example (or [edit an existing one](http://codepen.io/thgreasi/pen/ojYKeE)) to showcase your issue.
If you'd like to see a feature
implemented, you can file an issue, but know that pull requests for small
things like adding a line in a config file will get more attention than an
issue asking someone else to do it.
See below for [issues that have been discussed and will be rejected](#features-localforage-will-reject).
# Contributing to localForage
First off: thanks! Open source software (and thus all software) exists because
of people like you. <3
If you'd like to contribute to localForage, it's as simple as opening a pull
request on GitHub. After that someone will code review your work and either
ask you to fix any errors or merge the code into master. Here are a few tips:
* **all drivers must have the same public API**: refer to [the API tests](https://github.com/mozilla/localForage/blob/master/test/test.api.coffee) for how we ensure this, but simply put: all drivers should share the _exact same_ outward-facing API
* **do your work on a feature branch**: this keeps things clean and easy
* **try to rebase master into your branch**: this keeps the commit history clean and avoids merge commits inside feature branches
* **write tests**: if you're adding new features, _please_ write tests; likewise, if you're fixing a bug that wasn't previously caught by a test, please add one
* **run `grunt build` before you commit**: this will build out the files in the `dist/` folder and ensure your tests pass
Please commit changes at the top-level folder along with your changes in the
`src/` folder--**do not make these changes separate commits**. These are the
built versions of `localforage.js` and `localforage.min.js`, which are
used by bower.
If you have any questions, need some help, or anything else, don't feel shy!
The team behind this library is often available on IRC
([irc.mozilla.org](https://wiki.mozilla.org/IRC) on the `#apps` channel).
## Coding Style
All code can be tested for style by running the unit tests (`npm test`). This will make sure your code conforms to our styleguide. (You can read the rules in `.jshint` and `.jscsrc`.)
## Features localForage will reject
### node.js support
localForage is a browser library with a specific focus on client-side,
offline storage. It is not a general-purpose storage library and is not meant
to allow for the same API on the client and the server. Implementing the
localForage API wouldn't be hard (it's just localStorage with callbacks and
ES6 promises), but it's a job for another library.
### Legacy browser support
Basically this means anything before IE 8. I know there are hacky ways to
support storage with cookies or IE Userdata or whatever, but anything worse
than localStorage isn't worth investing into.

201
node_modules/localforage/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Mozilla
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

258
node_modules/localforage/README.md generated vendored Normal file
View File

@@ -0,0 +1,258 @@
# localForage
[![Build Status](https://travis-ci.org/localForage/localForage.svg?branch=master)](http://travis-ci.org/localForage/localForage)
[![NPM version](https://badge.fury.io/js/localforage.svg)](http://badge.fury.io/js/localforage)
[![Dependency Status](https://img.shields.io/david/localForage/localForage.svg)](https://david-dm.org/localForage/localForage)
[![npm](https://img.shields.io/npm/dm/localforage.svg?maxAge=2592000)](https://npmcharts.com/compare/localforage?minimal=true)
[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/localforage/badge?style=rounded)](https://www.jsdelivr.com/package/npm/localforage)
[![minzipped size](https://badgen.net/bundlephobia/minzip/localforage)](https://bundlephobia.com/result?p=localforage@1.10.0)
localForage is a fast and simple storage library for JavaScript. localForage
improves the offline experience of your web app by using asynchronous storage
(IndexedDB or WebSQL) with a simple, `localStorage`-like API.
localForage uses localStorage in browsers with no IndexedDB or
WebSQL support. See [the wiki for detailed compatibility info][supported browsers].
To use localForage, just drop a single JavaScript file into your page:
```html
<script src="localforage/dist/localforage.js"></script>
<script>localforage.getItem('something', myCallback);</script>
```
Try the [live example](http://codepen.io/thgreasi/pen/ojYKeE).
Download the [latest localForage from GitHub](https://github.com/localForage/localForage/releases/latest), or install with
[npm](https://www.npmjs.com/):
```bash
npm install localforage
```
[supported browsers]: https://github.com/localForage/localForage/wiki/Supported-Browsers-Platforms
## Support
Lost? Need help? Try the
[localForage API documentation](https://localforage.github.io/localForage). [localForage API文档也有中文版。](https://localforage.docschina.org)
If you're having trouble using the library, running the tests, or want to contribute to localForage, please look through the [existing issues](https://github.com/localForage/localForage/issues) for your problem first before creating a new one. If you still need help, [feel free to file an issue](https://github.com/localForage/localForage/issues/new).
# How to use localForage
## Callbacks vs Promises
Because localForage uses async storage, it has an async API.
It's otherwise exactly the same as the
[localStorage API](https://hacks.mozilla.org/2009/06/localstorage/).
localForage has a dual API that allows you to either use Node-style callbacks
or [Promises](https://www.promisejs.org/). If you are unsure which one is right for you, it's recommended to use Promises.
Here's an example of the Node-style callback form:
```js
localforage.setItem('key', 'value', function (err) {
// if err is non-null, we got an error
localforage.getItem('key', function (err, value) {
// if err is non-null, we got an error. otherwise, value is the value
});
});
```
And the Promise form:
```js
localforage.setItem('key', 'value').then(function () {
return localforage.getItem('key');
}).then(function (value) {
// we got our value
}).catch(function (err) {
// we got an error
});
```
Or, use `async`/`await`:
```js
try {
const value = await localforage.getItem('somekey');
// This code runs once the value has been loaded
// from the offline store.
console.log(value);
} catch (err) {
// This code runs if there were any errors.
console.log(err);
}
```
For more examples, please visit [the API docs](https://localforage.github.io/localForage).
## Storing Blobs, TypedArrays, and other JS objects
You can store any type in localForage; you aren't limited to strings like in
localStorage. Even if localStorage is your storage backend, localForage
automatically does `JSON.parse()` and `JSON.stringify()` when getting/setting
values.
localForage supports storing all native JS objects that can be serialized to
JSON, as well as ArrayBuffers, Blobs, and TypedArrays. Check the
[API docs][api] for a full list of types supported by localForage.
All types are supported in every storage backend, though storage limits in
localStorage make storing many large Blobs impossible.
[api]: https://localforage.github.io/localForage/#data-api-setitem
## Configuration
You can set database information with the `config()` method.
Available options are `driver`, `name`, `storeName`, `version`, `size`, and
`description`.
Example:
```javascript
localforage.config({
driver : localforage.WEBSQL, // Force WebSQL; same as using setDriver()
name : 'myApp',
version : 1.0,
size : 4980736, // Size of database, in bytes. WebSQL-only for now.
storeName : 'keyvaluepairs', // Should be alphanumeric, with underscores.
description : 'some description'
});
```
**Note:** you must call `config()` _before_ you interact with your data. This
means calling `config()` before using `getItem()`, `setItem()`, `removeItem()`,
`clear()`, `key()`, `keys()` or `length()`.
## Multiple instances
You can create multiple instances of localForage that point to different stores
using `createInstance`. All the configuration options used by
[`config`](#configuration) are supported.
``` javascript
var store = localforage.createInstance({
name: "nameHere"
});
var otherStore = localforage.createInstance({
name: "otherName"
});
// Setting the key on one of these doesn't affect the other.
store.setItem("key", "value");
otherStore.setItem("key", "value2");
```
## RequireJS
You can use localForage with [RequireJS](http://requirejs.org/):
```javascript
define(['localforage'], function(localforage) {
// As a callback:
localforage.setItem('mykey', 'myvalue', console.log);
// With a Promise:
localforage.setItem('mykey', 'myvalue').then(console.log);
});
```
## TypeScript
If you have the [`allowSyntheticDefaultImports` compiler option](https://www.typescriptlang.org/docs/handbook/compiler-options.html) set to `true` in your [tsconfig.json](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) (supported in TypeScript v1.8+), you should use:
```javascript
import localForage from "localforage";
```
Otherwise you should use one of the following:
```javascript
import * as localForage from "localforage";
// or, in case that the typescript version that you are using
// doesn't support ES6 style imports for UMD modules like localForage
import localForage = require("localforage");
```
## Framework Support
If you use a framework listed, there's a localForage storage driver for the
models in your framework so you can store data offline with localForage. We
have drivers for the following frameworks:
* [AngularJS](https://github.com/ocombe/angular-localForage)
* [Angular 4 and up](https://github.com/Alorel/ngforage/)
* [Backbone](https://github.com/localForage/localForage-backbone)
* [Ember](https://github.com/genkgo/ember-localforage-adapter)
* [Vue](https://github.com/dmlzj/vlf)
* [NuxtJS](https://github.com/nuxt-community/localforage-module)
If you have a driver you'd like listed, please
[open an issue](https://github.com/localForage/localForage/issues/new) to have it
added to this list.
## Custom Drivers
You can create your own driver if you want; see the
[`defineDriver`](https://localforage.github.io/localForage/#driver-api-definedriver) API docs.
There is a [list of custom drivers on the wiki][custom drivers].
[custom drivers]: https://github.com/localForage/localForage/wiki/Custom-Drivers
# Working on localForage
You'll need [node/npm](http://nodejs.org/) and
[bower](http://bower.io/#installing-bower).
To work on localForage, you should start by
[forking it](https://github.com/localForage/localForage/fork) and installing its
dependencies. Replace `USERNAME` with your GitHub username and run the
following:
```bash
# Install bower globally if you don't have it:
npm install -g bower
# Replace USERNAME with your GitHub username:
git clone git@github.com:USERNAME/localForage.git
cd localForage
npm install
bower install
```
Omitting the bower dependencies will cause the tests to fail!
## Running Tests
You need PhantomJS installed to run local tests. Run `npm test` (or,
directly: `grunt test`). Your code must also pass the
[linter](http://jshint.com/).
localForage is designed to run in the browser, so the tests explicitly require
a browser environment. Local tests are run on a headless WebKit (using
[PhantomJS](http://phantomjs.org)).
When you submit a pull request, tests will be run against all browsers that
localForage supports on Travis CI using [Sauce Labs](https://saucelabs.com/).
## Library Size
As of version 1.7.3 the payload added to your app is rather small. Served using gzip compression, localForage will add less than 10k to your total bundle size:
<dl>
<dt>minified</dt><dd>`~29kB`</dd>
<dt>gzipped</dt><dd>`~8.8kB`</dd>
<dt>brotli'd</dt><dd>`~7.8kB`</dd>
</dl>
# License
This program is free software; it is distributed under an
[Apache License](https://github.com/localForage/localForage/blob/master/LICENSE).
---
Copyright (c) 2013-2016 [Mozilla](https://mozilla.org)
([Contributors](https://github.com/localForage/localForage/graphs/contributors)).

27
node_modules/localforage/bower.json generated vendored Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "localforage",
"main": ["dist/localforage.js"],
"ignore": [
".travis.yml",
"CONTRIBUTING.md",
"config.rb",
"Gemfile",
"Gemfile.lock",
"Rakefile",
"LICENSE",
"docs*",
"examples*",
"test*",
"site*"
],
"dependencies": {},
"devDependencies": {
"es6-promise": "~1.0.0",
"requirejs": "~2.1.10",
"mocha": "~3.4.2",
"expect": "~0.3.1",
"assert": "~0.1.0",
"modernizr": "~2.8.1"
},
"version": "1.10.0"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,357 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('localStorageWrapper', ['module', 'exports', '../utils/isLocalStorageValid', '../utils/serializer', '../utils/promise', '../utils/executeCallback', '../utils/normalizeKey', '../utils/getCallback'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('../utils/isLocalStorageValid'), require('../utils/serializer'), require('../utils/promise'), require('../utils/executeCallback'), require('../utils/normalizeKey'), require('../utils/getCallback'));
} else {
var mod = {
exports: {}
};
factory(mod, mod.exports, global.isLocalStorageValid, global.serializer, global.promise, global.executeCallback, global.normalizeKey, global.getCallback);
global.localStorageWrapper = mod.exports;
}
})(this, function (module, exports, _isLocalStorageValid, _serializer, _promise, _executeCallback, _normalizeKey, _getCallback) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _isLocalStorageValid2 = _interopRequireDefault(_isLocalStorageValid);
var _serializer2 = _interopRequireDefault(_serializer);
var _promise2 = _interopRequireDefault(_promise);
var _executeCallback2 = _interopRequireDefault(_executeCallback);
var _normalizeKey2 = _interopRequireDefault(_normalizeKey);
var _getCallback2 = _interopRequireDefault(_getCallback);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
// If IndexedDB isn't available, we'll fall back to localStorage.
// Note that this will have considerable performance and storage
// side-effects (all data will be serialized on save and only data that
// can be converted to a string via `JSON.stringify()` will be saved).
function _getKeyPrefix(options, defaultConfig) {
var keyPrefix = options.name + '/';
if (options.storeName !== defaultConfig.storeName) {
keyPrefix += options.storeName + '/';
}
return keyPrefix;
}
// Check if localStorage throws when saving an item
function checkIfLocalStorageThrows() {
var localStorageTestKey = '_localforage_support_test';
try {
localStorage.setItem(localStorageTestKey, true);
localStorage.removeItem(localStorageTestKey);
return false;
} catch (e) {
return true;
}
}
// Check if localStorage is usable and allows to save an item
// This method checks if localStorage is usable in Safari Private Browsing
// mode, or in any other case where the available quota for localStorage
// is 0 and there wasn't any saved items yet.
function _isLocalStorageUsable() {
return !checkIfLocalStorageThrows() || localStorage.length > 0;
}
// Config the localStorage backend, using options set in the config.
function _initStorage(options) {
var self = this;
var dbInfo = {};
if (options) {
for (var i in options) {
dbInfo[i] = options[i];
}
}
dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig);
if (!_isLocalStorageUsable()) {
return _promise2.default.reject();
}
self._dbInfo = dbInfo;
dbInfo.serializer = _serializer2.default;
return _promise2.default.resolve();
}
// Remove all keys from the datastore, effectively destroying all data in
// the app's key/value store!
function clear(callback) {
var self = this;
var promise = self.ready().then(function () {
var keyPrefix = self._dbInfo.keyPrefix;
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Retrieve an item from the store. Unlike the original async_storage
// library in Gaia, we don't modify return values at all. If a key's value
// is `undefined`, we pass that value to the callback function.
function getItem(key, callback) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = self.ready().then(function () {
var dbInfo = self._dbInfo;
var result = localStorage.getItem(dbInfo.keyPrefix + key);
// If a result was found, parse it from the serialized
// string into a JS object. If result isn't truthy, the key
// is likely undefined and we'll pass it straight to the
// callback.
if (result) {
result = dbInfo.serializer.deserialize(result);
}
return result;
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Iterate over all items in the store.
function iterate(iterator, callback) {
var self = this;
var promise = self.ready().then(function () {
var dbInfo = self._dbInfo;
var keyPrefix = dbInfo.keyPrefix;
var keyPrefixLength = keyPrefix.length;
var length = localStorage.length;
// We use a dedicated iterator instead of the `i` variable below
// so other keys we fetch in localStorage aren't counted in
// the `iterationNumber` argument passed to the `iterate()`
// callback.
//
// See: github.com/mozilla/localForage/pull/435#discussion_r38061530
var iterationNumber = 1;
for (var i = 0; i < length; i++) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) !== 0) {
continue;
}
var value = localStorage.getItem(key);
// If a result was found, parse it from the serialized
// string into a JS object. If result isn't truthy, the
// key is likely undefined and we'll pass it straight
// to the iterator.
if (value) {
value = dbInfo.serializer.deserialize(value);
}
value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);
if (value !== void 0) {
return value;
}
}
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Same as localStorage's key() method, except takes a callback.
function key(n, callback) {
var self = this;
var promise = self.ready().then(function () {
var dbInfo = self._dbInfo;
var result;
try {
result = localStorage.key(n);
} catch (error) {
result = null;
}
// Remove the prefix from the key, if a key is found.
if (result) {
result = result.substring(dbInfo.keyPrefix.length);
}
return result;
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function keys(callback) {
var self = this;
var promise = self.ready().then(function () {
var dbInfo = self._dbInfo;
var length = localStorage.length;
var keys = [];
for (var i = 0; i < length; i++) {
var itemKey = localStorage.key(i);
if (itemKey.indexOf(dbInfo.keyPrefix) === 0) {
keys.push(itemKey.substring(dbInfo.keyPrefix.length));
}
}
return keys;
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Supply the number of keys in the datastore to the callback function.
function length(callback) {
var self = this;
var promise = self.keys().then(function (keys) {
return keys.length;
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Remove an item from the store, nice and simple.
function removeItem(key, callback) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = self.ready().then(function () {
var dbInfo = self._dbInfo;
localStorage.removeItem(dbInfo.keyPrefix + key);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Set a key's value and run an optional callback once the value is set.
// Unlike Gaia's implementation, the callback function is passed the value,
// in case you want to operate on that value only after you're sure it
// saved, or something like that.
function setItem(key, value, callback) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = self.ready().then(function () {
// Convert undefined values to null.
// https://github.com/mozilla/localForage/pull/42
if (value === undefined) {
value = null;
}
// Save the original value to pass to the callback.
var originalValue = value;
return new _promise2.default(function (resolve, reject) {
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, function (value, error) {
if (error) {
reject(error);
} else {
try {
localStorage.setItem(dbInfo.keyPrefix + key, value);
resolve(originalValue);
} catch (e) {
// localStorage capacity exceeded.
// TODO: Make this a specific error/event.
if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
reject(e);
}
reject(e);
}
}
});
});
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function dropInstance(options, callback) {
callback = _getCallback2.default.apply(this, arguments);
options = typeof options !== 'function' && options || {};
if (!options.name) {
var currentConfig = this.config();
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = _promise2.default.reject('Invalid arguments');
} else {
promise = new _promise2.default(function (resolve) {
if (!options.storeName) {
resolve(options.name + '/');
} else {
resolve(_getKeyPrefix(options, self._defaultConfig));
}
}).then(function (keyPrefix) {
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
});
}
(0, _executeCallback2.default)(promise, callback);
return promise;
}
var localStorageWrapper = {
_driver: 'localStorageWrapper',
_initStorage: _initStorage,
_support: (0, _isLocalStorageValid2.default)(),
iterate: iterate,
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
length: length,
key: key,
keys: keys,
dropInstance: dropInstance
};
exports.default = localStorageWrapper;
module.exports = exports['default'];
});

474
node_modules/localforage/build/es5src/drivers/websql.js generated vendored Normal file
View File

@@ -0,0 +1,474 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('webSQLStorage', ['module', 'exports', '../utils/isWebSQLValid', '../utils/serializer', '../utils/promise', '../utils/executeCallback', '../utils/normalizeKey', '../utils/getCallback'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('../utils/isWebSQLValid'), require('../utils/serializer'), require('../utils/promise'), require('../utils/executeCallback'), require('../utils/normalizeKey'), require('../utils/getCallback'));
} else {
var mod = {
exports: {}
};
factory(mod, mod.exports, global.isWebSQLValid, global.serializer, global.promise, global.executeCallback, global.normalizeKey, global.getCallback);
global.webSQLStorage = mod.exports;
}
})(this, function (module, exports, _isWebSQLValid, _serializer, _promise, _executeCallback, _normalizeKey, _getCallback) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _isWebSQLValid2 = _interopRequireDefault(_isWebSQLValid);
var _serializer2 = _interopRequireDefault(_serializer);
var _promise2 = _interopRequireDefault(_promise);
var _executeCallback2 = _interopRequireDefault(_executeCallback);
var _normalizeKey2 = _interopRequireDefault(_normalizeKey);
var _getCallback2 = _interopRequireDefault(_getCallback);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
/*
* Includes code from:
*
* base64-arraybuffer
* https://github.com/niklasvh/base64-arraybuffer
*
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*/
function createDbTable(t, dbInfo, callback, errorCallback) {
t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' ' + '(id INTEGER PRIMARY KEY, key unique, value)', [], callback, errorCallback);
}
// Open the WebSQL database (automatically creates one if one didn't
// previously exist), using any options set in the config.
function _initStorage(options) {
var self = this;
var dbInfo = {
db: null
};
if (options) {
for (var i in options) {
dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];
}
}
var dbInfoPromise = new _promise2.default(function (resolve, reject) {
// Open the database; the openDatabase API will automatically
// create it for us if it doesn't exist.
try {
dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);
} catch (e) {
return reject(e);
}
// Create our key/value table if it doesn't exist.
dbInfo.db.transaction(function (t) {
createDbTable(t, dbInfo, function () {
self._dbInfo = dbInfo;
resolve();
}, function (t, error) {
reject(error);
});
}, reject);
});
dbInfo.serializer = _serializer2.default;
return dbInfoPromise;
}
function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) {
t.executeSql(sqlStatement, args, callback, function (t, error) {
if (error.code === error.SYNTAX_ERR) {
t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name = ?", [dbInfo.storeName], function (t, results) {
if (!results.rows.length) {
// if the table is missing (was deleted)
// re-create it table and retry
createDbTable(t, dbInfo, function () {
t.executeSql(sqlStatement, args, callback, errorCallback);
}, errorCallback);
} else {
errorCallback(t, error);
}
}, errorCallback);
} else {
errorCallback(t, error);
}
}, errorCallback);
}
function getItem(key, callback) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {
var result = results.rows.length ? results.rows.item(0).value : null;
// Check to see if this is serialized content we need to
// unpack.
if (result) {
result = dbInfo.serializer.deserialize(result);
}
resolve(result);
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function iterate(iterator, callback) {
var self = this;
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {
var rows = results.rows;
var length = rows.length;
for (var i = 0; i < length; i++) {
var item = rows.item(i);
var result = item.value;
// Check to see if this is serialized content
// we need to unpack.
if (result) {
result = dbInfo.serializer.deserialize(result);
}
result = iterator(result, item.key, i + 1);
// void(0) prevents problems with redefinition
// of `undefined`.
if (result !== void 0) {
resolve(result);
return;
}
}
resolve();
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function _setItem(key, value, callback, retriesLeft) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
// The localStorage API doesn't return undefined values in an
// "expected" way, so undefined is always cast to null in all
// drivers. See: https://github.com/mozilla/localForage/pull/42
if (value === undefined) {
value = null;
}
// Save the original value to pass to the callback.
var originalValue = value;
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, function (value, error) {
if (error) {
reject(error);
} else {
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'INSERT OR REPLACE INTO ' + dbInfo.storeName + ' ' + '(key, value) VALUES (?, ?)', [key, value], function () {
resolve(originalValue);
}, function (t, error) {
reject(error);
});
}, function (sqlError) {
// The transaction failed; check
// to see if it's a quota error.
if (sqlError.code === sqlError.QUOTA_ERR) {
// We reject the callback outright for now, but
// it's worth trying to re-run the transaction.
// Even if the user accepts the prompt to use
// more storage on Safari, this error will
// be called.
//
// Try to re-run the transaction.
if (retriesLeft > 0) {
resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));
return;
}
reject(sqlError);
}
});
}
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function setItem(key, value, callback) {
return _setItem.apply(this, [key, value, callback, 1]);
}
function removeItem(key, callback) {
var self = this;
key = (0, _normalizeKey2.default)(key);
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {
resolve();
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Deletes every item in the table.
// TODO: Find out if this resets the AUTO_INCREMENT number.
function clear(callback) {
var self = this;
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'DELETE FROM ' + dbInfo.storeName, [], function () {
resolve();
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Does a simple `COUNT(key)` to get the number of items stored in
// localForage.
function length(callback) {
var self = this;
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
// Ahhh, SQL makes this one soooooo easy.
tryExecuteSql(t, dbInfo, 'SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {
var result = results.rows.item(0).c;
resolve(result);
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// Return the key located at key index X; essentially gets the key from a
// `WHERE id = ?`. This is the most efficient way I can think to implement
// this rarely-used (in my experience) part of the API, but it can seem
// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so
// the ID of each key will change every time it's updated. Perhaps a stored
// procedure for the `setItem()` SQL would solve this problem?
// TODO: Don't change ID on `setItem()`.
function key(n, callback) {
var self = this;
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {
var result = results.rows.length ? results.rows.item(0).key : null;
resolve(result);
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
function keys(callback) {
var self = this;
var promise = new _promise2.default(function (resolve, reject) {
self.ready().then(function () {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function (t) {
tryExecuteSql(t, dbInfo, 'SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {
var keys = [];
for (var i = 0; i < results.rows.length; i++) {
keys.push(results.rows.item(i).key);
}
resolve(keys);
}, function (t, error) {
reject(error);
});
});
}).catch(reject);
});
(0, _executeCallback2.default)(promise, callback);
return promise;
}
// https://www.w3.org/TR/webdatabase/#databases
// > There is no way to enumerate or delete the databases available for an origin from this API.
function getAllStoreNames(db) {
return new _promise2.default(function (resolve, reject) {
db.transaction(function (t) {
t.executeSql('SELECT name FROM sqlite_master ' + "WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'", [], function (t, results) {
var storeNames = [];
for (var i = 0; i < results.rows.length; i++) {
storeNames.push(results.rows.item(i).name);
}
resolve({
db: db,
storeNames: storeNames
});
}, function (t, error) {
reject(error);
});
}, function (sqlError) {
reject(sqlError);
});
});
}
function dropInstance(options, callback) {
callback = _getCallback2.default.apply(this, arguments);
var currentConfig = this.config();
options = typeof options !== 'function' && options || {};
if (!options.name) {
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = _promise2.default.reject('Invalid arguments');
} else {
promise = new _promise2.default(function (resolve) {
var db;
if (options.name === currentConfig.name) {
// use the db reference of the current instance
db = self._dbInfo.db;
} else {
db = openDatabase(options.name, '', '', 0);
}
if (!options.storeName) {
// drop all database tables
resolve(getAllStoreNames(db));
} else {
resolve({
db: db,
storeNames: [options.storeName]
});
}
}).then(function (operationInfo) {
return new _promise2.default(function (resolve, reject) {
operationInfo.db.transaction(function (t) {
function dropTable(storeName) {
return new _promise2.default(function (resolve, reject) {
t.executeSql('DROP TABLE IF EXISTS ' + storeName, [], function () {
resolve();
}, function (t, error) {
reject(error);
});
});
}
var operations = [];
for (var i = 0, len = operationInfo.storeNames.length; i < len; i++) {
operations.push(dropTable(operationInfo.storeNames[i]));
}
_promise2.default.all(operations).then(function () {
resolve();
}).catch(function (e) {
reject(e);
});
}, function (sqlError) {
reject(sqlError);
});
});
});
}
(0, _executeCallback2.default)(promise, callback);
return promise;
}
var webSQLStorage = {
_driver: 'webSQLStorage',
_initStorage: _initStorage,
_support: (0, _isWebSQLValid2.default)(),
iterate: iterate,
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
length: length,
key: key,
keys: keys,
dropInstance: dropInstance
};
exports.default = webSQLStorage;
module.exports = exports['default'];
});

408
node_modules/localforage/build/es5src/localforage.js generated vendored Normal file
View File

@@ -0,0 +1,408 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('localforage', ['module', 'exports', './drivers/indexeddb', './drivers/websql', './drivers/localstorage', './utils/serializer', './utils/promise', './utils/executeCallback', './utils/executeTwoCallbacks', './utils/includes', './utils/isArray'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('./drivers/indexeddb'), require('./drivers/websql'), require('./drivers/localstorage'), require('./utils/serializer'), require('./utils/promise'), require('./utils/executeCallback'), require('./utils/executeTwoCallbacks'), require('./utils/includes'), require('./utils/isArray'));
} else {
var mod = {
exports: {}
};
factory(mod, mod.exports, global.indexeddb, global.websql, global.localstorage, global.serializer, global.promise, global.executeCallback, global.executeTwoCallbacks, global.includes, global.isArray);
global.localforage = mod.exports;
}
})(this, function (module, exports, _indexeddb, _websql, _localstorage, _serializer, _promise, _executeCallback, _executeTwoCallbacks, _includes, _isArray) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _indexeddb2 = _interopRequireDefault(_indexeddb);
var _websql2 = _interopRequireDefault(_websql);
var _localstorage2 = _interopRequireDefault(_localstorage);
var _serializer2 = _interopRequireDefault(_serializer);
var _promise2 = _interopRequireDefault(_promise);
var _executeCallback2 = _interopRequireDefault(_executeCallback);
var _executeTwoCallbacks2 = _interopRequireDefault(_executeTwoCallbacks);
var _includes2 = _interopRequireDefault(_includes);
var _isArray2 = _interopRequireDefault(_isArray);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
// Drivers are stored here when `defineDriver()` is called.
// They are shared across all instances of localForage.
var DefinedDrivers = {};
var DriverSupport = {};
var DefaultDrivers = {
INDEXEDDB: _indexeddb2.default,
WEBSQL: _websql2.default,
LOCALSTORAGE: _localstorage2.default
};
var DefaultDriverOrder = [DefaultDrivers.INDEXEDDB._driver, DefaultDrivers.WEBSQL._driver, DefaultDrivers.LOCALSTORAGE._driver];
var OptionalDriverMethods = ['dropInstance'];
var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'].concat(OptionalDriverMethods);
var DefaultConfig = {
description: '',
driver: DefaultDriverOrder.slice(),
name: 'localforage',
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size
// we can use without a prompt.
size: 4980736,
storeName: 'keyvaluepairs',
version: 1.0
};
function callWhenReady(localForageInstance, libraryMethod) {
localForageInstance[libraryMethod] = function () {
var _args = arguments;
return localForageInstance.ready().then(function () {
return localForageInstance[libraryMethod].apply(localForageInstance, _args);
});
};
}
function extend() {
for (var i = 1; i < arguments.length; i++) {
var arg = arguments[i];
if (arg) {
for (var key in arg) {
if (arg.hasOwnProperty(key)) {
if ((0, _isArray2.default)(arg[key])) {
arguments[0][key] = arg[key].slice();
} else {
arguments[0][key] = arg[key];
}
}
}
}
}
return arguments[0];
}
var LocalForage = function () {
function LocalForage(options) {
_classCallCheck(this, LocalForage);
for (var driverTypeKey in DefaultDrivers) {
if (DefaultDrivers.hasOwnProperty(driverTypeKey)) {
var driver = DefaultDrivers[driverTypeKey];
var driverName = driver._driver;
this[driverTypeKey] = driverName;
if (!DefinedDrivers[driverName]) {
// we don't need to wait for the promise,
// since the default drivers can be defined
// in a blocking manner
this.defineDriver(driver);
}
}
}
this._defaultConfig = extend({}, DefaultConfig);
this._config = extend({}, this._defaultConfig, options);
this._driverSet = null;
this._initDriver = null;
this._ready = false;
this._dbInfo = null;
this._wrapLibraryMethodsWithReady();
this.setDriver(this._config.driver).catch(function () {});
}
// Set any config values for localForage; can be called anytime before
// the first API call (e.g. `getItem`, `setItem`).
// We loop through options so we don't overwrite existing config
// values.
LocalForage.prototype.config = function config(options) {
// If the options argument is an object, we use it to set values.
// Otherwise, we return either a specified config value or all
// config values.
if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
// If localforage is ready and fully initialized, we can't set
// any new configuration values. Instead, we return an error.
if (this._ready) {
return new Error("Can't call config() after localforage " + 'has been used.');
}
for (var i in options) {
if (i === 'storeName') {
options[i] = options[i].replace(/\W/g, '_');
}
if (i === 'version' && typeof options[i] !== 'number') {
return new Error('Database version must be a number.');
}
this._config[i] = options[i];
}
// after all config options are set and
// the driver option is used, try setting it
if ('driver' in options && options.driver) {
return this.setDriver(this._config.driver);
}
return true;
} else if (typeof options === 'string') {
return this._config[options];
} else {
return this._config;
}
};
LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {
var promise = new _promise2.default(function (resolve, reject) {
try {
var driverName = driverObject._driver;
var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');
// A driver name should be defined and not overlap with the
// library-defined, default drivers.
if (!driverObject._driver) {
reject(complianceError);
return;
}
var driverMethods = LibraryMethods.concat('_initStorage');
for (var i = 0, len = driverMethods.length; i < len; i++) {
var driverMethodName = driverMethods[i];
// when the property is there,
// it should be a method even when optional
var isRequired = !(0, _includes2.default)(OptionalDriverMethods, driverMethodName);
if ((isRequired || driverObject[driverMethodName]) && typeof driverObject[driverMethodName] !== 'function') {
reject(complianceError);
return;
}
}
var configureMissingMethods = function configureMissingMethods() {
var methodNotImplementedFactory = function methodNotImplementedFactory(methodName) {
return function () {
var error = new Error('Method ' + methodName + ' is not implemented by the current driver');
var promise = _promise2.default.reject(error);
(0, _executeCallback2.default)(promise, arguments[arguments.length - 1]);
return promise;
};
};
for (var _i = 0, _len = OptionalDriverMethods.length; _i < _len; _i++) {
var optionalDriverMethod = OptionalDriverMethods[_i];
if (!driverObject[optionalDriverMethod]) {
driverObject[optionalDriverMethod] = methodNotImplementedFactory(optionalDriverMethod);
}
}
};
configureMissingMethods();
var setDriverSupport = function setDriverSupport(support) {
if (DefinedDrivers[driverName]) {
console.info('Redefining LocalForage driver: ' + driverName);
}
DefinedDrivers[driverName] = driverObject;
DriverSupport[driverName] = support;
// don't use a then, so that we can define
// drivers that have simple _support methods
// in a blocking manner
resolve();
};
if ('_support' in driverObject) {
if (driverObject._support && typeof driverObject._support === 'function') {
driverObject._support().then(setDriverSupport, reject);
} else {
setDriverSupport(!!driverObject._support);
}
} else {
setDriverSupport(true);
}
} catch (e) {
reject(e);
}
});
(0, _executeTwoCallbacks2.default)(promise, callback, errorCallback);
return promise;
};
LocalForage.prototype.driver = function driver() {
return this._driver || null;
};
LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {
var getDriverPromise = DefinedDrivers[driverName] ? _promise2.default.resolve(DefinedDrivers[driverName]) : _promise2.default.reject(new Error('Driver not found.'));
(0, _executeTwoCallbacks2.default)(getDriverPromise, callback, errorCallback);
return getDriverPromise;
};
LocalForage.prototype.getSerializer = function getSerializer(callback) {
var serializerPromise = _promise2.default.resolve(_serializer2.default);
(0, _executeTwoCallbacks2.default)(serializerPromise, callback);
return serializerPromise;
};
LocalForage.prototype.ready = function ready(callback) {
var self = this;
var promise = self._driverSet.then(function () {
if (self._ready === null) {
self._ready = self._initDriver();
}
return self._ready;
});
(0, _executeTwoCallbacks2.default)(promise, callback, callback);
return promise;
};
LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {
var self = this;
if (!(0, _isArray2.default)(drivers)) {
drivers = [drivers];
}
var supportedDrivers = this._getSupportedDrivers(drivers);
function setDriverToConfig() {
self._config.driver = self.driver();
}
function extendSelfWithDriver(driver) {
self._extend(driver);
setDriverToConfig();
self._ready = self._initStorage(self._config);
return self._ready;
}
function initDriver(supportedDrivers) {
return function () {
var currentDriverIndex = 0;
function driverPromiseLoop() {
while (currentDriverIndex < supportedDrivers.length) {
var driverName = supportedDrivers[currentDriverIndex];
currentDriverIndex++;
self._dbInfo = null;
self._ready = null;
return self.getDriver(driverName).then(extendSelfWithDriver).catch(driverPromiseLoop);
}
setDriverToConfig();
var error = new Error('No available storage method found.');
self._driverSet = _promise2.default.reject(error);
return self._driverSet;
}
return driverPromiseLoop();
};
}
// There might be a driver initialization in progress
// so wait for it to finish in order to avoid a possible
// race condition to set _dbInfo
var oldDriverSetDone = this._driverSet !== null ? this._driverSet.catch(function () {
return _promise2.default.resolve();
}) : _promise2.default.resolve();
this._driverSet = oldDriverSetDone.then(function () {
var driverName = supportedDrivers[0];
self._dbInfo = null;
self._ready = null;
return self.getDriver(driverName).then(function (driver) {
self._driver = driver._driver;
setDriverToConfig();
self._wrapLibraryMethodsWithReady();
self._initDriver = initDriver(supportedDrivers);
});
}).catch(function () {
setDriverToConfig();
var error = new Error('No available storage method found.');
self._driverSet = _promise2.default.reject(error);
return self._driverSet;
});
(0, _executeTwoCallbacks2.default)(this._driverSet, callback, errorCallback);
return this._driverSet;
};
LocalForage.prototype.supports = function supports(driverName) {
return !!DriverSupport[driverName];
};
LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {
extend(this, libraryMethodsAndProperties);
};
LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {
var supportedDrivers = [];
for (var i = 0, len = drivers.length; i < len; i++) {
var driverName = drivers[i];
if (this.supports(driverName)) {
supportedDrivers.push(driverName);
}
}
return supportedDrivers;
};
LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {
// Add a stub for each driver API method that delays the call to the
// corresponding driver method until localForage is ready. These stubs
// will be replaced by the driver methods as soon as the driver is
// loaded, so there is no performance impact.
for (var i = 0, len = LibraryMethods.length; i < len; i++) {
callWhenReady(this, LibraryMethods[i]);
}
};
LocalForage.prototype.createInstance = function createInstance(options) {
return new LocalForage(options);
};
return LocalForage;
}();
exports.default = new LocalForage();
module.exports = exports['default'];
});

View File

@@ -0,0 +1,256 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('localforageSerializer', ['module', 'exports', './createBlob'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('./createBlob'));
} else {
var mod = {
exports: {}
};
factory(mod, mod.exports, global.createBlob);
global.localforageSerializer = mod.exports;
}
})(this, function (module, exports, _createBlob) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createBlob2 = _interopRequireDefault(_createBlob);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
// Sadly, the best way to save binary data in WebSQL/localStorage is serializing
// it to Base64, so this is how we store it to prevent very strange errors with less
// verbose ways of binary <-> string data storage.
var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; /* eslint-disable no-bitwise */
var BLOB_TYPE_PREFIX = '~~local_forage_type~';
var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
var SERIALIZED_MARKER = '__lfsc__:';
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;
// OMG the serializations!
var TYPE_ARRAYBUFFER = 'arbf';
var TYPE_BLOB = 'blob';
var TYPE_INT8ARRAY = 'si08';
var TYPE_UINT8ARRAY = 'ui08';
var TYPE_UINT8CLAMPEDARRAY = 'uic8';
var TYPE_INT16ARRAY = 'si16';
var TYPE_INT32ARRAY = 'si32';
var TYPE_UINT16ARRAY = 'ur16';
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;
var toString = Object.prototype.toString;
function stringToBuffer(serializedString) {
// Fill the string into a ArrayBuffer.
var bufferLength = serializedString.length * 0.75;
var len = serializedString.length;
var i;
var p = 0;
var encoded1, encoded2, encoded3, encoded4;
if (serializedString[serializedString.length - 1] === '=') {
bufferLength--;
if (serializedString[serializedString.length - 2] === '=') {
bufferLength--;
}
}
var buffer = new ArrayBuffer(bufferLength);
var bytes = new Uint8Array(buffer);
for (i = 0; i < len; i += 4) {
encoded1 = BASE_CHARS.indexOf(serializedString[i]);
encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);
encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);
encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);
/*jslint bitwise: true */
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
}
return buffer;
}
// Converts a buffer to a string to store, serialized, in the backend
// storage library.
function bufferToString(buffer) {
// base64-arraybuffer
var bytes = new Uint8Array(buffer);
var base64String = '';
var i;
for (i = 0; i < bytes.length; i += 3) {
/*jslint bitwise: true */
base64String += BASE_CHARS[bytes[i] >> 2];
base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];
base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];
base64String += BASE_CHARS[bytes[i + 2] & 63];
}
if (bytes.length % 3 === 2) {
base64String = base64String.substring(0, base64String.length - 1) + '=';
} else if (bytes.length % 3 === 1) {
base64String = base64String.substring(0, base64String.length - 2) + '==';
}
return base64String;
}
// Serialize a value, afterwards executing a callback (which usually
// instructs the `setItem()` callback/promise to be executed). This is how
// we store binary data with localStorage.
function serialize(value, callback) {
var valueType = '';
if (value) {
valueType = toString.call(value);
}
// Cannot use `value instanceof ArrayBuffer` or such here, as these
// checks fail when running the tests using casper.js...
//
// TODO: See why those tests fail and use a better solution.
if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString.call(value.buffer) === '[object ArrayBuffer]')) {
// Convert binary arrays to a string and prefix the string with
// a special marker.
var buffer;
var marker = SERIALIZED_MARKER;
if (value instanceof ArrayBuffer) {
buffer = value;
marker += TYPE_ARRAYBUFFER;
} else {
buffer = value.buffer;
if (valueType === '[object Int8Array]') {
marker += TYPE_INT8ARRAY;
} else if (valueType === '[object Uint8Array]') {
marker += TYPE_UINT8ARRAY;
} else if (valueType === '[object Uint8ClampedArray]') {
marker += TYPE_UINT8CLAMPEDARRAY;
} else if (valueType === '[object Int16Array]') {
marker += TYPE_INT16ARRAY;
} else if (valueType === '[object Uint16Array]') {
marker += TYPE_UINT16ARRAY;
} else if (valueType === '[object Int32Array]') {
marker += TYPE_INT32ARRAY;
} else if (valueType === '[object Uint32Array]') {
marker += TYPE_UINT32ARRAY;
} else if (valueType === '[object Float32Array]') {
marker += TYPE_FLOAT32ARRAY;
} else if (valueType === '[object Float64Array]') {
marker += TYPE_FLOAT64ARRAY;
} else {
callback(new Error('Failed to get type for BinaryArray'));
}
}
callback(marker + bufferToString(buffer));
} else if (valueType === '[object Blob]') {
// Conver the blob to a binaryArray and then to a string.
var fileReader = new FileReader();
fileReader.onload = function () {
// Backwards-compatible prefix for the blob type.
var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);
callback(SERIALIZED_MARKER + TYPE_BLOB + str);
};
fileReader.readAsArrayBuffer(value);
} else {
try {
callback(JSON.stringify(value));
} catch (e) {
console.error("Couldn't convert value into a JSON string: ", value);
callback(null, e);
}
}
}
// Deserialize data we've inserted into a value column/field. We place
// special markers into our strings to mark them as encoded; this isn't
// as nice as a meta field, but it's the only sane thing we can do whilst
// keeping localStorage support intact.
//
// Oftentimes this will just deserialize JSON content, but if we have a
// special marker (SERIALIZED_MARKER, defined above), we will extract
// some kind of arraybuffer/binary data/typed array out of the string.
function deserialize(value) {
// If we haven't marked this string as being specially serialized (i.e.
// something other than serialized JSON), we can just return it and be
// done with it.
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {
return JSON.parse(value);
}
// The following code deals with deserializing some kind of Blob or
// TypedArray. First we separate out the type of data we're dealing
// with from the data itself.
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);
var blobType;
// Backwards-compatible blob type serialization strategy.
// DBs created with older versions of localForage will simply not have the blob type.
if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
blobType = matcher[1];
serializedString = serializedString.substring(matcher[0].length);
}
var buffer = stringToBuffer(serializedString);
// Return the right type based on the code/type set during
// serialization.
switch (type) {
case TYPE_ARRAYBUFFER:
return buffer;
case TYPE_BLOB:
return (0, _createBlob2.default)([buffer], { type: blobType });
case TYPE_INT8ARRAY:
return new Int8Array(buffer);
case TYPE_UINT8ARRAY:
return new Uint8Array(buffer);
case TYPE_UINT8CLAMPEDARRAY:
return new Uint8ClampedArray(buffer);
case TYPE_INT16ARRAY:
return new Int16Array(buffer);
case TYPE_UINT16ARRAY:
return new Uint16Array(buffer);
case TYPE_INT32ARRAY:
return new Int32Array(buffer);
case TYPE_UINT32ARRAY:
return new Uint32Array(buffer);
case TYPE_FLOAT32ARRAY:
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
default:
throw new Error('Unkown type: ' + type);
}
}
var localforageSerializer = {
serialize: serialize,
deserialize: deserialize,
stringToBuffer: stringToBuffer,
bufferToString: bufferToString
};
exports.default = localforageSerializer;
module.exports = exports['default'];
});

15
node_modules/localforage/component.json generated vendored Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "localforage",
"version": "1.10.0",
"dependencies": {
"then/promise": "5.0.0"
},
"scripts": [
"build/es5src/localforage.js",
"build/es5src/utils/serializer.js",
"build/es5src/drivers/indexeddb.js",
"build/es5src/drivers/localstorage.js",
"build/es5src/drivers/websql.js"
],
"main": "build/es5src/localforage.js"
}

31
node_modules/localforage/contribute.json generated vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "localforage",
"description": "Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.",
"repository": {
"url": "https://github.com/mozilla/localForage",
"license": "Apache 2.0",
"tests": "https://travis-ci.org/mozilla/localForage"
},
"participate": {
"home": "https://github.com/mozilla/localForage",
"docs": "http://mozilla.github.io/localForage",
"irc": "irc://irc.mozilla.org/#apps",
"irc-contacts": [
"tofumatt"
]
},
"bugs": {
"list": "https://github.com/mozilla/localForage/issues",
"report": "https://github.com/mozilla/localForage/issues/new",
"goodfirstbug": "https://github.com/mozilla/localForage/labels/help%20wanted"
},
"keywords": [
"javascript",
"indexeddb",
"localstorage",
"offline",
"storage",
"websql"
]
}

2816
node_modules/localforage/dist/localforage.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

7
node_modules/localforage/dist/localforage.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

2480
node_modules/localforage/dist/localforage.nopromises.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

73
node_modules/localforage/package.json generated vendored Normal file
View File

@@ -0,0 +1,73 @@
{
"name": "localforage",
"author": "Mozilla",
"license": "Apache-2.0",
"description": "Offline storage, improved.",
"keywords": [
"indexeddb",
"localstorage",
"storage",
"websql"
],
"version": "1.10.0",
"homepage": "https://github.com/localForage/localForage",
"repository": {
"type": "git",
"url": "git://github.com/localForage/localForage.git"
},
"scripts": {
"build": "node -e \"require('grunt').cli()\" null build",
"prettify": "prettier --write \"src/**/*.js\" \"test/**/*.js\"",
"publish-docs": "node -e \"require('grunt').cli()\" null copy build-rules-html publish-rules",
"serve": "node -e \"require('grunt').cli()\" null serve",
"test": "node -e \"require('grunt').cli()\" null test"
},
"devDependencies": {
"babel-core": "^6.5.1",
"babel-eslint": "^7.2.3",
"babel-loader": "^6.2.2",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-transform-es2015-modules-umd": "^6.5.0",
"babel-preset-es2015": "^6.6.0",
"babel-preset-es2015-loose": "^7.0.0",
"babelify": "^7.2.0",
"browserify-derequire": "^0.9.4",
"bundle-collapser": "^1.2.1",
"cors": "^2.3.1",
"eslint-config-prettier": "^2.9.0",
"grunt": "^0.4.2",
"grunt-babel": "^6.0.0",
"grunt-browserify": "^3.8.0",
"grunt-contrib-concat": "^0.3.0",
"grunt-contrib-connect": "^0.8.0",
"grunt-contrib-uglify": "^0.4.0",
"grunt-contrib-watch": "^0.5.0",
"grunt-es3-safe-recast": "^0.1.0",
"grunt-eslint": "^20.0.0",
"mocha-headless-chrome": "3.1.0",
"grunt-rollup": "^0.6.2",
"grunt-run": "^0.5.2",
"grunt-saucelabs": "^5.1.2",
"grunt-ts": "^6.0.0-beta.11",
"grunt-webpack": "^1.0.11",
"husky": "^2.3.0",
"lint-staged": "^8.1.7",
"load-grunt-tasks": "^0.4.0",
"mocha": "^3.4.2",
"prettier": "~1.12.0",
"rollupify": "^0.1.0",
"script-loader": "^0.6.1",
"typescript": "^2.0.3",
"uglify-js": "^2.3.x",
"webpack": "^1.12.13",
"webpack-dev-server": "^1.10.1"
},
"main": "dist/localforage.js",
"typings": "typings/localforage.d.ts",
"bugs": {
"url": "http://github.com/localForage/localForage/issues"
},
"dependencies": {
"lie": "3.1.1"
}
}

1116
node_modules/localforage/src/drivers/indexeddb.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

332
node_modules/localforage/src/drivers/localstorage.js generated vendored Normal file
View File

@@ -0,0 +1,332 @@
// If IndexedDB isn't available, we'll fall back to localStorage.
// Note that this will have considerable performance and storage
// side-effects (all data will be serialized on save and only data that
// can be converted to a string via `JSON.stringify()` will be saved).
import isLocalStorageValid from '../utils/isLocalStorageValid';
import serializer from '../utils/serializer';
import Promise from '../utils/promise';
import executeCallback from '../utils/executeCallback';
import normalizeKey from '../utils/normalizeKey';
import getCallback from '../utils/getCallback';
function _getKeyPrefix(options, defaultConfig) {
var keyPrefix = options.name + '/';
if (options.storeName !== defaultConfig.storeName) {
keyPrefix += options.storeName + '/';
}
return keyPrefix;
}
// Check if localStorage throws when saving an item
function checkIfLocalStorageThrows() {
var localStorageTestKey = '_localforage_support_test';
try {
localStorage.setItem(localStorageTestKey, true);
localStorage.removeItem(localStorageTestKey);
return false;
} catch (e) {
return true;
}
}
// Check if localStorage is usable and allows to save an item
// This method checks if localStorage is usable in Safari Private Browsing
// mode, or in any other case where the available quota for localStorage
// is 0 and there wasn't any saved items yet.
function _isLocalStorageUsable() {
return !checkIfLocalStorageThrows() || localStorage.length > 0;
}
// Config the localStorage backend, using options set in the config.
function _initStorage(options) {
var self = this;
var dbInfo = {};
if (options) {
for (var i in options) {
dbInfo[i] = options[i];
}
}
dbInfo.keyPrefix = _getKeyPrefix(options, self._defaultConfig);
if (!_isLocalStorageUsable()) {
return Promise.reject();
}
self._dbInfo = dbInfo;
dbInfo.serializer = serializer;
return Promise.resolve();
}
// Remove all keys from the datastore, effectively destroying all data in
// the app's key/value store!
function clear(callback) {
var self = this;
var promise = self.ready().then(function() {
var keyPrefix = self._dbInfo.keyPrefix;
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
});
executeCallback(promise, callback);
return promise;
}
// Retrieve an item from the store. Unlike the original async_storage
// library in Gaia, we don't modify return values at all. If a key's value
// is `undefined`, we pass that value to the callback function.
function getItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then(function() {
var dbInfo = self._dbInfo;
var result = localStorage.getItem(dbInfo.keyPrefix + key);
// If a result was found, parse it from the serialized
// string into a JS object. If result isn't truthy, the key
// is likely undefined and we'll pass it straight to the
// callback.
if (result) {
result = dbInfo.serializer.deserialize(result);
}
return result;
});
executeCallback(promise, callback);
return promise;
}
// Iterate over all items in the store.
function iterate(iterator, callback) {
var self = this;
var promise = self.ready().then(function() {
var dbInfo = self._dbInfo;
var keyPrefix = dbInfo.keyPrefix;
var keyPrefixLength = keyPrefix.length;
var length = localStorage.length;
// We use a dedicated iterator instead of the `i` variable below
// so other keys we fetch in localStorage aren't counted in
// the `iterationNumber` argument passed to the `iterate()`
// callback.
//
// See: github.com/mozilla/localForage/pull/435#discussion_r38061530
var iterationNumber = 1;
for (var i = 0; i < length; i++) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) !== 0) {
continue;
}
var value = localStorage.getItem(key);
// If a result was found, parse it from the serialized
// string into a JS object. If result isn't truthy, the
// key is likely undefined and we'll pass it straight
// to the iterator.
if (value) {
value = dbInfo.serializer.deserialize(value);
}
value = iterator(
value,
key.substring(keyPrefixLength),
iterationNumber++
);
if (value !== void 0) {
return value;
}
}
});
executeCallback(promise, callback);
return promise;
}
// Same as localStorage's key() method, except takes a callback.
function key(n, callback) {
var self = this;
var promise = self.ready().then(function() {
var dbInfo = self._dbInfo;
var result;
try {
result = localStorage.key(n);
} catch (error) {
result = null;
}
// Remove the prefix from the key, if a key is found.
if (result) {
result = result.substring(dbInfo.keyPrefix.length);
}
return result;
});
executeCallback(promise, callback);
return promise;
}
function keys(callback) {
var self = this;
var promise = self.ready().then(function() {
var dbInfo = self._dbInfo;
var length = localStorage.length;
var keys = [];
for (var i = 0; i < length; i++) {
var itemKey = localStorage.key(i);
if (itemKey.indexOf(dbInfo.keyPrefix) === 0) {
keys.push(itemKey.substring(dbInfo.keyPrefix.length));
}
}
return keys;
});
executeCallback(promise, callback);
return promise;
}
// Supply the number of keys in the datastore to the callback function.
function length(callback) {
var self = this;
var promise = self.keys().then(function(keys) {
return keys.length;
});
executeCallback(promise, callback);
return promise;
}
// Remove an item from the store, nice and simple.
function removeItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then(function() {
var dbInfo = self._dbInfo;
localStorage.removeItem(dbInfo.keyPrefix + key);
});
executeCallback(promise, callback);
return promise;
}
// Set a key's value and run an optional callback once the value is set.
// Unlike Gaia's implementation, the callback function is passed the value,
// in case you want to operate on that value only after you're sure it
// saved, or something like that.
function setItem(key, value, callback) {
var self = this;
key = normalizeKey(key);
var promise = self.ready().then(function() {
// Convert undefined values to null.
// https://github.com/mozilla/localForage/pull/42
if (value === undefined) {
value = null;
}
// Save the original value to pass to the callback.
var originalValue = value;
return new Promise(function(resolve, reject) {
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, function(value, error) {
if (error) {
reject(error);
} else {
try {
localStorage.setItem(dbInfo.keyPrefix + key, value);
resolve(originalValue);
} catch (e) {
// localStorage capacity exceeded.
// TODO: Make this a specific error/event.
if (
e.name === 'QuotaExceededError' ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
) {
reject(e);
}
reject(e);
}
}
});
});
});
executeCallback(promise, callback);
return promise;
}
function dropInstance(options, callback) {
callback = getCallback.apply(this, arguments);
options = (typeof options !== 'function' && options) || {};
if (!options.name) {
var currentConfig = this.config();
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = Promise.reject('Invalid arguments');
} else {
promise = new Promise(function(resolve) {
if (!options.storeName) {
resolve(`${options.name}/`);
} else {
resolve(_getKeyPrefix(options, self._defaultConfig));
}
}).then(function(keyPrefix) {
for (var i = localStorage.length - 1; i >= 0; i--) {
var key = localStorage.key(i);
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
});
}
executeCallback(promise, callback);
return promise;
}
var localStorageWrapper = {
_driver: 'localStorageWrapper',
_initStorage: _initStorage,
_support: isLocalStorageValid(),
iterate: iterate,
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
length: length,
key: key,
keys: keys,
dropInstance: dropInstance
};
export default localStorageWrapper;

610
node_modules/localforage/src/drivers/websql.js generated vendored Normal file
View File

@@ -0,0 +1,610 @@
import isWebSQLValid from '../utils/isWebSQLValid';
import serializer from '../utils/serializer';
import Promise from '../utils/promise';
import executeCallback from '../utils/executeCallback';
import normalizeKey from '../utils/normalizeKey';
import getCallback from '../utils/getCallback';
/*
* Includes code from:
*
* base64-arraybuffer
* https://github.com/niklasvh/base64-arraybuffer
*
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*/
function createDbTable(t, dbInfo, callback, errorCallback) {
t.executeSql(
`CREATE TABLE IF NOT EXISTS ${dbInfo.storeName} ` +
'(id INTEGER PRIMARY KEY, key unique, value)',
[],
callback,
errorCallback
);
}
// Open the WebSQL database (automatically creates one if one didn't
// previously exist), using any options set in the config.
function _initStorage(options) {
var self = this;
var dbInfo = {
db: null
};
if (options) {
for (var i in options) {
dbInfo[i] =
typeof options[i] !== 'string'
? options[i].toString()
: options[i];
}
}
var dbInfoPromise = new Promise(function(resolve, reject) {
// Open the database; the openDatabase API will automatically
// create it for us if it doesn't exist.
try {
dbInfo.db = openDatabase(
dbInfo.name,
String(dbInfo.version),
dbInfo.description,
dbInfo.size
);
} catch (e) {
return reject(e);
}
// Create our key/value table if it doesn't exist.
dbInfo.db.transaction(function(t) {
createDbTable(
t,
dbInfo,
function() {
self._dbInfo = dbInfo;
resolve();
},
function(t, error) {
reject(error);
}
);
}, reject);
});
dbInfo.serializer = serializer;
return dbInfoPromise;
}
function tryExecuteSql(t, dbInfo, sqlStatement, args, callback, errorCallback) {
t.executeSql(
sqlStatement,
args,
callback,
function(t, error) {
if (error.code === error.SYNTAX_ERR) {
t.executeSql(
'SELECT name FROM sqlite_master ' +
"WHERE type='table' AND name = ?",
[dbInfo.storeName],
function(t, results) {
if (!results.rows.length) {
// if the table is missing (was deleted)
// re-create it table and retry
createDbTable(
t,
dbInfo,
function() {
t.executeSql(
sqlStatement,
args,
callback,
errorCallback
);
},
errorCallback
);
} else {
errorCallback(t, error);
}
},
errorCallback
);
} else {
errorCallback(t, error);
}
},
errorCallback
);
}
function getItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`SELECT * FROM ${
dbInfo.storeName
} WHERE key = ? LIMIT 1`,
[key],
function(t, results) {
var result = results.rows.length
? results.rows.item(0).value
: null;
// Check to see if this is serialized content we need to
// unpack.
if (result) {
result = dbInfo.serializer.deserialize(result);
}
resolve(result);
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
function iterate(iterator, callback) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`SELECT * FROM ${dbInfo.storeName}`,
[],
function(t, results) {
var rows = results.rows;
var length = rows.length;
for (var i = 0; i < length; i++) {
var item = rows.item(i);
var result = item.value;
// Check to see if this is serialized content
// we need to unpack.
if (result) {
result = dbInfo.serializer.deserialize(
result
);
}
result = iterator(result, item.key, i + 1);
// void(0) prevents problems with redefinition
// of `undefined`.
if (result !== void 0) {
resolve(result);
return;
}
}
resolve();
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
function _setItem(key, value, callback, retriesLeft) {
var self = this;
key = normalizeKey(key);
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
// The localStorage API doesn't return undefined values in an
// "expected" way, so undefined is always cast to null in all
// drivers. See: https://github.com/mozilla/localForage/pull/42
if (value === undefined) {
value = null;
}
// Save the original value to pass to the callback.
var originalValue = value;
var dbInfo = self._dbInfo;
dbInfo.serializer.serialize(value, function(value, error) {
if (error) {
reject(error);
} else {
dbInfo.db.transaction(
function(t) {
tryExecuteSql(
t,
dbInfo,
`INSERT OR REPLACE INTO ${
dbInfo.storeName
} ` + '(key, value) VALUES (?, ?)',
[key, value],
function() {
resolve(originalValue);
},
function(t, error) {
reject(error);
}
);
},
function(sqlError) {
// The transaction failed; check
// to see if it's a quota error.
if (sqlError.code === sqlError.QUOTA_ERR) {
// We reject the callback outright for now, but
// it's worth trying to re-run the transaction.
// Even if the user accepts the prompt to use
// more storage on Safari, this error will
// be called.
//
// Try to re-run the transaction.
if (retriesLeft > 0) {
resolve(
_setItem.apply(self, [
key,
originalValue,
callback,
retriesLeft - 1
])
);
return;
}
reject(sqlError);
}
}
);
}
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
function setItem(key, value, callback) {
return _setItem.apply(this, [key, value, callback, 1]);
}
function removeItem(key, callback) {
var self = this;
key = normalizeKey(key);
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`DELETE FROM ${dbInfo.storeName} WHERE key = ?`,
[key],
function() {
resolve();
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
// Deletes every item in the table.
// TODO: Find out if this resets the AUTO_INCREMENT number.
function clear(callback) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`DELETE FROM ${dbInfo.storeName}`,
[],
function() {
resolve();
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
// Does a simple `COUNT(key)` to get the number of items stored in
// localForage.
function length(callback) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
// Ahhh, SQL makes this one soooooo easy.
tryExecuteSql(
t,
dbInfo,
`SELECT COUNT(key) as c FROM ${dbInfo.storeName}`,
[],
function(t, results) {
var result = results.rows.item(0).c;
resolve(result);
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
// Return the key located at key index X; essentially gets the key from a
// `WHERE id = ?`. This is the most efficient way I can think to implement
// this rarely-used (in my experience) part of the API, but it can seem
// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so
// the ID of each key will change every time it's updated. Perhaps a stored
// procedure for the `setItem()` SQL would solve this problem?
// TODO: Don't change ID on `setItem()`.
function key(n, callback) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`SELECT key FROM ${
dbInfo.storeName
} WHERE id = ? LIMIT 1`,
[n + 1],
function(t, results) {
var result = results.rows.length
? results.rows.item(0).key
: null;
resolve(result);
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
function keys(callback) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self
.ready()
.then(function() {
var dbInfo = self._dbInfo;
dbInfo.db.transaction(function(t) {
tryExecuteSql(
t,
dbInfo,
`SELECT key FROM ${dbInfo.storeName}`,
[],
function(t, results) {
var keys = [];
for (var i = 0; i < results.rows.length; i++) {
keys.push(results.rows.item(i).key);
}
resolve(keys);
},
function(t, error) {
reject(error);
}
);
});
})
.catch(reject);
});
executeCallback(promise, callback);
return promise;
}
// https://www.w3.org/TR/webdatabase/#databases
// > There is no way to enumerate or delete the databases available for an origin from this API.
function getAllStoreNames(db) {
return new Promise(function(resolve, reject) {
db.transaction(
function(t) {
t.executeSql(
'SELECT name FROM sqlite_master ' +
"WHERE type='table' AND name <> '__WebKitDatabaseInfoTable__'",
[],
function(t, results) {
var storeNames = [];
for (var i = 0; i < results.rows.length; i++) {
storeNames.push(results.rows.item(i).name);
}
resolve({
db,
storeNames
});
},
function(t, error) {
reject(error);
}
);
},
function(sqlError) {
reject(sqlError);
}
);
});
}
function dropInstance(options, callback) {
callback = getCallback.apply(this, arguments);
var currentConfig = this.config();
options = (typeof options !== 'function' && options) || {};
if (!options.name) {
options.name = options.name || currentConfig.name;
options.storeName = options.storeName || currentConfig.storeName;
}
var self = this;
var promise;
if (!options.name) {
promise = Promise.reject('Invalid arguments');
} else {
promise = new Promise(function(resolve) {
var db;
if (options.name === currentConfig.name) {
// use the db reference of the current instance
db = self._dbInfo.db;
} else {
db = openDatabase(options.name, '', '', 0);
}
if (!options.storeName) {
// drop all database tables
resolve(getAllStoreNames(db));
} else {
resolve({
db,
storeNames: [options.storeName]
});
}
}).then(function(operationInfo) {
return new Promise(function(resolve, reject) {
operationInfo.db.transaction(
function(t) {
function dropTable(storeName) {
return new Promise(function(resolve, reject) {
t.executeSql(
`DROP TABLE IF EXISTS ${storeName}`,
[],
function() {
resolve();
},
function(t, error) {
reject(error);
}
);
});
}
var operations = [];
for (
var i = 0, len = operationInfo.storeNames.length;
i < len;
i++
) {
operations.push(
dropTable(operationInfo.storeNames[i])
);
}
Promise.all(operations)
.then(function() {
resolve();
})
.catch(function(e) {
reject(e);
});
},
function(sqlError) {
reject(sqlError);
}
);
});
});
}
executeCallback(promise, callback);
return promise;
}
var webSQLStorage = {
_driver: 'webSQLStorage',
_initStorage: _initStorage,
_support: isWebSQLValid(),
iterate: iterate,
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
length: length,
key: key,
keys: keys,
dropInstance: dropInstance
};
export default webSQLStorage;

414
node_modules/localforage/src/localforage.js generated vendored Normal file
View File

@@ -0,0 +1,414 @@
import idbDriver from './drivers/indexeddb';
import websqlDriver from './drivers/websql';
import localstorageDriver from './drivers/localstorage';
import serializer from './utils/serializer';
import Promise from './utils/promise';
import executeCallback from './utils/executeCallback';
import executeTwoCallbacks from './utils/executeTwoCallbacks';
import includes from './utils/includes';
import isArray from './utils/isArray';
// Drivers are stored here when `defineDriver()` is called.
// They are shared across all instances of localForage.
const DefinedDrivers = {};
const DriverSupport = {};
const DefaultDrivers = {
INDEXEDDB: idbDriver,
WEBSQL: websqlDriver,
LOCALSTORAGE: localstorageDriver
};
const DefaultDriverOrder = [
DefaultDrivers.INDEXEDDB._driver,
DefaultDrivers.WEBSQL._driver,
DefaultDrivers.LOCALSTORAGE._driver
];
const OptionalDriverMethods = ['dropInstance'];
const LibraryMethods = [
'clear',
'getItem',
'iterate',
'key',
'keys',
'length',
'removeItem',
'setItem'
].concat(OptionalDriverMethods);
const DefaultConfig = {
description: '',
driver: DefaultDriverOrder.slice(),
name: 'localforage',
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size
// we can use without a prompt.
size: 4980736,
storeName: 'keyvaluepairs',
version: 1.0
};
function callWhenReady(localForageInstance, libraryMethod) {
localForageInstance[libraryMethod] = function() {
const _args = arguments;
return localForageInstance.ready().then(function() {
return localForageInstance[libraryMethod].apply(
localForageInstance,
_args
);
});
};
}
function extend() {
for (let i = 1; i < arguments.length; i++) {
const arg = arguments[i];
if (arg) {
for (let key in arg) {
if (arg.hasOwnProperty(key)) {
if (isArray(arg[key])) {
arguments[0][key] = arg[key].slice();
} else {
arguments[0][key] = arg[key];
}
}
}
}
}
return arguments[0];
}
class LocalForage {
constructor(options) {
for (let driverTypeKey in DefaultDrivers) {
if (DefaultDrivers.hasOwnProperty(driverTypeKey)) {
const driver = DefaultDrivers[driverTypeKey];
const driverName = driver._driver;
this[driverTypeKey] = driverName;
if (!DefinedDrivers[driverName]) {
// we don't need to wait for the promise,
// since the default drivers can be defined
// in a blocking manner
this.defineDriver(driver);
}
}
}
this._defaultConfig = extend({}, DefaultConfig);
this._config = extend({}, this._defaultConfig, options);
this._driverSet = null;
this._initDriver = null;
this._ready = false;
this._dbInfo = null;
this._wrapLibraryMethodsWithReady();
this.setDriver(this._config.driver).catch(() => {});
}
// Set any config values for localForage; can be called anytime before
// the first API call (e.g. `getItem`, `setItem`).
// We loop through options so we don't overwrite existing config
// values.
config(options) {
// If the options argument is an object, we use it to set values.
// Otherwise, we return either a specified config value or all
// config values.
if (typeof options === 'object') {
// If localforage is ready and fully initialized, we can't set
// any new configuration values. Instead, we return an error.
if (this._ready) {
return new Error(
"Can't call config() after localforage " + 'has been used.'
);
}
for (let i in options) {
if (i === 'storeName') {
options[i] = options[i].replace(/\W/g, '_');
}
if (i === 'version' && typeof options[i] !== 'number') {
return new Error('Database version must be a number.');
}
this._config[i] = options[i];
}
// after all config options are set and
// the driver option is used, try setting it
if ('driver' in options && options.driver) {
return this.setDriver(this._config.driver);
}
return true;
} else if (typeof options === 'string') {
return this._config[options];
} else {
return this._config;
}
}
// Used to define a custom driver, shared across all instances of
// localForage.
defineDriver(driverObject, callback, errorCallback) {
const promise = new Promise(function(resolve, reject) {
try {
const driverName = driverObject._driver;
const complianceError = new Error(
'Custom driver not compliant; see ' +
'https://mozilla.github.io/localForage/#definedriver'
);
// A driver name should be defined and not overlap with the
// library-defined, default drivers.
if (!driverObject._driver) {
reject(complianceError);
return;
}
const driverMethods = LibraryMethods.concat('_initStorage');
for (let i = 0, len = driverMethods.length; i < len; i++) {
const driverMethodName = driverMethods[i];
// when the property is there,
// it should be a method even when optional
const isRequired = !includes(
OptionalDriverMethods,
driverMethodName
);
if (
(isRequired || driverObject[driverMethodName]) &&
typeof driverObject[driverMethodName] !== 'function'
) {
reject(complianceError);
return;
}
}
const configureMissingMethods = function() {
const methodNotImplementedFactory = function(methodName) {
return function() {
const error = new Error(
`Method ${methodName} is not implemented by the current driver`
);
const promise = Promise.reject(error);
executeCallback(
promise,
arguments[arguments.length - 1]
);
return promise;
};
};
for (
let i = 0, len = OptionalDriverMethods.length;
i < len;
i++
) {
const optionalDriverMethod = OptionalDriverMethods[i];
if (!driverObject[optionalDriverMethod]) {
driverObject[
optionalDriverMethod
] = methodNotImplementedFactory(
optionalDriverMethod
);
}
}
};
configureMissingMethods();
const setDriverSupport = function(support) {
if (DefinedDrivers[driverName]) {
console.info(
`Redefining LocalForage driver: ${driverName}`
);
}
DefinedDrivers[driverName] = driverObject;
DriverSupport[driverName] = support;
// don't use a then, so that we can define
// drivers that have simple _support methods
// in a blocking manner
resolve();
};
if ('_support' in driverObject) {
if (
driverObject._support &&
typeof driverObject._support === 'function'
) {
driverObject._support().then(setDriverSupport, reject);
} else {
setDriverSupport(!!driverObject._support);
}
} else {
setDriverSupport(true);
}
} catch (e) {
reject(e);
}
});
executeTwoCallbacks(promise, callback, errorCallback);
return promise;
}
driver() {
return this._driver || null;
}
getDriver(driverName, callback, errorCallback) {
const getDriverPromise = DefinedDrivers[driverName]
? Promise.resolve(DefinedDrivers[driverName])
: Promise.reject(new Error('Driver not found.'));
executeTwoCallbacks(getDriverPromise, callback, errorCallback);
return getDriverPromise;
}
getSerializer(callback) {
const serializerPromise = Promise.resolve(serializer);
executeTwoCallbacks(serializerPromise, callback);
return serializerPromise;
}
ready(callback) {
const self = this;
const promise = self._driverSet.then(() => {
if (self._ready === null) {
self._ready = self._initDriver();
}
return self._ready;
});
executeTwoCallbacks(promise, callback, callback);
return promise;
}
setDriver(drivers, callback, errorCallback) {
const self = this;
if (!isArray(drivers)) {
drivers = [drivers];
}
const supportedDrivers = this._getSupportedDrivers(drivers);
function setDriverToConfig() {
self._config.driver = self.driver();
}
function extendSelfWithDriver(driver) {
self._extend(driver);
setDriverToConfig();
self._ready = self._initStorage(self._config);
return self._ready;
}
function initDriver(supportedDrivers) {
return function() {
let currentDriverIndex = 0;
function driverPromiseLoop() {
while (currentDriverIndex < supportedDrivers.length) {
let driverName = supportedDrivers[currentDriverIndex];
currentDriverIndex++;
self._dbInfo = null;
self._ready = null;
return self
.getDriver(driverName)
.then(extendSelfWithDriver)
.catch(driverPromiseLoop);
}
setDriverToConfig();
const error = new Error(
'No available storage method found.'
);
self._driverSet = Promise.reject(error);
return self._driverSet;
}
return driverPromiseLoop();
};
}
// There might be a driver initialization in progress
// so wait for it to finish in order to avoid a possible
// race condition to set _dbInfo
const oldDriverSetDone =
this._driverSet !== null
? this._driverSet.catch(() => Promise.resolve())
: Promise.resolve();
this._driverSet = oldDriverSetDone
.then(() => {
const driverName = supportedDrivers[0];
self._dbInfo = null;
self._ready = null;
return self.getDriver(driverName).then(driver => {
self._driver = driver._driver;
setDriverToConfig();
self._wrapLibraryMethodsWithReady();
self._initDriver = initDriver(supportedDrivers);
});
})
.catch(() => {
setDriverToConfig();
const error = new Error('No available storage method found.');
self._driverSet = Promise.reject(error);
return self._driverSet;
});
executeTwoCallbacks(this._driverSet, callback, errorCallback);
return this._driverSet;
}
supports(driverName) {
return !!DriverSupport[driverName];
}
_extend(libraryMethodsAndProperties) {
extend(this, libraryMethodsAndProperties);
}
_getSupportedDrivers(drivers) {
const supportedDrivers = [];
for (let i = 0, len = drivers.length; i < len; i++) {
const driverName = drivers[i];
if (this.supports(driverName)) {
supportedDrivers.push(driverName);
}
}
return supportedDrivers;
}
_wrapLibraryMethodsWithReady() {
// Add a stub for each driver API method that delays the call to the
// corresponding driver method until localForage is ready. These stubs
// will be replaced by the driver methods as soon as the driver is
// loaded, so there is no performance impact.
for (let i = 0, len = LibraryMethods.length; i < len; i++) {
callWhenReady(this, LibraryMethods[i]);
}
}
createInstance(options) {
return new LocalForage(options);
}
}
// The actual localForage object that we expose as a module or via a
// global. It's extended by pulling in one of our other libraries.
export default new LocalForage();

33
node_modules/localforage/src/utils/createBlob.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
// Abstracts constructing a Blob object, so it also works in older
// browsers that don't support the native Blob constructor. (i.e.
// old QtWebKit versions, at least).
// Abstracts constructing a Blob object, so it also works in older
// browsers that don't support the native Blob constructor. (i.e.
// old QtWebKit versions, at least).
function createBlob(parts, properties) {
/* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
parts = parts || [];
properties = properties || {};
try {
return new Blob(parts, properties);
} catch (e) {
if (e.name !== 'TypeError') {
throw e;
}
var Builder =
typeof BlobBuilder !== 'undefined'
? BlobBuilder
: typeof MSBlobBuilder !== 'undefined'
? MSBlobBuilder
: typeof MozBlobBuilder !== 'undefined'
? MozBlobBuilder
: WebKitBlobBuilder;
var builder = new Builder();
for (var i = 0; i < parts.length; i += 1) {
builder.append(parts[i]);
}
return builder.getBlob(properties.type);
}
}
export default createBlob;

14
node_modules/localforage/src/utils/executeCallback.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
function executeCallback(promise, callback) {
if (callback) {
promise.then(
function(result) {
callback(null, result);
},
function(error) {
callback(error);
}
);
}
}
export default executeCallback;

View File

@@ -0,0 +1,11 @@
function executeTwoCallbacks(promise, callback, errorCallback) {
if (typeof callback === 'function') {
promise.then(callback);
}
if (typeof errorCallback === 'function') {
promise.catch(errorCallback);
}
}
export default executeTwoCallbacks;

8
node_modules/localforage/src/utils/getCallback.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export default function getCallback() {
if (
arguments.length &&
typeof arguments[arguments.length - 1] === 'function'
) {
return arguments[arguments.length - 1];
}
}

25
node_modules/localforage/src/utils/idb.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
function getIDB() {
/* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */
try {
if (typeof indexedDB !== 'undefined') {
return indexedDB;
}
if (typeof webkitIndexedDB !== 'undefined') {
return webkitIndexedDB;
}
if (typeof mozIndexedDB !== 'undefined') {
return mozIndexedDB;
}
if (typeof OIndexedDB !== 'undefined') {
return OIndexedDB;
}
if (typeof msIndexedDB !== 'undefined') {
return msIndexedDB;
}
} catch (e) {
return;
}
}
var idb = getIDB();
export default idb;

18
node_modules/localforage/src/utils/includes.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
const sameValue = (x, y) =>
x === y ||
(typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
const includes = (array, searchElement) => {
const len = array.length;
let i = 0;
while (i < len) {
if (sameValue(array[i], searchElement)) {
return true;
}
i++;
}
return false;
};
export default includes;

7
node_modules/localforage/src/utils/isArray.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
const isArray =
Array.isArray ||
function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
export default isArray;

44
node_modules/localforage/src/utils/isIndexedDBValid.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import idb from './idb';
function isIndexedDBValid() {
try {
// Initialize IndexedDB; fall back to vendor-prefixed versions
// if needed.
if (!idb || !idb.open) {
return false;
}
// We mimic PouchDB here;
//
// We test for openDatabase because IE Mobile identifies itself
// as Safari. Oh the lulz...
var isSafari =
typeof openDatabase !== 'undefined' &&
/(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) &&
!/Chrome/.test(navigator.userAgent) &&
!/BlackBerry/.test(navigator.platform);
var hasFetch =
typeof fetch === 'function' &&
fetch.toString().indexOf('[native code') !== -1;
// Safari <10.1 does not meet our requirements for IDB support
// (see: https://github.com/pouchdb/pouchdb/issues/5572).
// Safari 10.1 shipped with fetch, we can use that to detect it.
// Note: this creates issues with `window.fetch` polyfills and
// overrides; see:
// https://github.com/localForage/localForage/issues/856
return (
(!isSafari || hasFetch) &&
typeof indexedDB !== 'undefined' &&
// some outdated implementations of IDB that appear on Samsung
// and HTC Android devices <4.4 are missing IDBKeyRange
// See: https://github.com/mozilla/localForage/issues/128
// See: https://github.com/mozilla/localForage/issues/272
typeof IDBKeyRange !== 'undefined'
);
} catch (e) {
return false;
}
}
export default isIndexedDBValid;

View File

@@ -0,0 +1,14 @@
function isLocalStorageValid() {
try {
return (
typeof localStorage !== 'undefined' &&
'setItem' in localStorage &&
// in IE8 typeof localStorage.setItem === 'object'
!!localStorage.setItem
);
} catch (e) {
return false;
}
}
export default isLocalStorageValid;

5
node_modules/localforage/src/utils/isWebSQLValid.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
function isWebSQLValid() {
return typeof openDatabase === 'function';
}
export default isWebSQLValid;

9
node_modules/localforage/src/utils/normalizeKey.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
export default function normalizeKey(key) {
// Cast the key to a string, as that's all we can set as a key.
if (typeof key !== 'string') {
console.warn(`${key} used as a key, but it is not a string.`);
key = String(key);
}
return key;
}

8
node_modules/localforage/src/utils/promise.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
// This is CommonJS because lie is an external dependency, so Rollup
// can just ignore it.
if (typeof Promise === 'undefined') {
// In the "nopromises" build this will just throw if you don't have
// a global promise object, but it would throw anyway later.
require('lie/polyfill');
}
export default Promise;

245
node_modules/localforage/src/utils/serializer.js generated vendored Normal file
View File

@@ -0,0 +1,245 @@
/* eslint-disable no-bitwise */
import createBlob from './createBlob';
// Sadly, the best way to save binary data in WebSQL/localStorage is serializing
// it to Base64, so this is how we store it to prevent very strange errors with less
// verbose ways of binary <-> string data storage.
var BASE_CHARS =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var BLOB_TYPE_PREFIX = '~~local_forage_type~';
var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
var SERIALIZED_MARKER = '__lfsc__:';
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;
// OMG the serializations!
var TYPE_ARRAYBUFFER = 'arbf';
var TYPE_BLOB = 'blob';
var TYPE_INT8ARRAY = 'si08';
var TYPE_UINT8ARRAY = 'ui08';
var TYPE_UINT8CLAMPEDARRAY = 'uic8';
var TYPE_INT16ARRAY = 'si16';
var TYPE_INT32ARRAY = 'si32';
var TYPE_UINT16ARRAY = 'ur16';
var TYPE_UINT32ARRAY = 'ui32';
var TYPE_FLOAT32ARRAY = 'fl32';
var TYPE_FLOAT64ARRAY = 'fl64';
var TYPE_SERIALIZED_MARKER_LENGTH =
SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;
var toString = Object.prototype.toString;
function stringToBuffer(serializedString) {
// Fill the string into a ArrayBuffer.
var bufferLength = serializedString.length * 0.75;
var len = serializedString.length;
var i;
var p = 0;
var encoded1, encoded2, encoded3, encoded4;
if (serializedString[serializedString.length - 1] === '=') {
bufferLength--;
if (serializedString[serializedString.length - 2] === '=') {
bufferLength--;
}
}
var buffer = new ArrayBuffer(bufferLength);
var bytes = new Uint8Array(buffer);
for (i = 0; i < len; i += 4) {
encoded1 = BASE_CHARS.indexOf(serializedString[i]);
encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);
encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);
encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);
/*jslint bitwise: true */
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return buffer;
}
// Converts a buffer to a string to store, serialized, in the backend
// storage library.
function bufferToString(buffer) {
// base64-arraybuffer
var bytes = new Uint8Array(buffer);
var base64String = '';
var i;
for (i = 0; i < bytes.length; i += 3) {
/*jslint bitwise: true */
base64String += BASE_CHARS[bytes[i] >> 2];
base64String += BASE_CHARS[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64String +=
BASE_CHARS[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64String += BASE_CHARS[bytes[i + 2] & 63];
}
if (bytes.length % 3 === 2) {
base64String = base64String.substring(0, base64String.length - 1) + '=';
} else if (bytes.length % 3 === 1) {
base64String =
base64String.substring(0, base64String.length - 2) + '==';
}
return base64String;
}
// Serialize a value, afterwards executing a callback (which usually
// instructs the `setItem()` callback/promise to be executed). This is how
// we store binary data with localStorage.
function serialize(value, callback) {
var valueType = '';
if (value) {
valueType = toString.call(value);
}
// Cannot use `value instanceof ArrayBuffer` or such here, as these
// checks fail when running the tests using casper.js...
//
// TODO: See why those tests fail and use a better solution.
if (
value &&
(valueType === '[object ArrayBuffer]' ||
(value.buffer &&
toString.call(value.buffer) === '[object ArrayBuffer]'))
) {
// Convert binary arrays to a string and prefix the string with
// a special marker.
var buffer;
var marker = SERIALIZED_MARKER;
if (value instanceof ArrayBuffer) {
buffer = value;
marker += TYPE_ARRAYBUFFER;
} else {
buffer = value.buffer;
if (valueType === '[object Int8Array]') {
marker += TYPE_INT8ARRAY;
} else if (valueType === '[object Uint8Array]') {
marker += TYPE_UINT8ARRAY;
} else if (valueType === '[object Uint8ClampedArray]') {
marker += TYPE_UINT8CLAMPEDARRAY;
} else if (valueType === '[object Int16Array]') {
marker += TYPE_INT16ARRAY;
} else if (valueType === '[object Uint16Array]') {
marker += TYPE_UINT16ARRAY;
} else if (valueType === '[object Int32Array]') {
marker += TYPE_INT32ARRAY;
} else if (valueType === '[object Uint32Array]') {
marker += TYPE_UINT32ARRAY;
} else if (valueType === '[object Float32Array]') {
marker += TYPE_FLOAT32ARRAY;
} else if (valueType === '[object Float64Array]') {
marker += TYPE_FLOAT64ARRAY;
} else {
callback(new Error('Failed to get type for BinaryArray'));
}
}
callback(marker + bufferToString(buffer));
} else if (valueType === '[object Blob]') {
// Conver the blob to a binaryArray and then to a string.
var fileReader = new FileReader();
fileReader.onload = function() {
// Backwards-compatible prefix for the blob type.
var str =
BLOB_TYPE_PREFIX +
value.type +
'~' +
bufferToString(this.result);
callback(SERIALIZED_MARKER + TYPE_BLOB + str);
};
fileReader.readAsArrayBuffer(value);
} else {
try {
callback(JSON.stringify(value));
} catch (e) {
console.error("Couldn't convert value into a JSON string: ", value);
callback(null, e);
}
}
}
// Deserialize data we've inserted into a value column/field. We place
// special markers into our strings to mark them as encoded; this isn't
// as nice as a meta field, but it's the only sane thing we can do whilst
// keeping localStorage support intact.
//
// Oftentimes this will just deserialize JSON content, but if we have a
// special marker (SERIALIZED_MARKER, defined above), we will extract
// some kind of arraybuffer/binary data/typed array out of the string.
function deserialize(value) {
// If we haven't marked this string as being specially serialized (i.e.
// something other than serialized JSON), we can just return it and be
// done with it.
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {
return JSON.parse(value);
}
// The following code deals with deserializing some kind of Blob or
// TypedArray. First we separate out the type of data we're dealing
// with from the data itself.
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
var type = value.substring(
SERIALIZED_MARKER_LENGTH,
TYPE_SERIALIZED_MARKER_LENGTH
);
var blobType;
// Backwards-compatible blob type serialization strategy.
// DBs created with older versions of localForage will simply not have the blob type.
if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
blobType = matcher[1];
serializedString = serializedString.substring(matcher[0].length);
}
var buffer = stringToBuffer(serializedString);
// Return the right type based on the code/type set during
// serialization.
switch (type) {
case TYPE_ARRAYBUFFER:
return buffer;
case TYPE_BLOB:
return createBlob([buffer], { type: blobType });
case TYPE_INT8ARRAY:
return new Int8Array(buffer);
case TYPE_UINT8ARRAY:
return new Uint8Array(buffer);
case TYPE_UINT8CLAMPEDARRAY:
return new Uint8ClampedArray(buffer);
case TYPE_INT16ARRAY:
return new Int16Array(buffer);
case TYPE_UINT16ARRAY:
return new Uint16Array(buffer);
case TYPE_INT32ARRAY:
return new Int32Array(buffer);
case TYPE_UINT32ARRAY:
return new Uint32Array(buffer);
case TYPE_FLOAT32ARRAY:
return new Float32Array(buffer);
case TYPE_FLOAT64ARRAY:
return new Float64Array(buffer);
default:
throw new Error('Unkown type: ' + type);
}
}
var localforageSerializer = {
serialize: serialize,
deserialize: deserialize,
stringToBuffer: stringToBuffer,
bufferToString: bufferToString
};
export default localforageSerializer;

123
node_modules/localforage/typings/localforage.d.ts generated vendored Normal file
View File

@@ -0,0 +1,123 @@
interface LocalForageDbInstanceOptions {
name?: string;
storeName?: string;
}
interface LocalForageOptions extends LocalForageDbInstanceOptions {
driver?: string | string[];
size?: number;
version?: number;
description?: string;
}
interface LocalForageDbMethodsCore {
getItem<T>(key: string, callback?: (err: any, value: T | null) => void): Promise<T | null>;
setItem<T>(key: string, value: T, callback?: (err: any, value: T) => void): Promise<T>;
removeItem(key: string, callback?: (err: any) => void): Promise<void>;
clear(callback?: (err: any) => void): Promise<void>;
length(callback?: (err: any, numberOfKeys: number) => void): Promise<number>;
key(keyIndex: number, callback?: (err: any, key: string) => void): Promise<string>;
keys(callback?: (err: any, keys: string[]) => void): Promise<string[]>;
iterate<T, U>(iteratee: (value: T, key: string, iterationNumber: number) => U,
callback?: (err: any, result: U) => void): Promise<U>;
}
interface LocalForageDropInstanceFn {
(dbInstanceOptions?: LocalForageDbInstanceOptions, callback?: (err: any) => void): Promise<void>;
}
interface LocalForageDriverMethodsOptional {
dropInstance?: LocalForageDropInstanceFn;
}
// duplicating LocalForageDriverMethodsOptional to preserve TS v2.0 support,
// since Partial<> isn't supported there
interface LocalForageDbMethodsOptional {
dropInstance: LocalForageDropInstanceFn;
}
interface LocalForageDriverDbMethods extends LocalForageDbMethodsCore, LocalForageDriverMethodsOptional {}
interface LocalForageDriverSupportFunc {
(): Promise<boolean>;
}
interface LocalForageDriver extends LocalForageDriverDbMethods {
_driver: string;
_initStorage(options: LocalForageOptions): void;
_support?: boolean | LocalForageDriverSupportFunc;
}
interface LocalForageSerializer {
serialize<T>(value: T | ArrayBuffer | Blob, callback: (value: string, error: any) => void): void;
deserialize<T>(value: string): T | ArrayBuffer | Blob;
stringToBuffer(serializedString: string): ArrayBuffer;
bufferToString(buffer: ArrayBuffer): string;
}
interface LocalForageDbMethods extends LocalForageDbMethodsCore, LocalForageDbMethodsOptional {}
interface LocalForage extends LocalForageDbMethods {
LOCALSTORAGE: string;
WEBSQL: string;
INDEXEDDB: string;
/**
* Set and persist localForage options. This must be called before any other calls to localForage are made, but can be called after localForage is loaded.
* If you set any config values with this method they will persist after driver changes, so you can call config() then setDriver()
* @param {LocalForageOptions} options?
*/
config(options: LocalForageOptions): boolean;
config(options: string): any;
config(): LocalForageOptions;
/**
* Create a new instance of localForage to point to a different store.
* All the configuration options used by config are supported.
* @param {LocalForageOptions} options
*/
createInstance(options: LocalForageOptions): LocalForage;
driver(): string;
/**
* Force usage of a particular driver or drivers, if available.
* @param {string} driver
*/
setDriver(driver: string | string[], callback?: () => void, errorCallback?: (error: any) => void): Promise<void>;
defineDriver(driver: LocalForageDriver, callback?: () => void, errorCallback?: (error: any) => void): Promise<void>;
/**
* Return a particular driver
* @param {string} driver
*/
getDriver(driver: string): Promise<LocalForageDriver>;
getSerializer(callback?: (serializer: LocalForageSerializer) => void): Promise<LocalForageSerializer>;
supports(driverName: string): boolean;
ready(callback?: (error: any) => void): Promise<void>;
}
declare module "localforage" {
let localforage: LocalForage;
export = localforage;
}