@es-joy/jsoe 0.0.2 → 0.2.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/.eslintrc.cjs +2 -1
- package/CHANGES.md +22 -0
- package/README.md +2 -2
- package/demo/index.html +12 -0
- package/demo/index.js +163 -0
- package/index.html +10 -0
- package/package.json +5 -5
- package/src/formatAndTypeChoices.js +245 -0
- package/src/formats/indexedDBKey.js +1 -1
- package/src/formats/json.js +1 -1
- package/src/formats/schemaAndArbitrary.js +1 -1
- package/src/formats/schemaOnly.js +1 -1
- package/src/formats/structuredCloning.js +4 -22
- package/src/formats.js +17 -206
- package/src/fundamentalTypes/BooleanObjectType.js +1 -1
- package/src/fundamentalTypes/NumberObjectType.js +1 -1
- package/src/fundamentalTypes/StringObjectType.js +1 -1
- package/src/fundamentalTypes/arrayReferenceType.js +1 -1
- package/src/fundamentalTypes/arrayType.js +3 -3
- package/src/fundamentalTypes/bigintType.js +1 -1
- package/src/fundamentalTypes/dateType.js +1 -1
- package/src/fundamentalTypes/nullType.js +1 -1
- package/src/fundamentalTypes/numberType.js +1 -1
- package/src/fundamentalTypes/objectReferenceType.js +1 -1
- package/src/fundamentalTypes/objectType.js +1 -1
- package/src/fundamentalTypes/regexpType.js +1 -1
- package/src/fundamentalTypes/sparseUndefinedType.js +1 -1
- package/src/fundamentalTypes/stringType.js +1 -1
- package/src/fundamentalTypes/undefinedType.js +1 -1
- package/src/index.js +7 -2
- package/src/jsoe.css +58 -0
- package/src/subTypes/falseType.js +1 -1
- package/src/subTypes/trueType.js +1 -1
- package/src/typeChoices.js +228 -104
- package/src/types.js +53 -35
package/.eslintrc.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
extends: ['ash-nazg/sauron-node-overrides', 'plugin:cypress/recommended'],
|
|
5
5
|
parserOptions: {
|
|
6
|
-
ecmaVersion:
|
|
6
|
+
ecmaVersion: 2022
|
|
7
7
|
},
|
|
8
8
|
settings: {
|
|
9
9
|
jsdoc: {
|
|
@@ -24,6 +24,7 @@ module.exports = {
|
|
|
24
24
|
'console',
|
|
25
25
|
'Date.toISOString',
|
|
26
26
|
'document.body',
|
|
27
|
+
'document.createDocumentFragment',
|
|
27
28
|
'document.querySelector',
|
|
28
29
|
'document.querySelectorAll',
|
|
29
30
|
'Error',
|
package/CHANGES.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# CHANGES TO `@es-joy/jsoe`
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- refactor(BREAKING): `typeChoices`->`formatAndTypeChoices`;
|
|
6
|
+
add different `typeChoices`, adding methods to both
|
|
7
|
+
- feat: add `getControlsForFormatAndValue` utility
|
|
8
|
+
- fix: ensure `setValue` removes existing content
|
|
9
|
+
- feat: add stylesheet
|
|
10
|
+
|
|
11
|
+
## 0.1.0
|
|
12
|
+
|
|
13
|
+
- refactor: have `getFormatAndSchemaChoices` return fragment of options
|
|
14
|
+
- refactor: avoid placement dependency for return results of `typeChoices`
|
|
15
|
+
- refactor: return array of return objects for easier direct embedding
|
|
16
|
+
in Jamilih
|
|
17
|
+
- docs: better API docs
|
|
18
|
+
- docs: add demo
|
|
19
|
+
- chore: switch port for testing
|
|
20
|
+
|
|
21
|
+
## 0.0.2
|
|
22
|
+
|
|
23
|
+
- fix: `node_modules` paths
|
|
24
|
+
|
|
3
25
|
## 0.0.1
|
|
4
26
|
|
|
5
27
|
- initial commit
|
package/README.md
CHANGED
|
@@ -4,7 +4,8 @@ JavaScript Object Editor.
|
|
|
4
4
|
|
|
5
5
|
Editing of arbitrary JavaScript objects.
|
|
6
6
|
|
|
7
|
-
See a [demo](https://
|
|
7
|
+
See a [demo](https://es-joy.github.io/jsoe/demo/) of this tool or
|
|
8
|
+
[a demo](https://brettz9.github.io/idb-manager/index-pages.html) of an
|
|
8
9
|
app using this tool.
|
|
9
10
|
|
|
10
11
|
## Formats
|
|
@@ -52,7 +53,6 @@ separate enumeration.
|
|
|
52
53
|
|
|
53
54
|
## To-dos
|
|
54
55
|
|
|
55
|
-
1. Create demo
|
|
56
56
|
1. Add tests of demo (lower priority as have tests in `idb-manager`)
|
|
57
57
|
1. Support Schemas based on a JSON serialization of Zod
|
|
58
58
|
1. Expand fundamental types
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>JSOE Demo</title>
|
|
6
|
+
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" />
|
|
7
|
+
<link rel="stylesheet" href="../src/jsoe.css" />
|
|
8
|
+
<script type="module" src="index.js"></script>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
package/demo/index.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {jml, body} from '../vendor/jamilih/dist/jml-es.js';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
typeChoices,
|
|
5
|
+
getFormatAndSchemaChoices,
|
|
6
|
+
formatAndTypeChoices,
|
|
7
|
+
getControlsForFormatAndValue,
|
|
8
|
+
Types // , Formats
|
|
9
|
+
} from '../src/index.js';
|
|
10
|
+
|
|
11
|
+
const keyPathNotExpectedTypeChoices = formatAndTypeChoices({
|
|
12
|
+
hasKeyPath: false,
|
|
13
|
+
typeNamespace: 'demo-keypath-not-expected'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
jml('section', {role: 'main'}, [
|
|
17
|
+
['h2', [
|
|
18
|
+
'Format and type choices: No key path expected (type can vary at root)'
|
|
19
|
+
]],
|
|
20
|
+
|
|
21
|
+
// Put inside form so can validate
|
|
22
|
+
['form', [
|
|
23
|
+
...keyPathNotExpectedTypeChoices.domArray
|
|
24
|
+
]],
|
|
25
|
+
|
|
26
|
+
['button', {
|
|
27
|
+
$on: {
|
|
28
|
+
click () {
|
|
29
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
30
|
+
alert(keyPathNotExpectedTypeChoices.getType());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, ['Get type']],
|
|
34
|
+
|
|
35
|
+
['button', {
|
|
36
|
+
$on: {
|
|
37
|
+
click () {
|
|
38
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
39
|
+
alert(keyPathNotExpectedTypeChoices.validValuesSet());
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}, ['Is valid']],
|
|
43
|
+
|
|
44
|
+
['button', {
|
|
45
|
+
$on: {
|
|
46
|
+
click () {
|
|
47
|
+
console.log(keyPathNotExpectedTypeChoices.getValue());
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, ['Log value']],
|
|
51
|
+
|
|
52
|
+
['button', {
|
|
53
|
+
$on: {
|
|
54
|
+
async click () {
|
|
55
|
+
await keyPathNotExpectedTypeChoices.setValue(42);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}, ['Initialize with a value']],
|
|
59
|
+
|
|
60
|
+
['h2', [
|
|
61
|
+
'Format and type choices: Key path expected (object required at root)'
|
|
62
|
+
]],
|
|
63
|
+
...formatAndTypeChoices({
|
|
64
|
+
hasKeyPath: true,
|
|
65
|
+
typeNamespace: 'demo-keypath-expected'
|
|
66
|
+
}).domArray,
|
|
67
|
+
|
|
68
|
+
['h2', [
|
|
69
|
+
'Format choices without type selection ' +
|
|
70
|
+
'(might use as retrieval return format)'
|
|
71
|
+
]],
|
|
72
|
+
['select', [
|
|
73
|
+
getFormatAndSchemaChoices()
|
|
74
|
+
]],
|
|
75
|
+
|
|
76
|
+
['h2', [
|
|
77
|
+
'Type choices only'
|
|
78
|
+
]],
|
|
79
|
+
|
|
80
|
+
(() => {
|
|
81
|
+
const typeSelection = typeChoices({
|
|
82
|
+
format: 'structuredCloning',
|
|
83
|
+
typeNamespace: 'demo-type-choices-only'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return ['form', {
|
|
87
|
+
$on: {
|
|
88
|
+
submit (e) {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}, [
|
|
93
|
+
...typeSelection.domArray,
|
|
94
|
+
['button', {
|
|
95
|
+
$on: {
|
|
96
|
+
click () {
|
|
97
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
98
|
+
alert(typeSelection.getType());
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}, ['Get type']],
|
|
102
|
+
|
|
103
|
+
['button', {
|
|
104
|
+
$on: {
|
|
105
|
+
click () {
|
|
106
|
+
// eslint-disable-next-line no-alert -- Simple demo
|
|
107
|
+
alert(typeSelection.validValuesSet());
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}, ['Is valid']],
|
|
111
|
+
|
|
112
|
+
['button', {
|
|
113
|
+
$on: {
|
|
114
|
+
click () {
|
|
115
|
+
console.log(typeSelection.getValue());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, ['Log value']],
|
|
119
|
+
|
|
120
|
+
['button', {
|
|
121
|
+
$on: {
|
|
122
|
+
async click () {
|
|
123
|
+
await typeSelection.setValue(42);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, ['Initialize with a value']]
|
|
127
|
+
]];
|
|
128
|
+
})(),
|
|
129
|
+
|
|
130
|
+
['h2', [
|
|
131
|
+
'Convert arbitrary value to an editable menu'
|
|
132
|
+
]],
|
|
133
|
+
|
|
134
|
+
await getControlsForFormatAndValue(
|
|
135
|
+
'structuredCloning', new Date('1999-01-01')
|
|
136
|
+
),
|
|
137
|
+
|
|
138
|
+
['h2', [
|
|
139
|
+
'Convert arbitrary value to a readonly menu'
|
|
140
|
+
]],
|
|
141
|
+
|
|
142
|
+
await getControlsForFormatAndValue(
|
|
143
|
+
'structuredCloning',
|
|
144
|
+
new Date('1999-01-01'), {
|
|
145
|
+
readonly: true
|
|
146
|
+
}
|
|
147
|
+
),
|
|
148
|
+
|
|
149
|
+
['h2', [
|
|
150
|
+
'Convert structured cloning string representation to value and log'
|
|
151
|
+
]],
|
|
152
|
+
['input', {
|
|
153
|
+
placeholder: 'e.g., ["abc", 17]',
|
|
154
|
+
$on: {
|
|
155
|
+
change () {
|
|
156
|
+
const value = Types.getValueForString(this.value, {
|
|
157
|
+
format: 'structuredCloning'
|
|
158
|
+
})[0];
|
|
159
|
+
console.log(value);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}]
|
|
163
|
+
], body);
|
package/index.html
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@es-joy/jsoe",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.js"
|
|
@@ -80,10 +80,10 @@
|
|
|
80
80
|
"scripts": {
|
|
81
81
|
"eslint": "eslint --ext=js,cjs,md,html .",
|
|
82
82
|
"lint": "npm run eslint --",
|
|
83
|
-
"coverage": "open-cli http://localhost:
|
|
84
|
-
"open": "open-cli http://localhost:
|
|
85
|
-
"start": "node server
|
|
86
|
-
"start-instrumented": "node server
|
|
83
|
+
"coverage": "open-cli http://localhost:8087/coverage/lcov-report/",
|
|
84
|
+
"open": "open-cli http://localhost:8087/demo/",
|
|
85
|
+
"start": "node server 8087",
|
|
86
|
+
"start-instrumented": "node server 8087 instrumented",
|
|
87
87
|
"cypress:open": "cypress open",
|
|
88
88
|
"rollup": "rollup -c",
|
|
89
89
|
"instrument-add": "nyc instrument src instrumented",
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import {jml} from '../vendor/jamilih/dist/jml-es.js';
|
|
2
|
+
import {buildTypeChoices} from './typeChoices.js';
|
|
3
|
+
import Types from './types.js';
|
|
4
|
+
import {getControlsForFormatAndValue} from './formats.js';
|
|
5
|
+
import {$e, DOM} from './utils/templateUtils.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Defaults to structured cloning.
|
|
9
|
+
* @todo Compose from format metadata, so can make user customizable.
|
|
10
|
+
* @param {object} cfg
|
|
11
|
+
* @param {string} [cfg.schema] (NOT IN USE)
|
|
12
|
+
* @param {boolean} [cfg.hasKeyPath] Whether or not a key path is expected; if
|
|
13
|
+
* true, an indexedDB key is not allowed here as a key does not support
|
|
14
|
+
* the object type which is needed for a key path.
|
|
15
|
+
* @returns {DocumentFragment}
|
|
16
|
+
*/
|
|
17
|
+
export const getFormatAndSchemaChoices = ({schema, hasKeyPath} = {}) => {
|
|
18
|
+
const hasSchema = typeof schema === 'string';
|
|
19
|
+
return [
|
|
20
|
+
['JSON only', {value: 'json'}],
|
|
21
|
+
...(hasKeyPath
|
|
22
|
+
? []
|
|
23
|
+
: [['IndexedDB key', {value: 'indexedDBKey'}]]),
|
|
24
|
+
['Structured Clone (via Typeson JSON)', {
|
|
25
|
+
value: 'structuredCloning', selected: !hasSchema
|
|
26
|
+
}]
|
|
27
|
+
/* schema:
|
|
28
|
+
...(hasSchema
|
|
29
|
+
? [
|
|
30
|
+
[`Schema + arbitrary: ${schema}`, {
|
|
31
|
+
value: 'schemaAndArbitrary',
|
|
32
|
+
dataset: {schema}
|
|
33
|
+
}],
|
|
34
|
+
[`Schema only: ${schema}`, {
|
|
35
|
+
value: 'schemaOnly',
|
|
36
|
+
dataset: {schema},
|
|
37
|
+
selected: hasSchema
|
|
38
|
+
}]
|
|
39
|
+
]
|
|
40
|
+
: []
|
|
41
|
+
)
|
|
42
|
+
*/
|
|
43
|
+
/*
|
|
44
|
+
// This can be supported for editing only
|
|
45
|
+
['Arbitrary (Non-Typeson-serializable will be read-only)', {
|
|
46
|
+
value: 'arbitrary',
|
|
47
|
+
title: 'Any value that the typeson-registry supports ' +
|
|
48
|
+
'for structured cloning'
|
|
49
|
+
}]
|
|
50
|
+
*/
|
|
51
|
+
].map(([optText, optAtts]) => {
|
|
52
|
+
return jml('option', optAtts, [optText]);
|
|
53
|
+
}).reduce((frag, option) => {
|
|
54
|
+
frag.append(option);
|
|
55
|
+
return frag;
|
|
56
|
+
}, document.createDocumentFragment());
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Builds a selector and container for types.
|
|
61
|
+
* @param {object} cfg
|
|
62
|
+
* @param {string} [cfg.schema] The schema name (NOT IN USE)
|
|
63
|
+
* @param {object} [cfg.schemaContent] The schema content (NOT IN USE)
|
|
64
|
+
* @param {boolean} [cfg.hasValue] Set to `true` if you are supplying
|
|
65
|
+
* your own value. If `false` and `hasKeyPath` is `true`,
|
|
66
|
+
* will initialize with an object.
|
|
67
|
+
* @param {boolean} [cfg.singleValue] (NOT IN USE)
|
|
68
|
+
* @param {boolean} [cfg.hasKeyPath] If this is set (because there is a keyPath
|
|
69
|
+
* to be found within the object) and `hasValue` is true, an object type
|
|
70
|
+
* will be set and required at the root level. This option will also
|
|
71
|
+
* prevent selection of indexedDB key at root (since a key cannot be a
|
|
72
|
+
* plain object).
|
|
73
|
+
* @param {string} [cfg.typeNamespace] Used to prevent conflicts with other
|
|
74
|
+
* instances of typeChoices on the page
|
|
75
|
+
* @returns {{
|
|
76
|
+
* formatChoices: FormatChoices,
|
|
77
|
+
* typesHolder: TypesHolder,
|
|
78
|
+
* domArray: [formatChoices: FormatChoices, typesHolder: TypesHolder],
|
|
79
|
+
* getValue: (stateObj: import('./types.js').StateObject,
|
|
80
|
+
* currentPath: string) => StructuredCloneValue,
|
|
81
|
+
* getType: () => string|undefined,
|
|
82
|
+
* validValuesSet: () => boolean
|
|
83
|
+
* }} The selector for types and the container for them. Both should be
|
|
84
|
+
* added to the page.
|
|
85
|
+
*/
|
|
86
|
+
export function formatAndTypeChoices ({
|
|
87
|
+
schema,
|
|
88
|
+
schemaContent,
|
|
89
|
+
hasValue,
|
|
90
|
+
singleValue,
|
|
91
|
+
hasKeyPath,
|
|
92
|
+
typeNamespace
|
|
93
|
+
}) {
|
|
94
|
+
const format = 'structuredCloning';
|
|
95
|
+
const formatChoices = jml('select', {
|
|
96
|
+
class: 'formatChoices',
|
|
97
|
+
hidden: singleValue,
|
|
98
|
+
// is: 'main-type-choices',
|
|
99
|
+
$custom: {
|
|
100
|
+
/**
|
|
101
|
+
* Sets the desired format and rebuilds the type choices.
|
|
102
|
+
* @callback SetFormat
|
|
103
|
+
* @param {string} valueFormat
|
|
104
|
+
* @returns {void}
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Rebuilds the type choices.
|
|
109
|
+
* @callback TypeChoiceBuilder
|
|
110
|
+
* @returns {void}
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @typedef {HTMLSelectElement} FormatChoices
|
|
115
|
+
* @property {SetFormat} $setFormat
|
|
116
|
+
* @property {TypeChoiceBuilder} $buildTypeChoices
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @type {SetFormat}
|
|
121
|
+
*/
|
|
122
|
+
$setFormat (valueFormat) {
|
|
123
|
+
this.value = valueFormat;
|
|
124
|
+
this.$buildTypeChoices();
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @type {TypeChoiceBuilder}
|
|
129
|
+
*/
|
|
130
|
+
$buildTypeChoices () {
|
|
131
|
+
DOM.removeChildren(typesHolder);
|
|
132
|
+
jml({'#': buildTypeChoices({
|
|
133
|
+
topRoot: $e(typesHolder, 'div[data-type]'),
|
|
134
|
+
resultType: 'both',
|
|
135
|
+
format: this.value,
|
|
136
|
+
typeNamespace,
|
|
137
|
+
requireObject: hasKeyPath,
|
|
138
|
+
objectHasValue: hasValue,
|
|
139
|
+
schema,
|
|
140
|
+
schemaContent
|
|
141
|
+
}).domArray}, typesHolder);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
$on: {change () {
|
|
145
|
+
this.$buildTypeChoices();
|
|
146
|
+
}}
|
|
147
|
+
}, [getFormatAndSchemaChoices({schema, hasKeyPath})]);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @callback TypeRootGetter
|
|
151
|
+
* @returns {void}
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @callback TypeSelectGetter
|
|
156
|
+
* @returns {void}
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @typedef {HTMLDivElement} TypesHolder
|
|
161
|
+
* @property {TypeRootGetter} $getTypeRoot
|
|
162
|
+
* @property {TypeSelectGetter} $getTypeSelect
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
const typesHolder = jml('div', {class: 'typesHolder', $custom: {
|
|
166
|
+
/**
|
|
167
|
+
* @type {TypeRootGetter}
|
|
168
|
+
*/
|
|
169
|
+
$getTypeRoot () {
|
|
170
|
+
return $e(this, 'div[data-type]');
|
|
171
|
+
},
|
|
172
|
+
/**
|
|
173
|
+
* @type {TypeSelectGetter}
|
|
174
|
+
*/
|
|
175
|
+
$getTypeSelect () {
|
|
176
|
+
return $e(this, `.typeChoices-${typeNamespace}`);
|
|
177
|
+
}
|
|
178
|
+
}});
|
|
179
|
+
|
|
180
|
+
jml({'#': buildTypeChoices({
|
|
181
|
+
resultType: 'both',
|
|
182
|
+
topRoot: $e(typesHolder, 'div[data-type]'),
|
|
183
|
+
format,
|
|
184
|
+
typeNamespace,
|
|
185
|
+
requireObject: hasKeyPath,
|
|
186
|
+
objectHasValue: hasValue,
|
|
187
|
+
schema,
|
|
188
|
+
schemaContent
|
|
189
|
+
}).domArray}, typesHolder);
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
formatChoices,
|
|
193
|
+
typesHolder,
|
|
194
|
+
// Easier for Jamilih
|
|
195
|
+
domArray: [formatChoices, typesHolder],
|
|
196
|
+
|
|
197
|
+
// Normal API
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @param {import('./types.js').StateObject} [stateObj] Will
|
|
201
|
+
* auto-set `typeNamespace` and `format`
|
|
202
|
+
* @param {string} [currentPath]
|
|
203
|
+
* @returns {StructuredCloneValue}
|
|
204
|
+
*/
|
|
205
|
+
getValue (stateObj, currentPath) {
|
|
206
|
+
const root = typesHolder.$getTypeRoot();
|
|
207
|
+
return Types.getValueForRoot(root, {
|
|
208
|
+
typeNamespace,
|
|
209
|
+
format: formatChoices.value,
|
|
210
|
+
...stateObj
|
|
211
|
+
}, currentPath);
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @returns {string|undefined}
|
|
216
|
+
*/
|
|
217
|
+
getType () {
|
|
218
|
+
const root = typesHolder.$getTypeRoot();
|
|
219
|
+
return Types.getTypeForRoot(root);
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @returns {boolean}
|
|
224
|
+
*/
|
|
225
|
+
validValuesSet () {
|
|
226
|
+
const root = typesHolder.$getTypeRoot();
|
|
227
|
+
const form = root.closest('form');
|
|
228
|
+
return Types.validValuesSet({form, typeNamespace});
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @param {StructuredCloneValue} value
|
|
233
|
+
* @param {import('./types.js').StateObject} stateObj
|
|
234
|
+
* @returns {Promise<void>}
|
|
235
|
+
*/
|
|
236
|
+
async setValue (value, stateObj) {
|
|
237
|
+
const rootEditUI = await getControlsForFormatAndValue(
|
|
238
|
+
formatChoices.value, value, stateObj
|
|
239
|
+
);
|
|
240
|
+
const type = Types.getTypeForRoot(rootEditUI);
|
|
241
|
+
const sel = typesHolder.$getTypeSelect();
|
|
242
|
+
sel.$addTypeAndEditUI({type, editUI: rootEditUI});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
package/src/formats/json.js
CHANGED
|
@@ -8,7 +8,7 @@ import * as structuredCloning from './structuredCloning.js';
|
|
|
8
8
|
import deepEqual from '../deepEqual.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* @type {FormatIterator}
|
|
11
|
+
* @type {import('./structuredCloning.js').FormatIterator}
|
|
12
12
|
*/
|
|
13
13
|
export const iterate = (records, stateObj) => {
|
|
14
14
|
console.log('records', records, stateObj);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Formats from '../formats.js';
|
|
2
2
|
import Types from '../types.js';
|
|
3
|
+
import {buildTypeChoices} from '../typeChoices.js';
|
|
3
4
|
import {
|
|
4
5
|
Typeson, unescapeKeyPathComponent, structuredCloningThrowing
|
|
5
6
|
} from '../../vendor/typeson-registry/dist/index.js';
|
|
@@ -16,22 +17,7 @@ import * as json from './json.js';
|
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* @
|
|
20
|
-
* typeNamespace: string,
|
|
21
|
-
* "readonly": boolean,
|
|
22
|
-
* format: string,
|
|
23
|
-
* schemaContent: string,
|
|
24
|
-
* getPossibleSchemasForPathAndType: (
|
|
25
|
-
* keypath: string,
|
|
26
|
-
* parentPath: string,
|
|
27
|
-
* arrayOrObjectPropertyName: string,
|
|
28
|
-
* valueType: string
|
|
29
|
-
* ) => StateObject
|
|
30
|
-
* }} StateObject
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @param {StateObject} stateObj
|
|
20
|
+
* @param {import('../types.js').StateObject} stateObj
|
|
35
21
|
* @returns {EncapsulateObserver}
|
|
36
22
|
*/
|
|
37
23
|
const encapsulateObserver = (stateObj) => {
|
|
@@ -119,7 +105,7 @@ const encapsulateObserver = (stateObj) => {
|
|
|
119
105
|
typeNamespace,
|
|
120
106
|
type: newType,
|
|
121
107
|
bringIntoFocus: false,
|
|
122
|
-
buildTypeChoices
|
|
108
|
+
buildTypeChoices,
|
|
123
109
|
format,
|
|
124
110
|
schemaContent,
|
|
125
111
|
schemaState: getPossibleSchemasForPathAndType,
|
|
@@ -260,11 +246,7 @@ const canonicalToAvailableType = (format, state, valType, v) => {
|
|
|
260
246
|
/**
|
|
261
247
|
* @callback FormatIterator
|
|
262
248
|
* @param {StructuredCloneValue} records
|
|
263
|
-
* @param {
|
|
264
|
-
* format: string
|
|
265
|
-
* error: Error
|
|
266
|
-
* rootUI: Element
|
|
267
|
-
* }} stateObj
|
|
249
|
+
* @param {import('../types.js').StateObject} stateObj
|
|
268
250
|
* @returns {Promise<Element>}
|
|
269
251
|
*/
|
|
270
252
|
|