@uistate/core 5.0.2 → 5.1.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.
Files changed (38) hide show
  1. package/eventStateNew.js +149 -0
  2. package/eventTest.js +1 -1
  3. package/examples/002-counter-improved/index.html +4 -1
  4. package/examples/003-input-reactive/index.html +4 -1
  5. package/examples/004-computed-state/index.html +9 -6
  6. package/examples/005-conditional-rendering/index.html +7 -4
  7. package/examples/006-list-rendering/index.html +8 -5
  8. package/examples/007-form-validation/index.html +11 -8
  9. package/examples/008-undo-redo/index.html +15 -12
  10. package/examples/009-localStorage-side-effects/index.html +7 -4
  11. package/examples/010-decoupled-components/index.html +6 -3
  12. package/examples/011-async-patterns/index.html +19 -16
  13. package/examples/028-counter-improved-eventTest/app/store.js +1 -1
  14. package/examples/028-counter-improved-eventTest/runtime/core/eventStateNew.js +149 -0
  15. package/examples/028-counter-improved-eventTest/tests/eventTest.js +1 -1
  16. package/examples/030-todo-app-with-eventTest/app/store.js +1 -1
  17. package/examples/030-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  18. package/examples/030-todo-app-with-eventTest/tests/eventTest.js +1 -1
  19. package/examples/031-todo-app-with-eventTest/app/store.js +1 -1
  20. package/examples/031-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  21. package/examples/031-todo-app-with-eventTest/runtime/extensions/eventState.plus.js +1 -1
  22. package/examples/031-todo-app-with-eventTest/tests/eventTest.js +1 -1
  23. package/examples/032-todo-app-with-eventTest/app/store.js +1 -1
  24. package/examples/032-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  25. package/examples/032-todo-app-with-eventTest/runtime/extensions/eventState.plus.js +1 -1
  26. package/examples/032-todo-app-with-eventTest/tests/eventTest.js +1 -1
  27. package/index.js +2 -2
  28. package/package.json +3 -1
  29. package/examples/002-counter-improved/eventState.js +0 -86
  30. package/examples/003-input-reactive/eventState.js +0 -86
  31. package/examples/004-computed-state/eventState.js +0 -86
  32. package/examples/005-conditional-rendering/eventState.js +0 -86
  33. package/examples/006-list-rendering/eventState.js +0 -86
  34. package/examples/007-form-validation/eventState.js +0 -86
  35. package/examples/008-undo-redo/eventState.js +0 -86
  36. package/examples/009-localStorage-side-effects/eventState.js +0 -86
  37. package/examples/010-decoupled-components/eventState.js +0 -86
  38. package/examples/011-async-patterns/eventState.js +0 -86
