@es-joy/jsoe 0.5.0 → 0.6.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 +2 -0
- package/.eslintrc.cjs +2 -0
- package/.nyc_output/out.json +121296 -0
- package/CHANGES.md +10 -0
- package/README.md +47 -21
- package/cypress.config.ts +13 -0
- package/demo/index-instrumented.html +29 -0
- package/demo/index.html +10 -1
- package/demo/index.js +482 -126
- package/dist/formatAndTypeChoices.d.ts +10 -4
- package/dist/formatAndTypeChoices.d.ts.map +1 -1
- package/dist/formats/json.d.ts.map +1 -1
- package/dist/formats/structuredCloning.d.ts +2 -1
- package/dist/formats/structuredCloning.d.ts.map +1 -1
- package/dist/fundamentalTypes/arrayType.d.ts +6 -37
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
- package/dist/fundamentalTypes/dateType.d.ts.map +1 -1
- package/dist/fundamentalTypes/errorType.d.ts +6 -0
- package/dist/fundamentalTypes/errorType.d.ts.map +1 -0
- package/dist/fundamentalTypes/mapType.d.ts +6 -0
- package/dist/fundamentalTypes/mapType.d.ts.map +1 -0
- package/dist/fundamentalTypes/nullType.d.ts.map +1 -1
- package/dist/fundamentalTypes/objectReferenceType.d.ts.map +1 -1
- package/dist/fundamentalTypes/setType.d.ts +6 -0
- package/dist/fundamentalTypes/setType.d.ts.map +1 -0
- package/dist/fundamentalTypes/sparseUndefinedType.d.ts.map +1 -1
- package/dist/fundamentalTypes/undefinedType.d.ts.map +1 -1
- package/dist/subTypes/blobHTMLType.d.ts +12 -6
- package/dist/subTypes/blobHTMLType.d.ts.map +1 -1
- package/dist/superTypes/SpecialNumberType.d.ts +14 -0
- package/dist/superTypes/SpecialNumberType.d.ts.map +1 -0
- package/dist/superTypes/SpecialRealNumberType.d.ts +6 -0
- package/dist/superTypes/SpecialRealNumberType.d.ts.map +1 -0
- package/dist/superTypes/errorsSpecialType.d.ts +8 -0
- package/dist/superTypes/errorsSpecialType.d.ts.map +1 -0
- package/dist/typeChoices.d.ts +4 -2
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts +85 -233
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/dialogs.d.ts +22 -22
- package/dist/utils/dialogs.d.ts.map +1 -1
- package/dist/utils/templateUtils.d.ts +6 -6
- package/dist/utils/templateUtils.d.ts.map +1 -1
- package/dist/vendor-imports.d.ts +1 -1
- package/package.json +39 -34
- package/rollup.config.js +14 -2
- package/server.js +1 -1
- package/src/formatAndTypeChoices.js +14 -13
- package/src/formats/indexedDBKey.js +2 -2
- package/src/formats/json.js +1 -2
- package/src/formats/structuredCloning.js +104 -29
- package/src/formats.js +2 -2
- package/src/fundamentalTypes/arrayReferenceType.js +3 -3
- package/src/fundamentalTypes/arrayType.js +384 -79
- package/src/fundamentalTypes/dateType.js +4 -6
- package/src/fundamentalTypes/errorType.js +416 -0
- package/src/fundamentalTypes/mapType.js +34 -0
- package/src/fundamentalTypes/nullType.js +1 -2
- package/src/fundamentalTypes/objectReferenceType.js +2 -1
- package/src/fundamentalTypes/regexpType.js +2 -2
- package/src/fundamentalTypes/setType.js +34 -0
- package/src/fundamentalTypes/sparseUndefinedType.js +2 -3
- package/src/fundamentalTypes/undefinedType.js +2 -3
- package/src/jsoe.css +3 -0
- package/src/subTypes/blobHTMLType.js +37 -33
- package/src/subTypes/falseType.js +2 -2
- package/src/subTypes/trueType.js +2 -2
- package/src/superTypes/{SpecialNumberSuperType.js → SpecialNumberType.js} +1 -1
- package/src/superTypes/{SpecialRealNumberSuperType.js → SpecialRealNumberType.js} +3 -2
- package/src/superTypes/errorsSpecialType.js +768 -0
- package/src/typeChoices.js +27 -20
- package/src/types.js +72 -40
- package/src/utils/dialogs.js +11 -12
- package/src/utils/jsonPointer.js +3 -3
- package/src/utils/templateUtils.js +4 -4
- package/src/vendor-imports.js +2 -2
- package/tsconfig.json +1 -1
- package/typings/CypressPlugins.d.ts +10 -0
- package/vendor/jamilih/dist/jml-es.js +126 -106
- package/vendor/typeson-registry/dist/index.js +188 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@es-joy/jsoe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"description": "Editing of arbitrary JavaScript objects",
|
|
14
14
|
"scripts": {
|
|
15
15
|
"tsc": "tsc",
|
|
16
|
-
"
|
|
16
|
+
"tsc-cypress": "tsc -p cypress/tsconfig.json",
|
|
17
|
+
"eslint": "eslint .",
|
|
17
18
|
"lint": "npm run eslint --",
|
|
18
19
|
"coverage": "open-cli http://localhost:8087/coverage/lcov-report/",
|
|
19
20
|
"open": "open-cli http://localhost:8087/demo/",
|
|
@@ -26,11 +27,11 @@
|
|
|
26
27
|
"instrument-remove-instrumented": "rimraf instrumented",
|
|
27
28
|
"instrument-remove": "run-p -c instrument-remove-cache instrument-remove-instrumented",
|
|
28
29
|
"copy-pages": "cp node_modules/sceditor/minified/themes/default.min.css vendor/sceditor/minified/themes/default.min.css && cp node_modules/sceditor/minified/sceditor.min.js vendor/sceditor/minified/sceditor.min.js && cp node_modules/sceditor/minified/formats/bbcode.js vendor/sceditor/minified/formats/bbcode.js && cp node_modules/sceditor/minified/formats/xhtml.js vendor/sceditor/minified/formats/xhtml.js",
|
|
29
|
-
"copy-index": "
|
|
30
|
+
"copy-index": "echo \"Copy our index.html file too? \"",
|
|
30
31
|
"copy-jamilih": "cp node_modules/jamilih/dist/jml-es.js vendor/jamilih/dist/jml-es.js",
|
|
31
32
|
"copy-typeson-registry": "cp node_modules/typeson-registry/dist/index.js vendor/typeson-registry/dist/index.js",
|
|
32
33
|
"copy": "run-p copy-jamilih copy-typeson-registry",
|
|
33
|
-
"instrument": "run-s -c instrument-remove instrument-add copy-index",
|
|
34
|
+
"instrument": "run-s -c instrument-remove instrument-add copy-index rollup",
|
|
34
35
|
"cypress:log": "ELECTRON_ENABLE_LOGGING=1 cypress run; nyc report",
|
|
35
36
|
"cypress": "cypress run; nyc report",
|
|
36
37
|
"test": "npm run eslint && npm run rollup && npm run cypress"
|
|
@@ -39,58 +40,62 @@
|
|
|
39
40
|
"cover 100%"
|
|
40
41
|
],
|
|
41
42
|
"nyc": {
|
|
43
|
+
"excludeAfterRemap": true,
|
|
42
44
|
"exclude": [
|
|
43
|
-
"node_modules/**"
|
|
45
|
+
"node_modules/**",
|
|
46
|
+
"src/fundamentalTypes/sparseUndefinedType.js"
|
|
44
47
|
]
|
|
45
48
|
},
|
|
46
49
|
"dependencies": {
|
|
47
50
|
"@brettz9/node-static": "^0.1.1",
|
|
48
|
-
"jamilih": "0.58.
|
|
51
|
+
"jamilih": "0.58.2",
|
|
49
52
|
"sceditor": "3.2.0",
|
|
50
|
-
"typeson-registry": "
|
|
53
|
+
"typeson-registry": "9.1.1"
|
|
51
54
|
},
|
|
52
55
|
"devDependencies": {
|
|
53
|
-
"@babel/core": "^7.
|
|
54
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
55
|
-
"@babel/preset-env": "^7.
|
|
56
|
-
"@babel/register": "^7.22.
|
|
56
|
+
"@babel/core": "^7.23.3",
|
|
57
|
+
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
|
|
58
|
+
"@babel/preset-env": "^7.23.3",
|
|
59
|
+
"@babel/register": "^7.22.15",
|
|
57
60
|
"@brettz9/eslint-plugin": "^1.0.4",
|
|
58
|
-
"@cypress/code-coverage": "^3.10
|
|
59
|
-
"@rollup/plugin-babel": "^6.0.
|
|
60
|
-
"@rollup/plugin-commonjs": "^25.0.
|
|
61
|
-
"@rollup/plugin-node-resolve": "^15.
|
|
62
|
-
"@
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
61
|
+
"@cypress/code-coverage": "^3.12.10",
|
|
62
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
63
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
64
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
65
|
+
"@stylistic/eslint-plugin": "^1.4.0",
|
|
66
|
+
"@types/jsdom": "^21.1.5",
|
|
67
|
+
"@types/node": "^20.9.2",
|
|
68
|
+
"axe-core": "^4.8.2",
|
|
69
|
+
"cypress": "^13.5.1",
|
|
70
|
+
"cypress-axe": "^1.5.0",
|
|
71
|
+
"eslint": "^8.54.0",
|
|
72
|
+
"eslint-config-ash-nazg": "^35.1.0",
|
|
68
73
|
"eslint-config-standard": "^17.1.0",
|
|
69
|
-
"eslint-plugin-array-func": "^
|
|
70
|
-
"eslint-plugin-compat": "^4.
|
|
71
|
-
"eslint-plugin-cypress": "^2.
|
|
74
|
+
"eslint-plugin-array-func": "^4.0.0",
|
|
75
|
+
"eslint-plugin-compat": "^4.2.0",
|
|
76
|
+
"eslint-plugin-cypress": "^2.15.1",
|
|
72
77
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
73
78
|
"eslint-plugin-html": "^7.1.0",
|
|
74
|
-
"eslint-plugin-import": "^2.
|
|
75
|
-
"eslint-plugin-jsdoc": "^46.
|
|
76
|
-
"eslint-plugin-markdown": "^3.0.
|
|
77
|
-
"eslint-plugin-n": "^16.
|
|
79
|
+
"eslint-plugin-import": "^2.29.0",
|
|
80
|
+
"eslint-plugin-jsdoc": "^46.9.0",
|
|
81
|
+
"eslint-plugin-markdown": "^3.0.1",
|
|
82
|
+
"eslint-plugin-n": "^16.3.1",
|
|
78
83
|
"eslint-plugin-no-unsanitized": "^4.0.2",
|
|
79
84
|
"eslint-plugin-no-use-extend-native": "^0.5.0",
|
|
80
85
|
"eslint-plugin-promise": "^6.1.1",
|
|
81
|
-
"eslint-plugin-sonarjs": "^0.
|
|
86
|
+
"eslint-plugin-sonarjs": "^0.23.0",
|
|
82
87
|
"eslint-plugin-standard": "^4.1.0",
|
|
83
|
-
"eslint-plugin-unicorn": "^
|
|
88
|
+
"eslint-plugin-unicorn": "^49.0.0",
|
|
84
89
|
"fast-deep-equal": "^3.1.3",
|
|
85
90
|
"jsdom": "^21.1.1",
|
|
86
91
|
"npm-run-all": "^4.1.5",
|
|
87
92
|
"nyc": "^15.1.0",
|
|
88
93
|
"open-cli": "^7.2.0",
|
|
89
|
-
"rimraf": "^5.0.
|
|
90
|
-
"rollup": "
|
|
91
|
-
"rollup-plugin-istanbul": "^
|
|
94
|
+
"rimraf": "^5.0.5",
|
|
95
|
+
"rollup": "4.5.0",
|
|
96
|
+
"rollup-plugin-istanbul": "^5.0.0",
|
|
92
97
|
"rollup-plugin-node-builtins": "^2.1.2",
|
|
93
|
-
"typescript": "^5.
|
|
98
|
+
"typescript": "^5.2.2"
|
|
94
99
|
},
|
|
95
100
|
"repository": {
|
|
96
101
|
"type": "git",
|
package/rollup.config.js
CHANGED
|
@@ -3,8 +3,20 @@ import {nodeResolve} from '@rollup/plugin-node-resolve';
|
|
|
3
3
|
import commonjs from '@rollup/plugin-commonjs';
|
|
4
4
|
// import babel from 'rollup-plugin-babel';
|
|
5
5
|
// import {terser} from 'rollup-plugin-terser';
|
|
6
|
+
import istanbul from 'rollup-plugin-istanbul';
|
|
6
7
|
|
|
7
|
-
export default {
|
|
8
|
+
export default [{
|
|
9
|
+
input: 'demo/index.js',
|
|
10
|
+
output: {
|
|
11
|
+
file: 'instrumented/demo/index.js',
|
|
12
|
+
format: 'es'
|
|
13
|
+
},
|
|
14
|
+
plugins: [
|
|
15
|
+
istanbul(),
|
|
16
|
+
nodeResolve(),
|
|
17
|
+
commonjs()
|
|
18
|
+
]
|
|
19
|
+
}, {
|
|
8
20
|
input: 'node_modules/fast-deep-equal/es6/index.js',
|
|
9
21
|
output: {
|
|
10
22
|
file: 'src/deepEqual.js',
|
|
@@ -26,4 +38,4 @@ export default {
|
|
|
26
38
|
include: 'node_modules/**'
|
|
27
39
|
})
|
|
28
40
|
]
|
|
29
|
-
};
|
|
41
|
+
}];
|
package/server.js
CHANGED
|
@@ -9,7 +9,7 @@ const fileServer = new statik.Server();
|
|
|
9
9
|
|
|
10
10
|
http.createServer(function (request, response) {
|
|
11
11
|
request.addListener('end', function () {
|
|
12
|
-
fileServer.serve(request, response, function (e, res) {
|
|
12
|
+
fileServer.serve(request, response, function (e /* , res */) {
|
|
13
13
|
if (e && (e.status === 404)) { // If the file wasn't found
|
|
14
14
|
fileServer.serveFile(
|
|
15
15
|
instrumented === 'instrumented'
|
|
@@ -21,7 +21,7 @@ import {$e, DOM} from './utils/templateUtils.js';
|
|
|
21
21
|
*/
|
|
22
22
|
export const getFormatAndSchemaChoices = ({schema, hasKeyPath} = {}) => {
|
|
23
23
|
const hasSchema = typeof schema === 'string';
|
|
24
|
-
// eslint-disable-next-line max-len -- Long
|
|
24
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
25
25
|
return /** @type {[optText: string, opts: {value: string, selected?: boolean}][]} */ ([
|
|
26
26
|
['JSON only', {value: 'json'}],
|
|
27
27
|
...(hasKeyPath
|
|
@@ -96,7 +96,7 @@ export const getFormatAndSchemaChoices = ({schema, hasKeyPath} = {}) => {
|
|
|
96
96
|
* domArray: [formatChoices: FormatChoices, typesHolder: TypesHolder],
|
|
97
97
|
* getValue: (stateObj: import('./types.js').StateObject,
|
|
98
98
|
* currentPath: string) => import('./formats.js').StructuredCloneValue,
|
|
99
|
-
* getType: () => string
|
|
99
|
+
* getType: () => string,
|
|
100
100
|
* validValuesSet: () => boolean,
|
|
101
101
|
* setValue: SetValue
|
|
102
102
|
* }} The selector for types and the container for them. Both should be
|
|
@@ -111,7 +111,7 @@ export function formatAndTypeChoices ({
|
|
|
111
111
|
typeNamespace
|
|
112
112
|
}) {
|
|
113
113
|
const format = 'structuredCloning';
|
|
114
|
-
const formatChoices = /** @type {
|
|
114
|
+
const formatChoices = /** @type {FormatChoices} */ (jml('select', {
|
|
115
115
|
class: 'formatChoices',
|
|
116
116
|
hidden: singleValue,
|
|
117
117
|
// is: 'main-type-choices',
|
|
@@ -130,9 +130,10 @@ export function formatAndTypeChoices ({
|
|
|
130
130
|
*/
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
|
-
* @typedef {HTMLSelectElement
|
|
134
|
-
*
|
|
135
|
-
*
|
|
133
|
+
* @typedef {HTMLSelectElement & {
|
|
134
|
+
* $setFormat: SetFormat,
|
|
135
|
+
* $buildTypeChoices: TypeChoiceBuilder
|
|
136
|
+
* }} FormatChoices
|
|
136
137
|
*/
|
|
137
138
|
|
|
138
139
|
/**
|
|
@@ -227,7 +228,7 @@ export function formatAndTypeChoices ({
|
|
|
227
228
|
* @returns {import('./formats.js').StructuredCloneValue}
|
|
228
229
|
*/
|
|
229
230
|
getValue (stateObj, currentPath) {
|
|
230
|
-
// eslint-disable-next-line max-len -- Long
|
|
231
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
231
232
|
const root = /** @type {HTMLDivElement & {$getTypeRoot: TypeRootGetter}} */ (
|
|
232
233
|
typesHolder
|
|
233
234
|
).$getTypeRoot();
|
|
@@ -241,10 +242,10 @@ export function formatAndTypeChoices ({
|
|
|
241
242
|
},
|
|
242
243
|
|
|
243
244
|
/**
|
|
244
|
-
* @returns {string
|
|
245
|
+
* @returns {string}
|
|
245
246
|
*/
|
|
246
247
|
getType () {
|
|
247
|
-
// eslint-disable-next-line max-len -- Long
|
|
248
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
248
249
|
const root = /** @type {HTMLDivElement & {$getTypeRoot: TypeRootGetter}} */ (
|
|
249
250
|
typesHolder
|
|
250
251
|
).$getTypeRoot();
|
|
@@ -255,7 +256,7 @@ export function formatAndTypeChoices ({
|
|
|
255
256
|
* @returns {boolean}
|
|
256
257
|
*/
|
|
257
258
|
validValuesSet () {
|
|
258
|
-
// eslint-disable-next-line max-len -- Long
|
|
259
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
259
260
|
const root = /** @type {HTMLDivElement & {$getTypeRoot: TypeRootGetter}} */ (
|
|
260
261
|
typesHolder
|
|
261
262
|
).$getTypeRoot();
|
|
@@ -276,12 +277,12 @@ export function formatAndTypeChoices ({
|
|
|
276
277
|
stateObj
|
|
277
278
|
)
|
|
278
279
|
);
|
|
279
|
-
const type =
|
|
280
|
-
// eslint-disable-next-line max-len -- Long
|
|
280
|
+
const type = Types.getTypeForRoot(rootEditUI);
|
|
281
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
281
282
|
const sel = /** @type {HTMLDivElement & {$getTypeSelect: TypeSelectGetter}} */ (
|
|
282
283
|
typesHolder
|
|
283
284
|
).$getTypeSelect();
|
|
284
|
-
// eslint-disable-next-line max-len -- Long
|
|
285
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
285
286
|
/** @type {HTMLSelectElement & {$addTypeAndEditUI: import('./typeChoices.js').AddTypeAndEditUI}} */ (
|
|
286
287
|
sel
|
|
287
288
|
).$addTypeAndEditUI({type, editUI: rootEditUI});
|
|
@@ -36,8 +36,8 @@ const indexedDBKey = {
|
|
|
36
36
|
if (!state || ['array'].includes(state)) {
|
|
37
37
|
return this.types();
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
return undefined;
|
|
39
|
+
// Can't be object, so shouldn't normally reach here
|
|
40
|
+
return undefined;
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
package/src/formats/json.js
CHANGED
|
@@ -46,8 +46,7 @@ const json = {
|
|
|
46
46
|
if (!state || ['array', 'object'].includes(state)) {
|
|
47
47
|
return this.types();
|
|
48
48
|
}
|
|
49
|
-
//
|
|
50
|
-
/* istanbul ignore next -- No other states apparently */
|
|
49
|
+
// Shouldn't normally reach here
|
|
51
50
|
return undefined;
|
|
52
51
|
}
|
|
53
52
|
};
|
|
@@ -17,9 +17,10 @@ import json from './json.js';
|
|
|
17
17
|
* type: import('../types.js').AvailableType,
|
|
18
18
|
* value: import('../formats.js').StructuredCloneValue,
|
|
19
19
|
* bringIntoFocus?: boolean,
|
|
20
|
+
* setAValue?: boolean,
|
|
20
21
|
* schemaContent?: object,
|
|
21
22
|
* schemaState?: import('../types.js').GetPossibleSchemasForPathAndType
|
|
22
|
-
* }) => HTMLElement} AddAndSetArrayElement
|
|
23
|
+
* }) => HTMLElement|null} AddAndSetArrayElement
|
|
23
24
|
*/
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -44,6 +45,10 @@ const encapsulateObserver = (stateObj) => {
|
|
|
44
45
|
* }}}
|
|
45
46
|
*/
|
|
46
47
|
const parents = {};
|
|
48
|
+
|
|
49
|
+
/** @type {string[]} */
|
|
50
|
+
const mapPaths = [];
|
|
51
|
+
|
|
47
52
|
return (observerObj) => {
|
|
48
53
|
const {
|
|
49
54
|
type,
|
|
@@ -57,13 +62,15 @@ const encapsulateObserver = (stateObj) => {
|
|
|
57
62
|
endIterateUnsetNumeric,
|
|
58
63
|
clone
|
|
59
64
|
} = observerObj;
|
|
60
|
-
// console.log('observerObj', observerObj);
|
|
61
65
|
if ('replaced' in observerObj) {
|
|
62
66
|
return;
|
|
63
67
|
}
|
|
64
68
|
if (cyclic === 'readonly' && !Array.isArray(observerObj.value)) {
|
|
65
69
|
return;
|
|
66
70
|
}
|
|
71
|
+
if (cyclic === 'readonly' && type === 'set') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
67
74
|
if (endIterateIn || endIterateOwn) {
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
@@ -73,6 +80,12 @@ const encapsulateObserver = (stateObj) => {
|
|
|
73
80
|
return;
|
|
74
81
|
}
|
|
75
82
|
|
|
83
|
+
// What other situations is this firing twice, and it
|
|
84
|
+
// shouldn't reach here?
|
|
85
|
+
if (observerObj.replacing && type === 'negativeZero') {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
76
89
|
/* istanbul ignore if -- Not part of format */
|
|
77
90
|
if (type === 'sparseUndefined') { // We'll handle otherwise
|
|
78
91
|
return;
|
|
@@ -119,12 +132,21 @@ const encapsulateObserver = (stateObj) => {
|
|
|
119
132
|
const parentPath = li === -1 ? '' : keypath.slice(0, li);
|
|
120
133
|
|
|
121
134
|
const hasChildren = [
|
|
122
|
-
'array', 'object',
|
|
135
|
+
'array', 'object', 'set', 'map',
|
|
123
136
|
// 'sparseArrays',
|
|
124
137
|
'arrayNonindexKeys'
|
|
125
138
|
].includes(newType);
|
|
126
139
|
|
|
140
|
+
// Maps are followed up by arrays which we don't want as such;
|
|
141
|
+
// we track the paths to avoid reporting these child arrays
|
|
142
|
+
const mapType = type === 'map' &&
|
|
143
|
+
Object.prototype.toString.call(value) === '[object Map]';
|
|
144
|
+
if (mapType) {
|
|
145
|
+
mapPaths.push(keypath);
|
|
146
|
+
}
|
|
147
|
+
|
|
127
148
|
if (!stateObj.rootUI) {
|
|
149
|
+
// console.log('vvvv0', newType, newValue);
|
|
128
150
|
stateObj.rootUI = Types.getUIForModeAndType({
|
|
129
151
|
readonly,
|
|
130
152
|
typeNamespace,
|
|
@@ -152,6 +174,18 @@ const encapsulateObserver = (stateObj) => {
|
|
|
152
174
|
* @type {HTMLElement &
|
|
153
175
|
* {$addAndSetArrayElement: AddAndSetArrayElement}}
|
|
154
176
|
*/ (stateObj.rootUI);
|
|
177
|
+
|
|
178
|
+
// Since we're skipping the array elements, we need to add the
|
|
179
|
+
// map element to the array index where the array children
|
|
180
|
+
// will be found (which we do want)
|
|
181
|
+
if (mapType) {
|
|
182
|
+
/** @type {Map<any, any>} */ [...value].forEach((_, i) => {
|
|
183
|
+
parents[i] = /**
|
|
184
|
+
* @type {HTMLElement &
|
|
185
|
+
* {$addAndSetArrayElement: AddAndSetArrayElement}}
|
|
186
|
+
*/ (stateObj.rootUI);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
155
189
|
return;
|
|
156
190
|
}
|
|
157
191
|
|
|
@@ -172,6 +206,22 @@ const encapsulateObserver = (stateObj) => {
|
|
|
172
206
|
return;
|
|
173
207
|
}
|
|
174
208
|
|
|
209
|
+
// Skip the array structures immediately following the Map,
|
|
210
|
+
// as map needs to handle
|
|
211
|
+
if (!mapType && mapPaths.some((mapPath) => {
|
|
212
|
+
if (mapPath === keypath ||
|
|
213
|
+
(mapPath === '' && (/^\d+$/u).test(keypath))) {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
const trailingIndex = keypath.match(/\.\d+$/u);
|
|
217
|
+
return (trailingIndex && mapPath !== '' &&
|
|
218
|
+
keypath.slice(0, -trailingIndex[0].length) === mapPath);
|
|
219
|
+
})) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// console.log('vvvv', newType, '::', newValue, '::', newValue?.cause);
|
|
224
|
+
|
|
175
225
|
const root = ui.$addAndSetArrayElement({
|
|
176
226
|
propName: arrayOrObjectPropertyName,
|
|
177
227
|
type: newType,
|
|
@@ -188,7 +238,16 @@ const encapsulateObserver = (stateObj) => {
|
|
|
188
238
|
})
|
|
189
239
|
*/
|
|
190
240
|
});
|
|
241
|
+
|
|
242
|
+
/* istanbul ignore if -- Guard for `null` return */
|
|
243
|
+
if (!root) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
191
247
|
if (!readonly) {
|
|
248
|
+
// Todo: Redundant with `typeObj.setValue`? Ensure `idb-manager`
|
|
249
|
+
// does not need both; this write-only would seem preferable
|
|
250
|
+
// to the block in `arrayType.js` if readonly indeed not needed
|
|
192
251
|
Types.setValue({
|
|
193
252
|
type: newType,
|
|
194
253
|
// eslint-disable-next-line object-shorthand -- TS
|
|
@@ -210,6 +269,18 @@ const encapsulateObserver = (stateObj) => {
|
|
|
210
269
|
*/ (
|
|
211
270
|
root
|
|
212
271
|
);
|
|
272
|
+
|
|
273
|
+
// Since we're skipping the array elements, we need to add the
|
|
274
|
+
// map element to the array index where the array children
|
|
275
|
+
// will be found (which we do want)
|
|
276
|
+
if (mapType) {
|
|
277
|
+
/** @type {Map<any, any>} */ [...value].forEach((_, i) => {
|
|
278
|
+
parents[`${keypath}.${i}`] = /**
|
|
279
|
+
* @type {HTMLElement &
|
|
280
|
+
* {$addAndSetArrayElement: AddAndSetArrayElement}}
|
|
281
|
+
*/ (root);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
213
284
|
}
|
|
214
285
|
});
|
|
215
286
|
};
|
|
@@ -247,7 +318,7 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
247
318
|
* @type {import('../types.js').AvailableType|undefined}
|
|
248
319
|
*/
|
|
249
320
|
let ret;
|
|
250
|
-
console.log('format, state, valType, v', format, state, valType, v);
|
|
321
|
+
// console.log('format, state, valType, v', format, state, valType, v);
|
|
251
322
|
|
|
252
323
|
/**
|
|
253
324
|
* @param {string} newValType
|
|
@@ -278,9 +349,9 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
278
349
|
})) {
|
|
279
350
|
return /** @type {import('../types.js').AvailableType} */ (ret);
|
|
280
351
|
}
|
|
281
|
-
console.log('ret', ret);
|
|
352
|
+
// console.log('ret', ret);
|
|
282
353
|
allowableTypes.some((allowableType) => {
|
|
283
|
-
// eslint-disable-next-line max-len -- Long
|
|
354
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
284
355
|
const typeObj = /** @type {import('../types.js').TypeObject & {childTypes: string[]}} */ (
|
|
285
356
|
Types.availableTypes[allowableType]
|
|
286
357
|
);
|
|
@@ -298,7 +369,7 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
298
369
|
}
|
|
299
370
|
return false;
|
|
300
371
|
});
|
|
301
|
-
console.log('ret2', ret);
|
|
372
|
+
// console.log('ret2', ret);
|
|
302
373
|
if (ret === undefined) {
|
|
303
374
|
return isInvalid(valType);
|
|
304
375
|
}
|
|
@@ -315,7 +386,7 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
315
386
|
/** @type {import('../formats.js').Format} */
|
|
316
387
|
const structuredCloning = {
|
|
317
388
|
iterate (records, stateObj) {
|
|
318
|
-
console.log('records', records);
|
|
389
|
+
// console.log('records', records);
|
|
319
390
|
if (!stateObj.format) {
|
|
320
391
|
stateObj.format = 'structuredCloning';
|
|
321
392
|
}
|
|
@@ -348,6 +419,12 @@ const structuredCloning = {
|
|
|
348
419
|
});
|
|
349
420
|
return typesForFormat;
|
|
350
421
|
}
|
|
422
|
+
// Todo: Could we implement schemas here by introducing new keys to
|
|
423
|
+
// `Types.contexts` which could be used rather than manual
|
|
424
|
+
// handling to determine a delimited group of children
|
|
425
|
+
if (state === 'errorsArray') {
|
|
426
|
+
return ['error', 'errors'];
|
|
427
|
+
}
|
|
351
428
|
return this.types();
|
|
352
429
|
/*
|
|
353
430
|
// Todo (low): These need to specify their own inner contexts
|
|
@@ -375,35 +452,33 @@ const structuredCloning = {
|
|
|
375
452
|
...jsonTypes,
|
|
376
453
|
'undef', // Explicit undefined only
|
|
377
454
|
'bigint',
|
|
378
|
-
'SpecialNumber', // '`NaN`, `Infinity`, `-Infinity`
|
|
455
|
+
'SpecialNumber', // '`NaN`, `Infinity`, `-Infinity`, `-0`
|
|
379
456
|
'date',
|
|
380
457
|
'regexp',
|
|
381
458
|
'BooleanObject',
|
|
382
459
|
'NumberObject',
|
|
383
460
|
'StringObject',
|
|
384
|
-
'
|
|
461
|
+
'error',
|
|
462
|
+
'errors',
|
|
463
|
+
'blobHTML',
|
|
464
|
+
'set',
|
|
465
|
+
'map'
|
|
385
466
|
// Ok, but will need some work
|
|
386
|
-
// '
|
|
387
|
-
// '
|
|
388
|
-
// 'arraybuffer', 'arraybufferview'
|
|
467
|
+
// 'blob', 'file', 'filelist',
|
|
468
|
+
// 'arraybuffer',
|
|
389
469
|
// 'dataview', 'imagedata', 'imagebitmap',
|
|
390
470
|
/*
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
// Intl (imperfect)
|
|
403
|
-
'IntlCollator',
|
|
404
|
-
'IntlDateTimeFormat',
|
|
405
|
-
'IntlNumberFormat'
|
|
406
|
-
*/
|
|
471
|
+
// Typed Arrays
|
|
472
|
+
'int8array',
|
|
473
|
+
'uint8array',
|
|
474
|
+
'uint8clampedarray',
|
|
475
|
+
'int16array',
|
|
476
|
+
'uint16array',
|
|
477
|
+
'int32array',
|
|
478
|
+
'uint32array',
|
|
479
|
+
'float32array',
|
|
480
|
+
'float64array',
|
|
481
|
+
*/
|
|
407
482
|
];
|
|
408
483
|
}
|
|
409
484
|
};
|
package/src/formats.js
CHANGED
|
@@ -56,8 +56,8 @@ const Formats = {
|
|
|
56
56
|
* @returns {Promise<Element>}
|
|
57
57
|
*/
|
|
58
58
|
export async function getControlsForFormatAndValue (format, record, stateObj) {
|
|
59
|
-
return await Formats.availableFormats[format]
|
|
60
|
-
|
|
59
|
+
return await Formats.availableFormats[format].
|
|
60
|
+
iterate(record, {
|
|
61
61
|
...stateObj,
|
|
62
62
|
// This had been before `stateObj` but should apparently have precedence
|
|
63
63
|
// or just avoid passing `format` to this function
|
|
@@ -35,7 +35,7 @@ const arrayReferenceType = {
|
|
|
35
35
|
structuredCloning: {
|
|
36
36
|
// after: 'sparseArrays',
|
|
37
37
|
after: 'arrayNonindexKeys',
|
|
38
|
-
contexts: ['arrayNonindexKeys', 'object']
|
|
38
|
+
contexts: ['arrayNonindexKeys', 'object', 'set']
|
|
39
39
|
// contexts: ['sparseArrays', 'object']
|
|
40
40
|
}
|
|
41
41
|
},
|
|
@@ -47,7 +47,7 @@ const arrayReferenceType = {
|
|
|
47
47
|
},
|
|
48
48
|
getValue ({root, stateObj, currentPath}) {
|
|
49
49
|
const referentPath = this.getInput({root}).value;
|
|
50
|
-
// eslint-disable-next-line max-len -- Long
|
|
50
|
+
// eslint-disable-next-line @stylistic/max-len -- Long
|
|
51
51
|
/* istanbul ignore else -- ArrayRef will not be a root, so should have stateObj */
|
|
52
52
|
if (stateObj) {
|
|
53
53
|
if (!stateObj.paths) {
|
|
@@ -97,7 +97,7 @@ const arrayReferenceType = {
|
|
|
97
97
|
'arrayNonindexKeys'
|
|
98
98
|
// 'sparseArrays'
|
|
99
99
|
].includes(
|
|
100
|
-
|
|
100
|
+
Types.getTypeForRoot(referent)
|
|
101
101
|
);
|
|
102
102
|
};
|
|
103
103
|
let message;
|