@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/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/CoCreate-app/CoCreate-state/graphs/contributors).
4
- You're encouraged to submit [pull requests](https://github.com/CoCreate-app/CoCreate-state/pulls),
5
- [propose features and discuss issues](https://github.com/CoCreate-app/CoCreate-state/issues).
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/CoCreate-app/CoCreate-state) and check out your copy.
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://gitlab.com/cocreatejs/CoCreate-state.git
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/CoCreate-app/CoCreate-state](https://github.com/CoCreate-app/CoCreate-state) and select your feature branch.
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://cocreate.app/docs/state) | [Changelog](https://github.com/CoCreate-app/CoCreate-state/blob/master/CHANGELOG.md) | [Issues](https://github.com/CoCreate-app/CoCreate-state/issues)
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.cocreate.app/state/latest/CoCreate-state.min.js"></script>
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/CoCreate-app/CoCreate-state/blob/master/CONTRIBUTING.md), open an [issue](https://github.com/CoCreate-app/CoCreate-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.
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/CoCreate-app/CoCreate-state/blob/master/LICENSE).
284
- - **Commercial use:** For-profit use requires a commercial license from [CoCreate](https://cocreate.app).
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
@@ -20,6 +20,6 @@
20
20
  </button>
21
21
 
22
22
  <!--<script src="../dist/CoCreate-state.js"></script>-->
23
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
23
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
24
24
  </body>
25
25
  </html>
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.cocreate.app/state/latest/CoCreate-state.min.css"
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.cocreate.app/CoCreate-attributes/CoCreate-attibutes.html"
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://CoCreate.app/dist/CoCreate.js"></script>
186
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
187
187
  </body>
188
188
  </html>
@@ -12,7 +12,7 @@
12
12
  <!-- CoCreate CSS CDN -->
13
13
  <link
14
14
  rel="stylesheet"
15
- href="https://cdn.cocreate.app/state/latest/CoCreate-state.min.css"
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.cocreate.app/state/latest/CoCreate-state.min.js"></script>
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://CoCreate.app/dist/CoCreate.js"></script>-->
47
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
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>
@@ -9,6 +9,6 @@
9
9
  >Click to state: goodbye</a
10
10
  >
11
11
 
12
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
12
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
13
13
  </body>
14
14
  </html>
@@ -60,6 +60,6 @@
60
60
  </div>
61
61
 
62
62
  <!--<script src="../dist/CoCreate-state.js"></script>-->
63
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
63
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
64
64
  </body>
65
65
  </html>
package/demo/test.html CHANGED
@@ -15,6 +15,6 @@
15
15
  <iframe src="./iframe.html"></iframe>
16
16
 
17
17
  <!--<script src="../dist/CoCreate-state.js"></script>-->
18
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
18
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
19
19
  </body>
20
20
  </html>
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://cocreate.app/images/favicon.ico" />
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 &amp; 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.cocreate.app/docs/state.png" />
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.cocreate.app/docs/state.png"
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/CoCreate-app/CoCreate-state"
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">&lt;script&gt;https://cdn.cocreate.app/state/latest/CoCreate-state.min.js&lt;/script&gt;</code></pre>
145
+ <pre><code class="language-html">&lt;script&gt;https://cdn.CoCreateJS.com/state/latest/CoCreate-state.min.js&lt;/script&gt;</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/CoCreate-app/CoCreate-state/tree/master/docs/index.html?message=docs%3A%20describe%20your%20change..."
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://CoCreate.app/dist/CoCreate.js"></script>
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": "1.31.0",
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://gitlab.com/cocreatejs/CoCreate-state.git"
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/CoCreate-app/CoCreate-state/issues"
30
+ "url": "https://github.com/CoCreateJS/state/issues"
31
31
  },
32
- "homepage": "https://cocreate.app/docs/state",
32
+ "homepage": "https://CoCreateJS.com/docs/state",
33
33
  "funding": {
34
34
  "type": "GitHub Sponsors ❤",
35
- "url": "https://github.com/sponsors/CoCreate-app"
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 = JSON.parse(stateValue);
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 json of [false, true]) {
38
- test(`source requests see the newly selected app (${json ? 'JSON' : 'nested attributes'})`, async () => {
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 trigger = json
44
- ? element({ state: JSON.stringify({ 'offcanvas-app-view': view, 'offcanvas-app-form': record }) })
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
+ });