@odoo/owl 3.0.0-alpha.34 → 3.0.0-alpha.36

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/dist/owl.es.js CHANGED
@@ -569,6 +569,9 @@ function triggerSignal(signal2) {
569
569
  }
570
570
  onWriteAtom(signal2[atomSymbol]);
571
571
  }
572
+ function signalRef() {
573
+ return buildSignal(null, (atom) => atom.value);
574
+ }
572
575
  function signalArray(initialValue) {
573
576
  return buildSignal(initialValue, (atom) => proxifyTarget(atom.value, atom));
574
577
  }
@@ -585,6 +588,7 @@ function signal(value) {
585
588
  return buildSignal(value, (atom) => atom.value);
586
589
  }
587
590
  signal.trigger = triggerSignal;
591
+ signal.ref = signalRef;
588
592
  signal.Array = signalArray;
589
593
  signal.Map = signalMap;
590
594
  signal.Object = signalObject;
@@ -778,33 +782,111 @@ function validateType(value, validation) {
778
782
  validation(createContext(issues, value, []));
779
783
  return issues;
780
784
  }
781
- function anyType() {
782
- return function validateAny() {
785
+ var defaultSymbol = /* @__PURE__ */ Symbol("default");
786
+ var innerTypeSymbol = /* @__PURE__ */ Symbol("innerType");
787
+ var shapeSymbol = /* @__PURE__ */ Symbol("shape");
788
+ var elementTypeSymbol = /* @__PURE__ */ Symbol("elementType");
789
+ var optionalSymbol = /* @__PURE__ */ Symbol("optional");
790
+ function getDefault(type) {
791
+ return typeof type === "function" ? type[defaultSymbol] : void 0;
792
+ }
793
+ function makeOptional(type, value) {
794
+ const validate = function validateOptional(context) {
795
+ if (context.value === void 0) {
796
+ return;
797
+ }
798
+ context.validate(type);
783
799
  };
800
+ validate[optionalSymbol] = true;
801
+ validate[innerTypeSymbol] = type;
802
+ if (value !== void 0) {
803
+ validate[defaultSymbol] = typeof value === "function" ? value : () => value;
804
+ }
805
+ return validate;
806
+ }
807
+ function isOptionalType(type) {
808
+ return typeof type === "function" && optionalSymbol in type;
809
+ }
810
+ function makeType(validate) {
811
+ validate.optional = (value) => makeOptional(validate, value);
812
+ return validate;
813
+ }
814
+ function applyDefaults(value, type) {
815
+ return applyDefaultsRec(value, type);
816
+ }
817
+ function applyDefaultsRec(value, type) {
818
+ if (typeof type !== "function") {
819
+ return value;
820
+ }
821
+ if (value === void 0) {
822
+ const factory = type[defaultSymbol];
823
+ if (!factory) {
824
+ return value;
825
+ }
826
+ value = factory();
827
+ }
828
+ const inner = type[innerTypeSymbol] || type;
829
+ if (typeof inner !== "function" || !value || typeof value !== "object") {
830
+ return value;
831
+ }
832
+ const elementType = inner[elementTypeSymbol];
833
+ if (elementType && Array.isArray(value)) {
834
+ let result2 = value;
835
+ for (let index = 0; index < value.length; index++) {
836
+ const newValue = applyDefaultsRec(value[index], elementType);
837
+ if (newValue !== value[index]) {
838
+ if (result2 === value) {
839
+ result2 = [...value];
840
+ }
841
+ result2[index] = newValue;
842
+ }
843
+ }
844
+ return result2;
845
+ }
846
+ const shape = inner[shapeSymbol];
847
+ if (!shape) {
848
+ return value;
849
+ }
850
+ let result = value;
851
+ for (const key in shape) {
852
+ const subValue = result[key];
853
+ const newValue = applyDefaultsRec(subValue, shape[key]);
854
+ if (newValue !== subValue) {
855
+ if (result === value) {
856
+ result = Array.isArray(value) ? [...value] : { ...value };
857
+ }
858
+ result[key] = newValue;
859
+ }
860
+ }
861
+ return result;
862
+ }
863
+ function anyType() {
864
+ return makeType(function validateAny() {
865
+ });
784
866
  }
785
867
  function booleanType() {
786
- return function validateBoolean(context) {
868
+ return makeType(function validateBoolean(context) {
787
869
  if (typeof context.value !== "boolean") {
788
870
  context.addIssue({ message: "value is not a boolean" });
789
871
  }
790
- };
872
+ });
791
873
  }
792
874
  function numberType() {
793
- return function validateNumber(context) {
875
+ return makeType(function validateNumber(context) {
794
876
  if (typeof context.value !== "number") {
795
877
  context.addIssue({ message: "value is not a number" });
796
878
  }
797
- };
879
+ });
798
880
  }
799
881
  function stringType() {
800
- return function validateString(context) {
882
+ return makeType(function validateString(context) {
801
883
  if (typeof context.value !== "string" && !(context.value instanceof String)) {
802
884
  context.addIssue({ message: "value is not a string" });
803
885
  }
804
- };
886
+ });
805
887
  }
806
888
  function arrayType(elementType) {
807
- return function validateArray(context) {
889
+ const validate = makeType(function validateArray(context) {
808
890
  if (!Array.isArray(context.value)) {
809
891
  context.addIssue({ message: "value is not an array" });
810
892
  return;
@@ -815,17 +897,21 @@ function arrayType(elementType) {
815
897
  for (let index = 0; index < context.value.length; index++) {
816
898
  context.withKey(index).validate(elementType);
817
899
  }
818
- };
900
+ });
901
+ if (elementType) {
902
+ validate[elementTypeSymbol] = elementType;
903
+ }
904
+ return validate;
819
905
  }
820
906
  function constructorType(constructor) {
821
- return function validateConstructor(context) {
907
+ return makeType(function validateConstructor(context) {
822
908
  if (!(typeof context.value === "function") || !(context.value === constructor || context.value.prototype instanceof constructor)) {
823
909
  context.addIssue({ message: `value is not '${constructor.name}' or an extension` });
824
910
  }
825
- };
911
+ });
826
912
  }
827
913
  function customValidator(type, validator, errorMessage = "value does not match custom validation") {
828
- return function validateCustom(context) {
914
+ return makeType(function validateCustom(context) {
829
915
  context.validate(type);
830
916
  if (!context.isValid) {
831
917
  return;
@@ -833,37 +919,37 @@ function customValidator(type, validator, errorMessage = "value does not match c
833
919
  if (!validator(context.value)) {
834
920
  context.addIssue({ message: errorMessage });
835
921
  }
836
- };
922
+ });
837
923
  }
838
924
  function functionType(parameters = [], result = void 0) {
839
- return function validateFunction(context) {
925
+ return makeType(function validateFunction(context) {
840
926
  if (typeof context.value !== "function") {
841
927
  context.addIssue({ message: "value is not a function" });
842
928
  }
843
- };
929
+ });
844
930
  }
845
931
  function instanceType(constructor) {
846
- return function validateInstanceType(context) {
932
+ return makeType(function validateInstanceType(context) {
847
933
  if (!(context.value instanceof constructor)) {
848
934
  context.addIssue({ message: `value is not an instance of '${constructor.name}'` });
849
935
  }
850
- };
936
+ });
851
937
  }
852
938
  function intersection(types22) {
853
- return function validateIntersection(context) {
939
+ return makeType(function validateIntersection(context) {
854
940
  for (const type of types22) {
855
941
  context.validate(type);
856
942
  }
857
- };
943
+ });
858
944
  }
859
945
  function literalType(literal) {
860
- return function validateLiteral(context) {
946
+ return makeType(function validateLiteral(context) {
861
947
  if (context.value !== literal) {
862
948
  context.addIssue({
863
949
  message: `value is not equal to ${typeof literal === "string" ? `'${literal}'` : literal}`
864
950
  });
865
951
  }
866
- };
952
+ });
867
953
  }
868
954
  function literalSelection(literals) {
869
955
  return union(literals.map(literalType));
@@ -891,15 +977,14 @@ function validateObject(context, schema, isStrict) {
891
977
  }
892
978
  const missingKeys = [];
893
979
  for (const key of keys) {
894
- const property = key.endsWith("?") ? key.slice(0, -1) : key;
895
- if (context.value[property] === void 0) {
896
- if (!key.endsWith("?")) {
897
- missingKeys.push(property);
980
+ if (context.value[key] === void 0) {
981
+ if (!isOptionalType(shape[key])) {
982
+ missingKeys.push(key);
898
983
  }
899
984
  continue;
900
985
  }
901
986
  if (isShape) {
902
- context.withKey(property).validate(shape[key]);
987
+ context.withKey(key).validate(shape[key]);
903
988
  }
904
989
  }
905
990
  if (missingKeys.length) {
@@ -912,7 +997,7 @@ function validateObject(context, schema, isStrict) {
912
997
  if (isStrict) {
913
998
  const unknownKeys = [];
914
999
  for (const key in context.value) {
915
- if (!keys.includes(key) && !(`${key}?` in shape)) {
1000
+ if (!keys.includes(key)) {
916
1001
  unknownKeys.push(key);
917
1002
  }
918
1003
  }
@@ -926,24 +1011,32 @@ function validateObject(context, schema, isStrict) {
926
1011
  }
927
1012
  }
928
1013
  function objectType(schema = {}) {
929
- return function validateLooseObject(context) {
1014
+ const validate = makeType(function validateLooseObject(context) {
930
1015
  validateObject(context, schema, false);
931
- };
1016
+ });
1017
+ if (!Array.isArray(schema)) {
1018
+ validate[shapeSymbol] = schema;
1019
+ }
1020
+ return validate;
932
1021
  }
933
1022
  function strictObjectType(schema) {
934
- return function validateStrictObject(context) {
1023
+ const validate = makeType(function validateStrictObject(context) {
935
1024
  validateObject(context, schema, true);
936
- };
1025
+ });
1026
+ if (!Array.isArray(schema)) {
1027
+ validate[shapeSymbol] = schema;
1028
+ }
1029
+ return validate;
937
1030
  }
938
1031
  function promiseType(type) {
939
- return function validatePromise(context) {
1032
+ return makeType(function validatePromise(context) {
940
1033
  if (!(context.value instanceof Promise)) {
941
1034
  context.addIssue({ message: "value is not a promise" });
942
1035
  }
943
- };
1036
+ });
944
1037
  }
945
1038
  function recordType(valueType) {
946
- return function validateRecord(context) {
1039
+ return makeType(function validateRecord(context) {
947
1040
  if (typeof context.value !== "object" || Array.isArray(context.value) || context.value === null) {
948
1041
  context.addIssue({ message: "value is not an object" });
949
1042
  return;
@@ -954,10 +1047,10 @@ function recordType(valueType) {
954
1047
  for (const key in context.value) {
955
1048
  context.withKey(key).validate(valueType);
956
1049
  }
957
- };
1050
+ });
958
1051
  }
959
1052
  function tuple(types22) {
960
- return function validateTuple(context) {
1053
+ const validate = makeType(function validateTuple(context) {
961
1054
  if (!Array.isArray(context.value)) {
962
1055
  context.addIssue({ message: "value is not an array" });
963
1056
  return;
@@ -969,10 +1062,12 @@ function tuple(types22) {
969
1062
  for (let index = 0; index < types22.length; index++) {
970
1063
  context.withKey(index).validate(types22[index]);
971
1064
  }
972
- };
1065
+ });
1066
+ validate[shapeSymbol] = types22;
1067
+ return validate;
973
1068
  }
974
1069
  function union(types22) {
975
- return function validateUnion(context) {
1070
+ return makeType(function validateUnion(context) {
976
1071
  let firstIssueIndex = 0;
977
1072
  const subIssues = [];
978
1073
  for (const type of types22) {
@@ -988,17 +1083,20 @@ function union(types22) {
988
1083
  message: "value does not match union type",
989
1084
  subIssues
990
1085
  });
991
- };
1086
+ });
992
1087
  }
993
1088
  function reactiveValueType(type) {
994
- return function validateReactiveValue(context) {
1089
+ return makeType(function validateReactiveValue(context) {
995
1090
  if (typeof context.value !== "function" || !context.value[atomSymbol]) {
996
1091
  context.addIssue({ message: "value is not a reactive value" });
997
1092
  }
998
- };
1093
+ });
999
1094
  }
1000
1095
  function ref(type) {
1001
- return union([literalType(null), instanceType(type)]);
1096
+ if (typeof HTMLElement === "undefined") {
1097
+ throw new Error("Cannot use ref in a non-DOM environment");
1098
+ }
1099
+ return union([literalType(null), instanceType(type || HTMLElement)]);
1002
1100
  }
1003
1101
  var types = {
1004
1102
  and: intersection,
@@ -1300,7 +1398,7 @@ function plugin(pluginType) {
1300
1398
  }
1301
1399
  return plugin2;
1302
1400
  }
1303
- function config(key, type, defaultValue) {
1401
+ function config(key, type) {
1304
1402
  const scope = useScope();
1305
1403
  if (!(scope instanceof PluginManager)) {
1306
1404
  throw new OwlError("Expected to be in a plugin scope");
@@ -1308,8 +1406,8 @@ function config(key, type, defaultValue) {
1308
1406
  if (scope.app.dev && type) {
1309
1407
  assertType(scope.config, types.object({ [key]: type }), "Config does not match the type");
1310
1408
  }
1311
- const configValue = scope.config[key.endsWith("?") ? key.slice(0, -1) : key];
1312
- return configValue === void 0 ? defaultValue : configValue;
1409
+ const configValue = scope.config[key];
1410
+ return configValue === void 0 ? getDefault(type)?.() : configValue;
1313
1411
  }
1314
1412
  var EventBus = class extends EventTarget {
1315
1413
  trigger(name, payload) {
@@ -1355,7 +1453,7 @@ function markup(valueOrStrings, ...placeholders) {
1355
1453
  }
1356
1454
 
1357
1455
  // ../owl-runtime/dist/owl-runtime.es.js
1358
- var version = "3.0.0-alpha.34";
1456
+ var version = "3.0.0-alpha.36";
1359
1457
  var fibersInError = /* @__PURE__ */ new WeakMap();
1360
1458
  var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
1361
1459
  function invokeErrorHandlers(node, error, finalize, markFibers) {
@@ -4162,12 +4260,12 @@ function onError(callback) {
4162
4260
  }
4163
4261
  handlers.push(callback.bind(scope.component));
4164
4262
  }
4165
- function staticProp(key, type, ...args) {
4263
+ function staticProp(key, type) {
4166
4264
  const node = getComponentScope();
4167
- const hasDefault = args.length > 0;
4265
+ const defaultFactory = getDefault(type);
4168
4266
  const propValue = node.props[key];
4169
4267
  if (node.app.dev) {
4170
- if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
4268
+ if (type !== void 0 && (!defaultFactory || propValue !== void 0)) {
4171
4269
  assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
4172
4270
  }
4173
4271
  node.willUpdateProps.push((nextProps) => {
@@ -4178,37 +4276,32 @@ function staticProp(key, type, ...args) {
4178
4276
  }
4179
4277
  });
4180
4278
  }
4181
- return propValue === void 0 && hasDefault ? args[0] : propValue;
4279
+ return propValue === void 0 && defaultFactory ? defaultFactory() : propValue;
4182
4280
  }
4183
4281
  function componentType() {
4184
4282
  return constructorType(Component);
4185
4283
  }
4186
- var types2 = { ...types, component: componentType };
4187
- function validateDefaults(schema) {
4188
- const validation = {};
4189
- if (Array.isArray(schema)) {
4190
- for (const key of schema) {
4191
- if (key.endsWith("?")) {
4192
- validation[key] = types2.any();
4193
- }
4194
- }
4195
- } else {
4196
- for (const key in schema) {
4197
- if (key.endsWith("?")) {
4198
- validation[key] = schema[key];
4284
+ var types2 = {
4285
+ ...types,
4286
+ component: componentType
4287
+ };
4288
+ function makeProps(type) {
4289
+ const node = getComponentScope();
4290
+ const { app, componentName } = node;
4291
+ let defaults = null;
4292
+ if (type && !Array.isArray(type)) {
4293
+ for (const key in type) {
4294
+ const factory = getDefault(type[key]);
4295
+ if (factory) {
4296
+ (defaults ||= {})[key] = factory();
4199
4297
  }
4200
4298
  }
4201
4299
  }
4202
- return types2.strictObject(validation);
4203
- }
4204
- function makeProps(type, defaults) {
4205
- const node = getComponentScope();
4206
- const { app, componentName } = node;
4207
4300
  if (defaults) {
4208
4301
  node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
4209
4302
  }
4210
4303
  function resolveValue(props2, key) {
4211
- if (props2[key] === void 0 && defaults) {
4304
+ if (props2[key] === void 0 && defaults && key in defaults) {
4212
4305
  return defaults[key];
4213
4306
  }
4214
4307
  return props2[key];
@@ -4234,16 +4327,20 @@ function makeProps(type, defaults) {
4234
4327
  }
4235
4328
  }
4236
4329
  if (type) {
4237
- const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
4238
- (key) => key.endsWith("?") ? key.slice(0, -1) : key
4239
- );
4330
+ const keys = Array.isArray(type) ? type : Object.keys(type);
4240
4331
  defineProps(keys);
4241
4332
  node.propsUpdated.push(() => updateSignals(keys));
4242
4333
  if (app.dev) {
4243
4334
  if (defaults) {
4335
+ const defaultedShape = {};
4336
+ for (const key in type) {
4337
+ if (key in defaults) {
4338
+ defaultedShape[key] = type[key];
4339
+ }
4340
+ }
4244
4341
  assertType(
4245
4342
  defaults,
4246
- validateDefaults(type),
4343
+ types2.object(defaultedShape),
4247
4344
  `Invalid component default props (${componentName})`
4248
4345
  );
4249
4346
  }
@@ -4261,13 +4358,6 @@ function makeProps(type, defaults) {
4261
4358
  keys2.push(k);
4262
4359
  }
4263
4360
  }
4264
- if (defaults) {
4265
- for (const k in defaults) {
4266
- if (!(k in props2)) {
4267
- keys2.push(k);
4268
- }
4269
- }
4270
- }
4271
4361
  return keys2;
4272
4362
  };
4273
4363
  let keys = getKeys(node.props);
@@ -4302,7 +4392,7 @@ var ErrorBoundary = class extends Component {
4302
4392
  <t t-call-slot="default"/>
4303
4393
  </t>
4304
4394
  `;
4305
- props = props({ "error?": types2.signal() }, { error: signal(null) });
4395
+ props = props({ error: types2.signal().optional(() => signal(null)) });
4306
4396
  setup() {
4307
4397
  onError((e) => this.props.error.set(e));
4308
4398
  }
@@ -4363,7 +4453,7 @@ var Suspense = class extends Component {
4363
4453
  <t t-call-slot="fallback"/>
4364
4454
  </t>
4365
4455
  `;
4366
- props = props({ slots: types2.object(["default", "fallback?"]) });
4456
+ props = props({ slots: types2.object({ default: types2.any(), fallback: types2.any().optional() }) });
4367
4457
  prepared = signal(false);
4368
4458
  mounted = signal(false);
4369
4459
  subRootMounted = false;
@@ -4419,8 +4509,8 @@ var blockDom = {
4419
4509
  };
4420
4510
  var __info__ = {
4421
4511
  version: App.version,
4422
- date: "2026-06-05T08:44:38.319Z",
4423
- hash: "3206cf27",
4512
+ date: "2026-06-11T18:30:46.327Z",
4513
+ hash: "eb837019",
4424
4514
  url: "https://github.com/odoo/owl"
4425
4515
  };
4426
4516
 
@@ -6609,6 +6699,7 @@ export {
6609
6699
  Suspense,
6610
6700
  TemplateSet,
6611
6701
  __info__,
6702
+ applyDefaults,
6612
6703
  assertType,
6613
6704
  asyncComputed,
6614
6705
  batched,
@@ -6616,6 +6707,7 @@ export {
6616
6707
  computed,
6617
6708
  config,
6618
6709
  effect,
6710
+ getDefault,
6619
6711
  getScope,
6620
6712
  globalTemplates,
6621
6713
  htmlEscape,
@@ -6636,6 +6728,7 @@ export {
6636
6728
  proxy,
6637
6729
  signal,
6638
6730
  status,
6731
+ types2 as t,
6639
6732
  toRaw,
6640
6733
  types2 as types,
6641
6734
  untrack,