Merge branch 'master' into chore/cache-node-modules

This commit is contained in:
Mark Nadal 2018-07-03 15:57:47 -07:00 committed by GitHub
commit 6ea408700e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 171 additions and 126 deletions

View File

@ -3,12 +3,10 @@ branches:
except: except:
- debug - debug
node_js: node_js:
- 4.0 - 4
- 4.2 - 6
- 5.0 - 8
- 6.8 - 10
- 7.9
- 8.6
cache: cache:
directories: directories:
- node_modules - node_modules

View File

@ -1,131 +1,178 @@
<html> <html>
<head> <head>
<title>Gun plugin for Vue</title> <title>Gun plugin for Vue</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script> <!-- This example works only with vue 1 -->
<script src="https://unpkg.com/vue"></script> <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
</head> <script src="https://unpkg.com/vue@1.0.0/dist/vue.min.js"></script>
<body> </head>
<div id="app"> <body>
This is example of simple Vue plugin. It works exatcly same as the Vue instance data property, but the name is gunData.<br> <div id="app">
The cool part is that every property in the gunData is realtime synced via gunDB to every other page viewer!<br> This is example of simple Vue plugin. It works exatcly same as the Vue instance data property, but the name is gunData.<br>
<table> The cool part is that every property in the gunData is realtime synced via gunDB to every other page viewer!<br>
<tr> <table>
<td> <tr>
Vue instance data: <td>
<pre>{{ $data }}</pre> Vue instance data:
</td> <pre v-html="prettyJSON($data)"></pre>
<td valign="top" style="text-align:right;"> </td>
test<br> <td valign="top" style="text-align:right;">
arr[1]<br> test<br>
obj.a<br> arr[1]<br>
deepObj.level1.prop<br> obj.a<br>
deepObj.level1.arr[1]<br> deepObj.level1.prop<br>
</td> deepObj.level1.arr[1]<br>
<td valign="top"> </td>
<input v-model="test"><br> <td valign="top">
<input v-model="arr[1]"><br> <input v-model="test"><br>
<input v-model="obj.a"><br> <input v-model="arr[1]"><br>
<input v-model="deepObj.level1.prop"><br> <input v-model="obj.a"><br>
<input v-model="deepObj.level1.arr[1]"><br> <input v-model="deepObj.level1.prop"><br>
<input v-if="obj.newProp_1" v-model="obj.newProp_1"><br> <input v-model="deepObj.level1.arr[1]"><br>
<br> <input v-if="obj.newProp_1" v-model="obj.newProp_1"><br>
<button @click="addProp()">Add new prop to obj</button> <br>
</td> <button @click="addProp()">Add new prop to obj</button>
</tr> </td>
</table> </tr>
</div> </table>
<script> </div>
Vue.config.productionTip = false; <script>
localStorage.clear(); Vue.config.productionTip = false;
var GunData = { localStorage.clear();
install: function(Vue, options) { var GunData = {
Vue.$gunData = { install: function (Vue, options) {
gun: Gun(options), Vue.$gunData = {
arrToGunObj: function(a) { gun: Gun(options),
var o = { _isArr: true }, l = a.length; arrToGunObj: function (a) {
for ( var i=0; i<l; i++ ) if ( a[i] !== undefined ) o[i] = a[i]; var o = { _isArr: true }, l = a.length;
return o; for (var i = 0; i < l; i++) if (a[i] !== undefined) o[i] = a[i];
}, return o;
addGunWatcher: function (keyPath,val,vm) { },
// console.log('addGunWatcher',keyPath); addGunWatcher: function (keyPath, val, vm) {
this.gun.get(vm.$options.$gunRootKey).path(keyPath) // console.log('addGunWatcher',keyPath);
.not(function(){ this.put(typeof val == 'object' && val.constructor === Array ? this.arrToGunObj(val) : val) }) this.gun.get(vm.$options.$gunRootKey).path(keyPath)
.on(function(gunVal,gunKey){ .not(function () { this.put(typeof val == 'object' && val.constructor === Array ? this.arrToGunObj(val) : val) })
if ( typeof gunVal == 'object' ) return; /* only do stuff on non objects */ .on(function (gunVal, gunKey) {
if (typeof gunVal == 'object') return; /* only do stuff on non objects */
var vmPath = vm; var vmPath = vm;
for ( var i=0, a=keyPath.split('.'), l=a.length; i<l-1; i++ ) vmPath = vmPath[a[i]]; for (var i = 0, a = keyPath.split('.'), l = a.length; i < l - 1; i++) vmPath = vmPath[a[i]];
if ( typeof vmPath[gunKey] == 'undefined' ) console.log('EIPÄ OO',gunkey); if (typeof vmPath[gunKey] == 'undefined') console.log('EIPÄ OO', gunkey);
if ( vmPath[gunKey] !== gunVal ) vm.$set(vmPath,vmPath.constructor === Array?gunKey*1:gunKey,gunVal); if (vmPath[gunKey] !== gunVal) vm.$set(vmPath, vmPath.constructor === Array ? gunKey * 1 : gunKey, gunVal);
},{ change:true }); }, { change: true });
}, },
timeout: { }, timeout: {},
vueWatcher: { }, vueWatcher: {},
addVueWatcher: function (keyPath,vm) { addVueWatcher: function (keyPath, vm) {
// console.log('VUE WATCHER',keyPath,vm.$options.$gunRootKey); // console.log('VUE WATCHER',keyPath,vm.$options.$gunRootKey);
this.vueWatcher[keyPath] = vm.$watch(keyPath, function(newVal) { this.vueWatcher[keyPath] = vm.$watch(keyPath, function (newVal) {
clearTimeout(Vue.$gunData.timeout[vm.$options.$gunRootKey+keyPath]); clearTimeout(Vue.$gunData.timeout[vm.$options.$gunRootKey + keyPath]);
Vue.$gunData.timeout[vm.$options.$gunRootKey+keyPath] = setTimeout(function(){ Vue.$gunData.gun.get(vm.$options.$gunRootKey).path(keyPath).put(newVal) },500); Vue.$gunData.timeout[vm.$options.$gunRootKey + keyPath] = setTimeout(function () { Vue.$gunData.gun.get(vm.$options.$gunRootKey).path(keyPath).put(newVal) }, 500);
}); });
}, },
addWatchers: function (obj,keyPath,vm) { addWatchers: function (obj, keyPath, vm) {
if ( keyPath ) keyPath += '.'; if (keyPath) keyPath += '.';
var o = {}, a = obj, ok = Object.keys(a), l = ok.length, k = '', v = ''; var o = {}, a = obj, ok = Object.keys(a), l = ok.length, k = '', v = '';
for ( var i=0; i<l, k=ok[i], v=a[k]; i++ ) { for (var i = 0; i < l, k = ok[i], v = a[k]; i++) {
if ( typeof v == 'object' ) { if (typeof v == 'object') {
this.addWatchers(v,keyPath+k,vm); this.addWatchers(v, keyPath + k, vm);
} else { } else {
// console.log('add watcher',k,v,keyPath+k); // console.log('add watcher',k,v,keyPath+k);
if ( !this.vueWatcher[keyPath+k] ) { if (!this.vueWatcher[keyPath + k]) {
Vue.$gunData.addVueWatcher(keyPath+k,vm); Vue.$gunData.addVueWatcher(keyPath + k, vm);
Vue.$gunData.addGunWatcher(keyPath+k,v,vm); Vue.$gunData.addGunWatcher(keyPath + k, v, vm);
}
} }
} }
} }
} }
Vue.mixin({
data: function() {
var o = {}, a = this.$options.gunData;
this.$options.$gunRootKey = (a._rootKey || window.location.hostname).replace(/\./g,'-');
delete a._rootKey;
for ( var k='',v='',i=0,ok=Object.keys(a),l=ok.length; i<l,k=ok[i],v=a[k]; i++ ) o[k] = v;
return o;
},
created: function() {
Vue.$gunData.addWatchers(this.$options.gunData,'',this)
}
});
} }
Vue.mixin({
data: function () {
var o = {}, a = this.$options.gunData;
this.$options.$gunRootKey = (a._rootKey || window.location.hostname).replace(/\./g, '-');
delete a._rootKey;
for (var k = '', v = '', i = 0, ok = Object.keys(a), l = ok.length; i < l, k = ok[i], v = a[k]; i++) o[k] = v;
return o;
},
created: function () {
Vue.$gunData.addWatchers(this.$options.gunData, '', this)
}
});
} }
}
/********************** SIMPLE NODE GUN SERVER EXAMPLE FOR BACKEND **********************/
// var http = require('http'), Gun = require('gun');
// Gun({ web: http.createServer().listen(8080) });
/********************** MODIFY WITH OUR OWN SERVER ADDRESS **********************/
// Vue.use(GunData, 'http://REPLACE.WITH.YOUR.GUN.SERVER:SERVERPORT/gun');
new Vue({ /********************** SIMPLE NODE GUN SERVER EXAMPLE FOR BACKEND **********************/
el: '#app', // var http = require('http'), Gun = require('gun');
methods: { // Gun({ web: http.createServer().listen(8080) });
addProp () { Vue.set(this.obj,'newProp_'+Object.keys(this.obj).length,'qwerty') }
}, /********************** MODIFY WITH OUR OWN SERVER ADDRESS **********************/
gunData : { // Vue.use(GunData, 'http://REPLACE.WITH.YOUR.GUN.SERVER:SERVERPORT/gun');
// _rootKey: 'put-your-gunDB-root-key-here', // DEFAULTS TO HOSTNAME
test : 'abc', var inst = new Vue({
arr : [1,2], el: '#app',
obj : { a:1 }, methods: {
deepObj: { addProp() { Vue.set(this.obj, 'newProp_' + Object.keys(this.obj).length, 'qwerty') },
level1: { // the prettyJSON code is from icebob https://jsfiddle.net/icebob/0mg1v81e/
arr : [1,2], prettyJSON: function (json) {
prop : 2 if (json) {
} json = JSON.stringify(json, undefined, 4);
json = json.replace(/&/g, '&').replace(/</g, '<').replace( />/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
} }
} }
}); },
</script> gunData: {
</body> // _rootKey: 'put-your-gunDB-root-key-here', // DEFAULTS TO HOSTNAME
</html test: 'abc',
arr: [1, 2],
obj: { a: 1 },
deepObj: {
level1: {
arr: [1, 2],
prop: 2
}
}
}
});
</script>
<style>
pre {
overflow: auto;
}
pre .string {
color: #885800;
}
pre .number {
color: blue;
}
pre .boolean {
color: magenta;
}
pre .null {
color: red;
}
pre .key {
color: green;
}
</style>
</body>
</html>