synstate-dom 0.2.0 → 0.4.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.
|
@@ -6,7 +6,8 @@ import type { Bindable, BindableValue } from './bindable.mjs';
|
|
|
6
6
|
* When every input is a constant, `fn` runs once and the result is a constant:
|
|
7
7
|
* a static part of the view never enters the graph. Otherwise the constants
|
|
8
8
|
* become `just` and the views are turned into observables, and the result is
|
|
9
|
-
* `
|
|
9
|
+
* synstate's `derive` over them: one observable, which passes on a result only
|
|
10
|
+
* when it is not `Object.is` the one it holds.
|
|
10
11
|
*/
|
|
11
12
|
export declare const derive: <const BS extends NonEmptyTuple<Bindable<unknown>>, R>(bindables: BS, fn: (...values: BindableValues<BS>) => R) => Bindable<R>;
|
|
12
13
|
/** The value types of a tuple of {@link Bindable}s, position by position. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.d.mts","sourceRoot":"","sources":["../../src/constant/derive.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"derive.d.mts","sourceRoot":"","sources":["../../src/constant/derive.mts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG9D;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,GAAI,KAAK,CAAC,EAAE,SAAS,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,aAC9D,EAAE,MACT,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,KACvC,QAAQ,CAAC,CAAC,CAkBZ,CAAC;AAEF,6EAA6E;AAC7E,MAAM,MAAM,cAAc,CAAC,EAAE,SAAS,SAAS,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,QAAQ,CAAC;KAC5E,CAAC,IAAI,MAAM,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACtC,CAAC,CAAC"}
|
package/dist/constant/derive.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { derive as deriveObservable, isObservable, } from 'synstate';
|
|
2
2
|
import { Arr } from 'ts-data-forge';
|
|
3
3
|
import { asConstant, isView } from '../internal/index.mjs';
|
|
4
4
|
import { toObservable } from './to-observable.mjs';
|
|
@@ -10,19 +10,19 @@ import { toObservable } from './to-observable.mjs';
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
export const derive = (bindables, fn) => {
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
const apply = (values) =>
|
|
19
19
|
|
|
20
|
-
fn
|
|
20
|
+
const project = fn;
|
|
21
21
|
if (Arr.every(bindables, isConstant)) {
|
|
22
|
-
return asConstant(
|
|
22
|
+
return asConstant(project(...bindables));
|
|
23
23
|
}
|
|
24
24
|
const observables = Arr.map(bindables, toObservable);
|
|
25
|
-
return
|
|
25
|
+
return deriveObservable(observables, project);
|
|
26
26
|
};
|
|
27
27
|
const isConstant = (bindable) => !isView(bindable) && !isObservable(bindable);
|
|
28
28
|
//# sourceMappingURL=derive.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.mjs","sourceRoot":"","sources":["../../src/constant/derive.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"derive.mjs","sourceRoot":"","sources":["../../src/constant/derive.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,gBAAgB,EAC1B,YAAY,GAEb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,SAAa,EACb,EAAwC,EAC3B,EAAE;IACf,oEAAoE;IACpE,wEAAwE;IACxE,wEAAwE;IACxE,oCAAoC;IACpC,iFAAiF;IACjF,MAAM,OAAO,GAAG,EAA0C,CAAC;IAE3D,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;QACrC,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GAAkD,GAAG,CAAC,GAAG,CACxE,SAAS,EACT,YAAY,CACb,CAAC;IAEF,OAAO,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC,CAAC;AAOF,MAAM,UAAU,GAAG,CAAC,QAA2B,EAAW,EAAE,CAC1D,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synstate-dom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Compiler-free fine-grained UI library that binds synstate observables directly to the DOM",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -44,24 +44,24 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@vitest/browser-playwright": "5.0.5",
|
|
47
|
-
"eslint-config-typed": "5.
|
|
48
|
-
"eslint-plugin-ts-data-forge": "0.10.
|
|
49
|
-
"eslint-plugin-ts-fortress": "1.3.
|
|
50
|
-
"eslint-plugin-ts-type-forge": "0.8.
|
|
47
|
+
"eslint-config-typed": "5.20.1",
|
|
48
|
+
"eslint-plugin-ts-data-forge": "0.10.4",
|
|
49
|
+
"eslint-plugin-ts-fortress": "1.3.9",
|
|
50
|
+
"eslint-plugin-ts-type-forge": "0.8.14",
|
|
51
51
|
"playwright": "1.64.1",
|
|
52
52
|
"prettier": "3.9.10",
|
|
53
53
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
54
54
|
"prettier-plugin-packagejson": "3.0.2",
|
|
55
|
-
"synstate": "
|
|
55
|
+
"synstate": "6.1.0",
|
|
56
56
|
"ts-data-forge": "14.10.0",
|
|
57
57
|
"ts-repo-utils": "10.7.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"synstate": ">=
|
|
60
|
+
"synstate": ">=6.1.0",
|
|
61
61
|
"ts-data-forge": ">=14.10.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
|
-
"node": ">=22.
|
|
64
|
+
"node": ">=22.23.4",
|
|
65
65
|
"pnpm": ">=9.0.0"
|
|
66
66
|
},
|
|
67
67
|
"publishConfig": {
|
package/src/constant/derive.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
derive as deriveObservable,
|
|
3
3
|
isObservable,
|
|
4
|
-
map,
|
|
5
4
|
type InitializedObservable,
|
|
6
5
|
} from 'synstate';
|
|
7
6
|
import { Arr } from 'ts-data-forge';
|
|
@@ -16,22 +15,22 @@ import { toObservable } from './to-observable.mjs';
|
|
|
16
15
|
* When every input is a constant, `fn` runs once and the result is a constant:
|
|
17
16
|
* a static part of the view never enters the graph. Otherwise the constants
|
|
18
17
|
* become `just` and the views are turned into observables, and the result is
|
|
19
|
-
* `
|
|
18
|
+
* synstate's `derive` over them: one observable, which passes on a result only
|
|
19
|
+
* when it is not `Object.is` the one it holds.
|
|
20
20
|
*/
|
|
21
21
|
export const derive = <const BS extends NonEmptyTuple<Bindable<unknown>>, R>(
|
|
22
22
|
bindables: BS,
|
|
23
23
|
fn: (...values: BindableValues<BS>) => R,
|
|
24
24
|
): Bindable<R> => {
|
|
25
|
-
// `
|
|
26
|
-
// the constants themselves, or
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
fn(...(values as BindableValues<BS>));
|
|
25
|
+
// `fn` is called with the value of each of `bindables`, position by
|
|
26
|
+
// position: the constants themselves, or their observables' values. The
|
|
27
|
+
// checker cannot follow a position through `Arr.map`, which carries one
|
|
28
|
+
// element type for the whole tuple.
|
|
29
|
+
// eslint-disable-next-line total-functions/no-unsafe-type-assertion -- see above
|
|
30
|
+
const project = fn as (...values: readonly unknown[]) => R;
|
|
32
31
|
|
|
33
32
|
if (Arr.every(bindables, isConstant)) {
|
|
34
|
-
return asConstant(
|
|
33
|
+
return asConstant(project(...bindables));
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
const observables: NonEmptyTuple<InitializedObservable<unknown>> = Arr.map(
|
|
@@ -39,7 +38,7 @@ export const derive = <const BS extends NonEmptyTuple<Bindable<unknown>>, R>(
|
|
|
39
38
|
toObservable,
|
|
40
39
|
);
|
|
41
40
|
|
|
42
|
-
return
|
|
41
|
+
return deriveObservable(observables, project);
|
|
43
42
|
};
|
|
44
43
|
|
|
45
44
|
/** The value types of a tuple of {@link Bindable}s, position by position. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createState, isObservable } from 'synstate';
|
|
1
|
+
import { createState, isChildObservable, isObservable } from 'synstate';
|
|
2
2
|
import { expectType } from 'ts-data-forge';
|
|
3
3
|
import type { Bindable } from './bindable.mjs';
|
|
4
4
|
import { constant } from './constant.mjs';
|
|
@@ -61,4 +61,28 @@ describe(derive, () => {
|
|
|
61
61
|
|
|
62
62
|
assert.strictEqual(result$.getSnapshot().value, '2-B');
|
|
63
63
|
});
|
|
64
|
+
|
|
65
|
+
test('observables give one observable, whose parents are the inputs', () => {
|
|
66
|
+
const [a$, setA] = createState(1);
|
|
67
|
+
|
|
68
|
+
const [b$] = createState(2);
|
|
69
|
+
|
|
70
|
+
const fn = vi.fn((a: number, b: number) => a + b);
|
|
71
|
+
|
|
72
|
+
const result = derive([a$, b$], fn);
|
|
73
|
+
|
|
74
|
+
const result$ = toObservable(result);
|
|
75
|
+
|
|
76
|
+
assert.isTrue(isChildObservable(result$));
|
|
77
|
+
|
|
78
|
+
if (isChildObservable(result$)) {
|
|
79
|
+
assert.deepStrictEqual(result$.parents, [a$, b$]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
setA(2);
|
|
83
|
+
|
|
84
|
+
assert.strictEqual(result$.getSnapshot().value, 4);
|
|
85
|
+
|
|
86
|
+
expect(fn).toHaveBeenCalledTimes(2);
|
|
87
|
+
});
|
|
64
88
|
});
|