Skip to content

Commit

Permalink
[REL] v2.4.0
Browse files Browse the repository at this point in the history
# v2.4.0

 - [IMP] owl: add basic support for sub roots
 - [IMP] make set of timeout-able hooks (and their timeouts) clearer by using a const map
 - [IMP] devtools: add support for file urls on chrome
  • Loading branch information
rfr-odoo committed Sep 30, 2024
1 parent eb2b32a commit 20c6cac
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 38 deletions.
107 changes: 72 additions & 35 deletions docs/owl.js
Original file line number Diff line number Diff line change
Expand Up @@ -2598,42 +2598,47 @@ class ComponentNode {
}

const TIMEOUT = Symbol("timeout");
const HOOK_TIMEOUT = {
onWillStart: 3000,
onWillUpdateProps: 3000,
};
function wrapError(fn, hookName) {
const error = new OwlError(`The following error occurred in ${hookName}: `);
const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`);
const error = new OwlError();
const timeoutError = new OwlError();
const node = getCurrent();
return (...args) => {
const onError = (cause) => {
error.cause = cause;
if (cause instanceof Error) {
error.message += `"${cause.message}"`;
}
else {
error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
}
error.message =
cause instanceof Error
? `The following error occurred in ${hookName}: "${cause.message}"`
: `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`;
throw error;
};
let result;
try {
const result = fn(...args);
if (result instanceof Promise) {
if (hookName === "onWillStart" || hookName === "onWillUpdateProps") {
const fiber = node.fiber;
Promise.race([
result.catch(() => { }),
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
console.log(timeoutError);
}
});
}
return result.catch(onError);
}
return result;
result = fn(...args);
}
catch (cause) {
onError(cause);
}
if (!(result instanceof Promise)) {
return result;
}
const timeout = HOOK_TIMEOUT[hookName];
if (timeout) {
const fiber = node.fiber;
Promise.race([
result.catch(() => { }),
new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), timeout)),
]).then((res) => {
if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) {
timeoutError.message = `${hookName}'s promise hasn't resolved after ${timeout / 1000} seconds`;
console.log(timeoutError);
}
});
}
return result.catch(onError);
};
}
// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -5552,7 +5557,7 @@ function compile(template, options = {}) {
}

// do not modify manually. This file is generated by the release script.
const version = "2.3.1";
const version = "2.4.0";

// -----------------------------------------------------------------------------
// Scheduler
Expand Down Expand Up @@ -5647,6 +5652,7 @@ class App extends TemplateSet {
constructor(Root, config = {}) {
super(config);
this.scheduler = new Scheduler();
this.subRoots = new Set();
this.root = null;
this.name = config.name || "";
this.Root = Root;
Expand All @@ -5665,14 +5671,42 @@ class App extends TemplateSet {
this.props = config.props || {};
}
mount(target, options) {
App.validateTarget(target);
if (this.dev) {
validateProps(this.Root, this.props, { __owl__: { app: this } });
}
const node = this.makeNode(this.Root, this.props);
const prom = this.mountNode(node, target, options);
this.root = node;
return prom;
const root = this.createRoot(this.Root, { props: this.props });
this.root = root.node;
this.subRoots.delete(root.node);
return root.mount(target, options);
}
createRoot(Root, config = {}) {
const props = config.props || {};
// hack to make sure the sub root get the sub env if necessary. for owl 3,
// would be nice to rethink the initialization process to make sure that
// we can create a ComponentNode and give it explicitely the env, instead
// of looking it up in the app
const env = this.env;
if (config.env) {
this.env = config.env;
}
const node = this.makeNode(Root, props);
if (config.env) {
this.env = env;
}
this.subRoots.add(node);
return {
node,
mount: (target, options) => {
App.validateTarget(target);
if (this.dev) {
validateProps(Root, props, { __owl__: { app: this } });
}
const prom = this.mountNode(node, target, options);
return prom;
},
destroy: () => {
this.subRoots.delete(node);
node.destroy();
this.scheduler.processTasks();
},
};
}
makeNode(Component, props) {
return new ComponentNode(Component, props, this, null, null);
Expand Down Expand Up @@ -5704,6 +5738,9 @@ class App extends TemplateSet {
}
destroy() {
if (this.root) {
for (let subroot of this.subRoots) {
subroot.destroy();
}
this.root.destroy();
this.scheduler.processTasks();
}
Expand Down Expand Up @@ -5981,6 +6018,6 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
export { App, Component, EventBus, OwlError, __info__, batched, blockDom, loadFile, markRaw, markup, mount, onError, onMounted, onPatched, onRendered, onWillDestroy, onWillPatch, onWillRender, onWillStart, onWillUnmount, onWillUpdateProps, reactive, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, validate, validateType, whenReady, xml };


__info__.date = '2024-08-14T14:25:23.038Z';
__info__.hash = '9c2d957';
__info__.date = '2024-09-30T08:49:29.420Z';
__info__.hash = 'eb2b32a';
__info__.url = 'https://github.com/odoo/owl';
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@odoo/owl",
"version": "2.3.1",
"version": "2.4.0",
"description": "Odoo Web Library (OWL)",
"main": "dist/owl.cjs.js",
"module": "dist/owl.es.js",
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// do not modify manually. This file is generated by the release script.
export const version = "2.3.1";
export const version = "2.4.0";

0 comments on commit 20c6cac

Please sign in to comment.