@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.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,111 @@ ${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 makeOptional(type, value) {
872
+ const validate = function validateOptional(context) {
873
+ if (context.value === void 0) {
874
+ return;
875
+ }
876
+ context.validate(type);
858
877
  };
878
+ validate[optionalSymbol] = true;
879
+ validate[innerTypeSymbol] = type;
880
+ if (value !== void 0) {
881
+ validate[defaultSymbol] = typeof value === "function" ? value : () => value;
882
+ }
883
+ return validate;
884
+ }
885
+ function isOptionalType(type) {
886
+ return typeof type === "function" && optionalSymbol in type;
887
+ }
888
+ function makeType(validate) {
889
+ validate.optional = (value) => makeOptional(validate, value);
890
+ return validate;
891
+ }
892
+ function applyDefaults(value, type) {
893
+ return applyDefaultsRec(value, type);
894
+ }
895
+ function applyDefaultsRec(value, type) {
896
+ if (typeof type !== "function") {
897
+ return value;
898
+ }
899
+ if (value === void 0) {
900
+ const factory = type[defaultSymbol];
901
+ if (!factory) {
902
+ return value;
903
+ }
904
+ value = factory();
905
+ }
906
+ const inner = type[innerTypeSymbol] || type;
907
+ if (typeof inner !== "function" || !value || typeof value !== "object") {
908
+ return value;
909
+ }
910
+ const elementType = inner[elementTypeSymbol];
911
+ if (elementType && Array.isArray(value)) {
912
+ let result2 = value;
913
+ for (let index = 0; index < value.length; index++) {
914
+ const newValue = applyDefaultsRec(value[index], elementType);
915
+ if (newValue !== value[index]) {
916
+ if (result2 === value) {
917
+ result2 = [...value];
918
+ }
919
+ result2[index] = newValue;
920
+ }
921
+ }
922
+ return result2;
923
+ }
924
+ const shape = inner[shapeSymbol];
925
+ if (!shape) {
926
+ return value;
927
+ }
928
+ let result = value;
929
+ for (const key in shape) {
930
+ const subValue = result[key];
931
+ const newValue = applyDefaultsRec(subValue, shape[key]);
932
+ if (newValue !== subValue) {
933
+ if (result === value) {
934
+ result = Array.isArray(value) ? [...value] : { ...value };
935
+ }
936
+ result[key] = newValue;
937
+ }
938
+ }
939
+ return result;
940
+ }
941
+ function anyType() {
942
+ return makeType(function validateAny() {
943
+ });
859
944
  }
860
945
  function booleanType() {
861
- return function validateBoolean(context) {
946
+ return makeType(function validateBoolean(context) {
862
947
  if (typeof context.value !== "boolean") {
863
948
  context.addIssue({ message: "value is not a boolean" });
864
949
  }
865
- };
950
+ });
866
951
  }
867
952
  function numberType() {
868
- return function validateNumber(context) {
953
+ return makeType(function validateNumber(context) {
869
954
  if (typeof context.value !== "number") {
870
955
  context.addIssue({ message: "value is not a number" });
871
956
  }
872
- };
957
+ });
873
958
  }
874
959
  function stringType() {
875
- return function validateString(context) {
960
+ return makeType(function validateString(context) {
876
961
  if (typeof context.value !== "string" && !(context.value instanceof String)) {
877
962
  context.addIssue({ message: "value is not a string" });
878
963
  }
879
- };
964
+ });
880
965
  }
881
966
  function arrayType(elementType) {
882
- return function validateArray(context) {
967
+ const validate = makeType(function validateArray(context) {
883
968
  if (!Array.isArray(context.value)) {
884
969
  context.addIssue({ message: "value is not an array" });
885
970
  return;
@@ -890,17 +975,21 @@ ${issueStrings}`);
890
975
  for (let index = 0; index < context.value.length; index++) {
891
976
  context.withKey(index).validate(elementType);
892
977
  }
893
- };
978
+ });
979
+ if (elementType) {
980
+ validate[elementTypeSymbol] = elementType;
981
+ }
982
+ return validate;
894
983
  }
895
984
  function constructorType(constructor) {
896
- return function validateConstructor(context) {
985
+ return makeType(function validateConstructor(context) {
897
986
  if (!(typeof context.value === "function") || !(context.value === constructor || context.value.prototype instanceof constructor)) {
898
987
  context.addIssue({ message: `value is not '${constructor.name}' or an extension` });
899
988
  }
900
- };
989
+ });
901
990
  }
902
991
  function customValidator(type, validator, errorMessage = "value does not match custom validation") {
903
- return function validateCustom(context) {
992
+ return makeType(function validateCustom(context) {
904
993
  context.validate(type);
905
994
  if (!context.isValid) {
906
995
  return;
@@ -908,37 +997,37 @@ ${issueStrings}`);
908
997
  if (!validator(context.value)) {
909
998
  context.addIssue({ message: errorMessage });
910
999
  }
911
- };
1000
+ });
912
1001
  }
913
1002
  function functionType(parameters = [], result = void 0) {
914
- return function validateFunction(context) {
1003
+ return makeType(function validateFunction(context) {
915
1004
  if (typeof context.value !== "function") {
916
1005
  context.addIssue({ message: "value is not a function" });
917
1006
  }
918
- };
1007
+ });
919
1008
  }
920
1009
  function instanceType(constructor) {
921
- return function validateInstanceType(context) {
1010
+ return makeType(function validateInstanceType(context) {
922
1011
  if (!(context.value instanceof constructor)) {
923
1012
  context.addIssue({ message: `value is not an instance of '${constructor.name}'` });
924
1013
  }
925
- };
1014
+ });
926
1015
  }
927
1016
  function intersection(types22) {
928
- return function validateIntersection(context) {
1017
+ return makeType(function validateIntersection(context) {
929
1018
  for (const type of types22) {
930
1019
  context.validate(type);
931
1020
  }
932
- };
1021
+ });
933
1022
  }
934
1023
  function literalType(literal) {
935
- return function validateLiteral(context) {
1024
+ return makeType(function validateLiteral(context) {
936
1025
  if (context.value !== literal) {
937
1026
  context.addIssue({
938
1027
  message: `value is not equal to ${typeof literal === "string" ? `'${literal}'` : literal}`
939
1028
  });
940
1029
  }
941
- };
1030
+ });
942
1031
  }
943
1032
  function literalSelection(literals) {
944
1033
  return union(literals.map(literalType));
@@ -966,15 +1055,14 @@ ${issueStrings}`);
966
1055
  }
967
1056
  const missingKeys = [];
968
1057
  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);
1058
+ if (context.value[key] === void 0) {
1059
+ if (!isOptionalType(shape[key])) {
1060
+ missingKeys.push(key);
973
1061
  }
974
1062
  continue;
975
1063
  }
976
1064
  if (isShape) {
977
- context.withKey(property).validate(shape[key]);
1065
+ context.withKey(key).validate(shape[key]);
978
1066
  }
979
1067
  }
980
1068
  if (missingKeys.length) {
@@ -987,7 +1075,7 @@ ${issueStrings}`);
987
1075
  if (isStrict) {
988
1076
  const unknownKeys = [];
989
1077
  for (const key in context.value) {
990
- if (!keys.includes(key) && !(`${key}?` in shape)) {
1078
+ if (!keys.includes(key)) {
991
1079
  unknownKeys.push(key);
992
1080
  }
993
1081
  }
@@ -1001,24 +1089,32 @@ ${issueStrings}`);
1001
1089
  }
1002
1090
  }
1003
1091
  function objectType(schema = {}) {
1004
- return function validateLooseObject(context) {
1092
+ const validate = makeType(function validateLooseObject(context) {
1005
1093
  validateObject(context, schema, false);
1006
- };
1094
+ });
1095
+ if (!Array.isArray(schema)) {
1096
+ validate[shapeSymbol] = schema;
1097
+ }
1098
+ return validate;
1007
1099
  }
1008
1100
  function strictObjectType(schema) {
1009
- return function validateStrictObject(context) {
1101
+ const validate = makeType(function validateStrictObject(context) {
1010
1102
  validateObject(context, schema, true);
1011
- };
1103
+ });
1104
+ if (!Array.isArray(schema)) {
1105
+ validate[shapeSymbol] = schema;
1106
+ }
1107
+ return validate;
1012
1108
  }
1013
1109
  function promiseType(type) {
1014
- return function validatePromise(context) {
1110
+ return makeType(function validatePromise(context) {
1015
1111
  if (!(context.value instanceof Promise)) {
1016
1112
  context.addIssue({ message: "value is not a promise" });
1017
1113
  }
1018
- };
1114
+ });
1019
1115
  }
1020
1116
  function recordType(valueType) {
1021
- return function validateRecord(context) {
1117
+ return makeType(function validateRecord(context) {
1022
1118
  if (typeof context.value !== "object" || Array.isArray(context.value) || context.value === null) {
1023
1119
  context.addIssue({ message: "value is not an object" });
1024
1120
  return;
@@ -1029,10 +1125,10 @@ ${issueStrings}`);
1029
1125
  for (const key in context.value) {
1030
1126
  context.withKey(key).validate(valueType);
1031
1127
  }
1032
- };
1128
+ });
1033
1129
  }
