@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.iife.js CHANGED
@@ -34,6 +34,7 @@ var owl = (() => {
34
34
  Suspense: () => Suspense,
35
35
  TemplateSet: () => TemplateSet,
36
36
  __info__: () => __info__,
37
+ applyDefaults: () => applyDefaults,
37
38
  assertType: () => assertType,
38
39
  asyncComputed: () => asyncComputed,
39
40
  batched: () => batched,
@@ -41,6 +42,7 @@ var owl = (() => {
41
42
  computed: () => computed,
42
43
  config: () => config,
43
44
  effect: () => effect,
45
+ getDefault: () => getDefault,
44
46
  getScope: () => getScope,
45
47
  globalTemplates: () => globalTemplates,
46
48
  htmlEscape: () => htmlEscape,
@@ -61,6 +63,7 @@ var owl = (() => {
61
63
  proxy: () => proxy,
62
64
  signal: () => signal,
63
65
  status: () => status,
66
+ t: () => types2,
64
67
  toRaw: () => toRaw,
65
68
  types: () => types2,
66
69
  untrack: () => untrack,
@@ -644,6 +647,9 @@ var owl = (() => {
644
647
  }
645
648
  onWriteAtom(signal2[atomSymbol]);
646
649
  }
650
+ function signalRef() {
651
+ return buildSignal(null, (atom) => atom.value);
652
+ }
647
653
  function signalArray(initialValue) {
648
654
  return buildSignal(initialValue, (atom) => proxifyTarget(atom.value, atom));
649
655
  }
@@ -660,6 +666,7 @@ var owl = (() => {
660
666
  return buildSignal(value, (atom) => atom.value);
661
667
  }
662
668
  signal.trigger = triggerSignal;
669
+ signal.ref = signalRef;
663
670
  signal.Array = signalArray;
664
671
  signal.Map = signalMap;
665
672
  signal.Object = signalObject;
@@ -853,33 +860,123 @@ ${issueStrings}`);
853
860
  validation(createContext(issues, value, []));
854
861
  return issues;
855
862
  }
856
- function anyType() {
857
- return function validateAny() {
863
+ var defaultSymbol = /* @__PURE__ */ Symbol("default");
864
+ var innerTypeSymbol = /* @__PURE__ */ Symbol("innerType");
865
+ var shapeSymbol = /* @__PURE__ */ Symbol("shape");
866
+ var elementTypeSymbol = /* @__PURE__ */ Symbol("elementType");
867
+ var optionalSymbol = /* @__PURE__ */ Symbol("optional");
868
+ function getDefault(type) {
869
+ return typeof type === "function" ? type[defaultSymbol] : void 0;
870
+ }
871
+ function hasDefaultValue(type) {
872
+ return typeof type === "function" && defaultSymbol in type;
873
+ }
874
+ function withDefault(type, value) {
875
+ const validate = function validateWithDefault(context) {
876
+ if (context.value === void 0) {
877
+ return;
878
+ }
879
+ context.validate(type);
880
+ };
881
+ validate[defaultSymbol] = typeof value === "function" ? value : () => value;
882
+ validate[innerTypeSymbol] = type;
883
+ return validate;
884
+ }
885
+ function makeOptional(type) {
886
+ const validate = function validateOptional(context) {
887
+ if (context.value === void 0) {
888
+ return;
889
+ }
890
+ context.validate(type);
858
891
  };
892
+ validate[optionalSymbol] = true;
893
+ validate[innerTypeSymbol] = type;
894
+ return validate;
895
+ }
896
+ function isOptionalType(type) {
897
+ return typeof type === "function" && optionalSymbol in type;
898
+ }
899
+ function makeType(validate) {
900
+ validate.default = (value) => withDefault(validate, value);
901
+ validate.optional = () => makeOptional(validate);
902
+ return validate;
903
+ }
904
+ function applyDefaults(value, type) {
905
+ return applyDefaultsRec(value, type);
906
+ }
907
+ function applyDefaultsRec(value, type) {
908
+ if (typeof type !== "function") {
909
+ return value;
910
+ }
911
+ if (value === void 0) {
912
+ const factory = type[defaultSymbol];
913
+ if (!factory) {
914
+ return value;
915
+ }
916
+ value = factory();
917
+ }
918
+ const inner = type[innerTypeSymbol] || type;
919
+ if (typeof inner !== "function" || !value || typeof value !== "object") {
920
+ return value;
921
+ }
922
+ const elementType = inner[elementTypeSymbol];
923
+ if (elementType && Array.isArray(value)) {
924
+ let result2 = value;
925
+ for (let index = 0; index < value.length; index++) {
926
+ const newValue = applyDefaultsRec(value[index], elementType);
927
+ if (newValue !== value[index]) {
928
+ if (result2 === value) {
929
+ result2 = [...value];
930
+ }
931
+ result2[index] = newValue;
932
+ }
933
+ }
934
+ return result2;
935
+ }
936
+ const shape = inner[shapeSymbol];
937
+ if (!shape) {
938
+ return value;
939
+ }
940
+ let result = value;
941
+ for (const key in shape) {
942
+ const subValue = result[key];
943
+ const newValue = applyDefaultsRec(subValue, shape[key]);
944
+ if (newValue !== subValue) {
945
+ if (result === value) {
946
+ result = Array.isArray(value) ? [...value] : { ...value };
947
+ }
948
+ result[key] = newValue;
949
+ }
950
+ }
951
+ return result;
952
+ }
953
+ function anyType() {
954
+ return makeType(function validateAny() {
955
+ });
859
956
  }
860
957
  function booleanType() {
861
- return function validateBoolean(context) {
958
+ return makeType(function validateBoolean(context) {
862
959
  if (typeof context.value !== "boolean") {
863
960
  context.addIssue({ message: "value is not a boolean" });
864
961
  }
865
- };
962
+ });
866
963
  }
867
964
  function numberType() {
868
- return function validateNumber(context) {
965
+ return makeType(function validateNumber(context) {
869
966
  if (typeof context.value !== "number") {
870
967
  context.addIssue({ message: "value is not a number" });
871
968
  }
872
- };
969
+ });
873
970
  }
874
971
  function stringType() {
875
- return function validateString(context) {
972
+ return makeType(function validateString(context) {
876
973
  if (typeof context.value !== "string" && !(context.value instanceof String)) {
877
974
  context.addIssue({ message: "value is not a string" });
878
975
  }
879
- };
976
+ });
880
977
  }
881
978
  function arrayType(elementType) {
882
- return function validateArray(context) {
979
+ const validate = makeType(function validateArray(context) {
883
980
  if (!Array.isArray(context.value)) {
884
981
  context.addIssue({ message: "value is not an array" });
885
982
  return;
@@ -890,17 +987,21 @@ ${issueStrings}`);
890
987
  for (let index = 0; index < context.value.length; index++) {
891
988
  context.withKey(index).validate(elementType);
892
989
  }
893
- };
990
+ });
991
+ if (elementType) {
992
+ validate[elementTypeSymbol] = elementType;
993
+ }
994
+ return validate;
894
995
  }
895
996
  function constructorType(constructor) {
896
- return function validateConstructor(context) {
997
+ return makeType(function validateConstructor(context) {
897
998
  if (!(typeof context.value === "function") || !(context.value === constructor || context.value.prototype instanceof constructor)) {
898
999
  context.addIssue({ message: `value is not '${constructor.name}' or an extension` });
899
1000
  }
900
- };
1001
+ });
901
1002
  }
902
1003
  function customValidator(type, validator, errorMessage = "value does not match custom validation") {
903
- return function validateCustom(context) {
1004
+ return makeType(function validateCustom(context) {
904
1005
  context.validate(type);
905
1006
  if (!context.isValid) {
906
1007
  return;
@@ -908,37 +1009,37 @@ ${issueStrings}`);
908
1009
  if (!validator(context.value)) {
909
1010
  context.addIssue({ message: errorMessage });
910
1011
  }
911
- };
1012
+ });
912
1013
  }
913
1014
  function functionType(parameters = [], result = void 0) {
914
- return function validateFunction(context) {
1015
+ return makeType(function validateFunction(context) {
915
1016
  if (typeof context.value !== "function") {
916
1017
  context.addIssue({ message: "value is not a function" });
917
1018
  }
918
- };
1019
+ });
919
1020
  }
920
1021
  function instanceType(constructor) {
921
- return function validateInstanceType(context) {
1022
+ return makeType(function validateInstanceType(context) {
922
1023
  if (!(context.value instanceof constructor)) {
923
1024
  context.addIssue({ message: `value is not an instance of '${constructor.name}'` });
924
1025
  }
925
- };
1026
+ });
926
1027
  }
927
1028
  function intersection(types22) {
928
- return function validateIntersection(context) {
1029
+ return makeType(function validateIntersection(context) {
929
1030
  for (const type of types22) {
930
1031
  context.validate(type);
931
1032
  }
932
- };
1033
+ });
933
1034
  }
934
1035
  function literalType(literal) {
935
- return function validateLiteral(context) {
1036
+ return makeType(function validateLiteral(context) {
936
1037
  if (context.value !== literal) {
937
1038
  context.addIssue({
938
1039
  message: `value is not equal to ${typeof literal === "string" ? `'${literal}'` : literal}`
939
1040
  });
940
1041
  }
941
- };
1042
+ });
942
1043
  }
943
1044
  function literalSelection(literals) {
944
1045
  return union(literals.map(literalType));
@@ -966,15 +1067,14 @@ ${issueStrings}`);
966
1067
  }
967
1068
  const missingKeys = [];
968
1069
  for (const key of keys) {
969
- const property = key.endsWith("?") ? key.slice(0, -1) : key;
970
- if (context.value[property] === void 0) {
971
- if (!key.endsWith("?")) {
972
- missingKeys.push(property);
1070
+ if (context.value[key] === void 0) {
1071
+ if (!isOptionalType(shape[key]) && !hasDefaultValue(shape[key])) {
1072
+ missingKeys.push(key);
973
1073
  }
974
1074
  continue;
975
1075
  }
976
1076
  if (isShape) {
977
- context.withKey(property).validate(shape[key]);
1077
+ context.withKey(key).validate(shape[key]);
978
1078
  }
979
1079
  }
980
1080
  if (missingKeys.length) {
@@ -987,7 +1087,7 @@ ${issueStrings}`);
987
1087
  if (isStrict) {
988
1088
  const unknownKeys = [];
989
1089
  for (const key in context.value) {
990
- if (!keys.includes(key) && !(`${key}?` in shape)) {
1090
+ if (!keys.includes(key)) {
991
1091
  unknownKeys.push(key);
992
1092
  }
993
1093
  }
@@ -1001,24 +1101,32 @@ ${issueStrings}`);
1001
1101
  }
1002
1102
  }
1003
1103
  function objectType(schema = {}) {
1004
- return function validateLooseObject(context) {
1104
+ const validate = makeType(function validateLooseObject(context) {
1005
1105
  validateObject(context, schema, false);
1006
- };
1106
+ });
1107
+ if (!Array.isArray(schema)) {
1108
+ validate[shapeSymbol] = schema;
1109
+ }
1110
+ return validate;
1007
1111
  }
1008
1112
  function strictObjectType(schema) {
1009
- return function validateStrictObject(context) {
1113
+ const validate = makeType(function validateStrictObject(context) {
1010
1114
  validateObject(context, schema, true);
1011
- };
1115
+ });
1116
+ if (!Array.isArray(schema)) {
1117
+ validate[shapeSymbol] = schema;
1118
+ }
1119
+ return validate;
1012
1120
  }
1013
1121
  function promiseType(type) {
1014
- return function validatePromise(context) {
1122
+ return makeType(function validatePromise(context) {
1015
1123
  if (!(context.value instanceof Promise)) {
1016
1124
  context.addIssue({ message: "value is not a promise" });
1017
1125
  }
1018
- };
1126
+ });
1019
1127
  }
1020
1128
  function recordType(valueType) {
1021
- return function validateRecord(context) {
1129
+ return makeType(function validateRecord(context) {
1022
1130
  if (typeof context.value !== "object" || Array.isArray(context.value) || context.value === null) {
1023
1131
  context.addIssue({ message: "value is not an object" });
1024
1132
  return;
@@ -1029,10 +1137,10 @@ ${issueStrings}`);
1029
1137
  for (const key in context.value) {
1030
1138
  context.withKey(key).validate(valueType);
1031
1139
  }
1032
- };
1140
+ });
1033
1141
  }
1034
1142
  function tuple(types22) {
1035
- return function validateTuple(context) {
1143
+ const validate = makeType(function validateTuple(context) {
1036
1144
  if (!Array.isArray(context.value)) {
1037
1145
  context.addIssue({ message: "value is not an array" });
1038
1146
  return;
@@ -1044,10 +1152,12 @@ ${issueStrings}`);
1044
1152
  for (let index = 0; index < types22.length; index++) {
1045
1153
  context.withKey(index).validate(types22[index]);
1046
1154
  }
1047
- };
1155
+ });
1156
+ validate[shapeSymbol] = types22;
1157
+ return validate;
1048
1158
  }
1049
1159
  function union(types22) {
1050
- return function validateUnion(context) {
1160
+ return makeType(function validateUnion(context) {
1051
1161
  let firstIssueIndex = 0;
1052
1162
  const subIssues = [];
1053
1163
  for (const type of types22) {
@@ -1063,17 +1173,20 @@ ${issueStrings}`);
1063
1173
  message: "value does not match union type",
1064
1174
  subIssues
1065
1175
  });
1066
- };
1176
+ });
1067
1177
  }
1068
1178
  function reactiveValueType(type) {
1069
- return function validateReactiveValue(context) {
1179
+ return makeType(function validateReactiveValue(context) {
1070
1180
  if (typeof context.value !== "function" || !context.value[atomSymbol]) {
1071
1181
  context.addIssue({ message: "value is not a reactive value" });
1072
1182
  }
1073
- };
1183
+ });
1074
1184
  }
1075
1185
  function ref(type) {
1076
- return union([literalType(null), instanceType(type)]);
1186
+ if (typeof HTMLElement === "undefined") {
1187
+ throw new Error("Cannot use ref in a non-DOM environment");
1188
+ }
1189
+ return union([literalType(null), instanceType(type || HTMLElement)]);
1077
1190
  }
1078
1191
  var types = {
1079
1192
  and: intersection,
@@ -1375,7 +1488,7 @@ ${issueStrings}`);
1375
1488
  }
1376
1489
  return plugin2;
1377
1490
  }
1378
- function config(key, type, defaultValue) {
1491
+ function config(key, type) {
1379
1492
  const scope = useScope();
1380
1493
  if (!(scope instanceof PluginManager)) {
1381
1494
  throw new OwlError("Expected to be in a plugin scope");
@@ -1383,8 +1496,8 @@ ${issueStrings}`);
1383
1496
  if (scope.app.dev && type) {
1384
1497
  assertType(scope.config, types.object({ [key]: type }), "Config does not match the type");
1385
1498
  }
1386
- const configValue = scope.config[key.endsWith("?") ? key.slice(0, -1) : key];
1387
- return configValue === void 0 ? defaultValue : configValue;
1499
+ const configValue = scope.config[key];
1500
+ return configValue === void 0 ? getDefault(type)?.() : configValue;
1388
1501
  }
1389
1502
  var EventBus = class extends EventTarget {
1390
1503
  trigger(name, payload) {
@@ -1430,7 +1543,7 @@ ${issueStrings}`);
1430
1543
  }
1431
1544
 
1432
1545
  // ../owl-runtime/dist/owl-runtime.es.js
1433
- var version = "3.0.0-alpha.34";
1546
+ var version = "3.0.0-alpha.35";
1434
1547
  var fibersInError = /* @__PURE__ */ new WeakMap();
1435
1548
  var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
1436
1549
  function invokeErrorHandlers(node, error, finalize, markFibers) {
@@ -3621,7 +3734,7 @@ ${issueStrings}`);
3621
3734
  }
3622
3735
  };
3623
3736
  var ObjectCreate = Object.create;
3624
- function withDefault(value, defaultValue) {
3737
+ function withDefault2(value, defaultValue) {
3625
3738
  return value === void 0 || value === null || value === false ? defaultValue : value;
3626
3739
  }
3627
3740
  function callSlot(ctx, parent, key, name, dynamic, extra, defaultContent) {
@@ -3907,7 +4020,7 @@ ${issueStrings}`);
3907
4020
  return toggler(subTemplate, template.call(owner, ctx, parent, key + subTemplate));
3908
4021
  }
3909
4022
  var helpers = {
3910
- withDefault,
4023
+ withDefault: withDefault2,
3911
4024
  zero: /* @__PURE__ */ Symbol("zero"),
3912
4025
  callSlot,
3913
4026
  withKey,
@@ -4237,12 +4350,12 @@ ${issueStrings}`);
4237
4350
  }
4238
4351
  handlers.push(callback.bind(scope.component));
4239
4352
  }
4240
- function staticProp(key, type, ...args) {
4353
+ function staticProp(key, type) {
4241
4354
  const node = getComponentScope();
4242
- const hasDefault = args.length > 0;
4355
+ const defaultFactory = getDefault(type);
4243
4356
  const propValue = node.props[key];
4244
4357
  if (node.app.dev) {
4245
- if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
4358
+ if (type !== void 0 && (!defaultFactory || propValue !== void 0)) {
4246
4359
  assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
4247
4360
  }
4248
4361
  node.willUpdateProps.push((nextProps) => {
@@ -4253,37 +4366,32 @@ ${issueStrings}`);
4253
4366
  }
4254
4367
  });
4255
4368
  }
4256
- return propValue === void 0 && hasDefault ? args[0] : propValue;
4369
+ return propValue === void 0 && defaultFactory ? defaultFactory() : propValue;
4257
4370
  }
4258
4371
  function componentType() {
4259
4372
  return constructorType(Component);
4260
4373
  }
4261
- var types2 = { ...types, component: componentType };
4262
- function validateDefaults(schema) {
4263
- const validation = {};
4264
- if (Array.isArray(schema)) {
4265
- for (const key of schema) {
4266
- if (key.endsWith("?")) {
4267
- validation[key] = types2.any();
4268
- }
4269
- }
4270
- } else {
4271
- for (const key in schema) {
4272
- if (key.endsWith("?")) {
4273
- validation[key] = schema[key];
4374
+ var types2 = {
4375
+ ...types,
4376
+ component: componentType
4377
+ };
4378
+ function makeProps(type) {
4379
+ const node = getComponentScope();
4380
+ const { app, componentName } = node;
4381
+ let defaults = null;
4382
+ if (type && !Array.isArray(type)) {
4383
+ for (const key in type) {
4384
+ const factory = getDefault(type[key]);
4385
+ if (factory) {
4386
+ (defaults ||= {})[key] = factory();
4274
4387
  }
4275
4388
  }
4276
4389
  }
4277
- return types2.strictObject(validation);
4278
- }
4279
- function makeProps(type, defaults) {
4280
- const node = getComponentScope();
4281
- const { app, componentName } = node;
4282
4390
  if (defaults) {
4283
4391
  node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
4284
4392
  }
4285
4393
  function resolveValue(props2, key) {
4286
- if (props2[key] === void 0 && defaults) {
4394
+ if (props2[key] === void 0 && defaults && key in defaults) {
4287
4395
  return defaults[key];
4288
4396
  }
4289
4397
  return props2[key];
@@ -4309,16 +4417,20 @@ ${issueStrings}`);
4309
4417
  }
4310
4418
  }
4311
4419
  if (type) {
4312
- const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
4313
- (key) => key.endsWith("?") ? key.slice(0, -1) : key
4314
- );
4420
+ const keys = Array.isArray(type) ? type : Object.keys(type);
4315
4421
  defineProps(keys);
4316
4422
  node.propsUpdated.push(() => updateSignals(keys));
4317
4423
  if (app.dev) {
4318
4424
  if (defaults) {
4425
+ const defaultedShape = {};
4426
+ for (const key in type) {
4427
+ if (key in defaults) {
4428
+ defaultedShape[key] = type[key];
4429
+ }
4430
+ }
4319
4431
  assertType(
4320
4432
  defaults,
4321
- validateDefaults(type),
4433
+ types2.object(defaultedShape),
4322
4434
  `Invalid component default props (${componentName})`
4323
4435
  );
4324
4436
  }
@@ -4336,13 +4448,6 @@ ${issueStrings}`);
4336
4448
  keys2.push(k);
4337
4449
  }
4338
4450
  }
4339
- if (defaults) {
4340
- for (const k in defaults) {
4341
- if (!(k in props2)) {
4342
- keys2.push(k);
4343
- }
4344
- }
4345
- }
4346
4451
  return keys2;
4347
4452
  };
4348
4453
  let keys = getKeys(node.props);
@@ -4377,7 +4482,7 @@ ${issueStrings}`);
4377
4482
  <t t-call-slot="default"/>
4378
4483
  </t>
4379
4484
  `;
4380
- props = props({ "error?": types2.signal() }, { error: signal(null) });
4485
+ props = props({ error: types2.signal().default(() => signal(null)) });
4381
4486
  setup() {
4382
4487
  onError((e) => this.props.error.set(e));
4383
4488
  }
@@ -4438,7 +4543,7 @@ ${issueStrings}`);
4438
4543
  <t t-call-slot="fallback"/>
4439
4544
  </t>
4440
4545
  `;
4441
- props = props({ slots: types2.object(["default", "fallback?"]) });
4546
+ props = props({ slots: types2.object({ default: types2.any(), fallback: types2.any().optional() }) });
4442
4547
  prepared = signal(false);
4443
4548
  mounted = signal(false);
4444
4549
  subRootMounted = false;
@@ -4494,8 +4599,8 @@ ${issueStrings}`);
4494
4599
  };
4495
4600
  var __info__ = {
4496
4601
  version: App.version,
4497
- date: "2026-06-05T08:44:38.319Z",
4498
- hash: "3206cf27",
4602
+ date: "2026-06-11T09:51:14.980Z",
4603
+ hash: "739fc964",
4499
4604
  url: "https://github.com/odoo/owl"
4500
4605
  };
4501
4606