├── src
├── .DS_Store
├── utils.ts
├── hash.ts
├── index.ts
├── set.ts
├── base.ts
├── zset.ts
├── mise.ts
└── list.ts
├── assets
├── mindb.png
└── banner.js
├── examples
├── editor
│ ├── assets
│ │ ├── icomoon.eot
│ │ ├── icomoon.ttf
│ │ ├── icomoon.woff
│ │ ├── icomoon.svg
│ │ ├── editor.css
│ │ └── marked.min.js
│ ├── flow
│ │ ├── 000.html
│ │ ├── 003.js
│ │ ├── 004.js
│ │ ├── 005.js
│ │ ├── 006.js
│ │ ├── 007.js
│ │ ├── 001.html
│ │ └── 002.html
│ └── index.html
├── AppManager
│ ├── t00.js
│ ├── mem.js
│ ├── t01.js
│ ├── t02.js
│ ├── index.html
│ ├── t03.js
│ ├── messages.js
│ ├── session.js
│ ├── t04.js
│ └── main.js
├── stores
│ ├── multilevel
│ │ ├── server.js
│ │ ├── client.js
│ │ └── nano_multilevel.js
│ ├── IndexedDB
│ │ ├── app.js
│ │ ├── indexed.js
│ │ └── events.js
│ ├── adobeair
│ │ ├── app.js
│ │ └── airstore.js
│ ├── LevelDB
│ │ ├── co.js
│ │ ├── package.json
│ │ ├── run.js
│ │ ├── min-level.js
│ │ ├── logger.js
│ │ ├── vender.js
│ │ └── tcp_service.js
│ ├── memoryStore
│ │ ├── mem.src.js
│ │ └── mem.js
│ ├── Store.js
│ │ └── app.js
│ └── node_with_file
│ │ ├── package.json
│ │ ├── app.js
│ │ └── filestore.js
└── pm2_5
│ └── assets
│ ├── moment_zh-cn.js
│ ├── async.min.js
│ └── pure-min.css
├── .npmignore
├── types
├── utils.d.ts
├── zset.d.ts
├── set.d.ts
├── list.d.ts
├── hash.d.ts
├── base.d.ts
├── mise.d.ts
└── index.d.ts
├── .gitignore
├── tsconfig.json
├── webpack.config.js
├── package.json
├── README_zhcn.md
├── README.md
└── History.md
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iwillwen/mindb/HEAD/src/.DS_Store
--------------------------------------------------------------------------------
/assets/mindb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iwillwen/mindb/HEAD/assets/mindb.png
--------------------------------------------------------------------------------
/examples/editor/assets/icomoon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iwillwen/mindb/HEAD/examples/editor/assets/icomoon.eot
--------------------------------------------------------------------------------
/examples/editor/assets/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iwillwen/mindb/HEAD/examples/editor/assets/icomoon.ttf
--------------------------------------------------------------------------------
/examples/editor/assets/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iwillwen/mindb/HEAD/examples/editor/assets/icomoon.woff
--------------------------------------------------------------------------------
/examples/AppManager/t00.js:
--------------------------------------------------------------------------------
1 | (function(undefined) {
2 | var AppManagerCore = {
3 | addNewApp: function(url, name, callback) {
4 | }
5 | };
6 | })();
7 |
--------------------------------------------------------------------------------
/examples/editor/flow/000.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Markdown Editor - NanoDB
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | lib-cov
3 | *.seed
4 | *.log
5 | *.csv
6 | *.dat
7 | *.out
8 | *.pid
9 | *.gz
10 |
11 | pids
12 | logs
13 | results
14 | doc
15 | test/assets/*
16 |
17 | node_modules
18 | coverage.html
19 | **.txt
20 | npm_debug.log
21 | .git
22 | .dropbox
--------------------------------------------------------------------------------
/types/utils.d.ts:
--------------------------------------------------------------------------------
1 | export declare function isObject(obj: any): boolean;
2 | export declare function arrayUnique(array: any[]): any[];
3 | export declare function arrayInter(array: any[], ...rest: any[]): any[];
4 | export declare function arrayDiff(array: any[], ...rest: any[]): any[];
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | lib-cov
3 | *.seed
4 | *.log
5 | *.csv
6 | *.dat
7 | *.out
8 | *.pid
9 | *.gz
10 |
11 | pids
12 | logs
13 | results
14 | doc
15 | test/assets/*
16 |
17 | node_modules
18 | coverage.html
19 | **.txt
20 | npm_debug.log
21 | .gitignore
22 | .npmignore
23 | .dropbox
--------------------------------------------------------------------------------
/examples/stores/multilevel/server.js:
--------------------------------------------------------------------------------
1 | var net = require('net');
2 | var multilevel = require('multilevel');
3 | var level = require('level');
4 | var db = level('/tmp/test.db', { encoding: 'json' });
5 |
6 | net.createServer(function(stream) {
7 | stream.pipe(multilevel.server(db)).pipe(stream);
8 | }).listen(8080);
--------------------------------------------------------------------------------
/examples/stores/IndexedDB/app.js:
--------------------------------------------------------------------------------
1 | min.store = new IndexedStore('myapp');
2 |
3 | min.multi()
4 | .incr('user_id')
5 | .incr('user_id')
6 | .incr('user_id')
7 | .exec(function(err, results) {
8 | if (err) {
9 | return console.error(err);
10 | }
11 |
12 | console.dir(results);
13 | });
--------------------------------------------------------------------------------
/examples/stores/adobeair/app.js:
--------------------------------------------------------------------------------
1 | nano.store = new EncryptedLocalStore();
2 |
3 | nano.multi()
4 | .incr('user_id')
5 | .incr('user_id')
6 | .incr('user_id')
7 | .exec(function(err, results) {
8 | if (err) {
9 | return console.error(err);
10 | }
11 |
12 | console.dir(results);
13 | });
--------------------------------------------------------------------------------
/examples/stores/LevelDB/co.js:
--------------------------------------------------------------------------------
1 | var co = require('co');
2 | var min = require('../../../');
3 | var LevelStore = require('./min-level');
4 |
5 | min.store = new LevelStore('./db');
6 |
7 | co(function *() {
8 | yield min.set('foo', 'bar');
9 | var value = yield min.get('foo');
10 |
11 | console.log(value); //=> bar
12 | })();
--------------------------------------------------------------------------------
/assets/banner.js:
--------------------------------------------------------------------------------
1 | var pkg = require('../package.json')
2 |
3 | var version = pkg.version
4 |
5 | exports.banner =
6 | "MinDB (version " + version + ") - Database on JavaScript\n\n" +
7 |
8 | "Will Wen Gunn(iwillwen) and other contributors\n\n" +
9 |
10 | "@license MIT-license\n" +
11 | "@copyright 2012-2018 iwillwen(willwengunn@gmail.com)"
12 |
--------------------------------------------------------------------------------
/examples/editor/flow/003.js:
--------------------------------------------------------------------------------
1 | // app.js
2 | (function($, global) {
3 | // Markdown Editor
4 | var editor = new Editor();
5 |
6 | // Elements
7 | var $saveBtn = $('#save');
8 | var $statusOut = $('#status');
9 | var $markdown = $('#markdown');
10 | var $title = $('#title');
11 | })(jQuery, window);
12 |
13 | function noop() { return false; }
--------------------------------------------------------------------------------
/examples/stores/memoryStore/mem.src.js:
--------------------------------------------------------------------------------
1 | class MemStore {
2 | constructor() {
3 | this.data = {}
4 | this.ready = true
5 | }
6 |
7 | set(key, value) {
8 | this.data[key] = value
9 | }
10 |
11 | get(key) {
12 | return this.data[key]
13 | }
14 |
15 | remove(key) {
16 | delete this.data[key]
17 | }
18 | }
19 |
20 | export default MemStore
21 |
--------------------------------------------------------------------------------
/examples/stores/Store.js/app.js:
--------------------------------------------------------------------------------
1 | require([ 'nano', 'store.js' ], function(nano, store) {
2 | nano.store = store;
3 |
4 | nano.multi()
5 | .incr('user_id')
6 | .incr('user_id')
7 | .incr('user_id')
8 | .exec(function(err, results) {
9 | if (err) {
10 | return console.error(err);
11 | }
12 |
13 | console.dir(results);
14 | });
15 | });
--------------------------------------------------------------------------------
/examples/stores/LevelDB/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "min-level",
3 | "version": "0.0.1",
4 | "description": "LevelDB StoreInterface for MinDB",
5 | "main": "min-level.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "mindb",
11 | "leveldb"
12 | ],
13 | "author": "iwillwen",
14 | "license": "MIT"
15 | }
16 |
--------------------------------------------------------------------------------
/examples/AppManager/mem.js:
--------------------------------------------------------------------------------
1 | function MemStore() {
2 | this.data = {}
3 | this.ready = true
4 | }
5 |
6 | MemStore.prototype.set = function(key, value) {
7 | this.data[key] = value
8 | }
9 |
10 | MemStore.prototype.get = function(key) {
11 | return this.data[key]
12 | }
13 |
14 | MemStore.prototype.remove = function(key) {
15 | delete this.data[key]
16 | }
17 |
18 | module.exports = MemStore
--------------------------------------------------------------------------------
/examples/stores/node_with_file/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "min-file",
3 | "version": "1.0.0",
4 | "description": "FileStore of MinDB in Node.js/Io.js",
5 | "main": "filestore.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "mindb",
11 | "file"
12 | ],
13 | "author": "iwillwen",
14 | "license": "MIT"
15 | }
16 |
--------------------------------------------------------------------------------
/examples/stores/multilevel/client.js:
--------------------------------------------------------------------------------
1 | var nano = require('../../nano');
2 | var MultiLevelStore = require('./nano_multilevel');
3 |
4 | nano.store = new MultiLevelStore('localhost', 8080);
5 |
6 | nano.multi()
7 | .sadd('foo', 'bar')
8 | .sadd('foo', 'test')
9 | .smembers('foo')
10 | .exec(function(err, results) {
11 | if (err) {
12 | return console.error(err);
13 | }
14 |
15 | console.dir(results[2][0]);
16 | });
--------------------------------------------------------------------------------
/examples/stores/node_with_file/app.js:
--------------------------------------------------------------------------------
1 | var min = require('../../dist/min');
2 | var FileStore = require('./filestore');
3 |
4 | min.store = new FileStore(__dirname + '/mydata.db');
5 |
6 | min.multi()
7 | .sadd('foo', 'bar')
8 | .sadd('foo', 'test')
9 | .smembers('foo')
10 | .exec(function(err, results) {
11 | if (err) {
12 | return console.error(err);
13 | }
14 |
15 | console.dir(results[2][0]);
16 | });
--------------------------------------------------------------------------------
/examples/stores/adobeair/airstore.js:
--------------------------------------------------------------------------------
1 | // For Adobe AIR EncryptedLocalStore
2 | function EncryptedLocalStore() {}
3 | EncryptedLocalStore.prototype.get = function(key) {
4 | return air.EncryptedLocalStore.getItem(key);
5 | };
6 | EncryptedLocalStore.prototype.set = function(key, value) {
7 | return air.EncryptedLocalStore.setItem(key, value);
8 | };
9 | EncryptedLocalStore.prototype.remove = function(key) {
10 | return air.EncryptedLocalStore.removeItem(key);
11 | };
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["es5", "es2015", "dom"],
4 | "rootDir": "./src",
5 | "outDir": "./dist/",
6 | "noImplicitAny": true,
7 | "module": "commonjs",
8 | "target": "es5",
9 | "sourceMap": true,
10 | "declaration": true,
11 | "declarationDir": "./types"
12 | },
13 | "exclude": [
14 | "node_modules",
15 | "build",
16 | "scripts",
17 | "acceptance-tests",
18 | "webpack",
19 | "jest",
20 | "src/setupTests.ts"
21 | ]
22 | }
--------------------------------------------------------------------------------
/examples/stores/LevelDB/run.js:
--------------------------------------------------------------------------------
1 | var async = require('async');
2 | var LevelStore = require('./min_level');
3 | var Benchmark = require('./benchmark');
4 | var min = require('./min');
5 |
6 | min.store = new LevelStore('/tmp/benchmark');
7 |
8 | var n = 0;
9 | var keys = [];
10 | (function loop() {
11 | var curr = Math.random().toString(32).substr(2);
12 |
13 | min.set('bench-' + curr, curr)
14 | .then(function() {
15 | if (++n < 1e4) {
16 | keys.push(curr);
17 | setTimeout(loop);
18 | } else {
19 | run();
20 | }
21 | });
22 | })();
--------------------------------------------------------------------------------
/examples/AppManager/t01.js:
--------------------------------------------------------------------------------
1 | (function(undefined) {
2 | var AppManagerCore = {
3 | addNewApp: function(url, name, callback) {
4 | var app = {
5 | url: url,
6 | name: name
7 | };
8 |
9 | min.incr('apps:id')
10 | .then(function(id) {
11 | app.id = parseInt(id);
12 |
13 | return min.sadd('apps:ids', id);
14 | })
15 | .then(function() {
16 | return min.hmset('app:' + app.id, app);
17 | })
18 | .then(
19 | callback.bind(null, null, app.id),
20 | callback
21 | );
22 | }
23 | };
24 | })();
--------------------------------------------------------------------------------
/examples/editor/flow/004.js:
--------------------------------------------------------------------------------
1 | // app.js
2 | (function($, global) {
3 | // Markdown Editor
4 | var editor = new Editor();
5 |
6 | // Elements
7 | var $saveBtn = $('#save');
8 | var $statusOut = $('#status');
9 | var $markdown = $('#markdown');
10 | var $title = $('#title');
11 |
12 | // Check the saved content
13 | nano.hgetall('md-example')
14 | .then(function(data) {
15 | $title.val(data.title);
16 | $markdown.val(data.content);
17 |
18 | editor.render($markdown.get(0));
19 | })
20 | .fail(function() {
21 | editor.render($markdown.get(0));
22 | });
23 | })(jQuery, window);
24 |
25 | function noop() { return false; }
--------------------------------------------------------------------------------
/examples/stores/multilevel/nano_multilevel.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var multilevel = require('multilevel');
3 | var net = require('net');
4 |
5 | function MultiLevelStore(host, port) {
6 | var stream = net.connect(port, host);
7 |
8 | var db = multilevel.client();
9 |
10 | stream.pipe(db.createRpcStream()).pipe(stream);
11 | this.db = db;
12 | this.async = true;
13 | }
14 | MultiLevelStore.prototype.get = function(key, callback) {
15 | this.db.get(key, callback);
16 | };
17 | MultiLevelStore.prototype.set = function(key, value, callback) {
18 | this.db.put(key, value, callback);
19 | };
20 | MultiLevelStore.prototype.remove = function(key, callback) {
21 | this.db.del(key, callback);
22 | };
23 |
24 | module.exports = MultiLevelStore;
--------------------------------------------------------------------------------
/examples/stores/LevelDB/min-level.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var events = require('events');
3 | var util = require('util');
4 |
5 | function LevelStore(filename, options) {
6 | LevelStore.super_.call(this);
7 |
8 | options = options || {};
9 |
10 | this.db = level(filename, options);
11 | this.filename = filename;
12 | this.ready = true;
13 | this.async = true;
14 | }
15 | util.inherits(LevelStore, events.EventEmitter);
16 | LevelStore.prototype.get = function(key, callback) {
17 | this.db.get(key, callback);
18 | };
19 | LevelStore.prototype.set = function(key, value, callback) {
20 | this.db.put(key, value, callback);
21 | };
22 | LevelStore.prototype.remove = function(key, callback) {
23 | this.db.del(key, callback);
24 | };
25 |
26 | module.exports = LevelStore;
--------------------------------------------------------------------------------
/examples/AppManager/t02.js:
--------------------------------------------------------------------------------
1 | (function(undefined) {
2 | var AppManagerCore = {
3 | addNewApp: function(url, name, callback) {
4 | var app = {
5 | url: url,
6 | name: name
7 | };
8 |
9 | min.incr('apps:id')
10 | .then(function(id) {
11 | app.id = parseInt(id);
12 |
13 | return min.sadd('apps:ids', id);
14 | })
15 | .then(function() {
16 | return min.hmset('app:' + app.id, app);
17 | })
18 | .then(
19 | callback.bind(null, null, app.id),
20 | callback
21 | );
22 | },
23 |
24 | removeApp: function(id, callback) {
25 | min.multi()
26 | .srem('apps:ids', id)
27 | .del('app:' + id)
28 | .exec(callback);
29 | }
30 | };
31 | })();
--------------------------------------------------------------------------------
/examples/AppManager/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AppManager
6 |
7 |
8 |
9 |
Apps:
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/editor/flow/005.js:
--------------------------------------------------------------------------------
1 | // app.js
2 | (function($, global) {
3 | // Markdown Editor
4 | var editor = new Editor();
5 |
6 | // Elements
7 | var $saveBtn = $('#save');
8 | var $statusOut = $('#status');
9 | var $markdown = $('#markdown');
10 | var $title = $('#title');
11 |
12 | // Check the saved content
13 | nano.hgetall('md-example')
14 | .then(function(data) {
15 | $title.val(data.title);
16 | $markdown.val(data.content);
17 |
18 | editor.render($markdown.get(0));
19 | })
20 | .fail(function() {
21 | editor.render($markdown.get(0));
22 | });
23 |
24 | // Save
25 | $saveBtn.on('click', function() {
26 | var md = editor.codemirror.getValue();
27 | var title = $title.val();
28 | });
29 | })(jQuery, window);
30 |
31 | function noop() { return false; }
--------------------------------------------------------------------------------
/types/zset.d.ts:
--------------------------------------------------------------------------------
1 | import { Base } from './base';
2 | export default class MinSet extends Base {
3 | zadd(key: string, score: number, member: any): Promise<0 | 1>;
4 | zcard(key: string): Promise;
5 | zcount(key: string, min: number, max: number): Promise;
6 | zrem(key: string, ...members: any[]): Promise;
7 | zscore(key: string, member: any): Promise;
8 | zrange(key: string, min: number, max: number): Promise;
9 | zrevrange(key: string, min: number, max: number): Promise;
10 | zincrby(key: string, increment: number, member: any): Promise;
11 | zdecrby(key: string, decrement: number, member: any): Promise;
12 | zrank(key: string, member: any): Promise;
13 | zrevrank(key: string, member: any): Promise;
14 | }
15 |
--------------------------------------------------------------------------------
/types/set.d.ts:
--------------------------------------------------------------------------------
1 | import { Base } from './base';
2 | export default class MinSet extends Base {
3 | sadd(key: string, ...members: any[]): Promise;
4 | srem(key: string, ...members: any[]): Promise;
5 | smembers(key: string): Promise;
6 | sismember(key: string, value: any): Promise;
7 | scard(key: string): Promise;
8 | smove(src: string, dest: string, member: any): Promise;
9 | srandmember(key: string): Promise;
10 | spop(key: string): Promise;
11 | sunion(...keys: string[]): Promise;
12 | sunionstore(dest: string, ...keys: string[]): Promise;
13 | sinter(...keys: string[]): Promise;
14 | sinterstore(dest: string, ...keys: string[]): Promise;
15 | sdiff(...keys: string[]): Promise;
16 | sdiffstore(dest: string, ...keys: string[]): Promise;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/editor/flow/006.js:
--------------------------------------------------------------------------------
1 | // app.js
2 | (function($, global) {
3 | // Markdown Editor
4 | var editor = new Editor();
5 |
6 | // Elements
7 | var $saveBtn = $('#save');
8 | var $statusOut = $('#status');
9 | var $markdown = $('#markdown');
10 | var $title = $('#title');
11 |
12 | // Check the saved content
13 | nano.hgetall('md-example')
14 | .then(function(data) {
15 | $title.val(data.title);
16 | $markdown.val(data.content);
17 |
18 | editor.render($markdown.get(0));
19 | })
20 | .fail(function() {
21 | editor.render($markdown.get(0));
22 | });
23 |
24 | // Save
25 | $saveBtn.on('click', function() {
26 | var md = editor.codemirror.getValue();
27 | var title = $title.val();
28 |
29 | nano.hmset('md-example', {
30 | title: title,
31 | content: md
32 | });
33 | });
34 |
35 |
36 | })(jQuery, window);
37 |
38 | function noop() { return false; }
39 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | export function isObject(obj: any) {
2 | return obj === Object(obj)
3 | }
4 |
5 | export function arrayUnique(array: any[]) {
6 | const u: any = {}
7 | const ret: any[] = []
8 | for (let i = 0, l = array.length; i < l; ++i) {
9 | if (u.hasOwnProperty(array[i]) && !isObject(array[i])) {
10 | continue
11 | }
12 | ret.push(array[i])
13 | u[array[i]] = 1
14 | }
15 | return ret
16 | }
17 |
18 | export function arrayInter(array: any[], ...rest: any[]) {
19 | return arrayUnique(array).filter(item => {
20 | let ret = true
21 |
22 | for (const other of rest) {
23 | if (other.indexOf(item) < 0) {
24 | ret = false
25 | }
26 | }
27 |
28 | return ret
29 | })
30 | }
31 |
32 | export function arrayDiff(array: any[], ...rest: any[]) {
33 | let inter = arrayInter(array, ...rest)
34 | let union = arrayUnique(array.concat(...rest))
35 | return union.filter(item => inter.indexOf(item) < 0)
36 | }
--------------------------------------------------------------------------------
/types/list.d.ts:
--------------------------------------------------------------------------------
1 | import { Base } from './base';
2 | export default class MinList extends Base {
3 | lpush(key: string, ...values: any[]): Promise;
4 | lpushx(key: string, ...values: any[]): Promise;
5 | rpush(key: string, ...values: any[]): Promise;
6 | rpushx(key: string, ...values: any[]): Promise;
7 | lpop(key: string): Promise;
8 | rpop(key: string): Promise;
9 | llen(key: string): Promise;
10 | lrange(key: string, start: number, stop: number): Promise;
11 | lrem(key: string, count: number, value: any): Promise;
12 | lset(key: string, index: number, value: any): Promise;
13 | ltrim(key: string, start: number, stop: number): Promise;
14 | lindex(key: string, index: number): Promise;
15 | linsertBefore(key: string, pivot: any, value: any): Promise;
16 | linsertAfter(key: string, pivot: any, value: any): Promise;
17 | rpoplpush(src: string, dest: string): Promise;
18 | lpoprpush(src: string, dest: string): Promise;
19 | }
20 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 |
2 | const webpack = require('webpack')
3 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
4 | const b = require('./assets/banner')
5 | const path = require('path')
6 | const os = require('os')
7 |
8 | module.exports = {
9 | entry: './src/index.ts',
10 | module: {
11 | rules: [
12 | {
13 | test: /\.ts/,
14 | use: 'ts-loader',
15 | exclude: /node_modules/
16 | }
17 | ]
18 | },
19 | devtool: 'source-map',
20 | output: {
21 | path: path.resolve(__dirname, 'dist'),
22 | filename: 'min.js',
23 | library: 'min',
24 | libraryTarget: 'umd',
25 | umdNamedDefine: true,
26 | sourceMapFilename: 'min.map'
27 | },
28 | resolve: {
29 | extensions: [ '.ts' ]
30 | },
31 | mode: 'production',
32 | optimization: {
33 | usedExports: true,
34 | minimizer: [
35 | new UglifyJsPlugin({
36 | parallel: os.cpus().length,
37 | sourceMap: true
38 | })
39 | ]
40 | },
41 | plugins: [
42 | new webpack.BannerPlugin({
43 | banner: b.banner
44 | })
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/examples/editor/flow/007.js:
--------------------------------------------------------------------------------
1 | // app.js
2 | (function($, global) {
3 | // Markdown Editor
4 | var editor = new Editor();
5 |
6 | // Elements
7 | var $saveBtn = $('#save');
8 | var $statusOut = $('#status');
9 | var $markdown = $('#markdown');
10 | var $title = $('#title');
11 |
12 | // Check the saved content
13 | nano.hgetall('md-example')
14 | .then(function(data) {
15 | $title.val(data.title);
16 | $markdown.val(data.content);
17 |
18 | editor.render($markdown.get(0));
19 | })
20 | .fail(function() {
21 | editor.render($markdown.get(0));
22 | });
23 |
24 | // Save
25 | $saveBtn.on('click', function() {
26 | var md = editor.codemirror.getValue();
27 | var title = $title.val();
28 |
29 | nano.hmset('md-example', {
30 | title: title,
31 | content: md
32 | })
33 | .then(function() {
34 | $statusOut.text('Saved 已保存,请尝试刷新页面。');
35 | })
36 | .fail(function(err) {
37 | $statusOut.text('出错!' + err.message);
38 | });
39 | });
40 |
41 |
42 | })(jQuery, window);
43 |
44 | function noop() { return false; }
45 |
46 | // open http://localhost:8080
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "min",
3 | "family": "iwillwen",
4 | "version": "0.2.0",
5 | "description": "Database on JavaScript",
6 | "main": "dist/min.js",
7 | "typings": "types/index.d.ts",
8 | "directories": {
9 | "benchmark": "benchmark",
10 | "example": "examples",
11 | "test": "test"
12 | },
13 | "scripts": {
14 | "build": "node_modules/.bin/webpack"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git://github.com/iwillwen/mindb.git"
19 | },
20 | "keywords": [
21 | "html5",
22 | "redis",
23 | "database",
24 | "localstorage",
25 | "store"
26 | ],
27 | "author": "iwillwen",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/iwillwen/mindb/issues"
31 | },
32 | "homepage": "https://github.com/iwillwen/mindb",
33 | "devDependencies": {
34 | "ts-loader": "^5.3.1",
35 | "typescript": "^3.2.1",
36 | "uglify-js": "^2.4.15",
37 | "uglifyjs-webpack-plugin": "^2.0.1",
38 | "webpack": "^4.26.1",
39 | "webpack-cli": "^3.1.2",
40 | "@types/events": "^1.2.0",
41 | "events": "^3.0.0",
42 | "localforage": "^1.7.3"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/types/hash.d.ts:
--------------------------------------------------------------------------------
1 | import { Base } from './base';
2 | export default class MinHash extends Base {
3 | hset(key: string, field: string, value: any): Promise;
4 | hsetnx(key: string, field: string, value: any): Promise;
5 | hmset(key: string, doc: {
6 | [field: string]: any;
7 | }): Promise;
8 | hget(key: string, field: string): Promise;
9 | hmget(key: string, fields: string[]): Promise;
10 | hgetall(key: string): Promise<{
11 | [field: string]: any;
12 | }>;
13 | hdel(key: string, field: string): Promise;
14 | hlen(key: string): Promise;
15 | hkeys(key: string): Promise;
16 | hexists(key: string, field: string): Promise;
17 | hincr(key: string, field: string): Promise;
18 | hincrby(key: string, field: string, increment: number): Promise;
19 | hincrbyfloat(key: string, field: string, increment: number): Promise;
20 | hdecr(key: string, field: string): Promise;
21 | hdecrby(key: string, field: string, decrement: number): Promise;
22 | hdecrbyfloat(key: string, field: string, decrement: number): Promise;
23 | }
24 |
--------------------------------------------------------------------------------
/examples/AppManager/t03.js:
--------------------------------------------------------------------------------
1 | (function(undefined) {
2 | var AppManagerCore = {
3 | addNewApp: function(url, name, callback) {
4 | var app = {
5 | url: url,
6 | name: name
7 | };
8 |
9 | min.incr('apps:id')
10 | .then(function(id) {
11 | app.id = parseInt(id);
12 |
13 | return min.sadd('apps:ids', id);
14 | })
15 | .then(function() {
16 | return min.hmset('app:' + app.id, app);
17 | })
18 | .then(
19 | callback.bind(null, null, app.id),
20 | callback
21 | );
22 | },
23 |
24 | removeApp: function(id, callback) {
25 | min.multi()
26 | .srem('apps:ids', id)
27 | .del('app:' + id)
28 | .exec(callback);
29 | },
30 |
31 | listApps: function(callback) {
32 | min.smembers('apps:ids')
33 | .then(function(ids) {
34 | var multi = min.multi();
35 |
36 | ids.forEach(function(id) {
37 | multi.hgetall('app:' + id);
38 | });
39 |
40 | multi.exec(function(err, res) {
41 | if (err) return callback(err);
42 |
43 | callback(null, apps);
44 | })
45 | }, callback);
46 | }
47 | };
48 | })();
49 |
--------------------------------------------------------------------------------
/examples/stores/LevelDB/logger.js:
--------------------------------------------------------------------------------
1 | var min = require('../../../min');
2 | var LevelStore = require('./nano_level');
3 |
4 | min.store = new LevelStore('/tmp/mydb', { encoding: 'json' });
5 |
6 | var logger = exports;
7 |
8 | logger.log = function(ctx, callback) {
9 | callback = callback || noop;
10 |
11 | return min.incr('log-seq')
12 | .then(function(id) {
13 | return min.hmset('log-' + id, {
14 | type: 'log',
15 | content: ctx,
16 | time: Date.now()
17 | });
18 | })
19 | .then(function(key) {
20 | var id = parseInt(key.substr(4));
21 |
22 | callback(null, id);
23 | })
24 | .fail(function(err) {
25 | callback(err);
26 | });
27 | };
28 |
29 | logger.error = function(err, callback) {
30 | callback = callback || noop;
31 |
32 | return min.incr('log-seq')
33 | .then(function(id) {
34 | return min.hmset('log-' + id, {
35 | type: 'error',
36 | stack: err.stack,
37 | time: Date.now()
38 | });
39 | })
40 | .then(function(key) {
41 | var id = parseInt(key.substr(4));
42 |
43 | callback(null, id);
44 | })
45 | .fail(function(err) {
46 | callback(err);
47 | });
48 | };
49 |
50 | function noop() {
51 | return false;
52 | }
--------------------------------------------------------------------------------
/examples/stores/LevelDB/vender.js:
--------------------------------------------------------------------------------
1 | var min = require('../../../min');
2 | var LevelStore = require('./nano_level');
3 | var net = require('net');
4 | var util = require('util');
5 |
6 | min.store = new LevelStore('/tmp/mydb', { encoding: 'json' });
7 |
8 | var server = net.createServer(function(stream) {
9 | stream.write(util.format('Simple Redis CLI Simulator: NanoDB with LevelDB on \'%s\'\r\n', min.store.filename));
10 | stream.write('> ');
11 |
12 | stream.on('data', function(data) {
13 | var args = data.toString().replace(/[\r\n]/g, '').split(' ');
14 |
15 | var command = args.shift().toLowerCase();
16 |
17 | switch (true) {
18 | // Exit
19 | case command == '\\q':
20 | stream.end('Bye!\n');
21 | break;
22 |
23 | // Command
24 | case (min.hasOwnProperty(command) && 'function' === typeof min[command]):
25 | min[command].apply(min, args)
26 | .then(function() {
27 | var result = slice.call(arguments).join(' ') + '\n> ';
28 |
29 | stream.write(result);
30 | })
31 | .fail(function(err) {
32 | stream.write(util.format('(error) ERR %s\n> ', err.messgae));
33 | });
34 | break;
35 |
36 | // Unknown command
37 | default:
38 | stream.write(util.format("(error) ERR unknown command '%s'\n> ", command.replace('\n', '')));
39 | }
40 | });
41 |
42 | stream.on('error', function(err) {
43 | console.error(err);
44 | });
45 | });
46 |
47 | server.listen(8081);
48 |
49 | var slice = [].slice;
--------------------------------------------------------------------------------
/examples/stores/LevelDB/tcp_service.js:
--------------------------------------------------------------------------------
1 | var min = require('../../../min');
2 | var LevelStore = require('./min-level');
3 | var net = require('net');
4 | var util = require('util');
5 |
6 | min.store = new LevelStore('/tmp/mydb', { encoding: 'json' });
7 |
8 | var server = net.createServer(function(stream) {
9 | stream.write(util.format('Simple Redis CLI Simulator: MinDB with LevelDB on \'%s\'\r\n', min.store.filename));
10 | stream.write('> ');
11 |
12 | stream.on('data', function(data) {
13 | var args = data.toString().replace(/[\r\n]/g, '').split(' ');
14 |
15 | var command = args.shift().toLowerCase();
16 |
17 | switch (true) {
18 | // Exit
19 | case command == '\\q':
20 | stream.end('Bye!\n');
21 | break;
22 |
23 | // Command
24 | case (min.hasOwnProperty(command) && 'function' === typeof min[command]):
25 | min[command].apply(min, args)
26 | .then(function() {
27 | var result = slice.call(arguments).join(' ') + '\n> ';
28 |
29 | stream.write(result);
30 | })
31 | .fail(function(err) {
32 | stream.write(util.format('(error) ERR %s\n> ', err.messgae));
33 | });
34 | break;
35 |
36 | // Unknown command
37 | default:
38 | stream.write(util.format("(error) ERR unknown command '%s'\n> ", command.replace('\n', '')));
39 | }
40 | });
41 |
42 | stream.on('error', function(err) {
43 | console.error(err);
44 | });
45 | });
46 |
47 | server.listen(8080);
48 |
49 | var slice = [].slice;
--------------------------------------------------------------------------------
/examples/stores/node_with_file/filestore.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var events = require('events')
3 | var util = require('util')
4 |
5 | function FileStore(filename) {
6 | var self = this
7 |
8 | this.filename = filename
9 | this.buffer = {}
10 |
11 | this.async = true
12 | this.ready = false
13 |
14 | fs.exists(filename, function(exists) {
15 | if (!exists) {
16 | fs.writeFile(filename, "{}", function(err) {
17 | if (err) return console.error(err)
18 |
19 | self.ready = true
20 | self.emit('ready')
21 | })
22 | } else {
23 | fs.readFile(filename, function(err, data) {
24 | if (err) return console.error(err)
25 |
26 | self.buffer = JSON.parse(data.toString())
27 |
28 | self.ready = true
29 | self.emit('ready')
30 | })
31 | }
32 | })
33 | }
34 | util.inherits(FileStore, events.EventEmitter)
35 | FileStore.prototype.set = function(key, value, callback) {
36 | var self = this
37 |
38 | self.buffer[key] = value
39 |
40 | fs.writeFile(self.filename, JSON.stringify(self.buffer), function(err) {
41 | if (err)
42 | return callback(err)
43 |
44 | callback()
45 | })
46 | }
47 | FileStore.prototype.get = function(key, callback) {
48 | var self = this
49 |
50 | if (self.buffer[key]) {
51 | return callback(null, self.buffer[key])
52 | } else {
53 | return callback(new Error('This key is not exists.'))
54 | }
55 | }
56 | FileStore.prototype.remove = function(key, callback) {
57 | var self = this
58 |
59 | delete self.buffer[key]
60 |
61 | fs.writeFile(self.filename, JSON.stringify(self.buffer), callback)
62 | }
63 |
64 | module.exports = FileStore
--------------------------------------------------------------------------------
/examples/AppManager/messages.js:
--------------------------------------------------------------------------------
1 | // Node shim
2 | if ('undefined' !== typeof process) {
3 | var min = require('min');
4 | var MemStore = require('./mem');
5 | min.store = new MemStore();
6 | } else {
7 | module = { exports: {} };
8 | }
9 |
10 | var Messages = (function(undefined) {
11 | var Messages = {
12 | pushMessage: function(appId, content, callback) {
13 | var msg = {
14 | content: content
15 | };
16 |
17 | min.incr('msgs:' + appId + ':id_seq')
18 | .then(function(id) {
19 | msg.id = parseInt(id);
20 |
21 | return min.sadd('msg:' + appId, id);
22 | })
23 | .then(function() {
24 | return min.set('msg:' + appId + ':' + msg.id, content);
25 | })
26 | .then(function() {
27 | callback(null, msg.id);
28 | }, callback);
29 | },
30 |
31 | pullMessages: function(appId, callback) {
32 | min.smembers('msg:' + appId)
33 | .then(function(msgIds) {
34 | return min.mget(msgIds.map(function(id) {
35 | return 'msg:' + appId + ':' + id;
36 | }));
37 | })
38 | .then(function(msgs) {
39 | return callback(null, msgs);
40 | }, callback);
41 | }
42 | };
43 |
44 | return Messages;
45 | })();
46 |
47 | var testMessages = module.exports = function() {
48 | var msgs = [
49 | 'foo',
50 | 'bar',
51 | 'abc'
52 | ];
53 |
54 | (function loop(arr) {
55 | var msg = arr.shift();
56 |
57 | if (!msg) return;
58 |
59 | Messages.pushMessage('test', msg, function(err, id) {
60 | return loop(arr);
61 | });
62 | })(msgs);
63 |
64 | Messages.pullMessages('test', function(err, res) {
65 | console.dir(res);
66 | });
67 | };
--------------------------------------------------------------------------------
/types/base.d.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from 'events';
2 | export declare enum TYPES {
3 | 'mix' = 0,
4 | 'hash' = 1,
5 | 'list' = 2,
6 | 'set' = 3,
7 | 'zset' = 4
8 | }
9 | export declare class Base extends EventEmitter {
10 | name: string;
11 | store: LocalForage;
12 | _keys: {
13 | [key: string]: TYPES;
14 | };
15 | constructor(name?: string);
16 | _setType(key: string, type: TYPES): Promise;
17 | _delType(key: string): Promise;
18 | _restoreKeys(): Promise;
19 | /**
20 | * Delete a key
21 | * @param {String} key Key
22 | * @return {Promise} Promise
23 | */
24 | del(key: string): Promise;
25 | /**
26 | * Check a key is exists or not
27 | * @param {String} key Key
28 | * @return {Promise} Promise Object
29 | */
30 | exists(key: string): Promise;
31 | is(key: string, type: TYPES): Promise;
32 | renamenx(key: string, newKey: string): Promise;
33 | rename(key: string, newKey: string): Promise;
34 | keys(pattern?: string): Promise;
35 | randomKey(): Promise;
36 | type(key: string): Promise;
37 | empty(): Promise;
38 | set(key: string, value: any): Promise;
39 | setnx(key: string, value: any): Promise;
40 | setex(key: string, seconds: number, value: any): Promise;
41 | psetex(key: string, milliseconds: number, value: any): Promise;
42 | mset(doc: {
43 | [key: string]: any;
44 | }): Promise;
45 | append(key: string, value: string): Promise;
46 | get(key: string): Promise;
47 | getrange(key: string, start: number, end: number): Promise;
48 | mget(keys: string[]): Promise;
49 | getset(key: string, value: any): Promise;
50 | strlen(key: string): Promise;
51 | incr(key: string): Promise;
52 | }
53 |
--------------------------------------------------------------------------------
/examples/editor/flow/001.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Markdown Editor - NanoDB
6 |
7 |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/stores/memoryStore/mem.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | (function (global, factory) {
4 | if (typeof define === "function" && define.amd) {
5 | define(["exports"], factory);
6 | } else if (typeof exports !== "undefined") {
7 | factory(exports);
8 | } else {
9 | var mod = {
10 | exports: {}
11 | };
12 | factory(mod.exports);
13 | global.memSrc = mod.exports;
14 | }
15 | })(this, function (exports) {
16 | Object.defineProperty(exports, "__esModule", {
17 | value: true
18 | });
19 |
20 | function _classCallCheck(instance, Constructor) {
21 | if (!(instance instanceof Constructor)) {
22 | throw new TypeError("Cannot call a class as a function");
23 | }
24 | }
25 |
26 | var _createClass = (function () {
27 | function defineProperties(target, props) {
28 | for (var i = 0; i < props.length; i++) {
29 | var descriptor = props[i];
30 | descriptor.enumerable = descriptor.enumerable || false;
31 | descriptor.configurable = true;
32 | if ("value" in descriptor) descriptor.writable = true;
33 | Object.defineProperty(target, descriptor.key, descriptor);
34 | }
35 | }
36 |
37 | return function (Constructor, protoProps, staticProps) {
38 | if (protoProps) defineProperties(Constructor.prototype, protoProps);
39 | if (staticProps) defineProperties(Constructor, staticProps);
40 | return Constructor;
41 | };
42 | })();
43 |
44 | var MemStore = (function () {
45 | function MemStore() {
46 | _classCallCheck(this, MemStore);
47 |
48 | this.data = {};
49 | this.ready = true;
50 | }
51 |
52 | _createClass(MemStore, [{
53 | key: "set",
54 | value: function set(key, value) {
55 | this.data[key] = value;
56 | }
57 | }, {
58 | key: "get",
59 | value: function get(key) {
60 | return this.data[key];
61 | }
62 | }, {
63 | key: "remove",
64 | value: function remove(key) {
65 | delete this.data[key];
66 | }
67 | }]);
68 |
69 | return MemStore;
70 | })();
71 |
72 | exports.default = MemStore;
73 | });
74 |
75 |
--------------------------------------------------------------------------------
/examples/editor/flow/002.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Markdown Editor - MinDB
6 |
7 |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Powered by editor
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/stores/IndexedDB/indexed.js:
--------------------------------------------------------------------------------
1 | window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
2 | window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
3 | window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
4 |
5 | // IndexedDB Store Interface for NanoDB
6 | function IndexedStore(name) {
7 | var self = this;
8 | self.async = true;
9 | self.storeName = name;
10 |
11 | // Open a database
12 | var req = indexedDB.open(name, 1);
13 | req.onerror = function(event) {
14 | console.error(new Error("Why didn't you allow my web app to use IndexedDB?!"));
15 | };
16 | req.onsuccess = function(event) {
17 | // Database
18 | self.db = event.target.result;
19 | };
20 | req.onupgradeneeded = function(event) {
21 | // ObjectStore
22 | self.store = self.db.createObjectStore('nano-' + name, { keyPath: "key" });
23 | // Ready
24 | self.ready = true;
25 | self.emit('ready');
26 | };
27 | }
28 | EventEmitter.inherits(IndexedStore);
29 | IndexedStore.prototype.get = function(key, callback) {
30 | // Fetch the objectstore
31 | var store = this.db
32 | .transaction('nano-' + this.storeName, 'readonly')
33 | .objectStore('nano-' + this.storeName);
34 |
35 | var req = store.get(key);
36 |
37 | req.onerror = function() {
38 | console.error(new Error("Something went wrong!"));
39 | };
40 | req.onsuccess = function(event) {
41 | var value = event.target.result.value;
42 |
43 | callback(null, value);
44 | };
45 | };
46 | IndexedStore.prototype.set = function(key, value, callback) {
47 | var store = this.db
48 | .transaction('nano-' + this.storeName, 'readwrite')
49 | .objectStore('nano-' + this.storeName);
50 |
51 | var req = store.put({
52 | key: key,
53 | value: value
54 | });
55 |
56 | req.onerror = function() {
57 | console.error(new Error("Something went wrong!"));
58 | };
59 | req.onsuccess = function(arguments) {
60 | callback(null, key, value);
61 | };
62 | };
63 | IndexedStore.prototype.remove = function(key, callback) {
64 | var store = this.db
65 | .transaction('nano-' + this.storeName, 'readwrite')
66 | .objectStore('nano-' + this.storeName);
67 |
68 | var req = store.delete(key);
69 |
70 | req.onerror = function() {
71 | console.error(new Error("Something went wrong!"));
72 | };
73 | req.onsuccess = function() {
74 | callback(null, key);
75 | };
76 | };
--------------------------------------------------------------------------------
/examples/AppManager/session.js:
--------------------------------------------------------------------------------
1 | var wrap = {};
2 |
3 | Object.defineProperty(wrap, 'session', {
4 | get: function() {
5 | return wrap.$session;
6 | },
7 | set: function(newValue) {
8 | var changes = objDiff(wrap.$session, newValue);
9 |
10 | var multi = min.multi();
11 |
12 | for (key in changes) {
13 | if (changes.hasOwnProperty(key)) {
14 | wrap.$session[key] = changes[key];
15 | multi.set('session:' + key, changes[key]);
16 | }
17 | }
18 |
19 | multi.exec(function(err, res) {
20 | console.log(err, res);
21 | })
22 | },
23 | configurable: true
24 | });
25 |
26 | Object.defineProperty(wrap, '$session', {
27 | get: function() {
28 | return {}
29 | },
30 | set: function(newValue) {
31 | console.log(newValue);
32 | }
33 | });
34 |
35 | function objDiff(obj1, obj2) {
36 | var keys1 = Object.keys(obj1);
37 | var keys2 = Object.keys(obj2);
38 |
39 | var diff = arrayDiff(keys2, keys1);
40 | var inter = arrayInter(keys2, keys1);
41 |
42 | console.log(keys1, keys2, diff, inter);
43 |
44 | var changes = {};
45 |
46 | diff.forEach(function(row) {
47 | changes[row] = obj2[row];
48 | });
49 |
50 | inter.forEach(function(row) {
51 | if (obj1[row] !== obj2[row]) {
52 | changes[row] = obj2[row];
53 | }
54 | });
55 |
56 | return changes;
57 | }
58 |
59 | function arrayDiff(array) {
60 | var rest = [].slice.call(arguments, 1);
61 | return array.filter(function(item) {
62 | var ret = true;
63 |
64 | for (var i = 0; i < rest.length; i++) {
65 | (function(index) {
66 | var other = rest[index];
67 |
68 | if (other.indexOf(item) >= 0) {
69 | ret = false;
70 | }
71 | })(i);
72 | }
73 |
74 | return ret;
75 | });
76 | }
77 |
78 | function arrayInter(array) {
79 | var rest = [].slice.call(arguments, 1);
80 | return arrayUnique(array).filter(function(item) {
81 | var ret = true;
82 |
83 | for (var i = 0; i < rest.length; i++) {
84 | (function(index) {
85 | var other = rest[index];
86 |
87 | if (other.indexOf(item) < 0) {
88 | ret = false;
89 | }
90 | })(i);
91 | }
92 |
93 | return ret;
94 | });
95 | }
96 |
97 | function arrayUnique(array) {
98 | var u = {};
99 | var ret = [];
100 | for (var i = 0, l = array.length; i < l; ++i) {
101 | if (u.hasOwnProperty(array[i]) && !utils.isObject(array[i])) {
102 | continue;
103 | }
104 | ret.push(array[i]);
105 | u[array[i]] = 1;
106 | }
107 | return ret;
108 | }
--------------------------------------------------------------------------------
/README_zhcn.md:
--------------------------------------------------------------------------------
1 | **JavaScript 数据库**
2 |
3 | 在 JavaScript 中对你的应用数据进行存储和操作。
4 | MinDB 提供一个标准的存储接口(`Store Interface`)和 **Redis** 风格的 API,你可以在任何 JavaScript 环境中使用。
5 |
6 | # 安装
7 |
8 | 普通`script`标签引入:
9 |
10 | ```html
11 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Powered by editor and MinDB
27 |
28 |
361 |
362 |