@es-joy/jsoe 0.3.0 → 0.4.0

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.
Files changed (189) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.cjs +1 -0
  3. package/.ncurc.cjs +9 -0
  4. package/CHANGES.md +4 -0
  5. package/demo/index.html +8 -0
  6. package/demo/index.js +1 -1
  7. package/dist/formatAndTypeChoices.d.ts +56 -0
  8. package/dist/formatAndTypeChoices.d.ts.map +1 -0
  9. package/dist/formats/indexedDBKey.d.ts +4 -0
  10. package/dist/formats/indexedDBKey.d.ts.map +1 -0
  11. package/dist/formats/json.d.ts +4 -0
  12. package/dist/formats/json.d.ts.map +1 -0
  13. package/dist/formats/schemaAndArbitrary.d.ts +6 -0
  14. package/dist/formats/schemaAndArbitrary.d.ts.map +1 -0
  15. package/dist/formats/schemaOnly.d.ts +6 -0
  16. package/dist/formats/schemaOnly.d.ts.map +1 -0
  17. package/dist/formats/structuredCloning.d.ts +20 -0
  18. package/dist/formats/structuredCloning.d.ts.map +1 -0
  19. package/dist/formats.d.ts +26 -0
  20. package/dist/formats.d.ts.map +1 -0
  21. package/dist/fundamentalTypes/BooleanObjectType.d.ts +8 -0
  22. package/dist/fundamentalTypes/BooleanObjectType.d.ts.map +1 -0
  23. package/dist/fundamentalTypes/NumberObjectType.d.ts +6 -0
  24. package/dist/fundamentalTypes/NumberObjectType.d.ts.map +1 -0
  25. package/dist/fundamentalTypes/StringObjectType.d.ts +6 -0
  26. package/dist/fundamentalTypes/StringObjectType.d.ts.map +1 -0
  27. package/dist/fundamentalTypes/arrayReferenceType.d.ts +8 -0
  28. package/dist/fundamentalTypes/arrayReferenceType.d.ts.map +1 -0
  29. package/dist/fundamentalTypes/arrayType.d.ts +60 -0
  30. package/dist/fundamentalTypes/arrayType.d.ts.map +1 -0
  31. package/dist/fundamentalTypes/bigintType.d.ts +6 -0
  32. package/dist/fundamentalTypes/bigintType.d.ts.map +1 -0
  33. package/dist/fundamentalTypes/dateType.d.ts +26 -0
  34. package/dist/fundamentalTypes/dateType.d.ts.map +1 -0
  35. package/dist/fundamentalTypes/nullType.d.ts +6 -0
  36. package/dist/fundamentalTypes/nullType.d.ts.map +1 -0
  37. package/dist/fundamentalTypes/numberType.d.ts +6 -0
  38. package/dist/fundamentalTypes/numberType.d.ts.map +1 -0
  39. package/dist/fundamentalTypes/objectReferenceType.d.ts +8 -0
  40. package/dist/fundamentalTypes/objectReferenceType.d.ts.map +1 -0
  41. package/dist/fundamentalTypes/objectType.d.ts +6 -0
  42. package/dist/fundamentalTypes/objectType.d.ts.map +1 -0
  43. package/dist/fundamentalTypes/regexpType.d.ts +8 -0
  44. package/dist/fundamentalTypes/regexpType.d.ts.map +1 -0
  45. package/dist/fundamentalTypes/sparseUndefinedType.d.ts +6 -0
  46. package/dist/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -0
  47. package/dist/fundamentalTypes/stringType.d.ts +6 -0
  48. package/dist/fundamentalTypes/stringType.d.ts.map +1 -0
  49. package/dist/fundamentalTypes/undefinedType.d.ts +6 -0
  50. package/dist/fundamentalTypes/undefinedType.d.ts.map +1 -0
  51. package/dist/index.d.ts +5 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/src/deepEqual.d.ts +3 -0
  54. package/dist/src/deepEqual.d.ts.map +1 -0
  55. package/dist/src/formatAndTypeChoices.d.ts +47 -0
  56. package/dist/src/formatAndTypeChoices.d.ts.map +1 -0
  57. package/dist/src/formats/indexedDBKey.d.ts +9 -0
  58. package/dist/src/formats/indexedDBKey.d.ts.map +1 -0
  59. package/dist/src/formats/json.d.ts +9 -0
  60. package/dist/src/formats/json.d.ts.map +1 -0
  61. package/dist/src/formats/schemaAndArbitrary.d.ts +6 -0
  62. package/dist/src/formats/schemaAndArbitrary.d.ts.map +1 -0
  63. package/dist/src/formats/schemaOnly.d.ts +6 -0
  64. package/dist/src/formats/schemaOnly.d.ts.map +1 -0
  65. package/dist/src/formats/structuredCloning.d.ts +15 -0
  66. package/dist/src/formats/structuredCloning.d.ts.map +1 -0
  67. package/dist/src/formats.d.ts +18 -0
  68. package/dist/src/formats.d.ts.map +1 -0
  69. package/dist/src/fundamentalTypes/BooleanObjectType.d.ts +6 -0
  70. package/dist/src/fundamentalTypes/BooleanObjectType.d.ts.map +1 -0
  71. package/dist/src/fundamentalTypes/NumberObjectType.d.ts +6 -0
  72. package/dist/src/fundamentalTypes/NumberObjectType.d.ts.map +1 -0
  73. package/dist/src/fundamentalTypes/StringObjectType.d.ts +6 -0
  74. package/dist/src/fundamentalTypes/StringObjectType.d.ts.map +1 -0
  75. package/dist/src/fundamentalTypes/arrayReferenceType.d.ts +6 -0
  76. package/dist/src/fundamentalTypes/arrayReferenceType.d.ts.map +1 -0
  77. package/dist/src/fundamentalTypes/arrayType.d.ts +6 -0
  78. package/dist/src/fundamentalTypes/arrayType.d.ts.map +1 -0
  79. package/dist/src/fundamentalTypes/bigintType.d.ts +6 -0
  80. package/dist/src/fundamentalTypes/bigintType.d.ts.map +1 -0
  81. package/dist/src/fundamentalTypes/dateType.d.ts +6 -0
  82. package/dist/src/fundamentalTypes/dateType.d.ts.map +1 -0
  83. package/dist/src/fundamentalTypes/nullType.d.ts +6 -0
  84. package/dist/src/fundamentalTypes/nullType.d.ts.map +1 -0
  85. package/dist/src/fundamentalTypes/numberType.d.ts +6 -0
  86. package/dist/src/fundamentalTypes/numberType.d.ts.map +1 -0
  87. package/dist/src/fundamentalTypes/objectReferenceType.d.ts +6 -0
  88. package/dist/src/fundamentalTypes/objectReferenceType.d.ts.map +1 -0
  89. package/dist/src/fundamentalTypes/objectType.d.ts +6 -0
  90. package/dist/src/fundamentalTypes/objectType.d.ts.map +1 -0
  91. package/dist/src/fundamentalTypes/regexpType.d.ts +6 -0
  92. package/dist/src/fundamentalTypes/regexpType.d.ts.map +1 -0
  93. package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts +6 -0
  94. package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -0
  95. package/dist/src/fundamentalTypes/stringType.d.ts +6 -0
  96. package/dist/src/fundamentalTypes/stringType.d.ts.map +1 -0
  97. package/dist/src/fundamentalTypes/undefinedType.d.ts +6 -0
  98. package/dist/src/fundamentalTypes/undefinedType.d.ts.map +1 -0
  99. package/dist/src/index.d.ts +5 -0
  100. package/dist/src/index.d.ts.map +1 -0
  101. package/dist/src/subTypes/blobHTMLType.d.ts +26 -0
  102. package/dist/src/subTypes/blobHTMLType.d.ts.map +1 -0
  103. package/dist/src/subTypes/falseType.d.ts +6 -0
  104. package/dist/src/subTypes/falseType.d.ts.map +1 -0
  105. package/dist/src/subTypes/trueType.d.ts +6 -0
  106. package/dist/src/subTypes/trueType.d.ts.map +1 -0
  107. package/dist/src/superTypes/SpecialNumberSuperType.d.ts +11 -0
  108. package/dist/src/superTypes/SpecialNumberSuperType.d.ts.map +1 -0
  109. package/dist/src/superTypes/SpecialRealNumberSuperType.d.ts +6 -0
  110. package/dist/src/superTypes/SpecialRealNumberSuperType.d.ts.map +1 -0
  111. package/dist/src/typeChoices.d.ts +30 -0
  112. package/dist/src/typeChoices.d.ts.map +1 -0
  113. package/dist/src/types.d.ts +333 -0
  114. package/dist/src/types.d.ts.map +1 -0
  115. package/dist/src/utils/dialogs.d.ts +29 -0
  116. package/dist/src/utils/dialogs.d.ts.map +1 -0
  117. package/dist/src/utils/jsonPointer.d.ts +42 -0
  118. package/dist/src/utils/jsonPointer.d.ts.map +1 -0
  119. package/dist/src/utils/templateUtils.d.ts +59 -0
  120. package/dist/src/utils/templateUtils.d.ts.map +1 -0
  121. package/dist/src/utils/types.d.ts +2 -0
  122. package/dist/src/utils/types.d.ts.map +1 -0
  123. package/dist/subTypes/blobHTMLType.d.ts +14 -0
  124. package/dist/subTypes/blobHTMLType.d.ts.map +1 -0
  125. package/dist/subTypes/falseType.d.ts +8 -0
  126. package/dist/subTypes/falseType.d.ts.map +1 -0
  127. package/dist/subTypes/trueType.d.ts +8 -0
  128. package/dist/subTypes/trueType.d.ts.map +1 -0
  129. package/dist/superTypes/SpecialNumberSuperType.d.ts +14 -0
  130. package/dist/superTypes/SpecialNumberSuperType.d.ts.map +1 -0
  131. package/dist/superTypes/SpecialRealNumberSuperType.d.ts +6 -0
  132. package/dist/superTypes/SpecialRealNumberSuperType.d.ts.map +1 -0
  133. package/dist/typeChoices.d.ts +103 -0
  134. package/dist/typeChoices.d.ts.map +1 -0
  135. package/dist/types.d.ts +523 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/utils/dialogs.d.ts +109 -0
  138. package/dist/utils/dialogs.d.ts.map +1 -0
  139. package/dist/utils/jsonPointer.d.ts +46 -0
  140. package/dist/utils/jsonPointer.d.ts.map +1 -0
  141. package/dist/utils/templateUtils.d.ts +59 -0
  142. package/dist/utils/templateUtils.d.ts.map +1 -0
  143. package/dist/utils/types.d.ts +2 -0
  144. package/dist/utils/types.d.ts.map +1 -0
  145. package/dist/vendor/jamilih/dist/jml-es.d.ts +436 -0
  146. package/dist/vendor/jamilih/dist/jml-es.d.ts.map +1 -0
  147. package/dist/vendor/typeson-registry/dist/index.d.ts +400 -0
  148. package/dist/vendor/typeson-registry/dist/index.d.ts.map +1 -0
  149. package/dist/vendor-imports.d.ts +3 -0
  150. package/dist/vendor-imports.d.ts.map +1 -0
  151. package/package.json +16 -11
  152. package/postorder-traversal.js +58 -0
  153. package/src/formatAndTypeChoices.js +95 -50
  154. package/src/formats/indexedDBKey.js +49 -57
  155. package/src/formats/json.js +47 -56
  156. package/src/formats/schemaOnly.js +12 -2
  157. package/src/formats/structuredCloning.js +162 -105
  158. package/src/formats.js +38 -10
  159. package/src/fundamentalTypes/BooleanObjectType.js +6 -4
  160. package/src/fundamentalTypes/NumberObjectType.js +5 -3
  161. package/src/fundamentalTypes/StringObjectType.js +1 -1
  162. package/src/fundamentalTypes/arrayReferenceType.js +29 -14
  163. package/src/fundamentalTypes/arrayType.js +789 -278
  164. package/src/fundamentalTypes/bigintType.js +2 -2
  165. package/src/fundamentalTypes/dateType.js +42 -14
  166. package/src/fundamentalTypes/nullType.js +1 -1
  167. package/src/fundamentalTypes/numberType.js +2 -2
  168. package/src/fundamentalTypes/objectReferenceType.js +7 -5
  169. package/src/fundamentalTypes/regexpType.js +45 -24
  170. package/src/fundamentalTypes/sparseUndefinedType.js +7 -1
  171. package/src/fundamentalTypes/stringType.js +1 -1
  172. package/src/fundamentalTypes/undefinedType.js +2 -2
  173. package/src/subTypes/blobHTMLType.js +42 -22
  174. package/src/subTypes/falseType.js +2 -2
  175. package/src/subTypes/trueType.js +2 -2
  176. package/src/superTypes/SpecialNumberSuperType.js +13 -6
  177. package/src/superTypes/SpecialRealNumberSuperType.js +11 -5
  178. package/src/typeChoices.js +137 -55
  179. package/src/types.js +309 -146
  180. package/src/utils/dialogs.js +98 -29
  181. package/src/utils/jsonPointer.js +4 -0
  182. package/src/utils/templateUtils.js +27 -12
  183. package/src/vendor-imports.js +8 -0
  184. package/tsconfig.json +18 -0
  185. package/typings/sceditor.d.ts +20 -0
  186. package/vendor/jamilih/dist/jml-es.js +1019 -389
  187. package/vendor/jamilih/dist/jml.d.ts +436 -0
  188. package/vendor/jamilih/package.json +136 -0
  189. package/vendor/typeson-registry/dist/index.js +365 -83