1034
1130
  function tuple(types22) {
1035
- return function validateTuple(context) {
1131
+ const validate = makeType(function validateTuple(context) {
1036
1132
  if (!Array.isArray(context.value)) {
1037
1133
  context.addIssue({ message: "value is not an array" });
1038
1134
  return;
@@ -1044,10 +1140,12 @@ ${issueStrings}`);
1044
1140
  for (let index = 0; index < types22.length; index++) {
1045
1141
  context.withKey(index).validate(types22[index]);
1046
1142
  }
1047
- };
1143
+ });
1144
+ validate[shapeSymbol] = types22;
1145
+ return validate;
1048
1146
  }
1049
1147
  function union(types22) {
1050
- return function validateUnion(context) {
1148
+ return makeType(function validateUnion(context) {
1051
1149
  let firstIssueIndex = 0;
1052
1150
  const subIssues = [];
1053
1151
  for (const type of types22) {
@@ -1063,17 +1161,20 @@ ${issueStrings}`);
1063
1161
  message: "value does not match union type",
1064
1162
  subIssues
1065
1163
  });
1066
- };
1164
+ });
1067
1165
  }
1068
1166
  function reactiveValueType(type) {
1069
- return function validateReactiveValue(context) {
1167
+ return makeType(function validateReactiveValue(context) {
1070
1168
  if (typeof context.value !== "function" || !context.value[atomSymbol]) {
1071
1169
  context.addIssue({ message: "value is not a reactive value" });
1072
1170
  }
1073
- };
1171
+ });
1074
1172
  }