@@ -0,0 +1,149 @@
1
+ /**
2
+ * EventState v2 - Optimized Path-Based State Management
3
+ *
4
+ * A lightweight, performant state management library using path-based subscriptions.
5
+ * Optimized for selective notifications and granular updates.
6
+ *
7
+ * Features:
8
+ * - Path-based get/set operations (e.g., 'user.profile.name')
9
+ * - Selective subscriptions (only relevant subscribers fire)
10
+ * - Wildcard subscriptions (e.g., 'user.*' catches all user changes)
11
+ * - Global subscriptions (e.g., '*' catches all changes)
12
+ * - Zero dependencies
13
+ * - ~2KB minified
14
+ *
15
+ * Performance characteristics:
16
+ * - 2-9x faster than Zustand for selective subscriptions
17
+ * - Competitive overall performance
18
+ * - Minimal rendering overhead (1.27x faster paint times)
19
+ *
20
+ * @example
21
+ * const store = createEventState({ count: 0, user: { name: 'Alice' } });
22
+ *
23
+ * // Subscribe to specific path (receives value directly)
24
+ * const unsub = store.subscribe('count', (value) => {
25
+ * console.log('Count changed:', value);
26
+ * });
27
+ *
28
+ * // Update state
29
+ * store.set('count', 1);
30
+ *
31
+ * // Get state
32
+ * const count = store.get('count');
33
+ *
34
+ * // Wildcard subscription
35
+ * store.subscribe('user.*', ({ path, value }) => {
36
+ * console.log(`User field ${path} changed to:`, value);
37
+ * });
38
+ *
39
+ * // Global subscription
40
+ * store.subscribe('*', ({ path, value }) => {
41
+ * console.log(`State changed at ${path}:`, value);
42
+ * });
43
+ *
44
+ * // Cleanup
45
+ * unsub();
46
+ * store.destroy();
47
+ */
48
+
49
+ export function createEventState(initial = {}) {
50
+ const state = JSON.parse(JSON.stringify(initial));
51
+ const listeners = new Map();
52
+ let destroyed = false;
53
+
54
+ return {
55
+ /**
56
+ * Get value at path
57
+ * @param {string} path - Dot-separated path (e.g., 'user.profile.name')
58
+ * @returns {*} Value at path, or entire state if no path provided
59
+ */
60
+ get(path) {
61
+ if (destroyed) throw new Error('Cannot get from destroyed store');
62
+ if (!path) return state;
63
+ return path.split(".").reduce((obj, key) => obj?.[key], state);
64
+ },
65
+
66
+ /**
67
+ * Set value at path and notify subscribers
68
+ * @param {string} path - Dot-separated path (e.g., 'user.profile.name')
69
+ * @param {*} value - New value
70
+ * @returns {*} The value that was set
71
+ */
72
+ set(path, value) {
73
+ if (destroyed) throw new Error('Cannot set on destroyed store');
74
+ if (!path) return value;
75
+
76
+ const parts = path.split(".");
77
+ const key = parts.pop();
78
+ let cur = state;
79
+
80
+ // Navigate to parent object, creating nested objects as needed
81
+ for (const p of parts) {
82
+ if (!cur[p]) cur[p] = {};
83
+ cur = cur[p];
84
+ }
85
+
86
+ const oldValue = cur[key];
87
+ cur[key] = value;
88
+
89
+ if (!destroyed) {
90
+ const detail = { path, value, oldValue };
91
+
92
+ // Notify exact path subscribers (pass value directly for backwards compatibility)
93
+ const exactListeners = listeners.get(path);
94
+ if (exactListeners) {
95
+ exactListeners.forEach(cb => cb(value));
96
+ }
97
+
98
+ // Notify wildcard subscribers for all parent paths (pass detail object)
99
+ for (let i = 0; i < parts.length; i++) {
100
+ const parentPath = parts.slice(0, i + 1).join('.');
101
+ const wildcardListeners = listeners.get(`${parentPath}.*`);
102
+ if (wildcardListeners) {
103
+ wildcardListeners.forEach(cb => cb(detail));
104
+ }
105
+ }
106
+
107
+ // Notify global subscribers (pass detail object)
108
+ const globalListeners = listeners.get('*');
109
+ if (globalListeners) {
110
+ globalListeners.forEach(cb => cb(detail));
111
+ }
112
+ }
113
+
114
+ return value;
115
+ },
116
+
117
+ /**
118
+ * Subscribe to changes at path
119
+ * @param {string} path - Path to subscribe to (supports wildcards: 'user.*', '*')
120
+ * @param {Function} handler - Callback function receiving { path, value, oldValue }
121
+ * @returns {Function} Unsubscribe function
122
+ */
123
+ subscribe(path, handler) {
124
+ if (destroyed) throw new Error('Cannot subscribe to destroyed store');
125
+ if (!path || typeof handler !== 'function') {
126
+ throw new TypeError('subscribe requires path and handler');
127
+ }
128
+
129
+ if (!listeners.has(path)) {
130
+ listeners.set(path, new Set());
131
+ }
132
+ listeners.get(path).add(handler);
133
+
134
+ return () => listeners.get(path)?.delete(handler);
135
+ },
136
+
137
+ /**
138
+ * Destroy store and clear all subscriptions
139
+ */
140
+ destroy() {
141
+ if (!destroyed) {
142
+ destroyed = true;
143
+ listeners.clear();
144
+ }
145
+ }
146
+ };
147
+ }
148
+
149
+ export default createEventState;
package/eventTest.js CHANGED
@@ -24,7 +24,7 @@
24
24
  * Provides TDD-style testing with type extraction capabilities
25
25
  */
26
26
 
27
- import { createEventState } from './eventState.js';
27
+ import { createEventState } from './eventStateNew.js';
28
28
 