@@ -18,7 +18,7 @@ const bigintType = {
18
18
  return {value: BigInt(s.slice(0, -1))};
19
19
  },
20
20
  getInput ({root}) {
21
- return $e(root, 'input');
21
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
22
22
  },
23
23
  setValue ({root, value}) {
24
24
  this.getInput({root}).value = String(value);
@@ -27,7 +27,7 @@ const bigintType = {
27
27
  const val = this.getInput({root}).value;
28
28
  return {
29
29
  message: 'Not a valid BigInt',
30
- valid: val && val.match(/^-?(\d+)$/u)
30
+ valid: Boolean(val && (/^-?(\d+)$/u).test(val))
31
31
  };
32
32
  },
33
33
  getValue ({root}) {
@@ -1,9 +1,22 @@
1
+ import {jml} from '../vendor-imports.js';
1
2
  import {$e} from '../utils/templateUtils.js';
2
- import {jml} from '../../vendor/jamilih/dist/jml-es.js';
3
3
  import Types from '../types.js';
4
4
 
5
5
  /**
6
- * @type {import('../types.js').TypeObject}
6
+ * @typedef {(
7
+ * legitimateInvalid?: true|undefined
8
+ * ) => void} SetValidity
9
+ */
10
+
11
+ /**
12
+ * @type {import('../types.js').TypeObject & {
13
+ * dateRegex: RegExp,
14
+ * isInvalid: (cfg: {root: HTMLDivElement}) => boolean,
15
+ * isValueInvalid: (
16
+ * value: import('../formats.js').StructuredCloneValue
17
+ * ) => boolean
18
+ * valid?: true
19
+ * }}
7
20
  */
8
21
  const dateType = {
9
22
  option: ['Date'],
@@ -21,12 +34,14 @@ const dateType = {
21
34
  return {value: new Date(s)};
22
35
  },
23
36
  getInput ({root}) {
24
- return $e(root, 'input[type="date"]');
37
+ return /** @type {HTMLInputElement} */ ($e(root, 'input[type="date"]'));
25
38
  },
26
39
  setValue ({root, value}) {
27
40
  const notANum = value && Number.isNaN(value.getTime());
28
41
  if (notANum) {
29
- $e(root, '.invalidDate').$setValidity(true);
42
+ /** @type {HTMLElement & {$setValidity: SetValidity}} */ (
43
+ $e(root, '.invalidDate')
44
+ ).$setValidity(true);
30
45
  return;
31
46
  }
32
47
  const dateStr = new Date(Date.parse(value)).toISOString();
@@ -50,12 +65,14 @@ const dateType = {
50
65
  };
51
66
  }
52
67
  return {
53
- valid: val.match(new RegExp(this.dateRegex, 'u')),
68
+ valid: new RegExp(this.dateRegex, 'u').test(val),
54
69
  message: 'Must match a valid date'
55
70
  }; // Input shouldn't allow anyways
56
71
  },
57
72
  isInvalid ({root}) {
58
- return !this.valid && $e(root, '.invalidDate').checked;
73
+ return !this.valid && /** @type {HTMLInputElement} */ (
74
+ $e(root, '.invalidDate')
75
+ ).checked;
59
76
  },
60
77
  getValue ({root}) {
61
78
  if (this.isInvalid({root})) {
@@ -77,11 +94,11 @@ const dateType = {
77
94
  },
78
95
  // Change to default to `new Date()` when can't be `NaN`
79
96
  // value (keys)?
80
- editUI ({topRoot, typeNamespace, value = ''}) {
97
+ editUI ({typeNamespace, value = ''}) {
81
98
  const notANum = this.isValueInvalid(value);
82
99
  const invalid = this.valid
83
100
  ? ''
84
- : jml('div', [
101
+ : /** @type {HTMLDivElement} */ (jml('div', [
85
102
  ['label', [
86
103
  'Invalid date',
87
104
  ['input', {
@@ -90,25 +107,36 @@ const dateType = {
90
107
  checked: notANum,
91
108
  name: `${typeNamespace}-invalidDate`,
92
109
  $custom: {
110
+ /**
111
+ * @type {SetValidity}
112
+ */
93
113
  $setValidity (legitimateInvalid) {
94
114
  console.log('legitimateInvalid', legitimateInvalid);
95
115
  if (legitimateInvalid === true) {
96
- this.checked = true;
116
+ /** @type {HTMLInputElement} */ (this).checked = true;
97
117
  }
98
- const label = invalid.previousElementSibling;
118
+ const label = /** @type {HTMLLabelElement} */ (
119
+ /** @type {HTMLDivElement} */ (
120
+ invalid
121
+ ).previousElementSibling
122
+ );
99
123
  label.hidden = Boolean(legitimateInvalid);
100
- const root = label.parentElement;
101
- Types.validate({type: 'date', root, topRoot});
124
+ const root = /** @type {HTMLDivElement} */ (
125
+ label.parentElement
126
+ );
127
+ Types.validate({type: 'date', root});
102
128
  }
103
129
  },
104
130
  $on: {
105
131
  click (e) {
106
- this.$setValidity();
132
+ /** @type {Element & {$setValidity: SetValidity}} */ (
133
+ this
134
+ ).$setValidity();
107
135
  }
108
136
  }
109
137
  }]
110
138
  ]]
111
- ]);
139
+ ]));
112
140
  return ['div', {dataset: {type: this.valid ? 'ValidDate' : 'date'}}, [
113
141
  ['label', {
114
142
  hidden: notANum
@@ -13,7 +13,7 @@ const nullType = {
13
13
  },
14
14
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
15
15
  getInput ({root}) {
16
- return $e(root, 'input');
16
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
17
17
  },
18
18
  editUI ({typeNamespace}) {
19
19
  return ['div', {dataset: {type: 'null'}}, [
@@ -21,7 +21,7 @@ const numberType = {
21
21
  return {value: Number(s)};
22
22
  },
23
23
  getInput ({root}) {
24
- return $e(root, 'input');
24
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
25
25
  },
26
26
  setValue ({root, value}) {
27
27
  this.getInput({root}).value = String(value);
@@ -30,7 +30,7 @@ const numberType = {
30
30
  const val = this.getInput({root}).value;
31
31
  return {
32
32
  message: 'Not a valid (finite) number',
33
- valid: val && val.match(/^-?(\d+|\d*\.\d+)$/u)
33
+ valid: Boolean(val && (/^-?(\d+|\d*\.\d+)$/u).test(val))
34
34
  };
35
35
  },
36
36
  getValue ({root}) {
@@ -1,7 +1,7 @@
1
1
  import Types from '../types.js';
2
2
 
3
3
  /**
4
- * @type {import('../types.js').TypeObject}
4
+ * @type {import('../types.js').TypeObject & {type: string}}
5
5
  */
6
6
  const objectReferenceType = {
7
7
  option: ['Object reference'],
@@ -11,7 +11,7 @@ const objectReferenceType = {
11
11
  return Types.availableTypes.arrayReference.toValue.apply(this, args);
12
12
  },
13
13
  resolveReference (...args) {
14
- return Types.availableTypes.arrayReference.resolveReference.apply(
14
+ return Types.availableTypes.arrayReference.resolveReference?.apply(
15
15
  this, args
16
16
  );
17
17
  },
@@ -29,16 +29,18 @@ const objectReferenceType = {
29
29
  return Types.availableTypes.arrayReference.getInput.apply(this, args);
30
30
  },
31
31
  setValue (...args) {
32
- return Types.availableTypes.arrayReference.setValue.apply(this, args);
32
+ return Types.availableTypes.arrayReference.setValue?.apply(this, args);
33
33
  },
34
34
  getValue (...args) {
35
35
  return Types.availableTypes.arrayReference.getValue.apply(this, args);
36
36
  },
37
37
  validate (...args) {
38
- return Types.availableTypes.arrayReference.validate.apply(this, args);
38
+ return /** @type {{message?: string | undefined; valid: boolean;}} */ (
39
+ Types.availableTypes.arrayReference.validate?.apply(this, args)
40
+ );
39
41
  },
40
42
  validateAll (...args) {
41
- return Types.availableTypes.arrayReference.validateAll.apply(this, args);
43
+ return Types.availableTypes.arrayReference.validateAll?.apply(this, args);
42
44
  },
43
45
  viewUI (...args) {
44
46
  return Types.availableTypes.arrayReference.viewUI.apply(this, args);
@@ -1,9 +1,9 @@
1
+ import {jml} from '../vendor-imports.js';
1
2
  import {$e} from '../utils/templateUtils.js';
2
- import {jml} from '../../vendor/jamilih/dist/jml-es.js';
3
3
  import Types from '../types.js';
4
4
 
5
5
  /**
6
- * @type {import('../types.js').TypeObject}
6
+ * @type {import('../types.js').TypeObject & {allowedFlags: string[]}}
7
7
  */
8
8
  const regexpType = {
9
9
  option: ['RegExp'],
@@ -16,18 +16,29 @@ const regexpType = {
16
16
  }})$`, 'u');
17
17
  },
18
18
  toValue (s) {
19
- const [, str, flags] = s.match(this.stringRegex());
19
+ /* istanbul ignore if */
20
+ if (typeof this.stringRegex !== 'function') {
21
+ throw new TypeError('Guard for TS');
22
+ }
23
+ const [, str, flags] = s.match(
24
+ /** @type {Required<import('../types.js').TypeObject>} */ (
25
+ this
26
+ ).stringRegex()
27
+ ) || [];
20
28
  return {value: new RegExp(str, flags)};
21
29
  },
22
30
  getInput ({root}) {
23
- return $e(root, 'input');
31
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
24
32
  },
25
33
  setValue ({root, value}) {
26
34
  this.getInput({root}).value = value.source;
27
- this.getSelect({root}).$set([...value.flags]);
35
+ /** @type {HTMLSelectElement & {$set: (flags: string[]) => void}} */
36
+ (/** @type {Required<import('../types.js').TypeObject>} */ (
37
+ this
38
+ ).getSelect({root})).$set([...value.flags]);
28
39
  },
29
40
  getSelect ({root}) {
30
- return $e(root, 'select');
41
+ return /** @type {HTMLSelectElement} */ ($e(root, 'select'));
31
42
  },
32
43
  validate ({root}) {
33
44
  try {
@@ -36,14 +47,16 @@ const regexpType = {
36
47
  } catch (err) {
37
48
  return {
38
49
  valid: false,
39
- message: err.message
50
+ message: /** @type {Error} */ (err).message
40
51
  };
41
52
  }
42
53
  },
43
54
  getValue ({root}) {
44
55
  return new RegExp(
45
56
  this.getInput({root}).value, // .replace(/\\/g, '\\\\'),
46
- [...this.getSelect({root}).selectedOptions].reduce((s, opt) => {
57
+ [...(/** @type {Required<import('../types.js').TypeObject>} */ (
58
+ this
59
+ )).getSelect({root}).selectedOptions].reduce((s, opt) => {
47
60
  return s + opt.value;
48
61
  }, '')
49
62
  );
@@ -54,11 +67,17 @@ const regexpType = {
54
67
  },
55
68
  editUI ({typeNamespace, value = {source: '', flags: ''}}) {
56
69
  // Todo (low): Add RegExp syntax highlighter
57
- const select = jml(
70
+ const select = /** @type {HTMLSelectElement} */ (jml(
58
71
  'select',
59
72
  {multiple: true, size: 5, $custom: {
73
+ /**
74
+ * @param {string[]} valArr
75
+ * @returns {void}
76
+ */
60
77
  $set (valArr) { // A useful reusable method for multiple selects
61
- [...this.options].forEach((opt) => {
78
+ [...(/** @type {HTMLSelectElement} */ (
79
+ this
80
+ )).options].forEach((opt) => {
62
81
  opt.selected = valArr.includes(opt.value);
63
82
  });
64
83
  }
@@ -68,21 +87,23 @@ const regexpType = {
68
87
  selected: value.flags.includes(flag)
69
88
  }, [flag]];
70
89
  })
90
+ ));
91
+ const root = /** @type {HTMLDivElement} */ (
92
+ jml('div', {dataset: {type: 'regexp'}}, [
93
+ ['label', [
94
+ 'Source ',
95
+ ['input', {
96
+ name: `${typeNamespace}-regexp`, type: 'text',
97
+ value: value.source
98
+ }]
99
+ ]],
100
+ ['br'],
101
+ ['label', [
102
+ 'Flags ',
103
+ select
104
+ ]]
105
+ ])
71
106
  );
72
- const root = jml('div', {dataset: {type: 'regexp'}}, [
73
- ['label', [
74
- 'Source ',
75
- ['input', {
76
- name: `${typeNamespace}-regexp`, type: 'text',
77
- value: value.source
78
- }]
79
- ]],
80
- ['br'],
81
- ['label', [
82
- 'Flags ',
83
- select
84
- ]]
85
- ]);
86
107
  // Could be disallowed flags; we might instead try in
87
108
  // advance which will work
88
109
  select.addEventListener('change', () => {
@@ -14,6 +14,12 @@ const sparseUndefinedType = {
14
14
  ]
15
15
  }
16
16
  },
17
+ toValue (_s) {
18
+ return {value: undefined};
19
+ },
20
+ getValue () {
21
+ return this.toValue('').value;
22
+ },
17
23
  /* istanbul ignore next -- Catching instead of this placeholder */
18
24
  viewUI (/* {value} */) {
19
25
  return ['i', {
@@ -22,7 +28,7 @@ const sparseUndefinedType = {
22
28
  },
23
29
  /* istanbul ignore next -- Catching instead of this placeholder */
24
30
  getInput ({root}) {
25
- return $e(root, 'input');
31
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
26
32
  },
27
33
  /* istanbul ignore next -- Catching instead of this placeholder */
28
34
  editUI ({typeNamespace}) {
@@ -10,7 +10,7 @@ const stringType = {
10
10
  return {value: s.slice(1, -1)};
11
11
  },
12
12
  getInput ({root}) {
13
- return $e(root, 'textarea');
13
+ return /** @type {HTMLTextAreaElement} */ ($e(root, 'textarea'));
14
14
  },
15
15
  setValue ({root, value}) {
16
16
  this.getInput({root}).value = value;
@@ -10,14 +10,14 @@ const undefinedType = {
10
10
  return {value: undefined};
11
11
  },
12
12
  getValue () {
13
- return this.toValue().value;
13
+ return this.toValue('').value;
14
14
  },
15
15
  viewUI (/* {value} */) {
16
16
  return ['i', {dataset: {type: 'undef'}}, ['undefined']];
17
17
  },
18
18
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
19
19
  getInput ({root}) {
20
- return $e(root, 'input');
20
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
21
21
  },
22
22
  editUI ({typeNamespace}) {
23
23
  return ['div', {dataset: {type: 'undef'}}, [
@@ -1,16 +1,25 @@
1
1
  /* globals sceditor */
2
- import {jml} from '../../vendor/jamilih/dist/jml-es.js';
2
+ import {jml} from '../vendor-imports.js';
3
3
  import {$e} from '../utils/templateUtils.js';
4
4
 
5
5
  import dialogs from '../utils/dialogs.js';
6
6
  import {isNullish} from '../utils/types.js';
7
7
 
8
+ /**
9
+ * @type {import('../types.js').TypeObject & {
10
+ * loadBlob: (blob: Blob) => Promise<FileReader>,
11
+ * sceditorInstance: {val: (val?: string) => string|void}
12
+ * }}
13
+ */
8
14
  const blobHTMLType = {
9
15
  // Todo (low): Support other content-types
10
16
  option: ['Blob (text/html)'],
11
17
  stringRegex: /^data:text\/html(?:;base64)?,.*$/u,
12
18
  valueMatch: (v) => v.type === 'text/html',
13
19
  superType: 'blob',
20
+ sceditorInstance: {val () {
21
+ throw new Error('Not yet instantiated');
22
+ }},
14
23
  toValue (s) {
15
24
  // Todo (low): `Blob` untested; use https://stackoverflow.com/a/30407840/271577 ?
16
25
  /**
@@ -42,7 +51,7 @@ const blobHTMLType = {
42
51
  },
43
52
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
44
53
  getInput ({root}) {
45
- return $e(root, 'textarea');
54
+ return /** @type {HTMLTextAreaElement} */ ($e(root, 'textarea'));
46
55
  },
47
56
  getValue (/* {root} */) {
48
57
  return this.toValue(
@@ -50,7 +59,7 @@ const blobHTMLType = {
50
59
  // this.getInput({root}).value
51
60
  ).value;
52
61
  },
53
- loadBlob (value) {
62
+ loadBlob (blob) {
54
63
  const reader = new FileReader();
55
64
  // eslint-disable-next-line promise/avoid-new
56
65
  return new Promise((resolve, reject) => {
@@ -64,32 +73,35 @@ const blobHTMLType = {
64
73
  reject(reader.error);
65
74
  }
66
75
  );
67
- reader.readAsText(value);
76
+ reader.readAsText(blob);
68
77
  });
69
78
  },
70
79
  async setValue ({/* root, */ value}) {
71
80
  const {result} = await this.loadBlob(value);
72
- this.sceditorInstance.val(result);
81
+ this.sceditorInstance.val(/** @type {string} */ (result));
73
82
  // this.getInput({root}).value = result;
74
83
  },
75
84
  viewUI ({value}) {
85
+ /** @type {string} */
76
86
  let val;
77
- const div = jml('div', {dataset: {type: 'blobHTML'}}, [
78
- 'HTML: ',
79
- ['button', {$on: {
80
- click () {
81
- dialogs.alert({message: ['div', [
82
- 'Source: ',
83
- ['textarea', {class: 'view-source'}, [val]]
84
- ]]});
85
- }
86
- }}, ['View source']]
87
- ]);
87
+ const div = /** @type {HTMLDivElement} */ (
88
+ jml('div', {dataset: {type: 'blobHTML'}}, [
89
+ 'HTML: ',
90
+ ['button', {$on: {
91
+ click () {
92
+ dialogs.alert({message: ['div', [
93
+ 'Source: ',
94
+ ['textarea', {class: 'view-source'}, [val]]
95
+ ]]});
96
+ }
97
+ }}, ['View source']]
98
+ ])
99
+ );
88
100
  // eslint-disable-next-line promise/prefer-await-to-then
89
101
  this.loadBlob(value).then(({
90
102
  result
91
103
  }) => {
92
- val = result;
104
+ val = /** @type {string} */ (result);
93
105
  jml('iframe', {
94
106
  sandbox: '',
95
107
  srcdoc: val
@@ -106,10 +118,16 @@ const blobHTMLType = {
106
118
  // return ['i', [`data:text/html,${value}`]];
107
119
  },
108
120
  editUI ({typeNamespace, value}) {
109
- const textarea = jml('textarea', {name: `${typeNamespace}-blobHTML`});
110
- const root = jml('div', {dataset: {type: 'blobHTML'}}, [
111
- textarea
112
- ]);
121
+ const textarea = /** @type {HTMLTextAreaElement} */ (
122
+ jml('textarea', {name: `${typeNamespace}-blobHTML`})
123
+ );
124
+ const root = /** @type {HTMLDivElement} */ (jml(
125
+ 'div',
126
+ {dataset: {type: 'blobHTML'}},
127
+ [
128
+ textarea
129
+ ]
130
+ ));
113
131
  setTimeout(() => {
114
132
  // Push onto these: https://www.sceditor.com/documentation/formats/xhtml/
115
133
  // sceditor.formats.xhtml.converters array
@@ -150,7 +168,9 @@ const blobHTMLType = {
150
168
  });
151
169
  this.sceditorInstance = sceditor.instance(textarea);
152
170
  if (!isNullish(value)) {
153
- this.setValue({root, value});
171
+ /** @type {Required<import('../types.js').TypeObject>} */ (
172
+ this
173
+ ).setValue({root, value});
154
174
  }
155
175
  });
156
176
  return [root];
@@ -1,7 +1,7 @@
1
1
  import {$e} from '../utils/templateUtils.js';
2
2
 
3
3
  /**
4
- * @type {import('../types.js').TypeObject}
4
+ * @type {import('../types.js').TypeObject & {ct: number}}
5
5
  */
6
6
  const falseType = {
7
7
  option: ['Boolean (false)', {value: 'false'}],
@@ -16,7 +16,7 @@ const falseType = {
16
16
  ct: 0,
17
17
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
18
18
  getInput ({root}) {
19
- return $e(root, 'input');
19
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
20
20
  },
21
21
  editUI ({typeNamespace}) {
22
22
  this.ct++;
@@ -1,7 +1,7 @@
1
1
  import {$e} from '../utils/templateUtils.js';
2
2
 
3
3
  /**
4
- * @type {import('../types.js').TypeObject}
4
+ * @type {import('../types.js').TypeObject & {ct: number}}
5
5
  */
6
6
  const trueType = {
7
7
  option: ['Boolean (true)', {value: 'true'}],
@@ -16,7 +16,7 @@ const trueType = {
16
16
  ct: 0,
17
17
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
18
18
  getInput ({root}) {
19
- return $e(root, 'input');
19
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
20
20
  },
21
21
  editUI ({typeNamespace}) {
22
22
  this.ct++;
@@ -1,8 +1,9 @@
1
1
  import {$e} from '../utils/templateUtils.js';
2
2
 
3
3
  /**
4
- * @typedef {TypeObject} SuperTypeObject
5
- * @property {string[]} childTypes
4
+ * @typedef {import('../types.js').TypeObject & {
5
+ * childTypes: string[]
6
+ * }} SuperTypeObject
6
7
  */
7
8
 
8
9
  /**
@@ -24,17 +25,23 @@ const SpecialNumberSuperType = {
24
25
  };
25
26
  },
26
27
  getSelect ({root}) {
27
- return $e(root, 'select');
28
+ return /** @type {HTMLSelectElement} */ ($e(root, 'select'));
28
29
  },
29
30
  /* istanbul ignore next -- No dupe keys, array refs, or validation */
30
31
  getInput ({root}) {
31
- return $e(root, 'select');
32
+ return /** @type {HTMLSelectElement} */ ($e(root, 'select'));
32
33
  },
33
34
  getValue ({root}) {
34
- return this.toValue(this.getSelect({root}).value).value;
35
+ return this.toValue(
36
+ /** @type {Required<import('../types.js').TypeObject>} */ (
37
+ this
38
+ ).getSelect({root}).value
39
+ ).value;
35
40
  },
36
41
  setValue ({root, value}) {
37
- this.getSelect({root}).value = String(value);
42
+ /** @type {Required<import('../types.js').TypeObject>} */ (
43
+ this
44
+ ).getSelect({root}).value = String(value);
38
45
  },
39
46
  viewUI ({value}) {
40
47
  return ['i', {dataset: {type: 'SpecialNumber'}}, [
@@ -1,7 +1,7 @@
1
1
  import {$e} from '../utils/templateUtils.js';
2
2
 
3
3
  /**
4
- * @type {SuperTypeObject}
4
+ * @type {import('./SpecialNumberSuperType.js').SuperTypeObject}
5
5
  */
6
6
  const SpecialRealNumberSuperType = {
7
7
  option: ['Special Real Number', {title: '`Infinity`, `-Infinity`, `-0`'}],
@@ -17,13 +17,19 @@ const SpecialRealNumberSuperType = {
17
17
  };
18
18
  },
19
19
  getSelect ({root}) {
20
- return $e(root, 'select');
20
+ return /** @type {HTMLSelectElement} */ ($e(root, 'select'));
21
21
  },
22
22
  getValue ({root}) {
23
- return this.toValue(this.getSelect({root}).value).value;
23
+ return this.toValue(
24
+ /** @type {Required<import('../types.js').TypeObject>} */ (
25
+ this
26
+ ).getSelect({root}).value
27
+ ).value;
24
28
  },
25
29
  setValue ({root, value}) {
26
- this.getSelect({root}).value = String(value);
30
+ /** @type {Required<import('../types.js').TypeObject>} */ (
31
+ this
32
+ ).getSelect({root}).value = String(value);
27
33
  },
28
34
  viewUI ({value}) {
29
35
  return ['i', {dataset: {type: 'SpecialRealNumber'}}, [
@@ -31,7 +37,7 @@ const SpecialRealNumberSuperType = {
31
37
  ]];
32
38
  },
33
39
  getInput ({root}) {
34
- return $e(root, 'select');
40
+ return /** @type {HTMLSelectElement} */ ($e(root, 'select'));
35
41
  },
36
42
  editUI ({typeNamespace, value = Number.POSITIVE_INFINITY}) {
37
43
  return ['div', {dataset: {type: 'SpecialRealNumber'}}, [