mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Merge branch 'sync-store' into develop
This commit is contained in:
commit
ef79dd95cf
20 changed files with 5019 additions and 189 deletions
File diff suppressed because one or more lines are too long
|
|
@ -15,6 +15,7 @@ import { NewBinding } from './bindings';
|
|||
import { Callback } from './calls';
|
||||
import { AddScript, InjectCSS } from './utils';
|
||||
import { AddIPCListener } from './ipc';
|
||||
import * as Store from './store';
|
||||
|
||||
// Initialise global if not already
|
||||
window.wails = window.wails || {};
|
||||
|
|
@ -42,6 +43,7 @@ var runtime = {
|
|||
Heartbeat,
|
||||
Acknowledge,
|
||||
},
|
||||
Store,
|
||||
_: internal,
|
||||
};
|
||||
|
||||
|
|
|
|||
82
runtime/js/core/store.js
Normal file
82
runtime/js/core/store.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
_ __ _ __
|
||||
| | / /___ _(_) /____
|
||||
| | /| / / __ `/ / / ___/
|
||||
| |/ |/ / /_/ / / (__ )
|
||||
|__/|__/\__,_/_/_/____/
|
||||
The lightweight framework for web-like apps
|
||||
(c) Lea Anthony 2019-present
|
||||
*/
|
||||
/* jshint esversion: 6 */
|
||||
|
||||
/**
|
||||
* Creates a new sync store with the given name and optional default value
|
||||
*
|
||||
* @export
|
||||
* @param {string} name
|
||||
* @param {*} optionalDefault
|
||||
*/
|
||||
export function New(name, optionalDefault) {
|
||||
|
||||
var data;
|
||||
|
||||
// Check we are initialised
|
||||
if( !window.wails) {
|
||||
throw Error('Wails is not initialised');
|
||||
}
|
||||
|
||||
// Store for the callbacks
|
||||
let callbacks = [];
|
||||
|
||||
// Subscribe to updates by providing a callback
|
||||
this.subscribe = (callback) => {
|
||||
callbacks.push(callback);
|
||||
};
|
||||
|
||||
// sets the store data to the provided `newdata` value
|
||||
this.set = (newdata) => {
|
||||
|
||||
data = newdata;
|
||||
|
||||
// Emit a notification to back end
|
||||
window.wails.Events.Emit('wails:sync:store:updatedbyfrontend:'+name, JSON.stringify(data));
|
||||
|
||||
// Notify callbacks
|
||||
callbacks.forEach( function(callback) {
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
|
||||
// update mutates the value in the store by calling the
|
||||
// provided method with the current value. The value returned
|
||||
// by the updater function will be set as the new store value
|
||||
this.update = (updater) => {
|
||||
var newValue = updater(data);
|
||||
this.set(newValue);
|
||||
};
|
||||
|
||||
// Setup event callback
|
||||
window.wails.Events.On('wails:sync:store:updatedbybackend:'+name, function(result) {
|
||||
|
||||
// Parse data
|
||||
result = JSON.parse(result);
|
||||
|
||||
// Todo: Potential preprocessing?
|
||||
|
||||
// Save data
|
||||
data = result;
|
||||
|
||||
// Notify callbacks
|
||||
callbacks.forEach( function(callback) {
|
||||
callback(data);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Set to the optional default if set
|
||||
if( optionalDefault ) {
|
||||
this.set(optionalDefault);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
3916
runtime/js/package-lock.json
generated
3916
runtime/js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,10 +13,12 @@ const Log = require('./log');
|
|||
const Browser = require('./browser');
|
||||
const Events = require('./events');
|
||||
const Init = require('./init');
|
||||
const Store = require('./store');
|
||||
|
||||
module.exports = {
|
||||
Log: Log,
|
||||
Browser: Browser,
|
||||
Events: Events,
|
||||
Init: Init
|
||||
Init: Init,
|
||||
Store: Store,
|
||||
};
|
||||
492
runtime/js/runtime/package-lock.json
generated
Normal file
492
runtime/js/runtime/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
{
|
||||
"name": "@wailsapp/runtime",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
|
||||
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
||||
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||
"dev": true
|
||||
},
|
||||
"dts-dom": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/dts-dom/-/dts-dom-3.6.0.tgz",
|
||||
"integrity": "sha512-on5jxTgt+A6r0Zyyz6ZRHXaAO7J1VPnOd6+AmvI1vH440AlAZZNc5rUHzgPuTjGlrVr1rOWQYNl7ZJK6rDohbw==",
|
||||
"dev": true
|
||||
},
|
||||
"dts-gen": {
|
||||
"version": "0.5.8",
|
||||
"resolved": "https://registry.npmjs.org/dts-gen/-/dts-gen-0.5.8.tgz",
|
||||
"integrity": "sha512-kIAV6dlHaF7r5J+tIuOC1BJls2P72YM0cyWQUR88zcJEpX2ccRZe+HmXLfkkvfPwjvSO3FEqUiyC8On/grx5qw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dts-dom": "^3.6.0",
|
||||
"parse-git-config": "^1.1.1",
|
||||
"typescript": "^3.5.1",
|
||||
"yargs": "^4.8.1"
|
||||
}
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
|
||||
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-exists": "^2.0.0",
|
||||
"pinkie-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fs-exists-sync": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
|
||||
"integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=",
|
||||
"dev": true
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
|
||||
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
|
||||
"dev": true
|
||||
},
|
||||
"git-config-path": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz",
|
||||
"integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"fs-exists-sync": "^0.1.0",
|
||||
"homedir-polyfill": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"homedir-polyfill": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parse-passwd": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
|
||||
"dev": true
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
||||
"dev": true
|
||||
},
|
||||
"is-extendable": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"is-utf8": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
||||
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
||||
"dev": true
|
||||
},
|
||||
"lcid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
||||
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"invert-kv": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
||||
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"parse-json": "^2.2.0",
|
||||
"pify": "^2.0.0",
|
||||
"pinkie-promise": "^2.0.0",
|
||||
"strip-bom": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
|
||||
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hosted-git-info": "^2.1.4",
|
||||
"resolve": "^1.10.0",
|
||||
"semver": "2 || 3 || 4 || 5",
|
||||
"validate-npm-package-license": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
|
||||
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lcid": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"parse-git-config": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz",
|
||||
"integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"fs-exists-sync": "^0.1.0",
|
||||
"git-config-path": "^1.0.1",
|
||||
"ini": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
|
||||
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"error-ex": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"parse-passwd": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
|
||||
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pinkie-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-type": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
||||
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"pify": "^2.0.0",
|
||||
"pinkie-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
||||
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
|
||||
"dev": true
|
||||
},
|
||||
"pinkie-promise": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
|
||||
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"load-json-file": "^1.0.0",
|
||||
"normalize-package-data": "^2.3.2",
|
||||
"path-type": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"read-pkg-up": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
|
||||
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"find-up": "^1.0.0",
|
||||
"read-pkg": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-correct": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
|
||||
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-expression-parse": "^3.0.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
|
||||
"dev": true
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
|
||||
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"spdx-license-ids": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
|
||||
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
||||
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-utf8": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.9.7",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
|
||||
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
|
||||
"dev": true
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"spdx-correct": "^3.0.0",
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
|
||||
"integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
|
||||
"dev": true
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
|
||||
"integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
|
||||
"integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^3.2.0",
|
||||
"decamelize": "^1.1.1",
|
||||
"get-caller-file": "^1.0.1",
|
||||
"lodash.assign": "^4.0.3",
|
||||
"os-locale": "^1.4.0",
|
||||
"read-pkg-up": "^1.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^1.0.1",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"which-module": "^1.0.0",
|
||||
"window-size": "^0.2.0",
|
||||
"y18n": "^3.2.1",
|
||||
"yargs-parser": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
|
||||
"integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^3.0.0",
|
||||
"lodash.assign": "^4.0.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@wailsapp/runtime",
|
||||
"version": "1.0.11",
|
||||
"version": "1.1.0",
|
||||
"description": "Wails Javascript runtime library",
|
||||
"main": "main.js",
|
||||
"types": "runtime.d.ts",
|
||||
|
|
@ -25,4 +25,4 @@
|
|||
"devDependencies": {
|
||||
"dts-gen": "^0.5.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
runtime/js/runtime/runtime.d.ts
vendored
3
runtime/js/runtime/runtime.d.ts
vendored
|
|
@ -21,6 +21,9 @@ declare const wailsapp__runtime: {
|
|||
Info(message: string): void;
|
||||
Warning(message: string): void;
|
||||
};
|
||||
Store: {
|
||||
New(name: string, optionalDefault?: any): any;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
27
runtime/js/runtime/store.js
Normal file
27
runtime/js/runtime/store.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
_ __ _ __
|
||||
| | / /___ _(_) /____
|
||||
| | /| / / __ `/ / / ___/
|
||||
| |/ |/ / /_/ / / (__ )
|
||||
|__/|__/\__,_/_/_/____/
|
||||
The lightweight framework for web-like apps
|
||||
(c) Lea Anthony 2019-present
|
||||
*/
|
||||
|
||||
/* jshint esversion: 6 */
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Store with the given name and optional default value
|
||||
*
|
||||
* @export
|
||||
* @param {string} name
|
||||
* @param {*} optionalDefault
|
||||
*/
|
||||
function New(name, optionalDefault) {
|
||||
return window.wails.Store.New(name, optionalDefault);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
New: New,
|
||||
};
|
||||
29
runtime/runtime.go
Normal file
29
runtime/runtime.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package runtime
|
||||
|
||||
import "github.com/wailsapp/wails/lib/interfaces"
|
||||
|
||||
// Runtime is the Wails Runtime Interface, given to a user who has defined the WailsInit method
|
||||
type Runtime struct {
|
||||
Events *Events
|
||||
Log *Log
|
||||
Dialog *Dialog
|
||||
Window *Window
|
||||
Browser *Browser
|
||||
FileSystem *FileSystem
|
||||
Store *StoreProvider
|
||||
}
|
||||
|
||||
// NewRuntime creates a new Runtime struct
|
||||
func NewRuntime(eventManager interfaces.EventManager, renderer interfaces.Renderer) *Runtime {
|
||||
result := &Runtime{
|
||||
Events: NewEvents(eventManager),
|
||||
Log: NewLog(),
|
||||
Dialog: NewDialog(renderer),
|
||||
Window: NewWindow(renderer),
|
||||
Browser: NewBrowser(),
|
||||
FileSystem: NewFileSystem(),
|
||||
}
|
||||
// We need a reference to itself
|
||||
result.Store = NewStoreProvider(result)
|
||||
return result
|
||||
}
|
||||
248
runtime/store.go
Normal file
248
runtime/store.go
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
// Package runtime contains all the methods and data structures related to the
|
||||
// runtime library of Wails. This includes both Go and JS runtimes.
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Options defines the optional data that may be used
|
||||
// when creating a Store
|
||||
type Options struct {
|
||||
|
||||
// The name of the store
|
||||
Name string
|
||||
|
||||
// The runtime to attach the store to
|
||||
Runtime *Runtime
|
||||
|
||||
// Indicates if notifying Go listeners should be notified of updates
|
||||
// synchronously (on the current thread) or asynchronously using
|
||||
// goroutines
|
||||
NotifySynchronously bool
|
||||
}
|
||||
|
||||
// StoreProvider is a struct that creates Stores
|
||||
type StoreProvider struct {
|
||||
runtime *Runtime
|
||||
}
|
||||
|
||||
// NewStoreProvider creates new stores using the provided Runtime reference.
|
||||
func NewStoreProvider(runtime *Runtime) *StoreProvider {
|
||||
return &StoreProvider{
|
||||
runtime: runtime,
|
||||
}
|
||||
}
|
||||
|
||||
// Store is where we keep named data
|
||||
type Store struct {
|
||||
name string
|
||||
data reflect.Value
|
||||
dataType reflect.Type
|
||||
eventPrefix string
|
||||
callbacks []func(interface{})
|
||||
runtime *Runtime
|
||||
notifySynchronously bool
|
||||
|
||||
// Lock
|
||||
mux sync.Mutex
|
||||
|
||||
// Error handler
|
||||
errorHandler func(error)
|
||||
}
|
||||
|
||||
// New creates a new store
|
||||
func (p *StoreProvider) New(name string, defaultValue interface{}) *Store {
|
||||
|
||||
dataType := reflect.TypeOf(defaultValue)
|
||||
|
||||
result := Store{
|
||||
name: name,
|
||||
runtime: p.runtime,
|
||||
data: reflect.ValueOf(defaultValue),
|
||||
dataType: dataType,
|
||||
}
|
||||
|
||||
// Setup the sync listener
|
||||
result.setupListener()
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
// OnError takes a function that will be called
|
||||
// whenever an error occurs
|
||||
func (s *Store) OnError(callback func(error)) {
|
||||
s.errorHandler = callback
|
||||
}
|
||||
|
||||
// Processes the updates sent by the front end
|
||||
func (s *Store) processUpdatedData(data string) error {
|
||||
|
||||
// Decode incoming data
|
||||
var rawdata json.RawMessage
|
||||
d := json.NewDecoder(bytes.NewBufferString(data))
|
||||
err := d.Decode(&rawdata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create a new instance of our data and unmarshal
|
||||
// the received value into it
|
||||
newData := reflect.New(s.dataType).Interface()
|
||||
err = json.Unmarshal(rawdata, &newData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lock mutex for writing
|
||||
s.mux.Lock()
|
||||
|
||||
// Handle nulls
|
||||
if newData == nil {
|
||||
s.data = reflect.Zero(s.dataType)
|
||||
} else {
|
||||
// Store the resultant value in the data store
|
||||
s.data = reflect.ValueOf(newData).Elem()
|
||||
}
|
||||
|
||||
// Unlock mutex
|
||||
s.mux.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setup listener for front end changes
|
||||
func (s *Store) setupListener() {
|
||||
|
||||
// Listen for updates from the front end
|
||||
s.runtime.Events.On("wails:sync:store:updatedbyfrontend:"+s.name, func(data ...interface{}) {
|
||||
|
||||
// Process the incoming data
|
||||
err := s.processUpdatedData(data[0].(string))
|
||||
|
||||
if err != nil {
|
||||
if s.errorHandler != nil {
|
||||
s.errorHandler(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Notify listeners
|
||||
s.notify()
|
||||
})
|
||||
}
|
||||
|
||||
// notify the listeners of the current data state
|
||||
func (s *Store) notify() {
|
||||
|
||||
// Execute callbacks
|
||||
for _, callback := range s.callbacks {
|
||||
|
||||
if s.notifySynchronously {
|
||||
callback(s.data)
|
||||
} else {
|
||||
go callback(s.data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Set will update the data held by the store
|
||||
// and notify listeners of the change
|
||||
func (s *Store) Set(data interface{}) error {
|
||||
|
||||
inType := reflect.TypeOf(data)
|
||||
|
||||
if inType != s.dataType {
|
||||
return fmt.Errorf("invalid data given in Store.Set(). Expected %s, got %s", s.dataType.String(), inType.String())
|
||||
}
|
||||
|
||||
// Save data
|
||||
s.mux.Lock()
|
||||
s.data = reflect.ValueOf(data)
|
||||
s.mux.Unlock()
|
||||
|
||||
// Stringify data
|
||||
newdata, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
if s.errorHandler != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Emit event to front end
|
||||
s.runtime.Events.Emit("wails:sync:store:updatedbybackend:"+s.name, string(newdata))
|
||||
|
||||
// Notify subscribers
|
||||
s.notify()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Subscribe will subscribe to updates to the store by
|
||||
// providing a callback. Any updates to the store are sent
|
||||
// to the callback
|
||||
func (s *Store) Subscribe(callback func(interface{})) {
|
||||
s.callbacks = append(s.callbacks, callback)
|
||||
}
|
||||
|
||||
// updaterCheck ensures the given function to Update() is
|
||||
// of the correct signature. Absolutely cannot wait for
|
||||
// generics to land rather than writing this nonsense.
|
||||
func (s *Store) updaterCheck(updater interface{}) error {
|
||||
|
||||
// Get type
|
||||
updaterType := reflect.TypeOf(updater)
|
||||
|
||||
// Check updater is a function
|
||||
if updaterType.Kind() != reflect.Func {
|
||||
return fmt.Errorf("invalid value given to store.Update(). Expected 'func(%s) %s'", s.dataType.String(), s.dataType.String())
|
||||
}
|
||||
|
||||
// Check input param
|
||||
if updaterType.NumIn() != 1 {
|
||||
return fmt.Errorf("invalid number of parameters given in updater function. Expected 1")
|
||||
}
|
||||
|
||||
// Check input data type
|
||||
if updaterType.In(0) != s.dataType {
|
||||
return fmt.Errorf("invalid type for input parameter given in updater function. Expected %s, got %s", s.dataType.String(), updaterType.In(0))
|
||||
}
|
||||
|
||||
// Check output param
|
||||
if updaterType.NumOut() != 1 {
|
||||
return fmt.Errorf("invalid number of return parameters given in updater function. Expected 1")
|
||||
}
|
||||
|
||||
// Check output data type
|
||||
if updaterType.Out(0) != s.dataType {
|
||||
return fmt.Errorf("invalid type for return parameter given in updater function. Expected %s, got %s", s.dataType.String(), updaterType.Out(0))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update takes a function that is passed the current state.
|
||||
// The result of that function is then set as the new state
|
||||
// of the store. This will notify listeners of the change
|
||||
func (s *Store) Update(updater interface{}) {
|
||||
|
||||
err := s.updaterCheck(updater)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Build args
|
||||
args := []reflect.Value{s.data}
|
||||
|
||||
// Make call
|
||||
results := reflect.ValueOf(updater).Call(args)
|
||||
|
||||
// We will only have 1 result. Set the store to it
|
||||
s.Set(results[0].Interface())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue