@cocreate/state 1.31.0 → 2.0.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/.github/FUNDING.yml +1 -1
- package/.github/workflows/automated.yml +18 -7
- package/CHANGELOG.md +423 -392
- package/CONTRIBUTING.md +6 -6
- package/README.md +5 -5
- package/demo/iframe.html +1 -1
- package/demo/index.html +3 -3
- package/demo/pass-prefix.html +2 -2
- package/demo/pass-value-input.1.html +2 -2
- package/demo/pass-value-input.html +1 -1
- package/demo/pass-value.html +1 -1
- package/demo/test.html +1 -1
- package/docs/index.html +7 -7
- package/package.json +5 -5
- package/src/index.js +109 -1
- package/test/source-state-order.test.cjs +39 -6
package/CONTRIBUTING.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Contributing to CoCreate-state
|
|
2
2
|
|
|
3
|
-
This project is work of [many contributors](https://github.com/
|
|
4
|
-
You're encouraged to submit [pull requests](https://github.com/
|
|
5
|
-
[propose features and discuss issues](https://github.com/
|
|
3
|
+
This project is work of [many contributors](https://github.com/CoCreateJS/state/graphs/contributors).
|
|
4
|
+
You're encouraged to submit [pull requests](https://github.com/CoCreateJS/state/pulls),
|
|
5
|
+
[propose features and discuss issues](https://github.com/CoCreateJS/state/issues).
|
|
6
6
|
|
|
7
7
|
In the examples below, substitute your Github username for `contributor` in URLs.
|
|
8
8
|
|
|
9
9
|
## Fork the Project
|
|
10
10
|
|
|
11
|
-
Fork the [project on Github](https://github.com/
|
|
11
|
+
Fork the [project on Github](https://github.com/CoCreateJS/state) and check out your copy.
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
git state https://github.com/contributor/CoCreate-state.git
|
|
15
15
|
cd CoCreate-state
|
|
16
|
-
git remote add upstream https://
|
|
16
|
+
git remote add upstream https://github.com/CoCreateJS/state.git
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Create a Topic Branch
|
|
@@ -74,7 +74,7 @@ git push origin my-feature-branch
|
|
|
74
74
|
|
|
75
75
|
## Make a Pull Request
|
|
76
76
|
|
|
77
|
-
Go to [https://github.com/
|
|
77
|
+
Go to [https://github.com/CoCreateJS/state](https://github.com/CoCreateJS/state) and select your feature branch.
|
|
78
78
|
Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
|
|
79
79
|
|
|
80
80
|
## Rebase
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
`@cocreate/state` provides declarative state persistence and state-driven UI updates for CoCreate applications. A source element stores selected values under one or more keys, and elements with matching `state-id` attributes replay those values into their attributes, values, classes, or element methods.
|
|
4
4
|
|
|
5
|
-
[Docs and demo](https://
|
|
5
|
+
[Docs and demo](https://CoCreateJS.com/docs/state) | [Changelog](https://github.com/CoCreateJS/state/blob/master/CHANGELOG.md) | [Issues](https://github.com/CoCreateJS/state/issues)
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
### CDN
|
|
10
10
|
|
|
11
11
|
```html
|
|
12
|
-
<script src="https://cdn.
|
|
12
|
+
<script src="https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.js"></script>
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### npm
|
|
@@ -274,11 +274,11 @@ Use the registered action name `state` and ensure the action element receives th
|
|
|
274
274
|
|
|
275
275
|
## Contributing
|
|
276
276
|
|
|
277
|
-
Please read the [contributing guide](https://github.com/
|
|
277
|
+
Please read the [contributing guide](https://github.com/CoCreateJS/state/blob/master/CONTRIBUTING.md), open an [issue](https://github.com/CoCreateJS/state/issues), or submit a pull request. Changes to storage selection, state shape, attribute assignment, history behavior, and the `stateEnd` event are compatibility-sensitive and should include documentation and examples.
|
|
278
278
|
|
|
279
279
|
## License
|
|
280
280
|
|
|
281
281
|
This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
|
|
282
282
|
|
|
283
|
-
- **Open source use:** For open-source projects and non-commercial use, the software is available under the AGPLv3. See the [LICENSE file](https://github.com/
|
|
284
|
-
- **Commercial use:** For-profit use requires a commercial license from [CoCreate](https://
|
|
283
|
+
- **Open source use:** For open-source projects and non-commercial use, the software is available under the AGPLv3. See the [LICENSE file](https://github.com/CoCreateJS/state/blob/master/LICENSE).
|
|
284
|
+
- **Commercial use:** For-profit use requires a commercial license from [CoCreate](https://CoCreateJS.com).
|
package/demo/iframe.html
CHANGED
package/demo/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<!-- CoCreate CSS CDN -->
|
|
13
13
|
<link
|
|
14
14
|
rel="stylesheet"
|
|
15
|
-
href="https://cdn.
|
|
15
|
+
href="https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.css"
|
|
16
16
|
type="text/css" />
|
|
17
17
|
<link rel="manifest" href="/manifest.webmanifest" />
|
|
18
18
|
</head>
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
|
|
81
81
|
<button>
|
|
82
82
|
<a
|
|
83
|
-
href="https://server.
|
|
83
|
+
href="https://server.CoCreateJS.com/CoCreate-attributes/CoCreate-attibutes.html"
|
|
84
84
|
target="_blank"
|
|
85
85
|
state-array="modules"
|
|
86
86
|
state-object="5ebc16fc8917bc59483a7e3b"
|
|
@@ -183,6 +183,6 @@
|
|
|
183
183
|
<div id="modal-viewport"></div>
|
|
184
184
|
|
|
185
185
|
<!--<script src="../dist/CoCreate-state.js"></script>-->
|
|
186
|
-
<script src="https://
|
|
186
|
+
<script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
|
|
187
187
|
</body>
|
|
188
188
|
</html>
|
package/demo/pass-prefix.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<!-- CoCreate CSS CDN -->
|
|
13
13
|
<link
|
|
14
14
|
rel="stylesheet"
|
|
15
|
-
href="https://cdn.
|
|
15
|
+
href="https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.css"
|
|
16
16
|
type="text/css" />
|
|
17
17
|
<link rel="manifest" href="/manifest.webmanifest" />
|
|
18
18
|
</head>
|
|
@@ -44,6 +44,6 @@
|
|
|
44
44
|
<div id="modal-viewport"></div>
|
|
45
45
|
|
|
46
46
|
<!--CoCreateJS CDN-->
|
|
47
|
-
<script src="https://cdn.
|
|
47
|
+
<script src="https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.js"></script>
|
|
48
48
|
</body>
|
|
49
49
|
</html>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
placeholder="Test 2"></textarea>
|
|
44
44
|
</form>
|
|
45
45
|
|
|
46
|
-
<!--<script src="https://
|
|
47
|
-
<script src="https://
|
|
46
|
+
<!--<script src="https://CoCreateJS.com/dist/CoCreate.js"></script>-->
|
|
47
|
+
<script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
|
|
48
48
|
</body>
|
|
49
49
|
</html>
|
package/demo/pass-value.html
CHANGED
package/demo/test.html
CHANGED
package/docs/index.html
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
rel="icon"
|
|
10
10
|
type="image/png"
|
|
11
11
|
sizes="32x32"
|
|
12
|
-
href="https://
|
|
12
|
+
href="https://CoCreateJS.com/images/favicon.ico" />
|
|
13
13
|
<meta
|
|
14
14
|
name="description"
|
|
15
15
|
content="Data attributes which can be used for components in CoCreate framework combined as a group of attributes that dynamically change attributes & fetch custom data" />
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<meta name="robots" content="index,follow" />
|
|
20
20
|
<meta
|
|
21
21
|
property="og:image"
|
|
22
|
-
content="https://cdn.
|
|
22
|
+
content="https://cdn.CoCreateJS.com/docs/state.png" />
|
|
23
23
|
|
|
24
24
|
<link
|
|
25
25
|
rel="stylesheet"
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
share-title="CoCreate-state"
|
|
74
74
|
share-height="600"
|
|
75
75
|
share-width="700"
|
|
76
|
-
share-media="https://cdn.
|
|
76
|
+
share-media="https://cdn.CoCreateJS.com/docs/state.png"
|
|
77
77
|
hover="display:block!important"
|
|
78
78
|
hover-query=".social-networks">
|
|
79
79
|
<div class="display:none social-networks">
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
></a>
|
|
105
105
|
</div>
|
|
106
106
|
<a
|
|
107
|
-
href="https://github.com/
|
|
107
|
+
href="https://github.com/CoCreateJS/CoCreate-state"
|
|
108
108
|
target="_blank"
|
|
109
109
|
class="margin-right:15px"
|
|
110
110
|
><i src="/assets/svg/github.svg"></i
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
<p class="padding:10px_0px line-height:1.5">
|
|
143
143
|
Or you can use cdn link:
|
|
144
144
|
</p>
|
|
145
|
-
<pre><code class="language-html"><script>https://cdn.
|
|
145
|
+
<pre><code class="language-html"><script>https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.js</script></code></pre>
|
|
146
146
|
|
|
147
147
|
<div
|
|
148
148
|
id="state-usage"
|
|
@@ -327,13 +327,13 @@
|
|
|
327
327
|
</div>
|
|
328
328
|
</div>
|
|
329
329
|
<button
|
|
330
|
-
href="https://github.com/
|
|
330
|
+
href="https://github.com/CoCreateJS/CoCreate-state/tree/master/docs/index.html?message=docs%3A%20describe%20your%20change..."
|
|
331
331
|
target="_blank"
|
|
332
332
|
class="display:flex justify-content:center align-items:center position:fixed bottom:15px right:15px height:50px width:50px border-radius:50% box-shadow:0px_2px_10px_0px_rgba(0,_0,_0,_0.4)">
|
|
333
333
|
<i src="../assets/svg/pencil-alt.svg"></i>
|
|
334
334
|
</button>
|
|
335
335
|
</main>
|
|
336
336
|
|
|
337
|
-
<script src="https://
|
|
337
|
+
<script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
|
|
338
338
|
</body>
|
|
339
339
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/state",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Data attributes which can be used for components in CoCreate framework combined as a group of attributes that dynamically change attributes & fetch custom data.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"state",
|
|
@@ -22,17 +22,17 @@
|
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "git+https://
|
|
25
|
+
"url": "git+https://github.com/CoCreateJS/state.git"
|
|
26
26
|
},
|
|
27
27
|
"author": "CoCreate LLC",
|
|
28
28
|
"license": "AGPL-3.0",
|
|
29
29
|
"bugs": {
|
|
30
|
-
"url": "https://github.com/
|
|
30
|
+
"url": "https://github.com/CoCreateJS/state/issues"
|
|
31
31
|
},
|
|
32
|
-
"homepage": "https://
|
|
32
|
+
"homepage": "https://CoCreateJS.com/docs/state",
|
|
33
33
|
"funding": {
|
|
34
34
|
"type": "GitHub Sponsors ❤",
|
|
35
|
-
"url": "https://github.com/sponsors/
|
|
35
|
+
"url": "https://github.com/sponsors/CoCreateJS"
|
|
36
36
|
},
|
|
37
37
|
"main": "./src/index.js",
|
|
38
38
|
"dependencies": {
|
package/src/index.js
CHANGED
|
@@ -56,10 +56,20 @@ function init() {
|
|
|
56
56
|
syncVisibleState();
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
* @environment client
|
|
63
|
+
*/
|
|
59
64
|
function initElements(elements) {
|
|
60
65
|
for (let element of elements) initElement(element);
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
* @environment client
|
|
72
|
+
*/
|
|
63
73
|
function initElement(element) {
|
|
64
74
|
let state_id = element.getAttribute("state-id");
|
|
65
75
|
if (!state_id) return;
|
|
@@ -255,6 +265,11 @@ function persistState({
|
|
|
255
265
|
}
|
|
256
266
|
}
|
|
257
267
|
|
|
268
|
+
/**
|
|
269
|
+
*
|
|
270
|
+
* @public
|
|
271
|
+
* @environment client
|
|
272
|
+
*/
|
|
258
273
|
function setState(state, options = {}) {
|
|
259
274
|
const sessionState = getStoredState(sessionStorage);
|
|
260
275
|
const localState = getStoredState(localStorage);
|
|
@@ -274,6 +289,11 @@ function setState(state, options = {}) {
|
|
|
274
289
|
return true;
|
|
275
290
|
}
|
|
276
291
|
|
|
292
|
+
/**
|
|
293
|
+
*
|
|
294
|
+
* @public
|
|
295
|
+
* @environment client
|
|
296
|
+
*/
|
|
277
297
|
async function stateAttributes(element) {
|
|
278
298
|
let sessionState = getStoredState(sessionStorage);
|
|
279
299
|
let localState = getStoredState(localStorage);
|
|
@@ -311,7 +331,9 @@ async function stateAttributes(element) {
|
|
|
311
331
|
|
|
312
332
|
if (stateValue) {
|
|
313
333
|
try {
|
|
314
|
-
const parsedState =
|
|
334
|
+
const parsedState = typeof stateValue === "string"
|
|
335
|
+
? JSON.parse(stateValue)
|
|
336
|
+
: stateValue;
|
|
315
337
|
if (mergeState(targetState, parsedState, updates)) {
|
|
316
338
|
if (isLocal) localChanged = true;
|
|
317
339
|
else sessionChanged = true;
|
|
@@ -482,3 +504,89 @@ init();
|
|
|
482
504
|
|
|
483
505
|
export { setState };
|
|
484
506
|
export default { initElements, initElement, stateAttributes, setState };
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
*
|
|
510
|
+
* @name state
|
|
511
|
+
* @kind member
|
|
512
|
+
* @attribute
|
|
513
|
+
* @environment client
|
|
514
|
+
*/
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
*
|
|
518
|
+
* @name state-id
|
|
519
|
+
* @kind member
|
|
520
|
+
* @attribute
|
|
521
|
+
* @environment client
|
|
522
|
+
*/
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
*
|
|
526
|
+
* @name state-localstorage
|
|
527
|
+
* @kind member
|
|
528
|
+
* @attribute
|
|
529
|
+
* @environment client
|
|
530
|
+
*/
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
*
|
|
534
|
+
* @name state-onstoragechange
|
|
535
|
+
* @kind member
|
|
536
|
+
* @attribute
|
|
537
|
+
* @environment client
|
|
538
|
+
*/
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
*
|
|
542
|
+
* @name state-overwrite
|
|
543
|
+
* @kind member
|
|
544
|
+
* @attribute
|
|
545
|
+
* @environment client
|
|
546
|
+
*/
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
*
|
|
550
|
+
* @name state-title
|
|
551
|
+
* @kind member
|
|
552
|
+
* @attribute
|
|
553
|
+
* @environment client
|
|
554
|
+
*/
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
*
|
|
558
|
+
* @name state-to
|
|
559
|
+
* @kind member
|
|
560
|
+
* @attribute
|
|
561
|
+
* @environment client
|
|
562
|
+
*/
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
*
|
|
566
|
+
* @name value
|
|
567
|
+
* @kind member
|
|
568
|
+
* @attribute
|
|
569
|
+
* @environment client
|
|
570
|
+
*/
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Data attributes which can be used for components in CoCreate framework combined as a group of attributes that dynamically change attributes & fetch custom data.
|
|
574
|
+
*
|
|
575
|
+
* @module state
|
|
576
|
+
* @environment client
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Declarative selectors recognized by this module.
|
|
581
|
+
*
|
|
582
|
+
* @name declarative-selectors
|
|
583
|
+
* @kind member
|
|
584
|
+
* @selectors
|
|
585
|
+
* @environment client
|
|
586
|
+
* @example
|
|
587
|
+
* ```json
|
|
588
|
+
* [
|
|
589
|
+
* "[state-id]"
|
|
590
|
+
* ]
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
@@ -8,9 +8,11 @@ const source = fs.readFileSync(path.join(__dirname, '../src/index.js'), 'utf8');
|
|
|
8
8
|
function setup() {
|
|
9
9
|
let stored = JSON.stringify({ 'offcanvas-app-form': { array: 'apps', object: 'previous' } });
|
|
10
10
|
const requests = [];
|
|
11
|
+
const warnings = [];
|
|
12
|
+
const updates = [];
|
|
11
13
|
const storage = { getItem: () => stored, setItem: (_, value) => { stored = value; } };
|
|
12
14
|
const context = vm.createContext({
|
|
13
|
-
console, sessionStorage: storage,
|
|
15
|
+
console: { ...console, warn: (...args) => warnings.push(args) }, sessionStorage: storage,
|
|
14
16
|
localStorage: { getItem: () => '{}', setItem() {} },
|
|
15
17
|
document: { title: 'Apps' }, location: { href: 'http://localhost/apps' },
|
|
16
18
|
history: { pushState() {} }, CustomEvent: class {},
|
|
@@ -19,12 +21,13 @@ function setup() {
|
|
|
19
21
|
normalizeUnset: () => [], unsetKeys() {}, _unsetStateId() {},
|
|
20
22
|
_getAttributeValues: async element => element.values,
|
|
21
23
|
_getStateId(values, target) {
|
|
24
|
+
updates.push({ target, values: JSON.parse(JSON.stringify(values)) });
|
|
22
25
|
if (target === 'offcanvas-app-view') requests.push(JSON.parse(stored)['offcanvas-app-form'].object);
|
|
23
26
|
}
|
|
24
27
|
});
|
|
25
28
|
vm.runInContext(source.slice(source.indexOf('function mergeState('), source.indexOf('function setState(')) +
|
|
26
29
|
source.slice(source.indexOf('async function stateAttributes('), source.indexOf('async function _getAttributeValues(')), context);
|
|
27
|
-
return { apply: context.stateAttributes, requests };
|
|
30
|
+
return { apply: context.stateAttributes, requests, warnings, updates, getState: () => JSON.parse(stored) };
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
function element(attributes, values = {}, children = []) {
|
|
@@ -34,14 +37,15 @@ function element(attributes, values = {}, children = []) {
|
|
|
34
37
|
querySelectorAll: () => children, closest: () => null, dispatchEvent() {} };
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
for (const
|
|
38
|
-
test(`source requests see the newly selected app (${
|
|
40
|
+
for (const format of ['nested attributes', 'JSON', 'evaluated object']) {
|
|
41
|
+
test(`source requests see the newly selected app (${format})`, async () => {
|
|
39
42
|
const { apply, requests } = setup();
|
|
40
43
|
for (const id of ['first-app', 'second-app']) {
|
|
41
44
|
const view = { src: '/apps/apps/aside.html' };
|
|
42
45
|
const record = { array: 'apps', object: id };
|
|
43
|
-
const
|
|
44
|
-
|
|
46
|
+
const state = { 'offcanvas-app-view': view, 'offcanvas-app-form': record };
|
|
47
|
+
const trigger = format !== 'nested attributes'
|
|
48
|
+
? element({ state: format === 'JSON' ? JSON.stringify(state) : state })
|
|
45
49
|
: element({ 'state-to': 'offcanvas-app-view' }, view,
|
|
46
50
|
[element({ 'state-to': 'offcanvas-app-form' }, record)]);
|
|
47
51
|
await apply(trigger);
|
|
@@ -49,3 +53,32 @@ for (const json of [false, true]) {
|
|
|
49
53
|
assert.deepEqual(requests, ['first-app', 'second-app']);
|
|
50
54
|
});
|
|
51
55
|
}
|
|
56
|
+
|
|
57
|
+
for (const evaluated of [false, true]) {
|
|
58
|
+
test(`new conversation reset accepts ${evaluated ? 'an AST-evaluated object' : 'JSON text'}`, async () => {
|
|
59
|
+
const { apply, warnings, updates, getState } = setup();
|
|
60
|
+
const state = {
|
|
61
|
+
'ai-conversation-messages': { 'filter-query-value': '', array: '', $renderValue: { object: [] } },
|
|
62
|
+
'ai-queue-conversation-filter': { 'filter-query-value': '' },
|
|
63
|
+
aiChat: { 'conversation-id': '' },
|
|
64
|
+
'ai-chat-conversation-id': { value: '' },
|
|
65
|
+
'ai-chat-model': { value: 'openai:gpt-5.4-nano', array: 'ai-conversations', object: '', realtime: 'false' }
|
|
66
|
+
};
|
|
67
|
+
await apply(element({ state: evaluated ? state : JSON.stringify(state) }));
|
|
68
|
+
assert.deepEqual(warnings, []);
|
|
69
|
+
for (const [id, values] of Object.entries(state)) {
|
|
70
|
+
assert.deepEqual(getState()[id], values);
|
|
71
|
+
assert.deepEqual(updates.find(update => update.target === id)?.values, values);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
test('malformed state JSON still warns without changing stored state', async () => {
|
|
77
|
+
const { apply, warnings, updates, getState } = setup();
|
|
78
|
+
const before = getState();
|
|
79
|
+
await apply(element({ state: '{broken' }));
|
|
80
|
+
assert.equal(warnings.length, 1);
|
|
81
|
+
assert.equal(warnings[0][0], 'Invalid state JSON:');
|
|
82
|
+
assert.deepEqual(updates, []);
|
|
83
|
+
assert.deepEqual(getState(), before);
|
|
84
|
+
});
|