Merge pull request #11615 from brucejo75/brucejo75/use_callback-hook

use callback-hook package
This commit is contained in:
Jan Dvorak
2021-09-06 18:48:57 +09:00
committed by GitHub
3 changed files with 135 additions and 17 deletions

View File

@@ -29,7 +29,8 @@
* `webapp@1.12`
- npm dependencies have been updated
- Added option to change runtime config in your app, [read more](https://github.com/meteor/meteor/pull/11506)
- Added hook to change runtime config delivered to the client app, [read more](https://github.com/meteor/meteor/pull/11506)
- Added hook to get notified when the app is updated, [read more](https://github.com/meteor/meteor/pull/11607)
- `@vlasky/whomst@0.1.7`
- Added `addUpdateNotifyHook` that gets called when runtime configuration is updated

View File

@@ -35,6 +35,7 @@ Package.onUse(function (api) {
'boilerplate-generator',
'webapp-hashing',
'inter-process-messaging',
'callback-hook'
], 'server');
// At response serving time, webapp uses browser-policy if it is loaded. If

View File

@@ -345,21 +345,35 @@ function getBoilerplate(request, arch) {
return getBoilerplateAsync(request, arch).await();
}
/**
* @summary Takes a runtime configuration object and
* returns an encoded runtime string.
* @locus Server
* @param {Object} rtimeConfig
* @returns {String}
*/
WebApp.encodeRuntimeConfig = function (rtimeConfig) {
return JSON.stringify(encodeURIComponent(JSON.stringify(rtimeConfig)));
}
WebApp.decodeRuntimeConfig = function (rtimeConfig) {
return JSON.parse(decodeURIComponent(JSON.parse(rtimeConfig)));
/**
* @summary Takes an encoded runtime string and returns
* a runtime configuration object.
* @locus Server
* @param {String} rtimeConfigString
* @returns {Object}
*/
WebApp.decodeRuntimeConfig = function (rtimeConfigStr) {
return JSON.parse(decodeURIComponent(JSON.parse(rtimeConfigStr)));
}
const runtimeConfig = {
// hooks will contain the callback functions
// set by the caller to addRuntimeConfigHook
hooks: [],
hooks: new Hook(),
// updateHooks will contain the callback functions
// set by the caller to addUpdatedConfigHook
updateHooks: [],
// set by the caller to addUpdatedNotifyHook
updateHooks: new Hook(),
// isUpdatedByArch is an object containing fields for each arch
// that this server supports.
// - Each field will be true when the server updates the runtimeConfig for that arch.
@@ -371,9 +385,55 @@ WebApp.decodeRuntimeConfig = function (rtimeConfig) {
isUpdatedByArch: {}
};
WebApp.addRuntimeConfigHook = function (hook) {
if(typeof hook !== 'function') throw new Error('WebApp.addRuntimeConfigHook must be a function');
runtimeConfig.hooks.push(hook);
/**
* @name addRuntimeConfigHookCallback(options)
* @locus Server
* @isprototype true
* @summary Callback for `addRuntimeConfigHook`.
*
* If the handler returns a _falsy_ value the hook will not
* modify the runtime configuration.
*
* If the handler returns a _String_ the hook will substitute
* the string for the encoded configuration string.
*
* **Warning:** the hook does not check the return value at all it is
* the responsibility of the caller to get the formatting correct using
* the helper functions.
*
* `addRuntimeConfigHookCallback` takes only one `Object` argument
* with the following fields:
* @param {Object} options
* @param {String} options.arch The architecture of the client
* requesting a new runtime configuration. This can be one of
* `web.browser`, `web.browser.legacy` or `web.cordova`.
* @param {Object} options.request
* A NodeJs [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
* https://nodejs.org/api/http.html#http_class_http_incomingmessage
* `Object` that can be used to get information about the incoming request.
* @param {String} options.encodedCurrentConfig The current configuration object
* encoded as a string for inclusion in the root html.
* @param {Boolean} options.updated `true` if the config for this architecture
* has been updated since last called, otherwise `false`. This flag can be used
* to cache the decoding/encoding for each architecture.
*/
/**
* @summary Hook that calls back when the meteor runtime configuration,
* `__meteor_runtime_config__` is being sent to any client.
*
* **returns**: <small>_Object_</small> `{ stop: function, callback: function }`
* - `stop` <small>_Function_</small> Call `stop()` to stop getting callbacks.
* - `callback` <small>_Function_</small> The passed in `callback`.
* @locus Server
* @param {addRuntimeConfigHookCallback} callback
* See `addRuntimeConfigHookCallback` description.
* @returns {Object} {{ stop: function, callback: function }}
* Call the returned `stop()` to stop getting callbacks.
* The passed in `callback` is returned also.
*/
WebApp.addRuntimeConfigHook = function (callback) {
return runtimeConfig.hooks.register(callback);
}
function getBoilerplateAsync(request, arch) {
@@ -415,14 +475,32 @@ function getBoilerplateAsync(request, arch) {
}));
}
// Notification hook whenever the runtime configuration is updated
// hook will pass an object with the following fields:
// - arch
// - manifest
// - runtimeConfig
WebApp.addUpdatedNotifyHook = function(hook) {
if(typeof hook !== 'function') throw new Error('WebApp.addUpdatedNotifyHook must be a function');
runtimeConfig.updateHooks.push(hook);
/**
* @name addUpdatedNotifyHookCallback(options)
* @summary callback handler for `addupdatedNotifyHook`
* @isprototype true
* @locus Server
* @param {Object} options
* @param {String} options.arch The architecture that is being updated.
* This can be one of `web.browser`, `web.browser.legacy` or `web.cordova`.
* @param {Object} options.manifest The new updated manifest object for
* this `arch`.
* @param {Object} options.runtimeConfig The new updated configuration
* object for this `arch`.
*/
/**
* @summary Hook that runs when the meteor runtime configuration
* is updated. Typically the configuration only changes during development mode.
* @locus Server
* @param {addUpdatedNotifyHookCallback} handler
* The `handler` is called on every change to an `arch` runtime configuration.
* See `addUpdatedNotifyHookCallback`.
* @returns {Object} {{ stop: function, callback: function }}
*/
WebApp.addUpdatedNotifyHook = function(handler) {
return runtimeConfig.updateHooks.register(handler);
}
WebAppInternals.generateBoilerplateInstance = function (arch,
@@ -1032,6 +1110,44 @@ function runWebAppServer() {
// other handlers added by package and application code.
app.use(WebAppInternals.meteorInternalHandlers = connect());
/**
* @name connectHandlersCallback(req, res, next)
* @locus Server
* @isprototype true
* @summary callback handler for `WebApp.connectHandlers`
* @param {Object} req
* a Node.js
* [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
* object with some extra properties. This argument can be used
* to get information about the incoming request.
* @param {Object} res
* a Node.js
* [ServerResponse](http://nodejs.org/api/http.html#http_class_http_serverresponse)
* object. Use this to write data that should be sent in response to the
* request, and call `res.end()` when you are done.
* @param {Function} next
* Calling this function will pass on the handling of
* this request to the next relevant handler.
*
*/
/**
* @method connectHandlers
* @memberof WebApp
* @locus Server
* @summary Register a handler for all HTTP requests.
* @param {String} [path]
* This handler will only be called on paths that match
* this string. The match has to border on a `/` or a `.`.
*
* For example, `/hello` will match `/hello/world` and
* `/hello.world`, but not `/hello_world`.
* @param {connectHandlersCallback} handler
* A handler function that will be called on HTTP requests.
* See `connectHandlersCallback`
*
*/
// Packages and apps can add handlers to this via WebApp.connectHandlers.
// They are inserted before our default handler.
var packageAndAppHandlers = connect();