@uistate/core 5.4.0 → 5.5.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/package.json +5 -7
- package/LICENSE-eventTest.md +0 -26
- package/eventTest.js +0 -196
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uistate/core",
|
|
3
|
-
"version": "5.
|
|
4
|
-
"description": "Lightweight event-driven state management with
|
|
3
|
+
"version": "5.5.0",
|
|
4
|
+
"description": "Lightweight event-driven state management with path-based subscriptions, wildcards, and async support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"exports": {
|
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
"eventState.js",
|
|
16
16
|
"eventStateNew.js",
|
|
17
17
|
"queryClient.js",
|
|
18
|
-
"
|
|
19
|
-
"LICENSE",
|
|
20
|
-
"LICENSE-eventTest.md"
|
|
18
|
+
"LICENSE"
|
|
21
19
|
],
|
|
22
20
|
"keywords": [
|
|
23
21
|
"state-management",
|
|
@@ -28,8 +26,8 @@
|
|
|
28
26
|
"zero-dependency",
|
|
29
27
|
"framework-free",
|
|
30
28
|
"micro-framework",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
29
|
+
"async-state",
|
|
30
|
+
"query-client"
|
|
33
31
|
],
|
|
34
32
|
"author": "Ajdin Imsirovic",
|
|
35
33
|
"license": "MIT",
|
package/LICENSE-eventTest.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Proprietary License for eventTest.js
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Ajdin Imsirovic
|
|
4
|
-
|
|
5
|
-
## Permitted Uses
|
|
6
|
-
|
|
7
|
-
You may use `eventTest.js` for:
|
|
8
|
-
- Personal projects
|
|
9
|
-
- Open-source projects
|
|
10
|
-
- Educational purposes
|
|
11
|
-
|
|
12
|
-
## Restrictions
|
|
13
|
-
|
|
14
|
-
You may NOT:
|
|
15
|
-
- Use this file in commercial products without a license
|
|
16
|
-
- Modify or create derivative works
|
|
17
|
-
- Redistribute this file separately from @uistate/core
|
|
18
|
-
- Remove or alter this license notice
|
|
19
|
-
|
|
20
|
-
## Commercial Licensing
|
|
21
|
-
|
|
22
|
-
For commercial use, please contact: your@email.com
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.
|
package/eventTest.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* eventTest.js - Event-Sequence Testing for UIstate
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2025 Ajdin Imsirovic
|
|
5
|
-
*
|
|
6
|
-
* This file is licensed under a PROPRIETARY LICENSE.
|
|
7
|
-
*
|
|
8
|
-
* Permission is hereby granted to USE this software for:
|
|
9
|
-
* - Personal projects
|
|
10
|
-
* - Open-source projects
|
|
11
|
-
* - Educational purposes
|
|
12
|
-
*
|
|
13
|
-
* RESTRICTIONS:
|
|
14
|
-
* - Commercial use requires a separate license (contact: your@email.com)
|
|
15
|
-
* - Modification and redistribution of this file are NOT permitted
|
|
16
|
-
* - This file may not be included in derivative works without permission
|
|
17
|
-
*
|
|
18
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
|
19
|
-
*
|
|
20
|
-
* For commercial licensing inquiries: your@email.com
|
|
21
|
-
*
|
|
22
|
-
* eventTest.js - Event-Sequence Testing for EventState
|
|
23
|
-
*
|
|
24
|
-
* Provides TDD-style testing with type extraction capabilities
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import { createEventState } from './eventStateNew.js';
|
|
28
|
-
|
|
29
|
-
export function createEventTest(initialState = {}) {
|
|
30
|
-
const store = createEventState(initialState);
|
|
31
|
-
const eventLog = [];
|
|
32
|
-
const typeAssertions = [];
|
|
33
|
-
|
|
34
|
-
// Spy on all events
|
|
35
|
-
store.subscribe('*', (detail) => {
|
|
36
|
-
const { path, value } = detail;
|
|
37
|
-
eventLog.push({ timestamp: Date.now(), path, value });
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const api = {
|
|
41
|
-
store,
|
|
42
|
-
|
|
43
|
-
// Trigger a state change
|
|
44
|
-
trigger(path, value) {
|
|
45
|
-
store.set(path, value);
|
|
46
|
-
return this;
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
// Assert exact value
|
|
50
|
-
assertPath(path, expected) {
|
|
51
|
-
const actual = store.get(path);
|
|
52
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
53
|
-
throw new Error(`Expected ${path} to be ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
|
|
54
|
-
}
|
|
55
|
-
return this;
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
// Assert type (for type generation)
|
|
59
|
-
assertType(path, expectedType) {
|
|
60
|
-
const actual = store.get(path);
|
|
61
|
-
const actualType = typeof actual;
|
|
62
|
-
|
|
63
|
-
if (actualType !== expectedType) {
|
|
64
|
-
throw new Error(`Expected ${path} to be type ${expectedType}, got ${actualType}`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Store for type generation
|
|
68
|
-
typeAssertions.push({ path, type: expectedType });
|
|
69
|
-
return this;
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
// Assert array with element shape (for type generation)
|
|
73
|
-
assertArrayOf(path, elementShape) {
|
|
74
|
-
const actual = store.get(path);
|
|
75
|
-
|
|
76
|
-
if (!Array.isArray(actual)) {
|
|
77
|
-
throw new Error(`Expected ${path} to be an array, got ${typeof actual}`);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Validate first element matches shape (if array not empty)
|
|
81
|
-
if (actual.length > 0) {
|
|
82
|
-
validateShape(actual[0], elementShape, path);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Store for type generation
|
|
86
|
-
typeAssertions.push({ path, type: 'array', elementShape });
|
|
87
|
-
return this;
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
// Assert object shape (for type generation)
|
|
91
|
-
assertShape(path, objectShape) {
|
|
92
|
-
const actual = store.get(path);
|
|
93
|
-
|
|
94
|
-
if (typeof actual !== 'object' || actual === null || Array.isArray(actual)) {
|
|
95
|
-
throw new Error(`Expected ${path} to be an object, got ${typeof actual}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
validateShape(actual, objectShape, path);
|
|
99
|
-
|
|
100
|
-
// Store for type generation
|
|
101
|
-
typeAssertions.push({ path, type: 'object', shape: objectShape });
|
|
102
|
-
return this;
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
// Assert array length
|
|
106
|
-
assertArrayLength(path, expectedLength) {
|
|
107
|
-
const actual = store.get(path);
|
|
108
|
-
|
|
109
|
-
if (!Array.isArray(actual)) {
|
|
110
|
-
throw new Error(`Expected ${path} to be an array`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (actual.length !== expectedLength) {
|
|
114
|
-
throw new Error(`Expected ${path} to have length ${expectedLength}, got ${actual.length}`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return this;
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
// Assert event fired N times
|
|
121
|
-
assertEventFired(path, times) {
|
|
122
|
-
const count = eventLog.filter(e => e.path === path).length;
|
|
123
|
-
if (times !== undefined && count !== times) {
|
|
124
|
-
throw new Error(`Expected ${path} to fire ${times} times, fired ${count}`);
|
|
125
|
-
}
|
|
126
|
-
return this;
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
// Get event log
|
|
130
|
-
getEventLog() {
|
|
131
|
-
return [...eventLog];
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
// Get type assertions (for type generation)
|
|
135
|
-
getTypeAssertions() {
|
|
136
|
-
return [...typeAssertions];
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
return api;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Helper to validate object shape
|
|
144
|
-
function validateShape(actual, shape, path) {
|
|
145
|
-
for (const [key, expectedType] of Object.entries(shape)) {
|
|
146
|
-
if (!(key in actual)) {
|
|
147
|
-
throw new Error(`Expected ${path} to have property ${key}`);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const actualValue = actual[key];
|
|
151
|
-
|
|
152
|
-
// Handle nested objects
|
|
153
|
-
if (typeof expectedType === 'object' && !Array.isArray(expectedType)) {
|
|
154
|
-
validateShape(actualValue, expectedType, `${path}.${key}`);
|
|
155
|
-
} else {
|
|
156
|
-
// Primitive type check
|
|
157
|
-
const actualType = typeof actualValue;
|
|
158
|
-
if (actualType !== expectedType) {
|
|
159
|
-
throw new Error(`Expected ${path}.${key} to be type ${expectedType}, got ${actualType}`);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Simple test runner
|
|
166
|
-
export function test(name, fn) {
|
|
167
|
-
try {
|
|
168
|
-
fn();
|
|
169
|
-
console.log(`✓ ${name}`);
|
|
170
|
-
return true;
|
|
171
|
-
} catch (error) {
|
|
172
|
-
console.error(`✗ ${name}`);
|
|
173
|
-
console.error(` ${error.message}`);
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Run multiple tests
|
|
179
|
-
export function runTests(tests) {
|
|
180
|
-
console.log('\n🧪 Running tests...\n');
|
|
181
|
-
|
|
182
|
-
let passed = 0;
|
|
183
|
-
let failed = 0;
|
|
184
|
-
|
|
185
|
-
for (const [name, fn] of Object.entries(tests)) {
|
|
186
|
-
if (test(name, fn)) {
|
|
187
|
-
passed++;
|
|
188
|
-
} else {
|
|
189
|
-
failed++;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
console.log(`\n📊 Results: ${passed} passed, ${failed} failed\n`);
|
|
194
|
-
|
|
195
|
-
return { passed, failed };
|
|
196
|
-
}
|