1075
1173
  function ref(type) {
1076
- return union([literalType(null), instanceType(type)]);
1174
+ if (typeof HTMLElement === "undefined") {
1175
+ throw new Error("Cannot use ref in a non-DOM environment");
1176
+ }
1177
+ return union([literalType(null), instanceType(type || HTMLElement)]);
1077
1178
  }
1078
1179
  var types = {
1079
1180
  and: intersection,
@@ -1375,7 +1476,7 @@ ${issueStrings}`);
1375
1476
  }
1376
1477
  return plugin2;
1377
1478
  }
1378
- function config(key, type, defaultValue) {
1479
+ function config(key, type) {
1379
1480
  const scope = useScope();
1380
1481
  if (!(scope instanceof PluginManager)) {
1381
1482
  throw new OwlError("Expected to be in a plugin scope");
@@ -1383,8 +1484,8 @@ ${issueStrings}`);
1383
1484
  if (scope.app.dev && type) {
1384
1485
  assertType(scope.config, types.object({ [key]: type }), "Config does not match the type");
1385
1486
  }
1386
- const configValue = scope.config[key.endsWith("?") ? key.slice(0, -1) : key];
1387
- return configValue === void 0 ? defaultValue : configValue;
1487
+ const configValue = scope.config[key];
1488
+ return configValue === void 0 ? getDefault(type)?.() : configValue;
1388
1489
  }
1389
1490
  var EventBus = class extends EventTarget {
1390
1491
  trigger(name, payload) {
@@ -1430,7 +1531,7 @@ ${issueStrings}`);
1430
1531
  }
1431
1532
 
1432
1533
  // ../owl-runtime/dist/owl-runtime.es.js
1433
- var version = "3.0.0-alpha.34";
1534
+ var version = "3.0.0-alpha.36";
1434
1535
  var fibersInError = /* @__PURE__ */ new WeakMap();
1435
1536
  var nodeErrorHandlers = /* @__PURE__ */ new WeakMap();
1436
1537
  function invokeErrorHandlers(node, error, finalize, markFibers) {
@@ -4237,12 +4338,12 @@ ${issueStrings}`);
4237
4338
  }
4238
4339
  handlers.push(callback.bind(scope.component));
4239
4340
  }
