@uistate/examples 1.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.
Files changed (137) hide show
  1. package/README.md +40 -0
  2. package/cssState/.gitkeep +0 -0
  3. package/eventState/001-counter/README.md +44 -0
  4. package/eventState/001-counter/index.html +33 -0
  5. package/eventState/002-counter-improved/README.md +44 -0
  6. package/eventState/002-counter-improved/index.html +47 -0
  7. package/eventState/003-input-reactive/README.md +44 -0
  8. package/eventState/003-input-reactive/index.html +33 -0
  9. package/eventState/004-computed-state/README.md +45 -0
  10. package/eventState/004-computed-state/index.html +65 -0
  11. package/eventState/005-conditional-rendering/README.md +42 -0
  12. package/eventState/005-conditional-rendering/index.html +39 -0
  13. package/eventState/006-list-rendering/README.md +49 -0
  14. package/eventState/006-list-rendering/index.html +63 -0
  15. package/eventState/007-form-validation/README.md +52 -0
  16. package/eventState/007-form-validation/index.html +102 -0
  17. package/eventState/008-undo-redo/README.md +70 -0
  18. package/eventState/008-undo-redo/index.html +108 -0
  19. package/eventState/009-localStorage-side-effects/README.md +72 -0
  20. package/eventState/009-localStorage-side-effects/index.html +57 -0
  21. package/eventState/010-decoupled-components/README.md +74 -0
  22. package/eventState/010-decoupled-components/index.html +93 -0
  23. package/eventState/011-async-patterns/README.md +98 -0
  24. package/eventState/011-async-patterns/index.html +132 -0
  25. package/eventState/028-counter-improved-eventTest/LICENSE +55 -0
  26. package/eventState/028-counter-improved-eventTest/README.md +131 -0
  27. package/eventState/028-counter-improved-eventTest/app/store.js +9 -0
  28. package/eventState/028-counter-improved-eventTest/index.html +49 -0
  29. package/eventState/028-counter-improved-eventTest/runtime/core/behaviors.runtime.js +282 -0
  30. package/eventState/028-counter-improved-eventTest/runtime/core/eventState.js +100 -0
  31. package/eventState/028-counter-improved-eventTest/runtime/core/eventStateNew.js +149 -0
  32. package/eventState/028-counter-improved-eventTest/runtime/core/helpers.js +212 -0
  33. package/eventState/028-counter-improved-eventTest/runtime/core/router.js +271 -0
  34. package/eventState/028-counter-improved-eventTest/store.d.ts +8 -0
  35. package/eventState/028-counter-improved-eventTest/style.css +170 -0
  36. package/eventState/028-counter-improved-eventTest/tests/README.md +208 -0
  37. package/eventState/028-counter-improved-eventTest/tests/counter.test.js +116 -0
  38. package/eventState/028-counter-improved-eventTest/tests/eventTest.js +176 -0
  39. package/eventState/028-counter-improved-eventTest/tests/generateTypes.js +168 -0
  40. package/eventState/028-counter-improved-eventTest/tests/run.js +20 -0
  41. package/eventState/030-todo-app-with-eventTest/LICENSE +55 -0
  42. package/eventState/030-todo-app-with-eventTest/README.md +121 -0
  43. package/eventState/030-todo-app-with-eventTest/app/router.js +25 -0
  44. package/eventState/030-todo-app-with-eventTest/app/store.js +16 -0
  45. package/eventState/030-todo-app-with-eventTest/app/views/home.js +11 -0
  46. package/eventState/030-todo-app-with-eventTest/app/views/todoDemo.js +88 -0
  47. package/eventState/030-todo-app-with-eventTest/index.html +65 -0
  48. package/eventState/030-todo-app-with-eventTest/runtime/core/behaviors.runtime.js +282 -0
  49. package/eventState/030-todo-app-with-eventTest/runtime/core/eventState.js +100 -0
  50. package/eventState/030-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  51. package/eventState/030-todo-app-with-eventTest/runtime/core/helpers.js +212 -0
  52. package/eventState/030-todo-app-with-eventTest/runtime/core/router.js +271 -0
  53. package/eventState/030-todo-app-with-eventTest/store.d.ts +18 -0
  54. package/eventState/030-todo-app-with-eventTest/style.css +170 -0
  55. package/eventState/030-todo-app-with-eventTest/tests/README.md +208 -0
  56. package/eventState/030-todo-app-with-eventTest/tests/eventTest.js +176 -0
  57. package/eventState/030-todo-app-with-eventTest/tests/generateTypes.js +189 -0
  58. package/eventState/030-todo-app-with-eventTest/tests/run.js +20 -0
  59. package/eventState/030-todo-app-with-eventTest/tests/todos.test.js +167 -0
  60. package/eventState/031-todo-app-with-eventTest/LICENSE +55 -0
  61. package/eventState/031-todo-app-with-eventTest/README.md +54 -0
  62. package/eventState/031-todo-app-with-eventTest/TUTORIAL.md +390 -0
  63. package/eventState/031-todo-app-with-eventTest/WHY_EVENTSTATE.md +777 -0
  64. package/eventState/031-todo-app-with-eventTest/app/bridges.js +113 -0
  65. package/eventState/031-todo-app-with-eventTest/app/router.js +26 -0
  66. package/eventState/031-todo-app-with-eventTest/app/store.js +15 -0
  67. package/eventState/031-todo-app-with-eventTest/app/views/home.js +46 -0
  68. package/eventState/031-todo-app-with-eventTest/app/views/todoDemo.js +69 -0
  69. package/eventState/031-todo-app-with-eventTest/devtools/dock.js +41 -0
  70. package/eventState/031-todo-app-with-eventTest/devtools/stateTracker.dock.js +10 -0
  71. package/eventState/031-todo-app-with-eventTest/devtools/stateTracker.js +246 -0
  72. package/eventState/031-todo-app-with-eventTest/devtools/telemetry.js +104 -0
  73. package/eventState/031-todo-app-with-eventTest/devtools/typeGenerator.js +339 -0
  74. package/eventState/031-todo-app-with-eventTest/index.html +103 -0
  75. package/eventState/031-todo-app-with-eventTest/package-lock.json +2184 -0
  76. package/eventState/031-todo-app-with-eventTest/package.json +24 -0
  77. package/eventState/031-todo-app-with-eventTest/runtime/core/behaviors.runtime.js +282 -0
  78. package/eventState/031-todo-app-with-eventTest/runtime/core/eventState.js +100 -0
  79. package/eventState/031-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  80. package/eventState/031-todo-app-with-eventTest/runtime/core/helpers.js +212 -0
  81. package/eventState/031-todo-app-with-eventTest/runtime/core/router.js +271 -0
  82. package/eventState/031-todo-app-with-eventTest/runtime/extensions/boundary.js +36 -0
  83. package/eventState/031-todo-app-with-eventTest/runtime/extensions/converge.js +63 -0
  84. package/eventState/031-todo-app-with-eventTest/runtime/extensions/eventState.plus.js +210 -0
  85. package/eventState/031-todo-app-with-eventTest/runtime/extensions/hydrate.js +157 -0
  86. package/eventState/031-todo-app-with-eventTest/runtime/extensions/queryBinding.js +69 -0
  87. package/eventState/031-todo-app-with-eventTest/runtime/forms/computed.js +78 -0
  88. package/eventState/031-todo-app-with-eventTest/runtime/forms/meta.js +51 -0
  89. package/eventState/031-todo-app-with-eventTest/runtime/forms/submitWithBoundary.js +28 -0
  90. package/eventState/031-todo-app-with-eventTest/runtime/forms/validators.js +55 -0
  91. package/eventState/031-todo-app-with-eventTest/store.d.ts +23 -0
  92. package/eventState/031-todo-app-with-eventTest/style.css +170 -0
  93. package/eventState/031-todo-app-with-eventTest/tests/README.md +208 -0
  94. package/eventState/031-todo-app-with-eventTest/tests/eventTest.js +176 -0
  95. package/eventState/031-todo-app-with-eventTest/tests/generateTypes.js +191 -0
  96. package/eventState/031-todo-app-with-eventTest/tests/run.js +20 -0
  97. package/eventState/031-todo-app-with-eventTest/tests/todos.test.js +192 -0
  98. package/eventState/032-todo-app-with-eventTest/LICENSE +55 -0
  99. package/eventState/032-todo-app-with-eventTest/README.md +54 -0
  100. package/eventState/032-todo-app-with-eventTest/TUTORIAL.md +390 -0
  101. package/eventState/032-todo-app-with-eventTest/WHY_EVENTSTATE.md +777 -0
  102. package/eventState/032-todo-app-with-eventTest/app/actions/index.js +153 -0
  103. package/eventState/032-todo-app-with-eventTest/app/bridges.js +113 -0
  104. package/eventState/032-todo-app-with-eventTest/app/router.js +26 -0
  105. package/eventState/032-todo-app-with-eventTest/app/store.js +15 -0
  106. package/eventState/032-todo-app-with-eventTest/app/views/home.js +46 -0
  107. package/eventState/032-todo-app-with-eventTest/app/views/todoDemo.js +69 -0
  108. package/eventState/032-todo-app-with-eventTest/devtools/dock.js +41 -0
  109. package/eventState/032-todo-app-with-eventTest/devtools/stateTracker.dock.js +10 -0
  110. package/eventState/032-todo-app-with-eventTest/devtools/stateTracker.js +246 -0
  111. package/eventState/032-todo-app-with-eventTest/devtools/telemetry.js +104 -0
  112. package/eventState/032-todo-app-with-eventTest/devtools/typeGenerator.js +339 -0
  113. package/eventState/032-todo-app-with-eventTest/index.html +87 -0
  114. package/eventState/032-todo-app-with-eventTest/package-lock.json +2184 -0
  115. package/eventState/032-todo-app-with-eventTest/package.json +24 -0
  116. package/eventState/032-todo-app-with-eventTest/runtime/core/behaviors.runtime.js +282 -0
  117. package/eventState/032-todo-app-with-eventTest/runtime/core/eventState.js +100 -0
  118. package/eventState/032-todo-app-with-eventTest/runtime/core/eventStateNew.js +149 -0
  119. package/eventState/032-todo-app-with-eventTest/runtime/core/helpers.js +212 -0
  120. package/eventState/032-todo-app-with-eventTest/runtime/core/router.js +271 -0
  121. package/eventState/032-todo-app-with-eventTest/runtime/extensions/boundary.js +36 -0
  122. package/eventState/032-todo-app-with-eventTest/runtime/extensions/converge.js +63 -0
  123. package/eventState/032-todo-app-with-eventTest/runtime/extensions/eventState.plus.js +210 -0
  124. package/eventState/032-todo-app-with-eventTest/runtime/extensions/hydrate.js +157 -0
  125. package/eventState/032-todo-app-with-eventTest/runtime/extensions/queryBinding.js +69 -0
  126. package/eventState/032-todo-app-with-eventTest/runtime/forms/computed.js +78 -0
  127. package/eventState/032-todo-app-with-eventTest/runtime/forms/meta.js +51 -0
  128. package/eventState/032-todo-app-with-eventTest/runtime/forms/submitWithBoundary.js +28 -0
  129. package/eventState/032-todo-app-with-eventTest/runtime/forms/validators.js +55 -0
  130. package/eventState/032-todo-app-with-eventTest/store.d.ts +23 -0
  131. package/eventState/032-todo-app-with-eventTest/style.css +170 -0
  132. package/eventState/032-todo-app-with-eventTest/tests/README.md +208 -0
  133. package/eventState/032-todo-app-with-eventTest/tests/eventTest.js +176 -0
  134. package/eventState/032-todo-app-with-eventTest/tests/generateTypes.js +191 -0
  135. package/eventState/032-todo-app-with-eventTest/tests/run.js +20 -0
  136. package/eventState/032-todo-app-with-eventTest/tests/todos.test.js +192 -0
  137. package/package.json +27 -0
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * generateTypes.js - Generate TypeScript definitions from test assertions
4
+ *
5
+ * Usage: node tests/generateTypes.js
6
+ */
7
+
8
+ import { createEventTest } from './eventTest.js';
9
+ import todosTests from './todos.test.js';
10
+ import { writeFileSync } from 'fs';
11
+ import { fileURLToPath } from 'url';
12
+ import { dirname, join } from 'path';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = dirname(__filename);
16
+
17
+ // Collect all type assertions from tests
18
+ const allAssertions = [];
19
+
20
+ console.log('🔍 Extracting types from tests...\n');
21
+
22
+ for (const [name, testFn] of Object.entries(todosTests)) {
23
+ try {
24
+ // Run test to collect assertions
25
+ testFn();
26
+ console.log(`✓ ${name}`);
27
+ } catch (error) {
28
+ // Test might fail, but we still want type assertions
29
+ console.log(`⚠ ${name} (failed but types extracted)`);
30
+ }
31
+ }
32
+
33
+ // Simple type generator (minimal version for Node.js)
34
+ class SimpleTypeGenerator {
35
+ constructor() {
36
+ this.pathTypes = new Map();
37
+ }
38
+
39
+ parseAssertions(assertions) {
40
+ for (const assertion of assertions) {
41
+ const { path, type, elementShape, shape } = assertion;
42
+
43
+ if (type === 'array' && elementShape) {
44
+ this.pathTypes.set(path, {
45
+ type: 'array',
46
+ element: elementShape
47
+ });
48
+ } else if (type === 'object' && shape) {
49
+ this.pathTypes.set(path, {
50
+ type: 'object',
51
+ shape: shape
52
+ });
53
+ } else if (type) {
54
+ this.pathTypes.set(path, { type });
55
+ }
56
+ }
57
+ }
58
+
59
+ buildTree() {
60
+ const tree = {};
61
+
62
+ for (const [path, typeInfo] of this.pathTypes) {
63
+ const parts = path.split('.');
64
+ let current = tree;
65
+
66
+ for (let i = 0; i < parts.length; i++) {
67
+ const part = parts[i];
68
+
69
+ if (i === parts.length - 1) {
70
+ current[part] = { __typeInfo: typeInfo };
71
+ } else {
72
+ if (!current[part]) {
73
+ current[part] = {};
74
+ }
75
+ current = current[part];
76
+ }
77
+ }
78
+ }
79
+
80
+ return tree;
81
+ }
82
+
83
+ formatType(typeInfo) {
84
+ if (typeof typeInfo === 'string') return typeInfo;
85
+
86
+ if (typeInfo.type === 'array' && typeInfo.element) {
87
+ const elementType = this.formatShape(typeInfo.element);
88
+ return `Array<${elementType}>`;
89
+ }
90
+
91
+ if (typeInfo.type === 'object' && typeInfo.shape) {
92
+ return this.formatShape(typeInfo.shape);
93
+ }
94
+
95
+ return typeInfo.type || 'unknown';
96
+ }
97
+
98
+ formatShape(shape) {
99
+ if (typeof shape === 'string') return shape;
100
+
101
+ const props = Object.entries(shape)
102
+ .map(([k, v]) => {
103
+ const type = typeof v === 'string' ? v : this.formatShape(v);
104
+ return `${k}: ${type}`;
105
+ })
106
+ .join('; ');
107
+
108
+ return `{ ${props} }`;
109
+ }
110
+
111
+ generateInterface(obj, indent = 0) {
112
+ const lines = [];
113
+ const spaces = ' '.repeat(indent);
114
+
115
+ for (const [key, value] of Object.entries(obj)) {
116
+ if (value.__typeInfo) {
117
+ const type = this.formatType(value.__typeInfo);
118
+ lines.push(`${spaces}${key}: ${type};`);
119
+ } else {
120
+ lines.push(`${spaces}${key}: {`);
121
+ lines.push(this.generateInterface(value, indent + 1));
122
+ lines.push(`${spaces}};`);
123
+ }
124
+ }
125
+
126
+ return lines.join('\n');
127
+ }
128
+
129
+ generateDTS() {
130
+ const lines = [
131
+ '// Auto-generated from test assertions',
132
+ '// DO NOT EDIT - regenerate by running: node tests/generateTypes.js',
133
+ '',
134
+ 'export interface StoreState {',
135
+ ];
136
+
137
+ const tree = this.buildTree();
138
+ lines.push(this.generateInterface(tree, 1));
139
+ lines.push('}');
140
+ lines.push('');
141
+ lines.push('export default StoreState;');
142
+ lines.push('');
143
+
144
+ return lines.join('\n');
145
+ }
146
+ }
147
+
148
+ // Note: We need to actually collect assertions from test execution
149
+ // For now, manually define expected types based on test assertions
150
+ const manualAssertions = [
151
+ {
152
+ path: 'domain.todos.items',
153
+ type: 'array',
154
+ elementShape: {
155
+ id: 'number',
156
+ text: 'string',
157
+ done: 'boolean'
158
+ }
159
+ },
160
+ {
161
+ path: 'ui.todos.filter',
162
+ type: 'string'
163
+ },
164
+ {
165
+ path: 'intent.todo.add',
166
+ type: 'object',
167
+ shape: {
168
+ text: 'string'
169
+ }
170
+ },
171
+ {
172
+ path: 'intent.todo.toggle',
173
+ type: 'object',
174
+ shape: {
175
+ id: 'number'
176
+ }
177
+ }
178
+ ];
179
+
180
+ const generator = new SimpleTypeGenerator();
181
+ generator.parseAssertions(manualAssertions);
182
+
183
+ const dts = generator.generateDTS();
184
+
185
+ // Write to file
186
+ const outputPath = join(__dirname, '..', 'store.d.ts');
187
+ writeFileSync(outputPath, dts, 'utf-8');
188
+
189
+ console.log(`\n✅ Generated ${outputPath}`);
190
+ console.log('\n📝 Type definitions:\n');
191
+ console.log(dts);
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * run.js - Test runner for Node.js
4
+ *
5
+ * Usage: node tests/run.js
6
+ */
7
+
8
+ import { runTests } from './eventTest.js';
9
+ import todosTests from './todos.test.js';
10
+
11
+ // Combine all test suites
12
+ const allTests = {
13
+ ...todosTests
14
+ };
15
+
16
+ // Run tests
17
+ const results = runTests(allTests);
18
+
19
+ // Exit with appropriate code
20
+ process.exit(results.failed > 0 ? 1 : 0);
@@ -0,0 +1,192 @@
1
+ /**
2
+ * todos.test.js - Event-sequence tests for todo functionality
3
+ *
4
+ * These tests define the behavior AND types of the todo domain
5
+ */
6
+
7
+ import { createEventTest, test, runTests } from './eventTest.js';
8
+
9
+ // Helper to set up todo bridges on a test store
10
+ function setupTodoBridges(store) {
11
+ let nextId = 1;
12
+
13
+ // Add todo
14
+ store.subscribe('intent.todo.add', (detail) => {
15
+ const { text } = detail;
16
+ const items = store.get('domain.todos.items') || [];
17
+ const todo = { id: nextId++, text: String(text || '').trim(), done: false };
18
+ if (!todo.text) return;
19
+ store.set('domain.todos.items', [...items, todo]);
20
+ });
21
+
22
+ // Toggle todo
23
+ store.subscribe('intent.todo.toggle', (detail) => {
24
+ const { id } = detail;
25
+ const items = store.get('domain.todos.items') || [];
26
+ const out = items.map(t => (String(t?.id) === String(id)) ? { ...t, done: !t.done } : t);
27
+ store.set('domain.todos.items', out);
28
+ });
29
+
30
+ // Clear completed
31
+ store.subscribe('intent.todo.clearCompleted', () => {
32
+ const items = store.get('domain.todos.items') || [];
33
+ store.set('domain.todos.items', items.filter(t => !t.done));
34
+ });
35
+
36
+ // UI filter
37
+ store.subscribe('intent.ui.filter', (detail) => {
38
+ const { filter } = detail;
39
+ const f = (filter === 'active' || filter === 'completed') ? filter : 'all';
40
+ store.set('ui.todos.filter', f);
41
+ });
42
+ }
43
+
44
+ // Test suite
45
+ const tests = {
46
+ 'add todo creates correct structure': () => {
47
+ const t = createEventTest({
48
+ domain: { todos: { items: [] } }
49
+ });
50
+
51
+ // Set up bridges for this test
52
+ setupTodoBridges(t.store);
53
+
54
+ // Trigger intent
55
+ t.trigger('intent.todo.add', { text: 'Buy milk' });
56
+
57
+ // Assert array structure and element types
58
+ t.assertArrayOf('domain.todos.items', {
59
+ id: 'number',
60
+ text: 'string',
61
+ done: 'boolean'
62
+ });
63
+
64
+ // Assert array length
65
+ t.assertArrayLength('domain.todos.items', 1);
66
+
67
+ // Assert specific values
68
+ const items = t.store.get('domain.todos.items');
69
+ if (items[0].text !== 'Buy milk') {
70
+ throw new Error('Expected first todo text to be "Buy milk"');
71
+ }
72
+ if (items[0].done !== false) {
73
+ throw new Error('Expected first todo to not be done');
74
+ }
75
+ },
76
+
77
+ 'toggle todo changes done state': () => {
78
+ const t = createEventTest({
79
+ domain: { todos: { items: [{ id: 1, text: 'Buy milk', done: false }] } }
80
+ });
81
+
82
+ // Set up bridges for this test
83
+ setupTodoBridges(t.store);
84
+
85
+ // Trigger toggle
86
+ t.trigger('intent.todo.toggle', { id: 1 });
87
+
88
+ // Assert structure
89
+ t.assertArrayOf('domain.todos.items', {
90
+ id: 'number',
91
+ text: 'string',
92
+ done: 'boolean'
93
+ });
94
+
95
+ // Assert done is now true
96
+ const items = t.store.get('domain.todos.items');
97
+ if (items[0].done !== true) {
98
+ throw new Error('Expected todo to be done');
99
+ }
100
+ },
101
+
102
+ 'clear completed removes done todos': () => {
103
+ const t = createEventTest({
104
+ domain: {
105
+ todos: {
106
+ items: [
107
+ { id: 1, text: 'Buy milk', done: true },
108
+ { id: 2, text: 'Walk dog', done: false }
109
+ ]
110
+ }
111
+ }
112
+ });
113
+
114
+ // Set up bridges for this test
115
+ setupTodoBridges(t.store);
116
+
117
+ // Trigger clear
118
+ t.trigger('intent.todo.clearCompleted');
119
+
120
+ // Assert only active todo remains
121
+ t.assertArrayLength('domain.todos.items', 1);
122
+
123
+ const items = t.store.get('domain.todos.items');
124
+ if (items[0].text !== 'Walk dog') {
125
+ throw new Error('Expected only "Walk dog" to remain');
126
+ }
127
+ },
128
+
129
+ 'filter intent updates filter state': () => {
130
+ const t = createEventTest({
131
+ ui: { todos: { filter: 'all' } }
132
+ });
133
+
134
+ // Set up bridges for this test
135
+ setupTodoBridges(t.store);
136
+
137
+ // Trigger filter change
138
+ t.trigger('intent.ui.filter', { filter: 'active' });
139
+
140
+ // Assert type
141
+ t.assertType('ui.todos.filter', 'string');
142
+
143
+ // Assert value
144
+ t.assertPath('ui.todos.filter', 'active');
145
+ },
146
+
147
+ 'intent.todo.add has correct shape': () => {
148
+ const t = createEventTest({});
149
+
150
+ // Trigger intent
151
+ t.trigger('intent.todo.add', { text: 'Buy milk' });
152
+
153
+ // Assert intent shape (for type generation)
154
+ t.assertShape('intent.todo.add', {
155
+ text: 'string'
156
+ });
157
+ },
158
+
159
+ 'intent.todo.toggle has correct shape': () => {
160
+ const t = createEventTest({});
161
+
162
+ // Trigger intent
163
+ t.trigger('intent.todo.toggle', { id: 1 });
164
+
165
+ // Assert intent shape
166
+ t.assertShape('intent.todo.toggle', {
167
+ id: 'number'
168
+ });
169
+ },
170
+
171
+ 'empty todos array is valid': () => {
172
+ const t = createEventTest({
173
+ domain: { todos: { items: [] } }
174
+ });
175
+
176
+ // Assert empty array is still typed correctly
177
+ t.assertArrayOf('domain.todos.items', {
178
+ id: 'number',
179
+ text: 'string',
180
+ done: 'boolean'
181
+ });
182
+
183
+ t.assertArrayLength('domain.todos.items', 0);
184
+ }
185
+ };
186
+
187
+ // Run tests if executed directly
188
+ if (import.meta.url === `file://${process.argv[1]}`) {
189
+ runTests(tests);
190
+ }
191
+
192
+ export default tests;
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@uistate/examples",
3
+ "version": "1.0.0",
4
+ "description": "Example applications and patterns for @uistate/core — eventState and cssState",
5
+ "type": "module",
6
+ "files": [
7
+ "eventState/",
8
+ "cssState/"
9
+ ],
10
+ "keywords": [
11
+ "uistate",
12
+ "examples",
13
+ "state-management",
14
+ "event-driven",
15
+ "css-state",
16
+ "tutorials"
17
+ ],
18
+ "author": "Ajdin Imsirovic",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/ImsirovicAjdin/uistate-examples"
23
+ },
24
+ "peerDependencies": {
25
+ "@uistate/core": ">=5.0.0"
26
+ }
27
+ }