rask-ui 0.25.0 → 0.25.4
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/dist/component.d.ts +1 -0
- package/dist/component.d.ts.map +1 -1
- package/dist/component.js +5 -4
- package/dist/createContext.d.ts.map +1 -1
- package/dist/createContext.js +1 -4
- package/package.json +2 -2
- package/dist/asyncState.d.ts +0 -16
- package/dist/asyncState.d.ts.map +0 -1
- package/dist/asyncState.js +0 -24
- package/dist/compiler.d.ts +0 -2
- package/dist/compiler.d.ts.map +0 -1
- package/dist/compiler.js +0 -1
- package/dist/context.d.ts +0 -5
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -29
- package/dist/createAsync.d.ts +0 -39
- package/dist/createAsync.d.ts.map +0 -1
- package/dist/createAsync.js +0 -47
- package/dist/createAsync.test.d.ts +0 -2
- package/dist/createAsync.test.d.ts.map +0 -1
- package/dist/createAsync.test.js +0 -110
- package/dist/createMutation.d.ts +0 -43
- package/dist/createMutation.d.ts.map +0 -1
- package/dist/createMutation.js +0 -76
- package/dist/createMutation.test.d.ts +0 -2
- package/dist/createMutation.test.d.ts.map +0 -1
- package/dist/createMutation.test.js +0 -168
- package/dist/createQuery.d.ts +0 -42
- package/dist/createQuery.d.ts.map +0 -1
- package/dist/createQuery.js +0 -80
- package/dist/createQuery.test.d.ts +0 -2
- package/dist/createQuery.test.d.ts.map +0 -1
- package/dist/createQuery.test.js +0 -156
- package/dist/createRef.d.ts +0 -6
- package/dist/createRef.d.ts.map +0 -1
- package/dist/createRef.js +0 -8
- package/dist/createState.d.ts +0 -26
- package/dist/createState.d.ts.map +0 -1
- package/dist/createState.js +0 -94
- package/dist/createState.test.d.ts +0 -2
- package/dist/createState.test.d.ts.map +0 -1
- package/dist/createState.test.js +0 -111
- package/dist/createView.d.ts +0 -54
- package/dist/createView.d.ts.map +0 -1
- package/dist/createView.js +0 -68
- package/dist/createView.test.d.ts +0 -2
- package/dist/createView.test.d.ts.map +0 -1
- package/dist/createView.test.js +0 -203
- package/dist/error.d.ts +0 -16
- package/dist/error.d.ts.map +0 -1
- package/dist/error.js +0 -17
- package/dist/jsx.d.ts +0 -257
- package/dist/observation.test.d.ts +0 -2
- package/dist/observation.test.d.ts.map +0 -1
- package/dist/observation.test.js +0 -150
- package/dist/suspense.d.ts +0 -25
- package/dist/suspense.d.ts.map +0 -1
- package/dist/suspense.js +0 -97
- package/dist/test-setup.d.ts +0 -16
- package/dist/test-setup.d.ts.map +0 -1
- package/dist/test-setup.js +0 -40
- package/dist/test.d.ts +0 -2
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -24
package/dist/createState.test.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { createState } from './createState';
|
|
3
|
-
import { Observer } from './observation';
|
|
4
|
-
describe('createState', () => {
|
|
5
|
-
it('should create a reactive proxy from an object', () => {
|
|
6
|
-
const state = createState({ count: 0 });
|
|
7
|
-
expect(state.count).toBe(0);
|
|
8
|
-
});
|
|
9
|
-
it('should allow mutations', () => {
|
|
10
|
-
const state = createState({ count: 0 });
|
|
11
|
-
state.count = 5;
|
|
12
|
-
expect(state.count).toBe(5);
|
|
13
|
-
});
|
|
14
|
-
it('should return the same proxy for the same object', () => {
|
|
15
|
-
const obj = { count: 0 };
|
|
16
|
-
const proxy1 = createState(obj);
|
|
17
|
-
const proxy2 = createState(obj);
|
|
18
|
-
expect(proxy1).toBe(proxy2);
|
|
19
|
-
});
|
|
20
|
-
it('should create nested proxies for nested objects', () => {
|
|
21
|
-
const state = createState({ user: { name: 'Alice', age: 30 } });
|
|
22
|
-
state.user.name = 'Bob';
|
|
23
|
-
expect(state.user.name).toBe('Bob');
|
|
24
|
-
});
|
|
25
|
-
it('should handle arrays reactively', () => {
|
|
26
|
-
const state = createState({ items: [1, 2, 3] });
|
|
27
|
-
state.items.push(4);
|
|
28
|
-
expect(state.items).toEqual([1, 2, 3, 4]);
|
|
29
|
-
});
|
|
30
|
-
it('should track property access in observers', () => {
|
|
31
|
-
const state = createState({ count: 0 });
|
|
32
|
-
let renderCount = 0;
|
|
33
|
-
const observer = new Observer(() => {
|
|
34
|
-
renderCount++;
|
|
35
|
-
});
|
|
36
|
-
const dispose = observer.observe();
|
|
37
|
-
state.count; // Access property to track it
|
|
38
|
-
dispose();
|
|
39
|
-
expect(renderCount).toBe(0);
|
|
40
|
-
// Mutate after observation setup
|
|
41
|
-
const dispose2 = observer.observe();
|
|
42
|
-
const value = state.count; // Track
|
|
43
|
-
dispose2(); // Stop observing, subscriptions are now active
|
|
44
|
-
state.count = 1;
|
|
45
|
-
// Wait for microtask
|
|
46
|
-
return new Promise((resolve) => {
|
|
47
|
-
queueMicrotask(() => {
|
|
48
|
-
expect(renderCount).toBeGreaterThan(0);
|
|
49
|
-
resolve(undefined);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
it('should handle property deletion', () => {
|
|
54
|
-
const state = createState({ count: 0, temp: 'value' });
|
|
55
|
-
delete state.temp;
|
|
56
|
-
expect(state.temp).toBeUndefined();
|
|
57
|
-
expect('temp' in state).toBe(false);
|
|
58
|
-
});
|
|
59
|
-
it('should not create proxies for functions', () => {
|
|
60
|
-
const fn = () => 'hello';
|
|
61
|
-
const state = createState({ method: fn });
|
|
62
|
-
expect(state.method).toBe(fn);
|
|
63
|
-
expect(state.method()).toBe('hello');
|
|
64
|
-
});
|
|
65
|
-
it('should handle symbol properties', () => {
|
|
66
|
-
const sym = Symbol('test');
|
|
67
|
-
const state = createState({ [sym]: 'value' });
|
|
68
|
-
expect(state[sym]).toBe('value');
|
|
69
|
-
});
|
|
70
|
-
it('should notify observers only on actual changes', () => {
|
|
71
|
-
const state = createState({ count: 0 });
|
|
72
|
-
let notifyCount = 0;
|
|
73
|
-
const observer = new Observer(() => {
|
|
74
|
-
notifyCount++;
|
|
75
|
-
});
|
|
76
|
-
const dispose = observer.observe();
|
|
77
|
-
state.count; // Track
|
|
78
|
-
dispose();
|
|
79
|
-
state.count = 0; // Same value - should still notify per current implementation
|
|
80
|
-
state.count = 0;
|
|
81
|
-
return new Promise((resolve) => {
|
|
82
|
-
queueMicrotask(() => {
|
|
83
|
-
// The implementation notifies even for same value, except for optimization cases
|
|
84
|
-
observer.dispose();
|
|
85
|
-
resolve(undefined);
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
it('should handle deeply nested objects', () => {
|
|
90
|
-
const state = createState({
|
|
91
|
-
level1: {
|
|
92
|
-
level2: {
|
|
93
|
-
level3: {
|
|
94
|
-
value: 'deep',
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
state.level1.level2.level3.value = 'modified';
|
|
100
|
-
expect(state.level1.level2.level3.value).toBe('modified');
|
|
101
|
-
});
|
|
102
|
-
it('should handle array mutations correctly', () => {
|
|
103
|
-
const state = createState({ items: [1, 2, 3] });
|
|
104
|
-
state.items.pop();
|
|
105
|
-
expect(state.items).toEqual([1, 2]);
|
|
106
|
-
state.items.unshift(0);
|
|
107
|
-
expect(state.items).toEqual([0, 1, 2]);
|
|
108
|
-
state.items.splice(1, 1, 99);
|
|
109
|
-
expect(state.items).toEqual([0, 99, 2]);
|
|
110
|
-
});
|
|
111
|
-
});
|
package/dist/createView.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
type Simplify<T> = {
|
|
2
|
-
[K in keyof T]: T[K];
|
|
3
|
-
} & {};
|
|
4
|
-
type MergeTwo<A extends object, B extends object> = Simplify<Omit<A, keyof B> & B>;
|
|
5
|
-
type MergeMany<T extends readonly object[]> = T extends [
|
|
6
|
-
infer H extends object,
|
|
7
|
-
...infer R extends object[]
|
|
8
|
-
] ? MergeTwo<H, MergeMany<R>> : {};
|
|
9
|
-
/**
|
|
10
|
-
* Creates a view that merges multiple objects (reactive or not) into a single object while
|
|
11
|
-
* maintaining reactivity through getters. Properties from later arguments override earlier ones.
|
|
12
|
-
*
|
|
13
|
-
* @warning **Do not destructure the returned view object!** Destructuring breaks reactivity
|
|
14
|
-
* because it extracts plain values instead of maintaining getter access. This is the same rule
|
|
15
|
-
* as other reactive primitives.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* // ❌ Bad - destructuring loses reactivity
|
|
19
|
-
* function Component() {
|
|
20
|
-
* const state = createState({ count: 0 });
|
|
21
|
-
* const helpers = { increment: () => state.count++ };
|
|
22
|
-
* const view = createView(state, helpers);
|
|
23
|
-
* const { count, increment } = view; // Don't do this!
|
|
24
|
-
* return () => <button onClick={increment}>{count}</button>; // Won't update!
|
|
25
|
-
* }
|
|
26
|
-
*
|
|
27
|
-
* // ✅ Good - access properties directly in render
|
|
28
|
-
* function Component() {
|
|
29
|
-
* const state = createState({ count: 0 });
|
|
30
|
-
* const helpers = { increment: () => state.count++ };
|
|
31
|
-
* const view = createView(state, helpers);
|
|
32
|
-
* return () => <button onClick={view.increment}>{view.count}</button>; // Reactive!
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* // Merge multiple reactive objects
|
|
37
|
-
* const state = createState({ count: 0 });
|
|
38
|
-
* const user = createState({ name: "Alice" });
|
|
39
|
-
* const view = createView(state, user);
|
|
40
|
-
* // view has both count and name properties, maintaining reactivity
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* // Later arguments override earlier ones
|
|
44
|
-
* const a = { x: 1, y: 2 };
|
|
45
|
-
* const b = { y: 3, z: 4 };
|
|
46
|
-
* const view = createView(a, b);
|
|
47
|
-
* // view.x === 1, view.y === 3, view.z === 4
|
|
48
|
-
*
|
|
49
|
-
* @param args - Objects to merge (reactive or plain objects)
|
|
50
|
-
* @returns A view object with getters for all properties, maintaining reactivity
|
|
51
|
-
*/
|
|
52
|
-
export declare function createView<T extends readonly object[]>(...args: T): MergeMany<T>;
|
|
53
|
-
export {};
|
|
54
|
-
//# sourceMappingURL=createView.d.ts.map
|
package/dist/createView.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createView.d.ts","sourceRoot":"","sources":["../src/createView.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,EAAE,CAAC;AAEjD,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,QAAQ,CAC1D,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CACrB,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI,CAAC,SAAS;IACtD,MAAM,CAAC,SAAS,MAAM;IACtB,GAAG,MAAM,CAAC,SAAS,MAAM,EAAE;CAC5B,GACG,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GACzB,EAAE,CAAC;AAEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,EACpD,GAAG,IAAI,EAAE,CAAC,GACT,SAAS,CAAC,CAAC,CAAC,CA0Bd"}
|
package/dist/createView.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a view that merges multiple objects (reactive or not) into a single object while
|
|
3
|
-
* maintaining reactivity through getters. Properties from later arguments override earlier ones.
|
|
4
|
-
*
|
|
5
|
-
* @warning **Do not destructure the returned view object!** Destructuring breaks reactivity
|
|
6
|
-
* because it extracts plain values instead of maintaining getter access. This is the same rule
|
|
7
|
-
* as other reactive primitives.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* // ❌ Bad - destructuring loses reactivity
|
|
11
|
-
* function Component() {
|
|
12
|
-
* const state = createState({ count: 0 });
|
|
13
|
-
* const helpers = { increment: () => state.count++ };
|
|
14
|
-
* const view = createView(state, helpers);
|
|
15
|
-
* const { count, increment } = view; // Don't do this!
|
|
16
|
-
* return () => <button onClick={increment}>{count}</button>; // Won't update!
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* // ✅ Good - access properties directly in render
|
|
20
|
-
* function Component() {
|
|
21
|
-
* const state = createState({ count: 0 });
|
|
22
|
-
* const helpers = { increment: () => state.count++ };
|
|
23
|
-
* const view = createView(state, helpers);
|
|
24
|
-
* return () => <button onClick={view.increment}>{view.count}</button>; // Reactive!
|
|
25
|
-
* }
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* // Merge multiple reactive objects
|
|
29
|
-
* const state = createState({ count: 0 });
|
|
30
|
-
* const user = createState({ name: "Alice" });
|
|
31
|
-
* const view = createView(state, user);
|
|
32
|
-
* // view has both count and name properties, maintaining reactivity
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* // Later arguments override earlier ones
|
|
36
|
-
* const a = { x: 1, y: 2 };
|
|
37
|
-
* const b = { y: 3, z: 4 };
|
|
38
|
-
* const view = createView(a, b);
|
|
39
|
-
* // view.x === 1, view.y === 3, view.z === 4
|
|
40
|
-
*
|
|
41
|
-
* @param args - Objects to merge (reactive or plain objects)
|
|
42
|
-
* @returns A view object with getters for all properties, maintaining reactivity
|
|
43
|
-
*/
|
|
44
|
-
export function createView(...args) {
|
|
45
|
-
const result = {};
|
|
46
|
-
const seen = new Set();
|
|
47
|
-
for (let i = args.length - 1; i >= 0; i--) {
|
|
48
|
-
const src = args[i];
|
|
49
|
-
// mimic Object.assign: only enumerable own property keys
|
|
50
|
-
for (const key of Reflect.ownKeys(src)) {
|
|
51
|
-
if (seen.has(key))
|
|
52
|
-
continue;
|
|
53
|
-
const desc = Object.getOwnPropertyDescriptor(src, key);
|
|
54
|
-
if (!desc || !desc.enumerable)
|
|
55
|
-
continue;
|
|
56
|
-
// Capture the current source for this key (last write wins).
|
|
57
|
-
Object.defineProperty(result, key, {
|
|
58
|
-
enumerable: true,
|
|
59
|
-
configurable: true,
|
|
60
|
-
get: () => src[key],
|
|
61
|
-
// Optional write-through (commented out by default):
|
|
62
|
-
// set: (value) => { (src as any)[key as any] = value; },
|
|
63
|
-
});
|
|
64
|
-
seen.add(key);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createView.test.d.ts","sourceRoot":"","sources":["../src/createView.test.ts"],"names":[],"mappings":""}
|
package/dist/createView.test.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { createView } from './createView';
|
|
3
|
-
import { createState } from './createState';
|
|
4
|
-
import { Observer } from './observation';
|
|
5
|
-
describe('createView', () => {
|
|
6
|
-
it('should merge two plain objects', () => {
|
|
7
|
-
const a = { x: 1, y: 2 };
|
|
8
|
-
const b = { z: 3 };
|
|
9
|
-
const view = createView(a, b);
|
|
10
|
-
expect(view.x).toBe(1);
|
|
11
|
-
expect(view.y).toBe(2);
|
|
12
|
-
expect(view.z).toBe(3);
|
|
13
|
-
});
|
|
14
|
-
it('should allow later arguments to override earlier ones', () => {
|
|
15
|
-
const a = { x: 1, y: 2 };
|
|
16
|
-
const b = { y: 3, z: 4 };
|
|
17
|
-
const view = createView(a, b);
|
|
18
|
-
expect(view.x).toBe(1);
|
|
19
|
-
expect(view.y).toBe(3); // b.y overrides a.y
|
|
20
|
-
expect(view.z).toBe(4);
|
|
21
|
-
});
|
|
22
|
-
it('should maintain reactivity with reactive objects', async () => {
|
|
23
|
-
const state = createState({ count: 0 });
|
|
24
|
-
const view = createView(state);
|
|
25
|
-
let renderCount = 0;
|
|
26
|
-
let lastValue = 0;
|
|
27
|
-
const observer = new Observer(() => {
|
|
28
|
-
renderCount++;
|
|
29
|
-
});
|
|
30
|
-
const dispose = observer.observe();
|
|
31
|
-
lastValue = view.count; // Track the property
|
|
32
|
-
dispose();
|
|
33
|
-
expect(renderCount).toBe(0);
|
|
34
|
-
state.count = 5;
|
|
35
|
-
// Wait for microtask to process notification
|
|
36
|
-
await new Promise((resolve) => {
|
|
37
|
-
queueMicrotask(() => {
|
|
38
|
-
expect(renderCount).toBe(1);
|
|
39
|
-
lastValue = view.count;
|
|
40
|
-
expect(lastValue).toBe(5);
|
|
41
|
-
resolve(undefined);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
it('should merge reactive and plain objects while maintaining reactivity', () => {
|
|
46
|
-
const state = createState({ count: 0 });
|
|
47
|
-
const helpers = {
|
|
48
|
-
increment() {
|
|
49
|
-
state.count++;
|
|
50
|
-
},
|
|
51
|
-
decrement() {
|
|
52
|
-
state.count--;
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
const view = createView(state, helpers);
|
|
56
|
-
expect(view.count).toBe(0);
|
|
57
|
-
expect(typeof view.increment).toBe('function');
|
|
58
|
-
expect(typeof view.decrement).toBe('function');
|
|
59
|
-
view.increment();
|
|
60
|
-
expect(view.count).toBe(1);
|
|
61
|
-
view.decrement();
|
|
62
|
-
expect(view.count).toBe(0);
|
|
63
|
-
});
|
|
64
|
-
it('should merge multiple reactive objects', () => {
|
|
65
|
-
const state1 = createState({ count: 0 });
|
|
66
|
-
const state2 = createState({ name: 'Alice' });
|
|
67
|
-
const state3 = createState({ age: 25 });
|
|
68
|
-
const view = createView(state1, state2, state3);
|
|
69
|
-
expect(view.count).toBe(0);
|
|
70
|
-
expect(view.name).toBe('Alice');
|
|
71
|
-
expect(view.age).toBe(25);
|
|
72
|
-
state1.count = 10;
|
|
73
|
-
state2.name = 'Bob';
|
|
74
|
-
state3.age = 30;
|
|
75
|
-
expect(view.count).toBe(10);
|
|
76
|
-
expect(view.name).toBe('Bob');
|
|
77
|
-
expect(view.age).toBe(30);
|
|
78
|
-
});
|
|
79
|
-
it('should reflect changes in source objects', () => {
|
|
80
|
-
const source = { x: 1 };
|
|
81
|
-
const view = createView(source);
|
|
82
|
-
expect(view.x).toBe(1);
|
|
83
|
-
source.x = 2;
|
|
84
|
-
expect(view.x).toBe(2);
|
|
85
|
-
});
|
|
86
|
-
it('should handle property override order correctly', () => {
|
|
87
|
-
const a = { x: 1, y: 2, z: 3 };
|
|
88
|
-
const b = { y: 20 };
|
|
89
|
-
const c = { z: 30 };
|
|
90
|
-
const view = createView(a, b, c);
|
|
91
|
-
expect(view.x).toBe(1); // From a
|
|
92
|
-
expect(view.y).toBe(20); // From b (overrides a)
|
|
93
|
-
expect(view.z).toBe(30); // From c (overrides a)
|
|
94
|
-
});
|
|
95
|
-
it('should only include enumerable properties', () => {
|
|
96
|
-
const obj = { x: 1 };
|
|
97
|
-
Object.defineProperty(obj, 'hidden', {
|
|
98
|
-
value: 42,
|
|
99
|
-
enumerable: false,
|
|
100
|
-
});
|
|
101
|
-
const view = createView(obj);
|
|
102
|
-
expect(view.x).toBe(1);
|
|
103
|
-
expect(view.hidden).toBeUndefined();
|
|
104
|
-
});
|
|
105
|
-
it('should handle symbol keys', () => {
|
|
106
|
-
const sym = Symbol('test');
|
|
107
|
-
const obj = { x: 1, [sym]: 'symbol value' };
|
|
108
|
-
const view = createView(obj);
|
|
109
|
-
expect(view.x).toBe(1);
|
|
110
|
-
expect(view[sym]).toBe('symbol value');
|
|
111
|
-
});
|
|
112
|
-
it('should track dependencies for each property independently', async () => {
|
|
113
|
-
const state = createState({ count: 0, name: 'Alice' });
|
|
114
|
-
const view = createView(state);
|
|
115
|
-
let countRenderCount = 0;
|
|
116
|
-
let nameRenderCount = 0;
|
|
117
|
-
// Observer that only accesses count
|
|
118
|
-
const countObserver = new Observer(() => {
|
|
119
|
-
countRenderCount++;
|
|
120
|
-
});
|
|
121
|
-
const dispose1 = countObserver.observe();
|
|
122
|
-
view.count; // Track count
|
|
123
|
-
dispose1();
|
|
124
|
-
expect(countRenderCount).toBe(0);
|
|
125
|
-
// Change count - should trigger
|
|
126
|
-
state.count = 1;
|
|
127
|
-
await new Promise((resolve) => {
|
|
128
|
-
queueMicrotask(() => {
|
|
129
|
-
expect(countRenderCount).toBe(1);
|
|
130
|
-
resolve(undefined);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
// Change name - should NOT trigger (not tracked)
|
|
134
|
-
state.name = 'Bob';
|
|
135
|
-
await new Promise((resolve) => {
|
|
136
|
-
queueMicrotask(() => {
|
|
137
|
-
expect(countRenderCount).toBe(1); // Still 1
|
|
138
|
-
resolve(undefined);
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
// Now track name with a different observer
|
|
142
|
-
const nameObserver = new Observer(() => {
|
|
143
|
-
nameRenderCount++;
|
|
144
|
-
});
|
|
145
|
-
const dispose2 = nameObserver.observe();
|
|
146
|
-
view.name; // Track name
|
|
147
|
-
dispose2();
|
|
148
|
-
expect(nameRenderCount).toBe(0);
|
|
149
|
-
// Change name - should trigger name observer
|
|
150
|
-
state.name = 'Charlie';
|
|
151
|
-
await new Promise((resolve) => {
|
|
152
|
-
queueMicrotask(() => {
|
|
153
|
-
expect(nameRenderCount).toBe(1);
|
|
154
|
-
resolve(undefined);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
it('should return the same value type as source', () => {
|
|
159
|
-
const obj = { nums: [1, 2, 3], nested: { x: 1 } };
|
|
160
|
-
const view = createView(obj);
|
|
161
|
-
expect(Array.isArray(view.nums)).toBe(true);
|
|
162
|
-
expect(view.nums).toEqual([1, 2, 3]);
|
|
163
|
-
expect(typeof view.nested).toBe('object');
|
|
164
|
-
expect(view.nested.x).toBe(1);
|
|
165
|
-
});
|
|
166
|
-
it('should handle empty merge', () => {
|
|
167
|
-
const view = createView({});
|
|
168
|
-
expect(Object.keys(view).length).toBe(0);
|
|
169
|
-
});
|
|
170
|
-
it('should merge single object', () => {
|
|
171
|
-
const obj = { x: 1, y: 2 };
|
|
172
|
-
const view = createView(obj);
|
|
173
|
-
expect(view.x).toBe(1);
|
|
174
|
-
expect(view.y).toBe(2);
|
|
175
|
-
});
|
|
176
|
-
it('should maintain function context', () => {
|
|
177
|
-
const state = createState({ count: 0 });
|
|
178
|
-
const methods = {
|
|
179
|
-
increment() {
|
|
180
|
-
state.count++;
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
const view = createView(state, methods);
|
|
184
|
-
expect(view.count).toBe(0);
|
|
185
|
-
view.increment();
|
|
186
|
-
expect(view.count).toBe(1);
|
|
187
|
-
expect(state.count).toBe(1);
|
|
188
|
-
});
|
|
189
|
-
it('should work with reactive state and computed-like patterns', () => {
|
|
190
|
-
const state = createState({ firstName: 'John', lastName: 'Doe' });
|
|
191
|
-
const computed = {
|
|
192
|
-
get fullName() {
|
|
193
|
-
return `${state.firstName} ${state.lastName}`;
|
|
194
|
-
},
|
|
195
|
-
};
|
|
196
|
-
const view = createView(state, computed);
|
|
197
|
-
expect(view.firstName).toBe('John');
|
|
198
|
-
expect(view.lastName).toBe('Doe');
|
|
199
|
-
expect(view.fullName).toBe('John Doe');
|
|
200
|
-
state.firstName = 'Jane';
|
|
201
|
-
expect(view.fullName).toBe('Jane Doe');
|
|
202
|
-
});
|
|
203
|
-
});
|
package/dist/error.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Component, VNode } from "inferno";
|
|
2
|
-
export declare class ErrorBoundary extends Component<{
|
|
3
|
-
children: any;
|
|
4
|
-
error: (error: unknown) => VNode;
|
|
5
|
-
}, {
|
|
6
|
-
error: unknown;
|
|
7
|
-
}> {
|
|
8
|
-
getChildContext(): {
|
|
9
|
-
notifyError: (error: unknown) => void;
|
|
10
|
-
};
|
|
11
|
-
state: {
|
|
12
|
-
error: null;
|
|
13
|
-
};
|
|
14
|
-
render(): any;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=error.d.ts.map
|
package/dist/error.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAE3C,qBAAa,aAAc,SAAQ,SAAS,CAC1C;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,CAAA;CAAE,EACnD;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CACnB;IACC,eAAe;6BAEU,OAAO;;IAKhC,KAAK;;MAAmB;IAExB,MAAM;CAOP"}
|
package/dist/error.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Component } from "inferno";
|
|
2
|
-
export class ErrorBoundary extends Component {
|
|
3
|
-
getChildContext() {
|
|
4
|
-
return {
|
|
5
|
-
notifyError: (error) => {
|
|
6
|
-
this.setState({ error });
|
|
7
|
-
},
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
state = { error: null };
|
|
11
|
-
render() {
|
|
12
|
-
if (this.state.error) {
|
|
13
|
-
return this.props.error(this.state.error);
|
|
14
|
-
}
|
|
15
|
-
return this.props.children;
|
|
16
|
-
}
|
|
17
|
-
}
|