4240
- function staticProp(key, type, ...args) {
4341
+ function staticProp(key, type) {
4241
4342
  const node = getComponentScope();
4242
- const hasDefault = args.length > 0;
4343
+ const defaultFactory = getDefault(type);
4243
4344
  const propValue = node.props[key];
4244
4345
  if (node.app.dev) {
4245
- if (type !== void 0 && (!hasDefault || propValue !== void 0)) {
4346
+ if (type !== void 0 && (!defaultFactory || propValue !== void 0)) {
4246
4347
  assertType(propValue, type, `Invalid prop '${key}' in '${node.componentName}'`);
4247
4348
  }
4248
4349
  node.willUpdateProps.push((nextProps) => {
@@ -4253,37 +4354,32 @@ ${issueStrings}`);
4253
4354
  }
4254
4355
  });
4255
4356
  }
4256
- return propValue === void 0 && hasDefault ? args[0] : propValue;
4357
+ return propValue === void 0 && defaultFactory ? defaultFactory() : propValue;
4257
4358
  }
4258
4359
  function componentType() {
4259
4360
  return constructorType(Component);
4260
4361
  }
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];
4362
+ var types2 = {
4363
+ ...types,
4364
+ component: componentType
4365
+ };
4366
+ function makeProps(type) {
4367
+ const node = getComponentScope();
4368
+ const { app, componentName } = node;
4369
+ let defaults = null;
4370
+ if (type && !Array.isArray(type)) {
4371
+ for (const key in type) {
4372
+ const factory = getDefault(type[key]);
4373
+ if (factory) {
4374
+ (defaults ||= {})[key] = factory();
4274
4375
  }
4275
4376
  }
4276
4377
  }
4277
- return types2.strictObject(validation);
4278
- }
4279
- function makeProps(type, defaults) {
4280
- const node = getComponentScope();
4281
- const { app, componentName } = node;
4282
4378
  if (defaults) {
4283
4379
  node.defaultProps = Object.assign(node.defaultProps || {}, defaults);
4284
4380
  }
4285
4381
  function resolveValue(props2, key) {
4286
- if (props2[key] === void 0 && defaults) {
4382
+ if (props2[key] === void 0 && defaults && key in defaults) {
4287
4383
  return defaults[key];
4288
4384
  }
4289
4385
  return props2[key];
@@ -4309,16 +4405,20 @@ ${issueStrings}`);
4309
4405
  }
4310
4406
  }
4311
4407
  if (type) {
4312
- const keys = (Array.isArray(type) ? type : Object.keys(type)).map(
4313
- (key) => key.endsWith("?") ? key.slice(0, -1) : key
4314
- );
4408
+ const keys = Array.isArray(type) ? type : Object.keys(type);
4315
4409
  defineProps(keys);
4316
4410
  node.propsUpdated.push(() => updateSignals(keys));
4317
4411
  if (app.dev) {
4318
4412
  if (defaults) {
4413
+ const defaultedShape = {};
4414
+ for (const key in type) {
4415
+ if (key in defaults) {
4416
+ defaultedShape[key] = type[key];
4417
+ }
4418
+ }
4319
4419
  assertType(
4320
4420
  defaults,
4321
- validateDefaults(type),
4421
+ types2.object(defaultedShape),
4322
4422
  `Invalid component default props (${componentName})`
4323
4423
  );
4324
4424
  }
@@ -4336,13 +4436,6 @@ ${issueStrings}`);
4336
4436
  keys2.push(k);
4337
4437
  }
4338
4438
  }
4339
- if (defaults) {
4340
- for (const k in defaults) {
4341
- if (!(k in props2)) {
4342
- keys2.push(k);
4343
- }
4344
- }
4345
- }
4346
4439
  return keys2;
4347
4440
  };
4348
4441
  let keys = getKeys(node.props);
@@ -4377,7 +4470,7 @@ ${issueStrings}`);
4377
4470
  <t t-call-slot="default"/>
4378
4471
  </t>
4379
4472
  `;
4380
- props = props({ "error?": types2.signal() }, { error: signal(null) });
4473
+ props = props({ error: types2.signal().optional(() => signal(null)) });
4381
4474
  setup() {
4382
4475
  onError((e) => this.props.error.set(e));
4383
4476
  }
@@ -4438,7 +4531,7 @@ ${issueStrings}`);
4438
4531
  <t t-call-slot="fallback"/>
4439
4532
  </t>
4440
4533
  `;
4441
- props = props({ slots: types2.object(["default", "fallback?"]) });
4534
+ props = props({ slots: types2.object({ default: types2.any(), fallback: types2.any().optional() }) });
4442
4535
  prepared = signal(false);
4443
4536
  mounted = signal(false);
4444
4537
  subRootMounted = false;
@@ -4494,8 +4587,8 @@ ${issueStrings}`);
4494
4587
  };
4495
4588
  var __info__ = {
4496
4589
  version: App.version,
4497
- date: "2026-06-05T08:44:38.319Z",
4498
- hash: "3206cf27",
4590
+ date: "2026-06-11T18:30:46.327Z",
4591
+ hash: "eb837019",
4499
4592
  url: "https://github.com/odoo/owl"
4500
4593
  };
4501
4594