@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.
- package/.eslintignore +3 -0
- package/.eslintrc.cjs +1 -0
- package/.ncurc.cjs +9 -0
- package/CHANGES.md +4 -0
- package/demo/index.html +8 -0
- package/demo/index.js +1 -1
- package/dist/formatAndTypeChoices.d.ts +56 -0
- package/dist/formatAndTypeChoices.d.ts.map +1 -0
- package/dist/formats/indexedDBKey.d.ts +4 -0
- package/dist/formats/indexedDBKey.d.ts.map +1 -0
- package/dist/formats/json.d.ts +4 -0
- package/dist/formats/json.d.ts.map +1 -0
- package/dist/formats/schemaAndArbitrary.d.ts +6 -0
- package/dist/formats/schemaAndArbitrary.d.ts.map +1 -0
- package/dist/formats/schemaOnly.d.ts +6 -0
- package/dist/formats/schemaOnly.d.ts.map +1 -0
- package/dist/formats/structuredCloning.d.ts +20 -0
- package/dist/formats/structuredCloning.d.ts.map +1 -0
- package/dist/formats.d.ts +26 -0
- package/dist/formats.d.ts.map +1 -0
- package/dist/fundamentalTypes/BooleanObjectType.d.ts +8 -0
- package/dist/fundamentalTypes/BooleanObjectType.d.ts.map +1 -0
- package/dist/fundamentalTypes/NumberObjectType.d.ts +6 -0
- package/dist/fundamentalTypes/NumberObjectType.d.ts.map +1 -0
- package/dist/fundamentalTypes/StringObjectType.d.ts +6 -0
- package/dist/fundamentalTypes/StringObjectType.d.ts.map +1 -0
- package/dist/fundamentalTypes/arrayReferenceType.d.ts +8 -0
- package/dist/fundamentalTypes/arrayReferenceType.d.ts.map +1 -0
- package/dist/fundamentalTypes/arrayType.d.ts +60 -0
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -0
- package/dist/fundamentalTypes/bigintType.d.ts +6 -0
- package/dist/fundamentalTypes/bigintType.d.ts.map +1 -0
- package/dist/fundamentalTypes/dateType.d.ts +26 -0
- package/dist/fundamentalTypes/dateType.d.ts.map +1 -0
- package/dist/fundamentalTypes/nullType.d.ts +6 -0
- package/dist/fundamentalTypes/nullType.d.ts.map +1 -0
- package/dist/fundamentalTypes/numberType.d.ts +6 -0
- package/dist/fundamentalTypes/numberType.d.ts.map +1 -0
- package/dist/fundamentalTypes/objectReferenceType.d.ts +8 -0
- package/dist/fundamentalTypes/objectReferenceType.d.ts.map +1 -0
- package/dist/fundamentalTypes/objectType.d.ts +6 -0
- package/dist/fundamentalTypes/objectType.d.ts.map +1 -0
- package/dist/fundamentalTypes/regexpType.d.ts +8 -0
- package/dist/fundamentalTypes/regexpType.d.ts.map +1 -0
- package/dist/fundamentalTypes/sparseUndefinedType.d.ts +6 -0
- package/dist/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -0
- package/dist/fundamentalTypes/stringType.d.ts +6 -0
- package/dist/fundamentalTypes/stringType.d.ts.map +1 -0
- package/dist/fundamentalTypes/undefinedType.d.ts +6 -0
- package/dist/fundamentalTypes/undefinedType.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/src/deepEqual.d.ts +3 -0
- package/dist/src/deepEqual.d.ts.map +1 -0
- package/dist/src/formatAndTypeChoices.d.ts +47 -0
- package/dist/src/formatAndTypeChoices.d.ts.map +1 -0
- package/dist/src/formats/indexedDBKey.d.ts +9 -0
- package/dist/src/formats/indexedDBKey.d.ts.map +1 -0
- package/dist/src/formats/json.d.ts +9 -0
- package/dist/src/formats/json.d.ts.map +1 -0
- package/dist/src/formats/schemaAndArbitrary.d.ts +6 -0
- package/dist/src/formats/schemaAndArbitrary.d.ts.map +1 -0
- package/dist/src/formats/schemaOnly.d.ts +6 -0
- package/dist/src/formats/schemaOnly.d.ts.map +1 -0
- package/dist/src/formats/structuredCloning.d.ts +15 -0
- package/dist/src/formats/structuredCloning.d.ts.map +1 -0
- package/dist/src/formats.d.ts +18 -0
- package/dist/src/formats.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/BooleanObjectType.d.ts +6 -0
- package/dist/src/fundamentalTypes/BooleanObjectType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/NumberObjectType.d.ts +6 -0
- package/dist/src/fundamentalTypes/NumberObjectType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/StringObjectType.d.ts +6 -0
- package/dist/src/fundamentalTypes/StringObjectType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/arrayReferenceType.d.ts +6 -0
- package/dist/src/fundamentalTypes/arrayReferenceType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/arrayType.d.ts +6 -0
- package/dist/src/fundamentalTypes/arrayType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/bigintType.d.ts +6 -0
- package/dist/src/fundamentalTypes/bigintType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/dateType.d.ts +6 -0
- package/dist/src/fundamentalTypes/dateType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/nullType.d.ts +6 -0
- package/dist/src/fundamentalTypes/nullType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/numberType.d.ts +6 -0
- package/dist/src/fundamentalTypes/numberType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/objectReferenceType.d.ts +6 -0
- package/dist/src/fundamentalTypes/objectReferenceType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/objectType.d.ts +6 -0
- package/dist/src/fundamentalTypes/objectType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/regexpType.d.ts +6 -0
- package/dist/src/fundamentalTypes/regexpType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts +6 -0
- package/dist/src/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/stringType.d.ts +6 -0
- package/dist/src/fundamentalTypes/stringType.d.ts.map +1 -0
- package/dist/src/fundamentalTypes/undefinedType.d.ts +6 -0
- package/dist/src/fundamentalTypes/undefinedType.d.ts.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/subTypes/blobHTMLType.d.ts +26 -0
- package/dist/src/subTypes/blobHTMLType.d.ts.map +1 -0
- package/dist/src/subTypes/falseType.d.ts +6 -0
- package/dist/src/subTypes/falseType.d.ts.map +1 -0
- package/dist/src/subTypes/trueType.d.ts +6 -0
- package/dist/src/subTypes/trueType.d.ts.map +1 -0
- package/dist/src/superTypes/SpecialNumberSuperType.d.ts +11 -0
- package/dist/src/superTypes/SpecialNumberSuperType.d.ts.map +1 -0
- package/dist/src/superTypes/SpecialRealNumberSuperType.d.ts +6 -0
- package/dist/src/superTypes/SpecialRealNumberSuperType.d.ts.map +1 -0
- package/dist/src/typeChoices.d.ts +30 -0
- package/dist/src/typeChoices.d.ts.map +1 -0
- package/dist/src/types.d.ts +333 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils/dialogs.d.ts +29 -0
- package/dist/src/utils/dialogs.d.ts.map +1 -0
- package/dist/src/utils/jsonPointer.d.ts +42 -0
- package/dist/src/utils/jsonPointer.d.ts.map +1 -0
- package/dist/src/utils/templateUtils.d.ts +59 -0
- package/dist/src/utils/templateUtils.d.ts.map +1 -0
- package/dist/src/utils/types.d.ts +2 -0
- package/dist/src/utils/types.d.ts.map +1 -0
- package/dist/subTypes/blobHTMLType.d.ts +14 -0
- package/dist/subTypes/blobHTMLType.d.ts.map +1 -0
- package/dist/subTypes/falseType.d.ts +8 -0
- package/dist/subTypes/falseType.d.ts.map +1 -0
- package/dist/subTypes/trueType.d.ts +8 -0
- package/dist/subTypes/trueType.d.ts.map +1 -0
- package/dist/superTypes/SpecialNumberSuperType.d.ts +14 -0
- package/dist/superTypes/SpecialNumberSuperType.d.ts.map +1 -0
- package/dist/superTypes/SpecialRealNumberSuperType.d.ts +6 -0
- package/dist/superTypes/SpecialRealNumberSuperType.d.ts.map +1 -0
- package/dist/typeChoices.d.ts +103 -0
- package/dist/typeChoices.d.ts.map +1 -0
- package/dist/types.d.ts +523 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/dialogs.d.ts +109 -0
- package/dist/utils/dialogs.d.ts.map +1 -0
- package/dist/utils/jsonPointer.d.ts +46 -0
- package/dist/utils/jsonPointer.d.ts.map +1 -0
- package/dist/utils/templateUtils.d.ts +59 -0
- package/dist/utils/templateUtils.d.ts.map +1 -0
- package/dist/utils/types.d.ts +2 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/vendor/jamilih/dist/jml-es.d.ts +436 -0
- package/dist/vendor/jamilih/dist/jml-es.d.ts.map +1 -0
- package/dist/vendor/typeson-registry/dist/index.d.ts +400 -0
- package/dist/vendor/typeson-registry/dist/index.d.ts.map +1 -0
- package/dist/vendor-imports.d.ts +3 -0
- package/dist/vendor-imports.d.ts.map +1 -0
- package/package.json +16 -11
- package/postorder-traversal.js +58 -0
- package/src/formatAndTypeChoices.js +95 -50
- package/src/formats/indexedDBKey.js +49 -57
- package/src/formats/json.js +47 -56
- package/src/formats/schemaOnly.js +12 -2
- package/src/formats/structuredCloning.js +162 -105
- package/src/formats.js +38 -10
- package/src/fundamentalTypes/BooleanObjectType.js +6 -4
- package/src/fundamentalTypes/NumberObjectType.js +5 -3
- package/src/fundamentalTypes/StringObjectType.js +1 -1
- package/src/fundamentalTypes/arrayReferenceType.js +29 -14
- package/src/fundamentalTypes/arrayType.js +789 -278
- package/src/fundamentalTypes/bigintType.js +2 -2
- package/src/fundamentalTypes/dateType.js +42 -14
- package/src/fundamentalTypes/nullType.js +1 -1
- package/src/fundamentalTypes/numberType.js +2 -2
- package/src/fundamentalTypes/objectReferenceType.js +7 -5
- package/src/fundamentalTypes/regexpType.js +45 -24
- package/src/fundamentalTypes/sparseUndefinedType.js +7 -1
- package/src/fundamentalTypes/stringType.js +1 -1
- package/src/fundamentalTypes/undefinedType.js +2 -2
- package/src/subTypes/blobHTMLType.js +42 -22
- package/src/subTypes/falseType.js +2 -2
- package/src/subTypes/trueType.js +2 -2
- package/src/superTypes/SpecialNumberSuperType.js +13 -6
- package/src/superTypes/SpecialRealNumberSuperType.js +11 -5
- package/src/typeChoices.js +137 -55
- package/src/types.js +309 -146
- package/src/utils/dialogs.js +98 -29
- package/src/utils/jsonPointer.js +4 -0
- package/src/utils/templateUtils.js +27 -12
- package/src/vendor-imports.js +8 -0
- package/tsconfig.json +18 -0
- package/typings/sceditor.d.ts +20 -0
- package/vendor/jamilih/dist/jml-es.js +1019 -389
- package/vendor/jamilih/dist/jml.d.ts +436 -0
- package/vendor/jamilih/package.json +136 -0
- 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
|
|
12
|
+
import json from './json.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
* @
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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,
|
|
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[''] =
|
|
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
|
|
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({
|
|
164
|
-
|
|
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] =
|
|
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 {
|
|
230
|
+
* @param {import('../formats.js').AvailableFormat} format
|
|
187
231
|
* @param {string} state
|
|
188
|
-
* @param {
|
|
189
|
-
* @param {
|
|
232
|
+
* @param {import('../types.js').AvailableType} valType
|
|
233
|
+
* @param {import('../formats.js').StructuredCloneValue} v
|
|
190
234
|
* @throws {Error}
|
|
191
|
-
* @returns {
|
|
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
|
-
} =
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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
|
-
* @
|
|
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
|
-
|
|
36
|
-
|
|
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(
|
|
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
|
|
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
|
|
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,
|
|
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'),
|
|
112
|
+
/** @type {Element} */ ($e(referent, '.arrayItems')),
|
|
113
|
+
['fieldset', 'legend']
|
|
105
114
|
);
|
|
106
115
|
const childPropertyValues = legends.map(
|
|
107
|
-
(legend) => getPropertyValueFromLegend(
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
186
|
+
// eslint-disable-next-line object-shorthand -- TS
|
|
187
|
+
root: /** @type {HTMLDivElement} */ (root),
|
|
173
188
|
topRoot
|
|
174
189
|
});
|
|
175
190
|
});
|