29
29
  export function createEventTest(initialState = {}) {
30
30
  const store = createEventState(initialState);
@@ -4,6 +4,9 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>002 Counter Improved - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Counter: <span id="count">0</span></h1>
@@ -12,7 +15,7 @@
12
15
  <button id="double">x2</button>
13
16
 
14
17
  <script type="module">
15
- import { createEventState } from './eventState.js';
18
+ import { createEventState } from '@uistate/core';
16
19
 
17
20
  // Create store
18
21
  const store = createEventState({ count: 0 });
@@ -4,6 +4,9 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>003 Input Reactive - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Type something:</h1>
@@ -11,7 +14,7 @@
11
14
  <p id="output"></p>
12
15
 
13
16
  <script type="module">
14
- import { createEventState } from './eventState.js';
17
+ import { createEventState } from '@uistate/core';
15
18
 
16
19
  // Create store
17
20
  const store = createEventState({ text: '' });
@@ -4,23 +4,26 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>004 Computed State - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Computed State</h1>
10
-
13
+
11
14
  <label>First Name: <input type="text" id="firstName" placeholder="Abraham"></label><br>
12
15
  <label>Last Name: <input type="text" id="lastName" placeholder="Lincoln"></label><br>
13
-
16
+
14
17
  <p><strong>Full Name:</strong> <span id="fullName"></span></p>
15
18
  <p><strong>Character Count:</strong> <span id="charCount">0</span></p>
16
19
 
17
20
  <script type="module">
18
- import { createEventState } from './eventState.js';
21
+ import { createEventState } from '@uistate/core';
19
22
 
20
23
  // Create store
21
- const store = createEventState({
22
- firstName: '',
23
- lastName: ''
24
+ const store = createEventState({
25
+ firstName: '',
26
+ lastName: ''
24
27
  });
25
28
 
26
29
  // Computed: full name (derived from firstName + lastName)
@@ -4,19 +4,22 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>005 Conditional Rendering - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Conditional Rendering</h1>
10
-
13
+
11
14
  <label>
12
15
  <input type="checkbox" id="toggle">
13
16
  Show secret message
14
17
  </label>
15
-
16
- <p id="message" style="display: none;">🎉 You found the secret message!</p>
18
+
19
+ <p id="message" style="display: none;">You found the secret message!</p>
17
20
 
18
21
  <script type="module">
19
- import { createEventState } from './eventState.js';
22
+ import { createEventState } from '@uistate/core';
20
23
 
21
24
  // Create store
22
25
  const store = createEventState({ isVisible: false });
@@ -4,17 +4,20 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>006 List Rendering - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Shopping List</h1>
10
-
13
+
11
14
  <input type="text" id="itemInput" placeholder="Add item...">
12
15
  <button id="addBtn">Add</button>
13
-
16
+
14
17
  <ul id="itemList"></ul>
15
18
 
16
19
  <script type="module">
17
- import { createEventState } from './eventState.js';
20
+ import { createEventState } from '@uistate/core';
18
21
 
19
22
  // Create store
20
23
  const store = createEventState({ items: [] });
@@ -23,7 +26,7 @@
23
26
  const renderList = () => {
24
27
  const items = store.get('items');
25
28
  const list = document.getElementById('itemList');
26
-
29
+
27
30
  if (items.length === 0) {
28
31
  list.innerHTML = '<li><em>No items yet</em></li>';
29
32
  } else {
@@ -38,7 +41,7 @@
38
41
  document.getElementById('addBtn').onclick = () => {
39
42
  const input = document.getElementById('itemInput');
40
43
  const value = input.value.trim();
41
-
44
+
42
45
  if (value) {
43
46
  const items = store.get('items');
44
47
  store.set('items', [...items, value]);
@@ -4,30 +4,33 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>007 Form Validation - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Sign Up Form</h1>
10
-
13
+
11
14
  <label>
12
15
  Email:
13
16
  <input type="email" id="email" placeholder="you@example.com">
14
17
  </label>
15
18
  <p id="emailError" style="color: red;"></p>
16
-
19
+
17
20
  <label>
18
21
  Password:
19
22
  <input type="password" id="password" placeholder="Min 8 characters">
20
23
  </label>
21
24
  <p id="passwordError" style="color: red;"></p>
22
-
25
+
23
26
  <button id="submitBtn" disabled>Submit</button>
24
27
  <p id="submitMessage" style="color: green;"></p>
25
28
 
26
29
  <script type="module">
27
- import { createEventState } from './eventState.js';
30
+ import { createEventState } from '@uistate/core';
28
31
 
29
32
  // Create store
30
- const store = createEventState({
33
+ const store = createEventState({
31
34
  email: '',
32
35
  password: '',
33
36
  emailValid: false,
@@ -55,7 +58,7 @@
55
58
  store.subscribe('email', (value) => {
56
59
  const isValid = validateEmail(value);
57
60
  store.set('emailValid', isValid);
58
-
61
+
59
62
  const error = document.getElementById('emailError');
60
63
  error.textContent = value && !isValid ? 'Invalid email address' : '';
61
64
  });
@@ -64,7 +67,7 @@
64
67
  store.subscribe('password', (value) => {
65
68
  const isValid = validatePassword(value);
66
69
  store.set('passwordValid', isValid);
67
-
70
+
68
71
  const error = document.getElementById('passwordError');
69
72
  error.textContent = value && !isValid ? 'Password must be at least 8 characters' : '';
70
73
  });
@@ -87,7 +90,7 @@
87
90
  const email = store.get('email');
88
91
  const message = document.getElementById('submitMessage');
89
92
  message.textContent = `✓ Form submitted for ${email}`;
90
-
93
+
91
94
  // Clear form
92
95
  document.getElementById('email').value = '';
93
96
  document.getElementById('password').value = '';
@@ -4,25 +4,28 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>008 Undo/Redo - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Counter with Time Travel</h1>
10
-
13
+
11
14
  <h2>Count: <span id="count">0</span></h2>
12
-
15
+
13
16
  <button id="increment">+1</button>
14
17
  <button id="decrement">-1</button>
15
18
  <button id="double">×2</button>
16
-
19
+
17
20
  <hr>
18
-
21
+
19
22
  <button id="undo" disabled>⟲ Undo</button>
20
23
  <button id="redo" disabled>⟳ Redo</button>
21
-
24
+
22
25
  <p><small>History: <span id="historyInfo">0 states</span></small></p>
23
26
 
24
27
  <script type="module">
25
- import { createEventState } from './eventState.js';
28
+ import { createEventState } from '@uistate/core';
26
29
 
27
30
  // Create store
28
31
  const store = createEventState({ count: 0 });
@@ -36,29 +39,29 @@
36
39
  const updateUI = () => {
37
40
  const count = store.get('count');
38
41
  document.getElementById('count').textContent = count;
39
-
42
+
40
43
  // Update button states
41
44
  document.getElementById('undo').disabled = historyIndex === 0;
42
45
  document.getElementById('redo').disabled = historyIndex === history.length - 1;
43
-
46
+
44
47
  // Update history info
45
- document.getElementById('historyInfo').textContent =
48
+ document.getElementById('historyInfo').textContent =
46
49
  `${historyIndex + 1} of ${history.length} states`;
47
50
  };
48
51
 
49
52
  // Subscribe to count changes and record history
50
53
  store.subscribe('count', (value) => {
51
54
  updateUI();
52
-
55
+
53
56
  // Only record if not time traveling
54
57
  if (!isTimeTravel) {
55
58
  // Remove any "future" states if we're in the middle of history
56
59
  history = history.slice(0, historyIndex + 1);
57
-
60
+
58
61
  // Add new state
59
62
  history.push(value);
60
63
  historyIndex = history.length - 1;
61
-
64
+
62
65
  updateUI();
63
66
  }
64
67
  });
@@ -4,20 +4,23 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>009 localStorage Side Effects - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Persistent Counter</h1>
10
-
13
+
11
14
  <h2>Count: <span id="count">0</span></h2>
12
-
15
+
13
16
  <button id="increment">+1</button>
14
17
  <button id="decrement">-1</button>
15
18
  <button id="reset">Reset</button>
16
-
19
+
17
20
  <p><small>Reload the page - your count persists!</small></p>
18
21
 
19
22
  <script type="module">
20
- import { createEventState } from './eventState.js';
23
+ import { createEventState } from '@uistate/core';
21
24
 
22
25
  const STORAGE_KEY = 'eventstate-counter';
23
26
 
@@ -11,6 +11,9 @@
11
11
  margin: 10px 0;
12
12
  }
13
13
  </style>
14
+ <script type="importmap">
15
+ { "imports": { "@uistate/core": "../../index.js" } }
16
+ </script>
14
17
  </head>
15
18
  <body>
16
19
  <h1>Decoupled Components</h1>
@@ -37,10 +40,10 @@
37
40
  </div>
38
41
 
39
42
  <script type="module">
40
- import { createEventState } from './eventState.js';
43
+ import { createEventState } from '@uistate/core';
41
44
 
42
45
  // Shared store - the ONLY connection between components
43
- const store = createEventState({
46
+ const store = createEventState({
44
47
  message: '',
45
48
  messageCount: 0
46
49
  });
@@ -50,7 +53,7 @@
50
53
  document.getElementById('sendBtn').onclick = () => {
51
54
  const input = document.getElementById('messageInput');
52
55
  const value = input.value.trim();
53
-
56
+
54
57
  if (value) {
55
58
  store.set('message', value);
56
59
  store.set('messageCount', store.get('messageCount') + 1);
@@ -4,27 +4,30 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>011 Async Patterns - EventState</title>
7
+ <script type="importmap">
8
+ { "imports": { "@uistate/core": "../../index.js" } }
9
+ </script>
7
10
  </head>
8
11
  <body>
9
12
  <h1>Async Patterns</h1>
10
-
13
+
11
14
  <h2>Debounced Search</h2>
12
15
  <input type="text" id="searchInput" placeholder="Type to search...">
13
16
  <p id="searchStatus"></p>
14
17
  <p><strong>Search result:</strong> <span id="searchResult">(type something)</span></p>
15
-
18
+
16
19
  <hr>
17
-
20
+
18
21
  <h2>Simulated API Call</h2>
19
22
  <button id="fetchBtn">Fetch Data</button>
20
23
  <p id="loadingStatus"></p>
21
24
  <p><strong>Data:</strong> <span id="apiData">(not loaded)</span></p>
22
25
 
23
26
  <script type="module">
24
- import { createEventState } from './eventState.js';
27
+ import { createEventState } from '@uistate/core';
25
28
 
26
29
  // Create store
27
- const store = createEventState({
30
+ const store = createEventState({
28
31
  searchQuery: '',
29
32
  searchResult: '',
30
33
  isSearching: false,
@@ -48,16 +51,16 @@
48
51
  store.subscribe('searchQuery', async (value) => {
49
52
  // Clear previous timeout
50
53
  clearTimeout(searchTimeout);
51
-
54
+
52
55
  if (!value) {
53
56
  store.set('searchResult', '');
54
57
  store.set('isSearching', false);
55
58
  return;
56
59
  }
57
-
60
+
58
61
  // Show searching indicator
59
62
  store.set('isSearching', true);
60
-
63
+
61
64
  // Debounce: wait 300ms before searching
62
65
  searchTimeout = setTimeout(async () => {
63
66
  const result = await performSearch(value);
@@ -68,12 +71,12 @@
68
71
 
69
72
  // Update UI for search status
70
73
  store.subscribe('isSearching', (value) => {
71
- document.getElementById('searchStatus').textContent =
72
- value ? '🔍 Searching...' : '';
74
+ document.getElementById('searchStatus').textContent =
75
+ value ? 'Searching...' : '';
73
76
  });
74
77
 
75
78
  store.subscribe('searchResult', (value) => {
76
- document.getElementById('searchResult').textContent =
79
+ document.getElementById('searchResult').textContent =
77
80
  value || '(type something)';
78
81
  });
79
82
 
@@ -83,12 +86,12 @@
83
86
  };
84
87
 
85
88
  // ===== SIMULATED API CALL =====
86
-
89
+
87
90
  // Simulate API fetch
88
91
  const fetchData = () => {
89
92
  return new Promise((resolve) => {
90
93
  setTimeout(() => {
91
- resolve({
94
+ resolve({
92
95
  id: Math.floor(Math.random() * 1000),
93
96
  timestamp: new Date().toLocaleTimeString()
94
97
  });
@@ -98,7 +101,7 @@
98
101
 
99
102
  // Subscribe to loading state
100
103
  store.subscribe('isLoading', (value) => {
101
- document.getElementById('loadingStatus').textContent =
104
+ document.getElementById('loadingStatus').textContent =
102
105
  value ? '⏳ Loading...' : '';
103
106
  document.getElementById('fetchBtn').disabled = value;
104
107
  });
@@ -106,7 +109,7 @@
106
109
  // Subscribe to API data
107
110
  store.subscribe('apiData', (value) => {
108
111
  if (value) {
109
- document.getElementById('apiData').textContent =
112
+ document.getElementById('apiData').textContent =
110
113
  `ID: ${value.id}, Time: ${value.timestamp}`;
111
114
  }
112
115
  });
@@ -114,7 +117,7 @@
114
117
  // Fetch button
115
118
  document.getElementById('fetchBtn').onclick = async () => {
116
119
  store.set('isLoading', true);
117
-
120
+
118
121
  try {
119
122
  const data = await fetchData();
120
123
  store.set('apiData', data);
@@ -1,5 +1,5 @@
1
1
  // store.js — singleton eventState store for counter app
2
- import { createEventState } from '../runtime/core/eventState.js';
2
+ import { createEventState } from '../runtime/core/eventStateNew.js';
3
3
 
4
4
  const initial = {
5
5
  count: 0