rask-ui 0.10.4 → 0.10.5
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/createView.d.ts +21 -43
- package/dist/createView.d.ts.map +1 -1
- package/dist/createView.js +7 -45
- package/package.json +1 -1
package/dist/createView.d.ts
CHANGED
|
@@ -1,54 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Utility type that preserves unions while "flattening" object types.
|
|
3
|
+
*/
|
|
4
|
+
type Simplify<T> = T extends any ? {
|
|
2
5
|
[K in keyof T]: T[K];
|
|
3
|
-
}
|
|
4
|
-
|
|
6
|
+
} : never;
|
|
7
|
+
/**
|
|
8
|
+
* Merge two object types where properties from B override properties from A.
|
|
9
|
+
* Distributes over unions in A.
|
|
10
|
+
*/
|
|
11
|
+
type MergeTwo<A extends object, B extends object> = A extends any ? Simplify<Omit<A, keyof B> & B> : never;
|
|
12
|
+
/**
|
|
13
|
+
* Merge a readonly tuple of objects left-to-right, with later entries
|
|
14
|
+
* overriding earlier ones. Distributes over unions in the head element.
|
|
15
|
+
*/
|
|
5
16
|
type MergeMany<T extends readonly object[]> = T extends [
|
|
6
17
|
infer H extends object,
|
|
7
18
|
...infer R extends object[]
|
|
8
19
|
] ? MergeTwo<H, MergeMany<R>> : {};
|
|
9
20
|
/**
|
|
10
|
-
* Creates a view that merges multiple objects (reactive or not) into a single
|
|
11
|
-
* maintaining reactivity through getters. Properties from later
|
|
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
|
|
21
|
+
* Creates a view that merges multiple objects (reactive or not) into a single
|
|
22
|
+
* object while maintaining reactivity through getters. Properties from later
|
|
23
|
+
* arguments override earlier ones.
|
|
48
24
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
25
|
+
* ⚠️ Do not destructure the returned view object; always read properties
|
|
26
|
+
* directly from the view to preserve reactivity.
|
|
51
27
|
*/
|
|
28
|
+
export declare function createView<A extends object>(a: A): A;
|
|
29
|
+
export declare function createView<A extends object, B extends object>(a: A, b: B): MergeTwo<A, B>;
|
|
52
30
|
export declare function createView<T extends readonly object[]>(...args: T): MergeMany<T>;
|
|
53
31
|
export {};
|
|
54
32
|
//# sourceMappingURL=createView.d.ts.map
|
package/dist/createView.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createView.d.ts","sourceRoot":"","sources":["../src/createView.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createView.d.ts","sourceRoot":"","sources":["../src/createView.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,KAAK,CAAC;AAEpE;;;GAGG;AACH,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,GAC7D,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAC9B,KAAK,CAAC;AAEV;;;GAGG;AACH,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;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;AACtD,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EAC3D,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,GACH,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,EACpD,GAAG,IAAI,EAAE,CAAC,GACT,SAAS,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/createView.js
CHANGED
|
@@ -1,64 +1,22 @@
|
|
|
1
1
|
import { INSPECT_MARKER, INSPECTOR_ENABLED } from "./inspect";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a view that merges multiple objects (reactive or not) into a single object while
|
|
4
|
-
* maintaining reactivity through getters. Properties from later arguments override earlier ones.
|
|
5
|
-
*
|
|
6
|
-
* @warning **Do not destructure the returned view object!** Destructuring breaks reactivity
|
|
7
|
-
* because it extracts plain values instead of maintaining getter access. This is the same rule
|
|
8
|
-
* as other reactive primitives.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* // ❌ Bad - destructuring loses reactivity
|
|
12
|
-
* function Component() {
|
|
13
|
-
* const state = createState({ count: 0 });
|
|
14
|
-
* const helpers = { increment: () => state.count++ };
|
|
15
|
-
* const view = createView(state, helpers);
|
|
16
|
-
* const { count, increment } = view; // Don't do this!
|
|
17
|
-
* return () => <button onClick={increment}>{count}</button>; // Won't update!
|
|
18
|
-
* }
|
|
19
|
-
*
|
|
20
|
-
* // ✅ Good - access properties directly in render
|
|
21
|
-
* function Component() {
|
|
22
|
-
* const state = createState({ count: 0 });
|
|
23
|
-
* const helpers = { increment: () => state.count++ };
|
|
24
|
-
* const view = createView(state, helpers);
|
|
25
|
-
* return () => <button onClick={view.increment}>{view.count}</button>; // Reactive!
|
|
26
|
-
* }
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* // Merge multiple reactive objects
|
|
30
|
-
* const state = createState({ count: 0 });
|
|
31
|
-
* const user = createState({ name: "Alice" });
|
|
32
|
-
* const view = createView(state, user);
|
|
33
|
-
* // view has both count and name properties, maintaining reactivity
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* // Later arguments override earlier ones
|
|
37
|
-
* const a = { x: 1, y: 2 };
|
|
38
|
-
* const b = { y: 3, z: 4 };
|
|
39
|
-
* const view = createView(a, b);
|
|
40
|
-
* // view.x === 1, view.y === 3, view.z === 4
|
|
41
|
-
*
|
|
42
|
-
* @param args - Objects to merge (reactive or plain objects)
|
|
43
|
-
* @returns A view object with getters for all properties, maintaining reactivity
|
|
44
|
-
*/
|
|
45
2
|
export function createView(...args) {
|
|
46
3
|
const result = {};
|
|
47
4
|
const seen = new Set();
|
|
48
5
|
let notifyInspectorRef = {};
|
|
49
6
|
for (let i = args.length - 1; i >= 0; i--) {
|
|
50
7
|
const src = args[i];
|
|
8
|
+
if (!src)
|
|
9
|
+
continue;
|
|
51
10
|
if (INSPECTOR_ENABLED && src[INSPECT_MARKER]) {
|
|
52
11
|
src[INSPECT_MARKER] = notifyInspectorRef;
|
|
53
12
|
}
|
|
54
|
-
//
|
|
13
|
+
// Mimic Object.assign: only enumerable own property keys
|
|
55
14
|
for (const key of Reflect.ownKeys(src)) {
|
|
56
15
|
if (seen.has(key))
|
|
57
16
|
continue;
|
|
58
17
|
const desc = Object.getOwnPropertyDescriptor(src, key);
|
|
59
18
|
if (!desc || !desc.enumerable)
|
|
60
19
|
continue;
|
|
61
|
-
// Capture the current source for this key (last write wins).
|
|
62
20
|
Object.defineProperty(result, key, {
|
|
63
21
|
enumerable: true,
|
|
64
22
|
configurable: true,
|
|
@@ -67,6 +25,7 @@ export function createView(...args) {
|
|
|
67
25
|
if (!INSPECTOR_ENABLED || !notifyInspectorRef.current) {
|
|
68
26
|
return value;
|
|
69
27
|
}
|
|
28
|
+
// Propagate inspector marker into nested observables
|
|
70
29
|
if (value?.[INSPECT_MARKER]) {
|
|
71
30
|
value[INSPECT_MARKER] = {
|
|
72
31
|
current: {
|
|
@@ -76,6 +35,7 @@ export function createView(...args) {
|
|
|
76
35
|
};
|
|
77
36
|
}
|
|
78
37
|
else if (typeof value === "function") {
|
|
38
|
+
// Wrap actions to notify inspector
|
|
79
39
|
return (...params) => {
|
|
80
40
|
notifyInspectorRef.current.notify({
|
|
81
41
|
type: "action",
|
|
@@ -100,6 +60,7 @@ export function createView(...args) {
|
|
|
100
60
|
},
|
|
101
61
|
set: (value) => {
|
|
102
62
|
Object.defineProperty(notifyInspectorRef, "current", {
|
|
63
|
+
configurable: true,
|
|
103
64
|
get() {
|
|
104
65
|
return value.current;
|
|
105
66
|
},
|
|
@@ -107,5 +68,6 @@ export function createView(...args) {
|
|
|
107
68
|
},
|
|
108
69
|
});
|
|
109
70
|
}
|
|
71
|
+
// The overload signatures expose a precise type; this is the shared impl.
|
|
110
72
|
return result;
|
|
111
73
|
}
|