ethstats-server/web-app/.meteor/local/build/programs/server/packages/autoupdate.js

238 lines
18 KiB
JavaScript

(function () {
/* Imports */
var Meteor = Package.meteor.Meteor;
var WebApp = Package.webapp.WebApp;
var main = Package.webapp.main;
var WebAppInternals = Package.webapp.WebAppInternals;
var DDP = Package.ddp.DDP;
var DDPServer = Package.ddp.DDPServer;
var MongoInternals = Package.mongo.MongoInternals;
var Mongo = Package.mongo.Mongo;
var _ = Package.underscore._;
/* Package-scope variables */
var Autoupdate, ClientVersions;
(function () {
//////////////////////////////////////////////////////////////////////////////////
// //
// packages/autoupdate/autoupdate_server.js //
// //
//////////////////////////////////////////////////////////////////////////////////
//
// Publish the current client versions to the client. When a client // 1
// sees the subscription change and that there is a new version of the // 2
// client available on the server, it can reload. // 3
// // 4
// By default there are two current client versions. The refreshable client // 5
// version is identified by a hash of the client resources seen by the browser // 6
// that are refreshable, such as CSS, while the non refreshable client version // 7
// is identified by a hash of the rest of the client assets // 8
// (the HTML, code, and static files in the `public` directory). // 9
// // 10
// If the environment variable `AUTOUPDATE_VERSION` is set it will be // 11
// used as the client id instead. You can use this to control when // 12
// the client reloads. For example, if you want to only force a // 13
// reload on major changes, you can use a custom AUTOUPDATE_VERSION // 14
// which you only change when something worth pushing to clients // 15
// immediately happens. // 16
// // 17
// The server publishes a `meteor_autoupdate_clientVersions` // 18
// collection. There are two documents in this collection, a document // 19
// with _id 'version' which represnets the non refreshable client assets, // 20
// and a document with _id 'version-refreshable' which represents the // 21
// refreshable client assets. Each document has a 'version' field // 22
// which is equivalent to the hash of the relevant assets. The refreshable // 23
// document also contains a list of the refreshable assets, so that the client // 24
// can swap in the new assets without forcing a page refresh. Clients can // 25
// observe changes on these documents to detect when there is a new // 26
// version available. // 27
// // 28
// In this implementation only two documents are present in the collection // 29
// the current refreshable client version and the current nonRefreshable client // 30
// version. Developers can easily experiment with different versioning and // 31
// updating models by forking this package. // 32
// 33
var Future = Npm.require("fibers/future"); // 34
// 35
Autoupdate = {}; // 36
// 37
// The collection of acceptable client versions. // 38
ClientVersions = new Mongo.Collection("meteor_autoupdate_clientVersions", // 39
{ connection: null }); // 40
// 41
// The client hash includes __meteor_runtime_config__, so wait until // 42
// all packages have loaded and have had a chance to populate the // 43
// runtime config before using the client hash as our default auto // 44
// update version id. // 45
// 46
// Note: Tests allow people to override Autoupdate.autoupdateVersion before // 47
// startup. // 48
Autoupdate.autoupdateVersion = null; // 49
Autoupdate.autoupdateVersionRefreshable = null; // 50
Autoupdate.autoupdateVersionCordova = null; // 51
Autoupdate.appId = __meteor_runtime_config__.appId = process.env.APP_ID; // 52
// 53
var syncQueue = new Meteor._SynchronousQueue(); // 54
// 55
// updateVersions can only be called after the server has fully loaded. // 56
var updateVersions = function (shouldReloadClientProgram) { // 57
// Step 1: load the current client program on the server and update the // 58
// hash values in __meteor_runtime_config__. // 59
if (shouldReloadClientProgram) { // 60
WebAppInternals.reloadClientPrograms(); // 61
} // 62
// 63
// If we just re-read the client program, or if we don't have an autoupdate // 64
// version, calculate it. // 65
if (shouldReloadClientProgram || Autoupdate.autoupdateVersion === null) { // 66
Autoupdate.autoupdateVersion = // 67
process.env.AUTOUPDATE_VERSION || // 68
WebApp.calculateClientHashNonRefreshable(); // 69
} // 70
// If we just recalculated it OR if it was set by (eg) test-in-browser, // 71
// ensure it ends up in __meteor_runtime_config__. // 72
__meteor_runtime_config__.autoupdateVersion = // 73
Autoupdate.autoupdateVersion; // 74
// 75
Autoupdate.autoupdateVersionRefreshable = // 76
__meteor_runtime_config__.autoupdateVersionRefreshable = // 77
process.env.AUTOUPDATE_VERSION || // 78
WebApp.calculateClientHashRefreshable(); // 79
// 80
Autoupdate.autoupdateVersionCordova = // 81
__meteor_runtime_config__.autoupdateVersionCordova = // 82
process.env.AUTOUPDATE_VERSION || // 83
WebApp.calculateClientHashCordova(); // 84
// 85
// Step 2: form the new client boilerplate which contains the updated // 86
// assets and __meteor_runtime_config__. // 87
if (shouldReloadClientProgram) { // 88
WebAppInternals.generateBoilerplate(); // 89
} // 90
// 91
// XXX COMPAT WITH 0.8.3 // 92
if (! ClientVersions.findOne({current: true})) { // 93
// To ensure apps with version of Meteor prior to 0.9.0 (in // 94
// which the structure of documents in `ClientVersions` was // 95
// different) also reload. // 96
ClientVersions.insert({current: true}); // 97
} // 98
// 99
if (! ClientVersions.findOne({_id: "version"})) { // 100
ClientVersions.insert({ // 101
_id: "version", // 102
version: Autoupdate.autoupdateVersion // 103
}); // 104
} else { // 105
ClientVersions.update("version", { $set: { // 106
version: Autoupdate.autoupdateVersion // 107
}}); // 108
} // 109
// 110
if (! ClientVersions.findOne({_id: "version-cordova"})) { // 111
ClientVersions.insert({ // 112
_id: "version-cordova", // 113
version: Autoupdate.autoupdateVersionCordova, // 114
refreshable: false // 115
}); // 116
} else { // 117
ClientVersions.update("version-cordova", { $set: { // 118
version: Autoupdate.autoupdateVersionCordova // 119
}}); // 120
} // 121
// 122
// Use `onListening` here because we need to use // 123
// `WebAppInternals.refreshableAssets`, which is only set after // 124
// `WebApp.generateBoilerplate` is called by `main` in webapp. // 125
WebApp.onListening(function () { // 126
if (! ClientVersions.findOne({_id: "version-refreshable"})) { // 127
ClientVersions.insert({ // 128
_id: "version-refreshable", // 129
version: Autoupdate.autoupdateVersionRefreshable, // 130
assets: WebAppInternals.refreshableAssets // 131
}); // 132
} else { // 133
ClientVersions.update("version-refreshable", { $set: { // 134
version: Autoupdate.autoupdateVersionRefreshable, // 135
assets: WebAppInternals.refreshableAssets // 136
}}); // 137
} // 138
}); // 139
}; // 140
// 141
Meteor.publish( // 142
"meteor_autoupdate_clientVersions", // 143
function (appId) { // 144
// `null` happens when a client doesn't have an appId and passes // 145
// `undefined` to `Meteor.subscribe`. `undefined` is translated to // 146
// `null` as JSON doesn't have `undefined. // 147
check(appId, Match.OneOf(String, undefined, null)); // 148
// 149
// Don't notify clients using wrong appId such as mobile apps built with a // 150
// different server but pointing at the same local url // 151
if (Autoupdate.appId && appId && Autoupdate.appId !== appId) // 152
return []; // 153
// 154
return ClientVersions.find(); // 155
}, // 156
{is_auto: true} // 157
); // 158
// 159
Meteor.startup(function () { // 160
updateVersions(false); // 161
}); // 162
// 163
var fut = new Future(); // 164
// 165
// We only want 'refresh' to trigger 'updateVersions' AFTER onListen, // 166
// so we add a queued task that waits for onListen before 'refresh' can queue // 167
// tasks. Note that the `onListening` callbacks do not fire until after // 168
// Meteor.startup, so there is no concern that the 'updateVersions' calls from // 169
// 'refresh' will overlap with the `updateVersions` call from Meteor.startup. // 170
// 171
syncQueue.queueTask(function () { // 172
fut.wait(); // 173
}); // 174
// 175
WebApp.onListening(function () { // 176
fut.return(); // 177
}); // 178
// 179
var enqueueVersionsRefresh = function () { // 180
syncQueue.queueTask(function () { // 181
updateVersions(true); // 182
}); // 183
}; // 184
// 185
// Listen for the special {refresh: 'client'} message, which signals that a // 186
// client asset has changed. // 187
process.on('message', Meteor.bindEnvironment(function (m) { // 188
if (m && m.refresh === 'client') { // 189
enqueueVersionsRefresh(); // 190
} // 191
})); // 192
// 193
// Another way to tell the process to refresh: send SIGHUP signal // 194
process.on('SIGHUP', Meteor.bindEnvironment(function () { // 195
enqueueVersionsRefresh(); // 196
})); // 197
// 198
// 199
//////////////////////////////////////////////////////////////////////////////////
}).call(this);
/* Exports */
if (typeof Package === 'undefined') Package = {};
Package.autoupdate = {
Autoupdate: Autoupdate
};
})();
//# sourceMappingURL=autoupdate.js.map