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

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,123 @@ 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 hasDefaultValue(type) {
794
+ return typeof type === "function" && defaultSymbol in type;
795
+ }
796
+ function withDefault(type, value) {
797
+ const validate = function validateWithDefault(context) {
798
+ if (context.value === void 0) {
799
+ return;
800
+ }
801
+ context.validate(type);
802
+ };
803
+ validate[defaultSymbol] = typeof value === "function" ? value : () => value;
804
+ validate[innerTypeSymbol] = type;
805
+ return validate;
806
+ }
807
+ function makeOptional(type) {
808
+ const validate = function validateOptional(context) {
809
+ if (context.value === void 0) {
810
+ return;
811
+ }
812
+ context.validate(type);
783
813
  };
814
+ validate[optionalSymbol] = true;
815
+ validate[innerTypeSymbol] = type;
816
+ return validate;
817
+ }
818
+ function isOptionalType(type) {
819
+ return typeof type === "function" && optionalSymbol in type;
820
+ }
821
+ function makeType(validate) {
822
+ validate.default = (value) => withDefault(validate, value);
823
+ validate.optional = () => makeOptional(validate);
824
+ return validate;
825
+ }
826
+ function applyDefaults(value, type) {
827
+ return applyDefaultsRec(value, type);
828
+ }
829
+ function applyDefaultsRec(value, type) {
830
+ if (typeof type !== "function") {
831
+ return value;
832
+ }
833
+ if (value === void 0) {
834
+ const factory = type[defaultSymbol];
835
+ if (!factory) {
836
+ return value;
837
+ }
838
+ value = factory();
839
+ }
840
+ const inner = type[innerTypeSymbol] || type;
841
+ if (typeof inner !== "function" || !value || typeof value !== "object") {
842
+ return value;
843
+ }
844
+ const elementType = inner[elementTypeSymbol];
845
+ if (elementType && Array.isArray(value)) {
846
+ let result2 = value;
847
+ for (let index = 0; index < value.length; index++) {
848
+ const newValue = applyDefaultsRec(value[index], elementType);
849
+ if (newValue !== value[index]) {
850
+ if (result2 === value) {
851
+ result2 = [...value];
852
+ }
853
+ result2[index] = newValue;
854
+ }
855
+ }
856
+ return result2;
857
+ }
858
+ const shape = inner[shapeSymbol];
859
+ if (!shape) {
860
+ return value;
861
+ }
862
+ let result = value;
863
+ for (const key in shape) {
864
+ const subValue = result[key];
865
+ const newValue = applyDefaultsRec(subValue, shape[key]);
866
+ if (newValue !== subValue) {
867
+ if (result === value) {
868
+ result = Array.isArray(value) ? [...value] : { ...value };
869
+ }
870
+ result[key] = newValue;
871
+ }
872
+ }
873
+ return result;
874
+ }
875
+ function anyType() {
876
+ return makeType(function validateAny() {
877
+ });
784
878
  }
785
879
  function booleanType() {
786
- return function validateBoolean(context) {
880
+ return makeType(function validateBoolean(context) {
787
881
  if (typeof context.value !== "boolean") {
788
882
  context.addIssue({ message: "value is not a boolean" });
789
883
  }
790
- };
884
+ });
791
885
  }
792
886
  function numberType() {
793
- return function validateNumber(context) {
887
+ return makeType(function validateNumber(context) {
794
888
  if (typeof context.value !== "number") {
795
889
  context.addIssue({ message: "value is not a number" });
796
890
  }
797
- };
891
+ });
798
892
  }
799
893
  function stringType() {
800
- return function validateString(context) {
894
+ return makeType(function validateString(context) {
801
895
  if (typeof context.value !== "string" && !(context.value instanceof String)) {
802
896
  context.addIssue({ message: "value is not a string" });
803
897
  }
804
- };
898
+ });
805
899
  }
