@es-joy/jsoe 0.3.0 → 0.4.1

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 +8 -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 +17 -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
@@ -1,19 +1,29 @@
1
+ import {
2
+ Typeson, unescapeKeyPathComponent, structuredCloningThrowing
3
+ } from '../vendor-imports.js';
4
+
1
5
  import Formats from '../formats.js';
2
6
  import Types from '../types.js';
3
7
  import {buildTypeChoices} from '../typeChoices.js';
4
- import {
5
- Typeson, unescapeKeyPathComponent, structuredCloningThrowing
6
- } from '../../vendor/typeson-registry/dist/index.js';
7
8
  import {
8
9
  typesonPathToJSONPointer
9
10
  } from '../utils/jsonPointer.js';
10
11
 
11
- import * as json from './json.js';
12
+ import json from './json.js';
12
13
 
13
14
  /**
14
- * @callback EncapsulateObserver
15
- * @param {TypesonObserver} observerObj
16
- * @returns {void}
15
+ * @typedef {(info: {
16
+ * propName: string,
17
+ * type: import('../types.js').AvailableType,
18
+ * value: import('../formats.js').StructuredCloneValue,
19
+ * bringIntoFocus?: boolean,
20
+ * schemaContent?: object,
21
+ * schemaState?: import('../types.js').GetPossibleSchemasForPathAndType
22
+ * }) => Element} AddAndSetArrayElement
23
+ */
24
+
25
+ /**
26
+ * @typedef {import('typeson-registry').ObserverData} EncapsulateObserver
17
27
  */
18
28
 
19
29
  /**
@@ -22,9 +32,17 @@ import * as json from './json.js';
22
32
  */
