@odoo/owl 2.0.9 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -113,6 +113,7 @@ Are you new to Owl? This is the place to start!
113
113
  - [Why did Odoo build Owl?](doc/miscellaneous/why_owl.md)
114
114
  - [Changelog (from owl 1.x to 2.x)](CHANGELOG.md)
115
115
  - [Notes on compiled templates](doc/miscellaneous/compiled_template.md)
116
+ - [Owl devtools extension](doc/tools/devtools.md)
116
117
 
117
118
  ## Installing Owl
118
119
 
@@ -121,8 +122,28 @@ Owl is available on `npm` and can be installed with the following command:
121
122
  ```
122
123
  npm install @odoo/owl
123
124
  ```
124
-
125
125
  If you want to use a simple `<script>` tag, the last release can be downloaded here:
126
126
 
127
127
  - [owl](https://github.com/odoo/owl/releases/latest)
128
128
 
129
+ ## Installing Owl devtools
130
+
131
+ The Owl devtools browser extension is also available in the [release](https://github.com/odoo/owl/releases/latest):
132
+ Unzip the owl-devtools.zip file and follow the instructions depending on your browser:
133
+
134
+ ### Chrome
135
+
136
+ Go to your chrome extensions admin panel, activate developer mode and click on `Load unpacked`.
137
+ Select the devtools-chrome folder and that's it, your extension is active!
138
+ There is a convenient refresh button on the extension card (still on the same admin page) to update your code.
139
+ Do note that if you got some problems, you may need to completly remove and reload the extension to completly refresh the extension.
140
+
141
+ ### Firefox
142
+ Go to the address about:debugging#/runtime/this-firefox and click on `Load temporary Add-on...`.
143
+ Select any file in the devtools-firefox folder and that's it, your extension is active!
144
+ Here, you can use the reload button to refresh the extension.
145
+
146
+ Note that you may have to open another window or reload your tab to see the extension working.
147
+ Also note that the extension will only be active on pages that have a sufficient version of owl.
148
+
149
+
Binary file
package/dist/owl.cjs.js CHANGED
@@ -282,6 +282,96 @@ function updateClass(val, oldVal) {
282
282
  }
283
283
  }
284
284
 
285
+ /**
286
+ * Creates a batched version of a callback so that all calls to it in the same
287
+ * microtick will only call the original callback once.
288
+ *
289
+ * @param callback the callback to batch
290
+ * @returns a batched version of the original callback
291
+ */
292
+ function batched(callback) {
293
+ let called = false;
294
+ return async () => {
295
+ // This await blocks all calls to the callback here, then releases them sequentially
296
+ // in the next microtick. This line decides the granularity of the batch.
297
+ await Promise.resolve();
298
+ if (!called) {
299
+ called = true;
300
+ // wait for all calls in this microtick to fall through before resetting "called"
301
+ // so that only the first call to the batched function calls the original callback.
302
+ // Schedule this before calling the callback so that calls to the batched function
303
+ // within the callback will proceed only after resetting called to false, and have
304
+ // a chance to execute the callback again
305
+ Promise.resolve().then(() => (called = false));
306
+ callback();
307
+ }
308
+ };
309
+ }
310
+ /**
311
+ * Determine whether the given element is contained in its ownerDocument:
312
+ * either directly or with a shadow root in between.
313
+ */
314
+ function inOwnerDocument(el) {
315
+ if (!el) {
316
+ return false;
317
+ }
318
+ if (el.ownerDocument.contains(el)) {
319
+ return true;
320
+ }
321
+ const rootNode = el.getRootNode();
322
+ return rootNode instanceof ShadowRoot && el.ownerDocument.contains(rootNode.host);
323
+ }
324
+ function validateTarget(target) {
325
+ // Get the document and HTMLElement corresponding to the target to allow mounting in iframes
326
+ const document = target && target.ownerDocument;
327
+ if (document) {
328
+ const HTMLElement = document.defaultView.HTMLElement;
329
+ if (target instanceof HTMLElement || target instanceof ShadowRoot) {
330
+ if (!document.body.contains(target instanceof HTMLElement ? target : target.host)) {
331
+ throw new OwlError("Cannot mount a component on a detached dom node");
332
+ }
333
+ return;
334
+ }
335
+ }
336
+ throw new OwlError("Cannot mount component: the target is not a valid DOM element");
337
+ }
338
+ class EventBus extends EventTarget {
339
+ trigger(name, payload) {
340
+ this.dispatchEvent(new CustomEvent(name, { detail: payload }));
341
+ }
342
+ }
343
+ function whenReady(fn) {
344
+ return new Promise(function (resolve) {
345
+ if (document.readyState !== "loading") {
346
+ resolve(true);
347
+ }
348
+ else {
349
+ document.addEventListener("DOMContentLoaded", resolve, false);
350
+ }
351
+ }).then(fn || function () { });
352
+ }
353
+ async function loadFile(url) {
354
+ const result = await fetch(url);
355
+ if (!result.ok) {
356
+ throw new OwlError("Error while fetching xml templates");
357
+ }
358
+ return await result.text();
359
+ }
360
+ /*
361
+ * This class just transports the fact that a string is safe
362
+ * to be injected as HTML. Overriding a JS primitive is quite painful though
363
+ * so we need to redfine toString and valueOf.
364
+ */
365
+ class Markup extends String {
366
+ }
367
+ /*
368
+ * Marks a value as safe, that is, a value that can be injected as HTML directly.
369
+ * It should be used to wrap the value passed to a t-out directive to allow a raw rendering.
370
+ */
371
+ function markup(value) {
372
+ return new Markup(value);
373
+ }
374
+
285
375
  function createEventHandler(rawEvent) {
286
376
  const eventName = rawEvent.split(".")[0];
287
377
  const capture = rawEvent.includes(".capture");
@@ -301,7 +391,7 @@ function createElementHandler(evName, capture = false) {
301
391
  }
302
392
  function listener(ev) {
303
393
  const currentTarget = ev.currentTarget;
304
- if (!currentTarget || !currentTarget.ownerDocument.contains(currentTarget))
394
+ if (!currentTarget || !inOwnerDocument(currentTarget))
305
395
  return;
306
396
  const data = currentTarget[eventKey];
307
397
  if (!data)
@@ -2166,82 +2256,6 @@ function collectionsProxyHandler(target, callback, targetRawType) {
2166
2256
  });
2167
2257
  }
2168
2258
 
2169
- /**
2170
- * Creates a batched version of a callback so that all calls to it in the same
2171
- * microtick will only call the original callback once.
2172
- *
2173
- * @param callback the callback to batch
2174
- * @returns a batched version of the original callback
2175
- */
2176
- function batched(callback) {
2177
- let called = false;
2178
- return async () => {
2179
- // This await blocks all calls to the callback here, then releases them sequentially
2180
- // in the next microtick. This line decides the granularity of the batch.
2181
- await Promise.resolve();
2182
- if (!called) {
2183
- called = true;
2184
- // wait for all calls in this microtick to fall through before resetting "called"
2185
- // so that only the first call to the batched function calls the original callback.
2186
- // Schedule this before calling the callback so that calls to the batched function
2187
- // within the callback will proceed only after resetting called to false, and have
2188
- // a chance to execute the callback again
2189
- Promise.resolve().then(() => (called = false));
2190
- callback();
2191
- }
2192
- };
2193
- }
2194
- function validateTarget(target) {
2195
- // Get the document and HTMLElement corresponding to the target to allow mounting in iframes
2196
- const document = target && target.ownerDocument;
2197
- if (document) {
2198
- const HTMLElement = document.defaultView.HTMLElement;
2199
- if (target instanceof HTMLElement) {
2200
- if (!document.body.contains(target)) {
2201
- throw new OwlError("Cannot mount a component on a detached dom node");
2202
- }
2203
- return;
2204
- }
2205
- }
2206
- throw new OwlError("Cannot mount component: the target is not a valid DOM element");
2207
- }
2208
- class EventBus extends EventTarget {
2209
- trigger(name, payload) {
2210
- this.dispatchEvent(new CustomEvent(name, { detail: payload }));
2211
- }
2212
- }
2213
- function whenReady(fn) {
2214
- return new Promise(function (resolve) {
2215
- if (document.readyState !== "loading") {
2216
- resolve(true);
2217
- }
2218
- else {
2219
- document.addEventListener("DOMContentLoaded", resolve, false);
2220
- }
2221
- }).then(fn || function () { });
2222
- }
2223
- async function loadFile(url) {
2224
- const result = await fetch(url);
2225
- if (!result.ok) {
2226
- throw new OwlError("Error while fetching xml templates");
2227
- }
2228
- return await result.text();
2229
- }
2230
- /*
2231
- * This class just transports the fact that a string is safe
2232
- * to be injected as HTML. Overriding a JS primitive is quite painful though
2233
- * so we need to redfine toString and valueOf.
2234
- */
2235
- class Markup extends String {
2236
- }
2237
- /*
2238
- * Marks a value as safe, that is, a value that can be injected as HTML directly.
2239
- * It should be used to wrap the value passed to a t-out directive to allow a raw rendering.
2240
- */
2241
- function markup(value) {
2242
- return new Markup(value);
2243
- }
2244
-
2245
2259
  let currentNode = null;
2246
2260
  function getCurrent() {
2247
2261
  if (!currentNode) {
@@ -2293,6 +2307,7 @@ class ComponentNode {
2293
2307
  this.bdom = null;
2294
2308
  this.status = 0 /* NEW */;
2295
2309
  this.forceNextRender = false;
2310
+ this.nextProps = null;
2296
2311
  this.children = Object.create(null);
2297
2312
  this.refs = {};
2298
2313
  this.willStart = [];
@@ -2422,7 +2437,7 @@ class ComponentNode {
2422
2437
  this.status = 2 /* DESTROYED */;
2423
2438
  }
2424
2439
  async updateAndRender(props, parentFiber) {
2425
- const rawProps = props;
2440
+ this.nextProps = props;
2426
2441
  props = Object.assign({}, props);
2427
2442
  // update
2428
2443
  const fiber = makeChildFiber(this, parentFiber);
@@ -2446,7 +2461,6 @@ class ComponentNode {
2446
2461
  return;
2447
2462
  }
2448
2463
  component.props = props;
2449
- this.props = rawProps;
2450
2464
  fiber.render();
2451
2465
  const parentRoot = parentFiber.root;
2452
2466
  if (this.willPatch.length) {
@@ -2521,6 +2535,7 @@ class ComponentNode {
2521
2535
  // by the component will be patched independently in the appropriate
2522
2536
  // fiber.complete
2523
2537
  this._patch();
2538
+ this.props = this.nextProps;
2524
2539
  }
2525
2540
  }
2526
2541
  _patch() {
@@ -2871,14 +2886,27 @@ function validateType(key, value, descr) {
2871
2886
  if ("element" in descr) {
2872
2887
  result = validateArrayType(key, value, descr.element);
2873
2888
  }
2874
- else if ("shape" in descr && !result) {
2889
+ else if ("shape" in descr) {
2875
2890
  if (typeof value !== "object" || Array.isArray(value)) {
2876
2891
  result = `'${key}' is not an object`;
2877
2892
  }
2878
2893
  else {
2879
2894
  const errors = validateSchema(value, descr.shape);
2880
2895
  if (errors.length) {
2881
- result = `'${key}' has not the correct shape (${errors.join(", ")})`;
2896
+ result = `'${key}' doesn't have the correct shape (${errors.join(", ")})`;
2897
+ }
2898
+ }
2899
+ }
2900
+ else if ("values" in descr) {
2901
+ if (typeof value !== "object" || Array.isArray(value)) {
2902
+ result = `'${key}' is not an object`;
2903
+ }
2904
+ else {
2905
+ const errors = Object.entries(value)
2906
+ .map(([key, value]) => validateType(key, value, descr.values))
2907
+ .filter(Boolean);
2908
+ if (errors.length) {
2909
+ result = `some of the values in '${key}' are invalid (${errors.join(", ")})`;
2882
2910
  }
2883
2911
  }
2884
2912
  }
@@ -5481,8 +5509,8 @@ function compile(template, options = {}) {
5481
5509
  return new Function("app, bdom, helpers", code);
5482
5510
  }
5483
5511
 
5484
- // do not modify manually. This value is updated by the release script.
5485
- const version = "2.0.9";
5512
+ // do not modify manually. This file is generated by the release script.
5513
+ const version = "2.1.1";
5486
5514
 
5487
5515
  // -----------------------------------------------------------------------------
5488
5516
  // Scheduler
@@ -5775,7 +5803,7 @@ function useRef(name) {
5775
5803
  return {
5776
5804
  get el() {
5777
5805
  const el = refs[name];
5778
- return (el === null || el === void 0 ? void 0 : el.ownerDocument.contains(el)) ? el : null;
5806
+ return inOwnerDocument(el) ? el : null;
5779
5807
  },
5780
5808
  };
5781
5809
  }
@@ -5925,10 +5953,11 @@ exports.useRef = useRef;
5925
5953
  exports.useState = useState;
5926
5954
  exports.useSubEnv = useSubEnv;
5927
5955
  exports.validate = validate;
5956
+ exports.validateType = validateType;
5928
5957
  exports.whenReady = whenReady;
5929
5958
  exports.xml = xml;
5930
5959
 
5931
5960
 
5932
- __info__.date = '2023-03-13T09:55:19.784Z';
5933
- __info__.hash = '8893e02';
5961
+ __info__.date = '2023-04-17T09:09:34.568Z';
5962
+ __info__.hash = '4b9e6ba';
5934
5963
  __info__.url = 'https://github.com/odoo/owl';
package/dist/owl.es.js CHANGED
@@ -278,6 +278,96 @@ function updateClass(val, oldVal) {
278
278
  }
279
279
  }
280
280
 
281
+ /**
282
+ * Creates a batched version of a callback so that all calls to it in the same
283
+ * microtick will only call the original callback once.
284
+ *
285
+ * @param callback the callback to batch
286
+ * @returns a batched version of the original callback
287
+ */
288
+ function batched(callback) {
289
+ let called = false;
290
+ return async () => {
291
+ // This await blocks all calls to the callback here, then releases them sequentially
292
+ // in the next microtick. This line decides the granularity of the batch.
293
+ await Promise.resolve();
294
+ if (!called) {
295
+ called = true;
296
+ // wait for all calls in this microtick to fall through before resetting "called"
297
+ // so that only the first call to the batched function calls the original callback.
298
+ // Schedule this before calling the callback so that calls to the batched function
299
+ // within the callback will proceed only after resetting called to false, and have
300
+ // a chance to execute the callback again
301
+ Promise.resolve().then(() => (called = false));
302
+ callback();
303
+ }
304
+ };
305
+ }
306
+ /**
307
+ * Determine whether the given element is contained in its ownerDocument:
308
+ * either directly or with a shadow root in between.
309
+ */
310
+ function inOwnerDocument(el) {
311
+ if (!el) {
312
+ return false;
313
+ }
314
+ if (el.ownerDocument.contains(el)) {
315
+ return true;
316
+ }
317
+ const rootNode = el.getRootNode();
318
+ return rootNode instanceof ShadowRoot && el.ownerDocument.contains(rootNode.host);
319
+ }
320
+ function validateTarget(target) {
321
+ // Get the document and HTMLElement corresponding to the target to allow mounting in iframes
322
+ const document = target && target.ownerDocument;
323
+ if (document) {
324
+ const HTMLElement = document.defaultView.HTMLElement;
325
+ if (target instanceof HTMLElement || target instanceof ShadowRoot) {
326
+ if (!document.body.contains(target instanceof HTMLElement ? target : target.host)) {
327
+ throw new OwlError("Cannot mount a component on a detached dom node");
328
+ }
329
+ return;
330
+ }
331
+ }
332
+ throw new OwlError("Cannot mount component: the target is not a valid DOM element");
333
+ }
334
+ class EventBus extends EventTarget {
335
+ trigger(name, payload) {
336
+ this.dispatchEvent(new CustomEvent(name, { detail: payload }));
337
+ }
338
+ }
339
+ function whenReady(fn) {
340
+ return new Promise(function (resolve) {
341
+ if (document.readyState !== "loading") {
342
+ resolve(true);
343
+ }
344
+ else {
345
+ document.addEventListener("DOMContentLoaded", resolve, false);
346
+ }
347
+ }).then(fn || function () { });
348
+ }
349
+ async function loadFile(url) {
350
+ const result = await fetch(url);
351
+ if (!result.ok) {
352
+ throw new OwlError("Error while fetching xml templates");
353
+ }
354
+ return await result.text();
355
+ }
356
+ /*
357
+ * This class just transports the fact that a string is safe
358
+ * to be injected as HTML. Overriding a JS primitive is quite painful though
359
+ * so we need to redfine toString and valueOf.
360
+ */
361
+ class Markup extends String {
362
+ }
363
+ /*
364
+ * Marks a value as safe, that is, a value that can be injected as HTML directly.
365
+ * It should be used to wrap the value passed to a t-out directive to allow a raw rendering.
366
+ */
367
+ function markup(value) {
368
+ return new Markup(value);
369
+ }
370
+
281
371
  function createEventHandler(rawEvent) {
282
372
  const eventName = rawEvent.split(".")[0];
283
373
  const capture = rawEvent.includes(".capture");
@@ -297,7 +387,7 @@ function createElementHandler(evName, capture = false) {
297
387
  }
298
388
  function listener(ev) {
299
389
  const currentTarget = ev.currentTarget;
300
- if (!currentTarget || !currentTarget.ownerDocument.contains(currentTarget))
390
+ if (!currentTarget || !inOwnerDocument(currentTarget))
301
391
  return;
302
392
  const data = currentTarget[eventKey];
303
393
  if (!data)
@@ -2162,82 +2252,6 @@ function collectionsProxyHandler(target, callback, targetRawType) {
2162
2252
  });
2163
2253
  }
2164
2254
 
2165
- /**
2166
- * Creates a batched version of a callback so that all calls to it in the same
2167
- * microtick will only call the original callback once.
2168
- *
2169
- * @param callback the callback to batch
2170
- * @returns a batched version of the original callback
2171
- */
2172
- function batched(callback) {
2173
- let called = false;
2174
- return async () => {
2175
- // This await blocks all calls to the callback here, then releases them sequentially
2176
- // in the next microtick. This line decides the granularity of the batch.
2177
- await Promise.resolve();
2178
- if (!called) {
2179
- called = true;
2180
- // wait for all calls in this microtick to fall through before resetting "called"
2181
- // so that only the first call to the batched function calls the original callback.
2182
- // Schedule this before calling the callback so that calls to the batched function
2183
- // within the callback will proceed only after resetting called to false, and have
2184
- // a chance to execute the callback again
2185
- Promise.resolve().then(() => (called = false));
2186
- callback();
2187
- }
2188
- };
2189
- }
2190
- function validateTarget(target) {
2191
- // Get the document and HTMLElement corresponding to the target to allow mounting in iframes
2192
- const document = target && target.ownerDocument;
2193
- if (document) {
2194
- const HTMLElement = document.defaultView.HTMLElement;
2195
- if (target instanceof HTMLElement) {
2196
- if (!document.body.contains(target)) {
2197
- throw new OwlError("Cannot mount a component on a detached dom node");
2198
- }
2199
- return;
2200
- }
2201
- }
2202
- throw new OwlError("Cannot mount component: the target is not a valid DOM element");
2203
- }
2204
- class EventBus extends EventTarget {
2205
- trigger(name, payload) {
2206
- this.dispatchEvent(new CustomEvent(name, { detail: payload }));
2207
- }
2208
- }
2209
- function whenReady(fn) {
2210
- return new Promise(function (resolve) {
2211
- if (document.readyState !== "loading") {
2212
- resolve(true);
2213
- }
2214
- else {
2215
- document.addEventListener("DOMContentLoaded", resolve, false);
2216
- }
2217
- }).then(fn || function () { });
2218
- }
2219
- async function loadFile(url) {
2220
- const result = await fetch(url);
2221
- if (!result.ok) {
2222
- throw new OwlError("Error while fetching xml templates");
2223
- }
2224
- return await result.text();
2225
- }
2226
- /*
2227
- * This class just transports the fact that a string is safe
2228
- * to be injected as HTML. Overriding a JS primitive is quite painful though
2229
- * so we need to redfine toString and valueOf.
2230
- */
2231
- class Markup extends String {
2232
- }
2233
- /*
2234
- * Marks a value as safe, that is, a value that can be injected as HTML directly.
2235
- * It should be used to wrap the value passed to a t-out directive to allow a raw rendering.
2236
- */
2237
- function markup(value) {
2238
- return new Markup(value);
2239
- }
2240
-
2241
2255
  let currentNode = null;
2242
2256
  function getCurrent() {
2243
2257
  if (!currentNode) {
@@ -2289,6 +2303,7 @@ class ComponentNode {
2289
2303
  this.bdom = null;
2290
2304
  this.status = 0 /* NEW */;
2291
2305
  this.forceNextRender = false;
2306
+ this.nextProps = null;
2292
2307
  this.children = Object.create(null);
2293
2308
  this.refs = {};
2294
2309
  this.willStart = [];
@@ -2418,7 +2433,7 @@ class ComponentNode {
2418
2433
  this.status = 2 /* DESTROYED */;
2419
2434
  }
2420
2435
  async updateAndRender(props, parentFiber) {
2421
- const rawProps = props;
2436
+ this.nextProps = props;
2422
2437
  props = Object.assign({}, props);
2423
2438
  // update
2424
2439
  const fiber = makeChildFiber(this, parentFiber);
@@ -2442,7 +2457,6 @@ class ComponentNode {
2442
2457
  return;
2443
2458
  }
2444
2459
  component.props = props;
2445
- this.props = rawProps;
2446
2460
  fiber.render();
2447
2461
  const parentRoot = parentFiber.root;
2448
2462
  if (this.willPatch.length) {
@@ -2517,6 +2531,7 @@ class ComponentNode {
2517
2531
  // by the component will be patched independently in the appropriate
2518
2532
  // fiber.complete
2519
2533
  this._patch();
2534
+ this.props = this.nextProps;
2520
2535
  }
2521
2536
  }
2522
2537
  _patch() {
@@ -2867,14 +2882,27 @@ function validateType(key, value, descr) {
2867
2882
  if ("element" in descr) {
2868
2883
  result = validateArrayType(key, value, descr.element);
2869
2884
  }
2870
- else if ("shape" in descr && !result) {
2885
+ else if ("shape" in descr) {
2871
2886
  if (typeof value !== "object" || Array.isArray(value)) {
2872
2887
  result = `'${key}' is not an object`;
2873
2888
  }
2874
2889
  else {
2875
2890
  const errors = validateSchema(value, descr.shape);
2876
2891
  if (errors.length) {
2877
- result = `'${key}' has not the correct shape (${errors.join(", ")})`;
2892
+ result = `'${key}' doesn't have the correct shape (${errors.join(", ")})`;
2893
+ }
2894
+ }
2895
+ }
2896
+ else if ("values" in descr) {
2897
+ if (typeof value !== "object" || Array.isArray(value)) {
2898
+ result = `'${key}' is not an object`;
2899
+ }
2900
+ else {
2901
+ const errors = Object.entries(value)
2902
+ .map(([key, value]) => validateType(key, value, descr.values))
2903
+ .filter(Boolean);
2904
+ if (errors.length) {
2905
+ result = `some of the values in '${key}' are invalid (${errors.join(", ")})`;
2878
2906
  }
2879
2907
  }
2880
2908
  }
@@ -5477,8 +5505,8 @@ function compile(template, options = {}) {
5477
5505
  return new Function("app, bdom, helpers", code);
5478
5506
  }
5479
5507
 
5480
- // do not modify manually. This value is updated by the release script.
5481
- const version = "2.0.9";
5508
+ // do not modify manually. This file is generated by the release script.
5509
+ const version = "2.1.1";
5482
5510
 
5483
5511
  // -----------------------------------------------------------------------------
5484
5512
  // Scheduler
@@ -5771,7 +5799,7 @@ function useRef(name) {
5771
5799
  return {
5772
5800
  get el() {
5773
5801
  const el = refs[name];
5774
- return (el === null || el === void 0 ? void 0 : el.ownerDocument.contains(el)) ? el : null;
5802
+ return inOwnerDocument(el) ? el : null;
5775
5803
  },
5776
5804
  };
5777
5805
  }
@@ -5889,9 +5917,9 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
5889
5917
  });
5890
5918
  };
5891
5919
 
5892
- export { App, Component, EventBus, OwlError, __info__, 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, whenReady, xml };
5920
+ export { App, Component, EventBus, OwlError, __info__, 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 };
5893
5921
 
5894
5922
 
5895
- __info__.date = '2023-03-13T09:55:19.784Z';
5896
- __info__.hash = '8893e02';
5923
+ __info__.date = '2023-04-17T09:09:34.568Z';
5924
+ __info__.hash = '4b9e6ba';
5897
5925
  __info__.url = 'https://github.com/odoo/owl';