806
900
  function arrayType(elementType) {
807
- return function validateArray(context) {
901
+ const validate = makeType(function validateArray(context) {
808
902
  if (!Array.isArray(context.value)) {
809
903
  context.addIssue({ message: "value is not an array" });
810
904
  return;
@@ -815,17 +909,21 @@ function arrayType(elementType) {
815
909
  for (let index = 0; index < context.value.length; index++) {
816
910
  context.withKey(index).validate(elementType);
817
911
  }
818
- };
912
+ });
913
+ if (elementType) {
914
+ validate[elementTypeSymbol] = elementType;
915
+ }
916
+ return validate;
819
917
  }
820
918
  function constructorType(constructor) {
821
- return function validateConstructor(context) {
919
+ return makeType(function validateConstructor(context) {
822
920
  if (!(typeof context.value === "function") || !(context.value === constructor || context.value.prototype instanceof constructor)) {
823
921
  context.addIssue({ message: `value is not '${constructor.name}' or an extension` });
824
922
  }
825
- };
923
+ });
826
924
  }
827
925
  function customValidator(type, validator, errorMessage = "value does not match custom validation") {
828
- return function validateCustom(context) {
926
+ return makeType(function validateCustom(context) {
829
927
  context.validate(type);
830
928
  if (!context.isValid) {
831
929
  return;
@@ -833,37 +931,37 @@ function customValidator(type, validator, errorMessage = "value does not match c
833
931
  if (!validator(context.value)) {
834
932
  context.addIssue({ message: errorMessage });
835
933
  }
836
- };
934
+ });
837
935
  }
838
936
  function functionType(parameters = [], result = void 0) {
839
- return function validateFunction(context) {
937
+ return makeType(function validateFunction(context) {
840
938
  if (typeof context.value !== "function") {
841
939
  context.addIssue({ message: "value is not a function" });
842
940
  }
843
- };
941
+ });
844
942
  }
845
943
  function instanceType(constructor) {
846
- return function validateInstanceType(context) {
944
+ return makeType(function validateInstanceType(context) {
847
945
  if (!(context.value instanceof constructor)) {
848
946
  context.addIssue({ message: `value is not an instance of '${constructor.name}'` });
849
947
  }
850
- };
948
+ });
851
949
  }
852
950
  function intersection(types22) {
853
- return function validateIntersection(context) {
951
+ return makeType(function validateIntersection(context) {
854
952
  for (const type of types22) {
855
953
  context.validate(type);
856
954
  }
857
- };
955
+ });
858
956
  }
859
957
  function literalType(literal) {
860
- return function validateLiteral(context) {
958
+ return makeType(function validateLiteral(context) {
861
959
  if (context.value !== literal) {
862
960
  context.addIssue({
863
961
  message: `value is not equal to ${typeof literal === "string" ? `'${literal}'` : literal}`
864
962
  });
865
963
  }
866
- };
964
+ });
867
965
  }
868
966
  function literalSelection(literals) {
869
967
  return union(literals.map(literalType));
@@ -891,15 +989,14 @@ function validateObject(context, schema, isStrict) {
891
989
  }
892
990
  const missingKeys = [];
893
991
  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);
992
+ if (context.value[key] === void 0) {
993
+ if (!isOptionalType(shape[key]) && !hasDefaultValue(shape[key])) {
994
+ missingKeys.push(key);
898
995
  }
899
996
  continue;
900
997
  }
901
998
  if (isShape) {
902
- context.withKey(property).validate(shape[key]);
999
+ context.withKey(key).validate(shape[key]);
903
1000
  }
904
1001
  }
905
1002
  if (missingKeys.length) {
@@ -912,7 +1009,7 @@ function validateObject(context, schema, isStrict) {
912
1009
  if (isStrict) {
913
1010
  const unknownKeys = [];
914
1011
  for (const key in context.value) {
915
- if (!keys.includes(key) && !(`${key}?` in shape)) {
1012
+ if (!keys.includes(key)) {
916
1013
  unknownKeys.push(key);
917
1014
  }
918
1015
  }
@@ -926,24 +1023,32 @@ function validateObject(context, schema, isStrict) {
926
1023
  }
927
1024
  }
928
1025
  function objectType(schema = {}) {
929
- return function validateLooseObject(context) {
1026
+ const validate = makeType(function validateLooseObject(context) {
930
1027
  validateObject(context, schema, false);
931
- };
1028
+ });
1029
+ if (!Array.isArray(schema)) {
1030
+ validate[shapeSymbol] = schema;
1031
+ }
1032
+ return validate;
932
1033
  }
933
1034
  function strictObjectType(schema) {
934
- return function validateStrictObject(context) {
1035
+ const validate = makeType(function validateStrictObject(context) {
935
1036
  validateObject(context, schema, true);
936
- };
1037
+ });
1038
+ if (!Array.isArray(schema)) {
1039
+ validate[shapeSymbol] = schema;
1040
+ }
1041
+ return validate;
937
1042
  }
938
1043
  function promiseType(type) {
939
- return function validatePromise(context) {
1044
+ return makeType(function validatePromise(context) {
940
1045
  if (!(context.value instanceof Promise)) {
941
1046
  context.addIssue({ message: "value is not a promise" });
942
1047
  }
943
- };
1048
+ });
944
1049
  }
945
1050
  function recordType(valueType) {
946
- return function validateRecord(context) {
1051
+ return makeType(function validateRecord(context) {
947
1052
  if (typeof context.value !== "object" || Array.isArray(context.value) || context.value === null) {
948
1053
  context.addIssue({ message: "value is not an object" });
949
1054
  return;
@@ -954,10 +1059,10 @@ function recordType(valueType) {
954
1059
  for (const key in context.value) {
955
1060
  context.withKey(key).validate(valueType);
956
1061
  }
957
- };
1062
+ });
958
1063
  }
959
1064
  function tuple(types22) {
960
- return function validateTuple(context) {
1065
+ const validate = makeType(function validateTuple(context) {
961
1066
  if (!Array.isArray(context.value)) {
962
1067
  context.addIssue({ message: "value is not an array" });
963
1068
  return;
@@ -969,10 +1074,12 @@ function tuple(types22) {
969
1074
  for (let index = 0; index < types22.length; index++) {
970
1075
  context.withKey(index).validate(types22[index]);
971
1076
  }
972
- };
1077
+ });
1078
+ validate[shapeSymbol] = types22;
1079
+ return validate;
973
1080
  }
974
1081
  function union(types22) {
975
- return function validateUnion(context) {
1082
+ return makeType(function validateUnion(context) {
976
1083
  let firstIssueIndex = 0;
977
1084
  const subIssues = [];
978
1085
  for (const type of types22) {
@@ -988,17 +1095,20 @@ function union(types22) {
988
1095
  message: "value does not match union type",
989
1096
  subIssues
990
1097
  });
991
- };
1098
+ });
992
1099
  }
993
1100
  function reactiveValueType(type) {
994
- return function validateReactiveValue(context) {
1101
+ return makeType(function validateReactiveValue(context) {
995
1102
  if (typeof context.value !== "function" || !context.value[atomSymbol]) {
996
1103
  context.addIssue({ message: "value is not a reactive value" });
997
1104
  }
998
- };
1105
+ });
999
1106
  }
1000
1107
  function ref(type) {
1001
- return union([literalType(null), instanceType(type)]);
1108
+ if (typeof HTMLElement === "undefined") {
1109
+ throw new Error("Cannot use ref in a non-DOM environment");
1110
+ }
1111
+ return union([literalType(null), instanceType(type || HTMLElement)]);
1002
1112
  }
1003
1113
  var types = {
1004
1114
  and: intersection,
@@ -1300,7 +1410,7 @@ function plugin(pluginType) {
1300
1410
  }
1301
1411
  return plugin2;
1302
1412
  }
1303
- function config(key, type, defaultValue) {
1413
+ function config(key, type) {
1304
1414
  const scope = useScope();
1305
1415
  if (!(scope instanceof PluginManager)) {
1306
1416
  throw new OwlError("Expected to be in a plugin scope");
@@ -1308,8 +1418,8 @@ function config(key, type, defaultValue) {
1308
1418
  if (scope.app.dev && type) {
1309
1419
  assertType(scope.config, types.object({ [key]: type }), "Config does not match the type");
1310
1420
  }
1311
- const configValue = scope.config[key.endsWith("?") ? key.slice(0, -1) : key];
1312
- return configValue === void 0 ? defaultValue : configValue;
1421
+ const configValue = scope.config[key];
1422
+ return configValue === void 0 ? getDefault(type)?.() : configValue;
1313
1423
  }
1314
1424
  var EventBus = class extends EventTarget {
1315
1425
  trigger(name, payload) {
@@ -1355,7 +1465,7 @@ function markup(valueOrStrings, ...placeholders) {
1355
1465
  }
1356
1466
 
1357
1467
  // ../owl-runtime/dist/owl-runtime.es.js
1358
- var version = "3.0.0-alpha.34";
1468
+ var version = "3.0.0-alpha.35";
1359
1469
  var fibersInError = /* @__PURE__ */ new WeakMap();
1360
1470
  var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
1361
1471
  function invokeErrorHandlers(node, error, finalize, markFibers) {
@@ -3546,7 +3656,7 @@ var Component = class {
3546
3656
  }
3547
3657
  };
3548
3658
  var ObjectCreate = Object.create;
3549
- function withDefault(value, defaultValue) {
3659
+ function withDefault2(value, defaultValue) {
3550
3660
  return value === void 0 || value === null || value === false ? defaultValue : value;
3551
3661
  }
3552
3662
  function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
@@ -3832,7 +3942,7 @@ function callTemplate(subTemplate, owner, app, ctx, parent, key) {
3832
3942
  return toggler(subTemplate, template.call(owner, ctx, parent, key + subTemplate));
3833
3943
  }
3834
3944
  var helpers = {
3835
- withDefault,
3945
+ withDefault: withDefault2,
3836
3946
  zero: /* @__PURE__ */ Symbol("zero"),
3837
3947
  callSlot,
3838
3948
  withKey,
@@ -4162,12 +4272,12 @@ function onError(callback) {
4162
4272
  }
4163
4273
  handlers.push(callback.bind(scope.component));
4164
4274
  }
4165
- function staticProp(key, type, ...args) {
4275
+ function staticProp(key, type) {
4166
4276
  const node = getComponentScope();
4167
- const hasDefault = args.length > 0;
4277
+ const defaultFactory = getDefault(type);
4168
4278
  const propValue = node.props[key];
4169
4279
  if (node.app.dev) {
4170
- if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
4280
+ if (type !== void 0 && (!defaultFactory || propValue !== void 0)) {
4171
4281
  assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
4172
4282
  }
4173
4283
  node.willUpdateProps.push((nextProps) => {
@@ -4178,37 +4288,32 @@ function staticProp(key, type, ...args) {
4178
4288
  }
4179
4289
  });
4180
4290
  }
4181
- return propValue === void 0 && hasDefault ? args[0] : propValue;
4291
+ return propValue === void 0 && defaultFactory ? defaultFactory() : propValue;
4182
4292
  }
4183
4293
  function componentType() {
4184
4294
  return constructorType(Component);
4185
4295
  }
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];
4296
+ var types2 = {
4297
+ ...types,
4298
+ component: componentType
4299
+ };
4300
+ function makeProps(type) {
4301
+ const node = getComponentScope();
4302
+ const { app, componentName } = node;
4303
+ let defaults = null;
4304
+ if (type && !Array.isArray(type)) {
4305
+ for (const key in type) {
4306
+ const factory = getDefault(type[key]);
4307
+ if (factory) {
4308
+ (defaults ||= {})[key] = factory();
4199
4309
  }
4200
4310
  }
4201
4311
  }
4202
- return types2.strictObject(validation);
4203
- }
4204
- function makeProps(type, defaults) {
4205
- const node = getComponentScope();
4206
- const { app, componentName } = node;
4207
4312
  if (defaults) {
4208
4313
  node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
4209
4314
  }
4210
4315
  function resolveValue(props2, key) {
4211
- if (props2[key] === void 0 && defaults) {
4316
+ if (props2[key] === void 0 && defaults && key in defaults) {
4212
4317
  return defaults[key];
4213
4318
  }
4214
4319
  return props2[key];
@@ -4234,16 +4339,20 @@ function makeProps(type, defaults) {
4234
4339
  }
4235
4340
  }
4236
4341
  if (type) {
4237
- const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
4238
- (key) => key.endsWith("?") ? key.slice(0, -1) : key
4239
- );
4342
+ const keys = Array.isArray(type) ? type : Object.keys(type);
4240
4343
  defineProps(keys);
4241
4344
  node.propsUpdated.push(() => updateSignals(keys));
4242
4345
  if (app.dev) {
4243
4346
  if (defaults) {
4347
+ const defaultedShape = {};
4348
+ for (const key in type) {
4349
+ if (key in defaults) {
4350
+ defaultedShape[key] = type[key];
4351
+ }
4352
+ }
4244
4353
  assertType(
4245
4354
  defaults,
4246
- validateDefaults(type),
4355
+ types2.object(defaultedShape),
4247
4356
  `Invalid component default props (${componentName})`
4248
4357
  );
4249
4358
  }
@@ -4261,13 +4370,6 @@ function makeProps(type, defaults) {
4261
4370
  keys2.push(k);
4262
4371
  }
4263
4372
  }
4264
- if (defaults) {
4265
- for (const k in defaults) {
4266
- if (!(k in props2)) {
4267
- keys2.push(k);
4268
- }
4269
- }
4270
- }
4271
4373
  return keys2;
4272
4374
  };
4273
4375
  let keys = getKeys(node.props);
@@ -4302,7 +4404,7 @@ var ErrorBoundary = class extends Component {
4302
4404
  <t t-call-slot="default"/>
4303
4405
  </t>
4304
4406
  `;
4305
- props = props({ "error?": types2.signal() }, { error: signal(null) });
4407
+ props = props({ error: types2.signal().default(() => signal(null)) });
4306
4408
  setup() {
4307
4409
  onError((e) => this.props.error.set(e));
4308
4410
  }
@@ -4363,7 +4465,7 @@ var Suspense = class extends Component {
4363
4465
  <t t-call-slot="fallback"/>
4364
4466
  </t>
4365
4467
  `;
4366
- props = props({ slots: types2.object(["default", "fallback?"]) });
4468
+ props = props({ slots: types2.object({ default: types2.any(), fallback: types2.any().optional() }) });
4367
4469
  prepared = signal(false);
4368
4470
  mounted = signal(false);
4369
4471
  subRootMounted = false;
@@ -4419,8 +4521,8 @@ var blockDom = {
4419
4521
  };
4420
4522
  var __info__ = {
4421
4523
  version: App.version,
4422
- date: "2026-06-05T08:44:38.319Z",
4423
- hash: "3206cf27",
4524
+ date: "2026-06-11T09:51:14.980Z",
4525
+ hash: "739fc964",
4424
4526
  url: "https://github.com/odoo/owl"
4425
4527
  };
4426
4528
 
@@ -6609,6 +6711,7 @@ export {
6609
6711
  Suspense,
6610
6712
  TemplateSet,
6611
6713
  __info__,
6714
+ applyDefaults,
6612
6715
  assertType,
6613
6716
  asyncComputed,
6614
6717
  batched,
@@ -6616,6 +6719,7 @@ export {
6616
6719
  computed,
6617
6720
  config,
6618
6721
  effect,
6722
+ getDefault,
6619
6723
  getScope,
6620
6724
  globalTemplates,
6621
6725
  htmlEscape,
@@ -6636,6 +6740,7 @@ export {
6636
6740
  proxy,
6637
6741
  signal,
6638
6742
  status,
6743
+ types2 as t,
6639
6744
  toRaw,
6640
6745
  types2 as types,
6641
6746
  untrack,