23
33
  const encapsulateObserver = (stateObj) => {
24
34
  const {
25
- typeNamespace, readonly, format, schemaContent,
35
+ typeNamespace, readonly, format: frmt, schemaContent,
26
36
  getPossibleSchemasForPathAndType
27
37
  } = stateObj;
38
+
39
+ const format = /** @type {import('../formats.js').AvailableFormat} */ (frmt);
40
+
41
+ /**
42
+ * @type {{[key: string]: Element & {
43
+ * $addAndSetArrayElement: AddAndSetArrayElement
44
+ * }}}
45
+ */
28
46
  const parents = {};
29
47
  return (observerObj) => {
30
48
  const {
@@ -62,6 +80,7 @@ const encapsulateObserver = (stateObj) => {
62
80
 
63
81
  // console.log('observerObj', observerObj);
64
82
 
83
+ /** @type {import('../types.js').AvailableType} */
65
84
  let newType;
66
85
  let newValue = value;
67
86
 
@@ -79,11 +98,17 @@ const encapsulateObserver = (stateObj) => {
79
98
  } else {
80
99
  try {
81
100
  newType = canonicalToAvailableType(
82
- format, state, type, value
101
+ format,
102
+ state,
103
+ /**
104
+ * @type {import('../types.js').AvailableType}
105
+ */
106
+ (type),
107
+ value
83
108
  ); // Todo (low): Add state for second argument
84
109
  } catch (err) {
85
110
  console.log('err', type, err);
86
- stateObj.error = err;
111
+ stateObj.error = /** @type {Error} */ (err);
87
112
  return;
88
113
  }
89
114
  }
@@ -123,7 +148,10 @@ const encapsulateObserver = (stateObj) => {
123
148
  // type wanting the serialized data
124
149
  replaced
125
150
  });
126
- parents[''] = stateObj.rootUI;
151
+ parents[''] = /**
152
+ * @type {Element &
153
+ * {$addAndSetArrayElement: AddAndSetArrayElement}}
154
+ */ (stateObj.rootUI);
127
155
  return;
128
156
  }
129
157
 
@@ -140,9 +168,10 @@ const encapsulateObserver = (stateObj) => {
140
168
  // for circulars there?), could change Typeson to report `readonly`
141
169
  // for the nested items, in which case, we could block out `readonly`
142
170
  // instead of doing this here
143
- if (!ui || !ui.$addAndSetArrayElement) {
171
+ if (!ui || !('$addAndSetArrayElement' in ui)) {
144
172
  return;
145
173
  }
174
+
146
175
  const root = ui.$addAndSetArrayElement({
147
176
  propName: arrayOrObjectPropertyName,
148
177
  type: newType,
@@ -160,12 +189,27 @@ const encapsulateObserver = (stateObj) => {
160
189
  */
161
190
  });
162
191
  if (!readonly) {
163
- Types.setValue({type: newType, root, value: newValue});
164
- Types.validate({type: newType, root, topRoot: stateObj.rootUI});
192
+ Types.setValue({
193
+ type: newType,
194
+ // eslint-disable-next-line object-shorthand -- TS
195
+ root: /** @type {HTMLDivElement} */ (root),
196
+ value: newValue
197
+ });
198
+ Types.validate({
199
+ type: newType,
200
+ // eslint-disable-next-line object-shorthand -- TS
201
+ root: /** @type {HTMLDivElement} */ (root),
202
+ topRoot: /** @type {HTMLDivElement} */ (stateObj.rootUI)
203
+ });
165
204
  }
166
205
 
167
206
  if (hasChildren) {
168
- parents[keypath] = root;
207
+ parents[keypath] = /**
208
+ * @type {Element &
209
+ * {$addAndSetArrayElement: AddAndSetArrayElement}}
210
+ */ (
211
+ root
212
+ );
169
213
  }
170
214
  });
171
215
  };
@@ -183,23 +227,37 @@ const replaceTypes = (originTypes, replacements) => {
183
227
  };
184
228
 
185
229
  /**
186
- * @param {string} format
230
+ * @param {import('../formats.js').AvailableFormat} format
187
231
  * @param {string} state
188
- * @param {string} valType
189
- * @param {ArbitraryValue} v
232
+ * @param {import('../types.js').AvailableType} valType
233
+ * @param {import('../formats.js').StructuredCloneValue} v
190
234
  * @throws {Error}
191
- * @returns {string}
235
+ * @returns {import('../types.js').AvailableType}
192
236
  */
193
237
  const canonicalToAvailableType = (format, state, valType, v) => {
194
238
  const frmt = Formats.availableFormats[format];
195
239
  const {getTypesForState, convertFromTypeson, testInvalid} = frmt;
196
240
  const allowableTypes = getTypesForState.call(frmt, state);
241
+ /* istanbul ignore if -- Guard */
242
+ if (!allowableTypes) {
243
+ throw new Error('Unexpected undefined type for state');
244
+ }
245
+
246
+ /**
247
+ * @type {import('../types.js').AvailableType|undefined}
248
+ */
197
249
  let ret;
198
250
  console.log('format, state, valType, v', format, state, valType, v);
251
+
252
+ /**
253
+ * @param {string} newValType
254
+ * @throws {Error}
255
+ * @returns {never}
256
+ */
199
257
  const isInvalid = (newValType) => {
200
258
  console.log('newValType', newValType);
201
259
  const err = new Error('Invalid');
202
- err.newValType = newValType;
260
+ /** @type {Error & {newValType: string}} */ (err).newValType = newValType;
203
261
  throw err;
204
262
  };
205
263
  if (convertFromTypeson) {
@@ -218,13 +276,17 @@ const canonicalToAvailableType = (format, state, valType, v) => {
218
276
  }
219
277
  return false;
220
278
  })) {
221
- return ret;
279
+ return /** @type {import('../types.js').AvailableType} */ (ret);
222
280
  }
223
281
  console.log('ret', ret);
224
282
  allowableTypes.some((allowableType) => {
283
+ // eslint-disable-next-line max-len -- Long
284
+ const typeObj = /** @type {import('../types.js').TypeObject & {childTypes: string[]}} */ (
285
+ Types.availableTypes[allowableType]
286
+ );
225
287
  const {
226
288
  valueMatch, superType, childTypes
227
- } = Types.availableTypes[allowableType];
289
+ } = typeObj;
228
290
  if (
229
291
  (superType && valueMatch &&
230
292
  // Currently using for `true` and `false`
@@ -245,95 +307,87 @@ const canonicalToAvailableType = (format, state, valType, v) => {
245
307
 
246
308
  /**
247
309
  * @callback FormatIterator
248
- * @param {StructuredCloneValue} records
310
+ * @param {import('../formats.js').StructuredCloneValue} records
249
311
  * @param {import('../types.js').StateObject} stateObj
250
312
  * @returns {Promise<Element>}
251
313
  */
252
314
 
253
- /**
254
- * @type {FormatIterator}
255
- */
256
- export const iterate = (records, stateObj) => {
257
- console.log('records', records);
258
- if (!stateObj.format) {
259
- stateObj.format = 'structuredCloning';
260
- }
261
- // Todo: Replace this with async typeson?
262
- // eslint-disable-next-line promise/avoid-new
263
- return new Promise((resolve, reject) => {
264
- const typeson = new Typeson({
265
- encapsulateObserver: encapsulateObserver(stateObj)
266
- }).register(structuredCloningThrowing);
267
- typeson.encapsulate(records);
268
- // Todo (low): We might want to run async encapsulate for
269
- // async types (and put this after Promise resolves)
270
- if (stateObj.error) {
271
- reject(stateObj.error);
272
- } else {
273
- resolve(stateObj.rootUI);
315
+ /** @type {import('../formats.js').Format} */
316
+ const structuredCloning = {
317
+ iterate (records, stateObj) {
318
+ console.log('records', records);
319
+ if (!stateObj.format) {
320
+ stateObj.format = 'structuredCloning';
274
321
  }
275
- });
276
- };
277
-
278
- /**
279
- * @param {string} state
280
- * @returns {string[]}
281
- */
282
- export const getTypesForState = function (state) {
283
- if (state && Types.contexts.structuredCloning[state]) {
284
- const typesForFormat = this.getTypesForState() ||
285
- /* istanbul ignore next -- types should be an array */
286
- [];
287
- Types.contexts.structuredCloning[state].forEach(({type, after}) => {
288
- const precedingIdx = typesForFormat.indexOf(after);
289
- typesForFormat.splice(precedingIdx + 1, 0, type);
322
+ // Todo: Replace this with async typeson?
323
+ // eslint-disable-next-line promise/avoid-new
324
+ return new Promise((resolve, reject) => {
325
+ const typeson = new Typeson({
326
+ encapsulateObserver: encapsulateObserver(stateObj)
327
+ }).register(structuredCloningThrowing);
328
+ typeson.encapsulate(records);
329
+ // Todo (low): We might want to run async encapsulate for
330
+ // async types (and put this after Promise resolves)
331
+ if (stateObj.error) {
332
+ reject(stateObj.error);
333
+ } else {
334
+ resolve(/** @type {Required<import('../types.js').StateObject>} */ (
335
+ stateObj
336
+ ).rootUI);
337
+ }
290
338
  });
291
- return typesForFormat;
292
- }
293
- return this.types();
294
- /*
295
- // Todo (low): These need to specify their own inner contexts
296
- if (['map', 'set'].includes(state)) {return;}
297
- if ('int8array', 'uint8array', 'uint8clampedarray',
298
- 'int16array', 'uint16array', 'int32array',
299
- 'uint32array', 'float32array', 'float64array'
300
- ).includes(state)) {return;}
301
- */
302
- };
303
-
304
- /**
305
- * @returns {string[]}
306
- */
307
- export const types = () => {
308
- const jsonTypes = json.types();
309
- replaceTypes(jsonTypes, [
310
- [
311
- 'array',
312
- // 'sparseArrays',
313
- 'arrayNonindexKeys'
314
- ]
315
- ]);
316
- return [
317
- // This type is only for throwing upon cloning errors:
318
- // 'checkDataCloneException'
319
- // This type might be supported by evaluable JS or config passed in:
320
- // 'userObject'
321
- ...jsonTypes,
322
- 'undef', // Explicit undefined only
323
- 'bigint',
324
- 'SpecialNumber', // '`NaN`, `Infinity`, `-Infinity`'},
325
- 'date',
326
- 'regexp',
327
- 'BooleanObject',
328
- 'NumberObject',
329
- 'StringObject',
330
- 'blobHTML'
331
- // Ok, but will need some work
332
- // 'map', 'set',
333
- // 'blob', 'file', 'filelist'
334
- // 'arraybuffer', 'arraybufferview'
335
- // 'dataview', 'imagedata', 'imagebitmap',
339
+ },
340
+ getTypesForState (state) {
341
+ if (state && Types.contexts.structuredCloning[state]) {
342
+ const typesForFormat = this.getTypesForState() ||
343
+ /* istanbul ignore next -- types should be an array */
344
+ [];
345
+ Types.contexts.structuredCloning[state].forEach(({type, after}) => {
346
+ const precedingIdx = typesForFormat.indexOf(after);
347
+ typesForFormat.splice(precedingIdx + 1, 0, type);
348
+ });
349
+ return typesForFormat;
350
+ }
351
+ return this.types();
336
352
  /*
353
+ // Todo (low): These need to specify their own inner contexts
354
+ if (['map', 'set'].includes(state)) {return;}
355
+ if ('int8array', 'uint8array', 'uint8clampedarray',
356
+ 'int16array', 'uint16array', 'int32array',
357
+ 'uint32array', 'float32array', 'float64array'
358
+ ).includes(state)) {return;}
359
+ */
360
+ },
361
+ types () {
362
+ const jsonTypes = json.types();
363
+ replaceTypes(jsonTypes, [
364
+ [
365
+ 'array',
366
+ // 'sparseArrays',
367
+ 'arrayNonindexKeys'
368
+ ]
369
+ ]);
370
+ return [
371
+ // This type is only for throwing upon cloning errors:
372
+ // 'checkDataCloneException'
373
+ // This type might be supported by evaluable JS or config passed in:
374
+ // 'userObject'
375
+ ...jsonTypes,
376
+ 'undef', // Explicit undefined only
377
+ 'bigint',
378
+ 'SpecialNumber', // '`NaN`, `Infinity`, `-Infinity`'},
379
+ 'date',
380
+ 'regexp',
381
+ 'BooleanObject',
382
+ 'NumberObject',
383
+ 'StringObject',
384
+ 'blobHTML'
385
+ // Ok, but will need some work
386
+ // 'map', 'set',
387
+ // 'blob', 'file', 'filelist'
388
+ // 'arraybuffer', 'arraybufferview'
389
+ // 'dataview', 'imagedata', 'imagebitmap',
390
+ /*
337
391
  // Typed Arrays
338
392
  'int8array',
339
393
  'uint8array',
@@ -350,5 +404,8 @@ export const types = () => {
350
404
  'IntlDateTimeFormat',
351
405
  'IntlNumberFormat'
352
406
  */
353
- ];
407
+ ];
408
+ }
354
409
  };
410
+
411
+ export default structuredCloning;
package/src/formats.js CHANGED
@@ -1,20 +1,43 @@
1
- import * as indexedDBKey from './formats/indexedDBKey.js';
2
- import * as json from './formats/json.js';
3
- import * as structuredCloning from './formats/structuredCloning.js';
1
+ import indexedDBKey from './formats/indexedDBKey.js';
2
+ import json from './formats/json.js';
3
+ import structuredCloning from './formats/structuredCloning.js';
4
+
5
+ /**
6
+ * An arbitrary Structured Clone, JSON, etc. value.
7
+ * @typedef {any} StructuredCloneValue
8
+ */
4
9
 
5
10
  /* schema:
6
- const getTypeForFormatStateAndValue = ({format, state, value}) => {
11
+ export const getTypeForFormatStateAndValue = ({format, state, value}) => {
7
12
  const valType = new Typeson().register(
8
13
  structuredCloningThrowing
9
14
  ).rootTypeName(value);
10
15
  return canonicalToAvailableType(format, state, valType, value);
11
16
  };
12
- Formats.getTypeForFormatStateAndValue = getTypeForFormatStateAndValue;
13
17
  */
14
18
 
19
+ /**
20
+ * @typedef {"indexedDBKey"|"json"|"structuredCloning"} AvailableFormat
21
+ */
22
+
23
+ /**
24
+ * @typedef {{
25
+ * types: () => (import('./types.js').AvailableType)[],
26
+ * testInvalid?: (
27
+ * newType: string, value: Date|Array<StructuredCloneValue>
28
+ * ) => boolean|undefined,
29
+ * convertFromTypeson?: (
30
+ * typesonType: import('./types.js').AvailableType
31
+ * ) => import('./types.js').AvailableType|undefined,
32
+ * iterate: import('./formats/structuredCloning.js').FormatIterator,
33
+ * getTypesForState: (state?: string) => undefined|
34
+ * (import('./types.js').AvailableType)[]
35
+ * }} Format
36
+ */
37
+
15
38
  // Using methods ensure we have fresh copies
16
39
  const Formats = {
17
- availableFormats: {
40
+ availableFormats: /** @type {{[key: string]: Format}} */ ({
18
41
  indexedDBKey,
19
42
  json,
20
43
  // Todo (readme): these too? getTypesForState(state)
@@ -23,17 +46,22 @@ const Formats = {
23
46
  schemaOnly,
24
47
  */
25
48
  structuredCloning
26
- }
49
+ })
27
50
  };
28
51
 
29
52
  /**
30
- * @type {import('./formats/structuredCloning.js').FormatIterator}
53
+ * @param {AvailableFormat} format
54
+ * @param {StructuredCloneValue} record
55
+ * @param {import('./types.js').StateObject} stateObj
56
+ * @returns {Promise<Element>}
31
57
  */
32
58
  export async function getControlsForFormatAndValue (format, record, stateObj) {
33
59
  return await Formats.availableFormats[format]
34
60
  .iterate(record, {
35
- format,
36
- ...stateObj
61
+ ...stateObj,
62
+ // This had been before `stateObj` but should apparently have precedence
63
+ // or just avoid passing `format` to this function
64
+ format
37
65
  });
38
66
  }
39
67
 
@@ -1,7 +1,7 @@
1
1
  import {$e, $$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 BooleanObjectType = {
7
7
  option: ['BooleanObject'],
@@ -13,13 +13,15 @@ const BooleanObjectType = {
13
13
  };
14
14
  },
15
15
  getInput ({root}) {
16
- return $e(root, 'input');
16
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
17
17
  },
18
18
  getValue ({root}) {
19
- return this.toValue(String(this.getInput({root}).checked)).value;
19
+ return this.toValue(String(/** @type {HTMLInputElement} */ (
20
+ this.getInput({root})
21
+ ).checked)).value;
20
22
  },
21
23
  setValue ({root, value}) {
22
- const inputs = $$e(root, 'input');
24
+ const inputs = /** @type {HTMLInputElement[]} */ ($$e(root, 'input'));
23
25
  const input = inputs[value.valueOf() ? 0 : 1];
24
26
  input.checked = true;
25
27
  },
@@ -1,5 +1,5 @@
1
1
  import {$e} from '../utils/templateUtils.js';
2
- import Types from '../types.js';
2
+ import numberType from './numberType.js';
3
3
 
4
4
  /**
5
5
  * @type {import('../types.js').TypeObject}
@@ -12,10 +12,12 @@ const NumberObjectType = {
12
12
  return {value: new Number(s)};
13
13
  },
14
14
  validate ({root}) {
15
- return Types.availableTypes.number.validate({root});
15
+ return /** @type {Required<import('../types.js').TypeObject>} */ (
16
+ numberType
17
+ ).validate({root});
16
18
  },
17
19
  getInput ({root}) {
18
- return $e(root, 'input');
20
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
19
21
  },
20
22
  getValue ({root}) {
21
23
  return this.toValue(this.getInput({root}).value).value;
@@ -12,7 +12,7 @@ const StringObjectType = {
12
12
  },
13
13
  option: ['StringObject'],
14
14
  getInput ({root}) {
15
- return $e(root, 'textarea');
15
+ return /** @type {HTMLTextAreaElement} */ ($e(root, 'textarea'));
16
16
  },
17
17
  getValue ({root}) {
18
18
  return this.toValue(this.getInput({root}).value).value;
@@ -5,13 +5,16 @@ import {
5
5
  } from '../utils/jsonPointer.js';
6
6
 
7
7
  /**
8
- * @type {import('../types.js').TypeObject}
8
+ * @type {import('../types.js').TypeObject & {type: "array"}}
9
9
  */
10
10
  const arrayReferenceType = {
11
11
  option: ['Array reference'],
12
12
  type: 'array',
13
13
  stringRegex: /^arrayRef\((?:|\/[^)]*)\)$/u,
14
- toValue (s, {rootHolder, parent, parentPath}) {
14
+ toValue (s, info) {
15
+ const {
16
+ rootHolder, parent, parentPath
17
+ } = /** @type {import('../types.js').RootInfo} */ (info);
15
18
  const path = s.slice(`${this.type}Ref(`.length, -1);
16
19
  rootHolder.push([this.type, parent, parentPath, path]);
17
20
  return {assign: false};
@@ -37,7 +40,7 @@ const arrayReferenceType = {
37
40
  }
38
41
  },
39
42
  getInput ({root}) {
40
- return $e(root, 'input');
43
+ return /** @type {HTMLInputElement} */ ($e(root, 'input'));
41
44
  },
42
45
  setValue ({root, value}) {
43
46
  this.getInput({root}).value = value;
@@ -50,7 +53,7 @@ const arrayReferenceType = {
50
53
  if (!stateObj.paths) {
51
54
  stateObj.paths = {};
52
55
  }
53
- stateObj.paths[currentPath] = {
56
+ stateObj.paths[/** @type {string} */ (currentPath)] = {
54
57
  referentPath,
55
58
  // Todo (low): Should be utilized along with
56
59
  // other validation checking
@@ -64,6 +67,11 @@ const arrayReferenceType = {
64
67
  const {type} = this;
65
68
  const input = this.getInput({root});
66
69
  const path = input.value;
70
+
71
+ /**
72
+ * @param {string|undefined} message
73
+ * @returns {{valid: false, message: string|undefined}}
74
+ */
67
75
  const invalidMessage = (message) => {
68
76
  return {valid: false, message};
69
77
  };
@@ -89,7 +97,7 @@ const arrayReferenceType = {
89
97
  'arrayNonindexKeys'
90
98
  // 'sparseArrays'
91
99
  ].includes(
92
- Types.getTypeForRoot(referent)
100
+ /** @type {string} */ (Types.getTypeForRoot(referent))
93
101
  );
94
102
  };
95
103
  let message;
@@ -101,19 +109,23 @@ const arrayReferenceType = {
101
109
  // order)
102
110
  const legends = DOM.filterChildElements(
103
111
  // Ensure we are only getting one array level at a time
104
- $e(referent, '.arrayItems'), ['fieldset', 'legend']
112
+ /** @type {Element} */ ($e(referent, '.arrayItems')),
113
+ ['fieldset', 'legend']
105
114
  );
106
115
  const childPropertyValues = legends.map(
107
- (legend) => getPropertyValueFromLegend(legend)
116
+ (legend) => getPropertyValueFromLegend(
117
+ /** @type {HTMLLegendElement} */ (legend)
118
+ )
108
119
  );
109
120
  const partMatchIndex = childPropertyValues.indexOf(pathPart);
110
121
  if (partMatchIndex === -1) {
111
122
  message = "Specified path doesn't exist";
112
123
  return true;
113
124
  }
114
- referent = $e(
115
- legends[partMatchIndex].parentElement, 'div[data-type]'
116
- );
125
+ referent = /** @type {HTMLDivElement} */ ($e(
126
+ /** @type {Element} */ (legends[partMatchIndex].parentElement),
127
+ 'div[data-type]'
128
+ ));
117
129
  if (referent === root) {
118
130
  message = "Can't reference self";
119
131
  return true;
@@ -143,11 +155,11 @@ const arrayReferenceType = {
143
155
  // Condition to confirm that referenced element is an array or
144
156
  // object (or reference) with the designated `type`
145
157
  const referentType = Types.getTypeForRoot(referent);
146
- const referentBaseType = [
158
+ const referentBaseType = /** @type {(string|null|undefined)[]} */ ([
147
159
  'array',
148
160
  'arrayNonindexKeys'
149
161
  // 'sparseArrays'
150
- ].includes(referentType)
162
+ ]).includes(referentType)
151
163
  ? 'array'
152
164
  : (referentType === 'object'
153
165
  ? 'object'
@@ -165,11 +177,14 @@ const arrayReferenceType = {
165
177
  };
166
178
  },
167
179
  validateAll ({topRoot}) {
168
- const type = `${this.type}Reference`;
180
+ const type = /** @type {import('../types.js').AvailableType} */ (
181
+ `${this.type}Reference`
182
+ );
169
183
  $$e(topRoot, `div[data-type="${type}"]`).forEach((root) => {
170
184
  Types.validate({
171
185
  type,
172
- root,
186
+ // eslint-disable-next-line object-shorthand -- TS
187
+ root: /** @type {HTMLDivElement} */ (root),
173
188
  topRoot
174
189
  });
175
190
  });