synstate-dom 0.1.0 → 0.2.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/dist/control/for.d.mts +10 -5
- package/dist/control/for.d.mts.map +1 -1
- package/dist/control/for.mjs +39 -2
- package/dist/control/for.mjs.map +1 -1
- package/package.json +12 -12
- package/src/control/for.mts +72 -8
package/dist/control/for.d.mts
CHANGED
|
@@ -6,11 +6,16 @@ import { type JSX } from '../jsx/index.mjs';
|
|
|
6
6
|
* (SPEC.md 8.4).
|
|
7
7
|
*
|
|
8
8
|
* `children` is called once per key, inside a scope of the row's own, with
|
|
9
|
-
* observables of the element and its index.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* observables of the element and its index. The index is made only for a
|
|
10
|
+
* `children` that declares a second parameter (`children.length >= 2`); one
|
|
11
|
+
* that reads it otherwise, through a rest parameter or `arguments`, is given
|
|
12
|
+
* `undefined`.
|
|
13
|
+
*
|
|
14
|
+
* A row whose key stays is not rebuilt: its `item$` and `index$` are derived
|
|
15
|
+
* from `items`, so they update in the ordinary propagation, and nothing is
|
|
16
|
+
* written during it. A key that goes disposes its row's scope and removes its
|
|
17
|
+
* nodes; the rows that stay are moved as little as the longest increasing
|
|
18
|
+
* subsequence allows.
|
|
14
19
|
*
|
|
15
20
|
* `key` is required, as in React; `(_, i) => i` matches rows by position. A
|
|
16
21
|
* key that appears twice is reported with `console.error`, and its later
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"for.d.mts","sourceRoot":"","sources":["../../src/control/for.mts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,qBAAqB,EAG3B,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"for.d.mts","sourceRoot":"","sources":["../../src/control/for.mts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,qBAAqB,EAG3B,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAsB,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,6BAIlB,QAAQ,CAAC;IACV,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9B,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CACR,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,EAC/B,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,KAClC,GAAG,CAAC,OAAO,CAAC;CAClB,CAAC,KAAG,GAAG,CAAC,OAwML,CAAC"}
|
package/dist/control/for.mjs
CHANGED
|
@@ -19,10 +19,20 @@ import { longestIncreasingSubsequence } from './longest-increasing-subsequence.m
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
22
27
|
export const For = ({ items, key, children, }) => mountable(() => {
|
|
23
28
|
const parent = getCurrentScope();
|
|
24
29
|
const anchor = document.createComment('');
|
|
25
30
|
const entries$ = toObservable(items).pipe(map((list) => toEntries(list, key)));
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const usesIndex = children.length >= 2;
|
|
35
|
+
const callChildren = children;
|
|
26
36
|
const mut_rows = new Map();
|
|
27
37
|
const rowStarts = new WeakSet();
|
|
28
38
|
const mut_initial = { nodes: [] };
|
|
@@ -33,8 +43,9 @@ export const For = ({ items, key, children, }) => mountable(() => {
|
|
|
33
43
|
rowStarts.add(start);
|
|
34
44
|
const nodes = scope.run(() => {
|
|
35
45
|
const item$ = rowField(entries$, rowKey, entry.item, (e) => e.item);
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
return toNodes((usesIndex
|
|
47
|
+
? callChildren(item$, rowField(entries$, rowKey, entry.index, (e) => e.index))
|
|
48
|
+
: callChildren(item$)).mount());
|
|
38
49
|
});
|
|
39
50
|
const row = { scope, start };
|
|
40
51
|
scope.run(() => {
|
|
@@ -55,8 +66,31 @@ export const For = ({ items, key, children, }) => mountable(() => {
|
|
|
55
66
|
}
|
|
56
67
|
return mut_nodes;
|
|
57
68
|
};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
const removeAllAtOnceIfEveryKeyGoes = (previousOrder, entries) => {
|
|
76
|
+
if (!Arr.isNonEmpty(previousOrder) ||
|
|
77
|
+
previousOrder.some((rowKey) => entries.byKey.has(rowKey))) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const first = mut_rows.get(previousOrder[0]);
|
|
81
|
+
if (first === undefined) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const range = document.createRange();
|
|
85
|
+
range.setStartBefore(first.start);
|
|
86
|
+
range.setEndBefore(anchor);
|
|
87
|
+
range.deleteContents();
|
|
88
|
+
};
|
|
58
89
|
bindValue(entries$, (entries) => {
|
|
59
90
|
const previousOrder = Array.from(mut_rows.keys());
|
|
91
|
+
if (anchor.parentNode !== null) {
|
|
92
|
+
removeAllAtOnceIfEveryKeyGoes(previousOrder, entries);
|
|
93
|
+
}
|
|
60
94
|
for (const [rowKey, row] of mut_rows) {
|
|
61
95
|
if (entries.byKey.has(rowKey)) {
|
|
62
96
|
continue;
|
|
@@ -71,6 +105,9 @@ export const For = ({ items, key, children, }) => mountable(() => {
|
|
|
71
105
|
});
|
|
72
106
|
return;
|
|
73
107
|
}
|
|
108
|
+
if (Arr.eq(previousOrder, entries.order)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
74
111
|
const previousPosition = new Map(previousOrder
|
|
75
112
|
.filter((rowKey) => mut_rows.has(rowKey))
|
|
76
113
|
.map((rowKey, position) => [rowKey, position]));
|
package/dist/control/for.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"for.mjs","sourceRoot":"","sources":["../../src/control/for.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,WAAW,EACX,eAAe,EACf,GAAG,EACH,cAAc,GAIf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"for.mjs","sourceRoot":"","sources":["../../src/control/for.mts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synstate-dom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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",
|
|
@@ -43,22 +43,22 @@
|
|
|
43
43
|
"ts-type-forge": "^9.2.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@vitest/browser-playwright": "5.0.
|
|
47
|
-
"eslint-config-typed": "5.19.
|
|
48
|
-
"eslint-plugin-ts-data-forge": "0.10.
|
|
49
|
-
"eslint-plugin-ts-fortress": "1.3.
|
|
50
|
-
"eslint-plugin-ts-type-forge": "0.8.
|
|
51
|
-
"playwright": "1.64.
|
|
52
|
-
"prettier": "3.9.
|
|
46
|
+
"@vitest/browser-playwright": "5.0.5",
|
|
47
|
+
"eslint-config-typed": "5.19.2",
|
|
48
|
+
"eslint-plugin-ts-data-forge": "0.10.3",
|
|
49
|
+
"eslint-plugin-ts-fortress": "1.3.8",
|
|
50
|
+
"eslint-plugin-ts-type-forge": "0.8.13",
|
|
51
|
+
"playwright": "1.64.1",
|
|
52
|
+
"prettier": "3.9.10",
|
|
53
53
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
54
54
|
"prettier-plugin-packagejson": "3.0.2",
|
|
55
|
-
"synstate": "
|
|
56
|
-
"ts-data-forge": "14.
|
|
55
|
+
"synstate": "5.0.1",
|
|
56
|
+
"ts-data-forge": "14.10.0",
|
|
57
57
|
"ts-repo-utils": "10.7.1"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"synstate": ">=
|
|
61
|
-
"ts-data-forge": ">=14.
|
|
60
|
+
"synstate": ">=5.0.1",
|
|
61
|
+
"ts-data-forge": ">=14.10.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22.22.2",
|
package/src/control/for.mts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type Scope,
|
|
10
10
|
} from 'synstate';
|
|
11
11
|
import { Arr, Optional } from 'ts-data-forge';
|
|
12
|
+
import type { BivariantHack } from 'ts-type-forge';
|
|
12
13
|
import { toObservable, type Bindable } from '../constant/index.mjs';
|
|
13
14
|
import { bindValue } from '../internal/index.mjs';
|
|
14
15
|
import { mountable, toNodes, type JSX } from '../jsx/index.mjs';
|
|
@@ -19,11 +20,16 @@ import { longestIncreasingSubsequence } from './longest-increasing-subsequence.m
|
|
|
19
20
|
* (SPEC.md 8.4).
|
|
20
21
|
*
|
|
21
22
|
* `children` is called once per key, inside a scope of the row's own, with
|
|
22
|
-
* observables of the element and its index.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* observables of the element and its index. The index is made only for a
|
|
24
|
+
* `children` that declares a second parameter (`children.length >= 2`); one
|
|
25
|
+
* that reads it otherwise, through a rest parameter or `arguments`, is given
|
|
26
|
+
* `undefined`.
|
|
27
|
+
*
|
|
28
|
+
* A row whose key stays is not rebuilt: its `item$` and `index$` are derived
|
|
29
|
+
* from `items`, so they update in the ordinary propagation, and nothing is
|
|
30
|
+
* written during it. A key that goes disposes its row's scope and removes its
|
|
31
|
+
* nodes; the rows that stay are moved as little as the longest increasing
|
|
32
|
+
* subsequence allows.
|
|
27
33
|
*
|
|
28
34
|
* `key` is required, as in React; `(_, i) => i` matches rows by position. A
|
|
29
35
|
* key that appears twice is reported with `console.error`, and its later
|
|
@@ -50,6 +56,18 @@ export const For = <T,>({
|
|
|
50
56
|
map((list) => toEntries(list, key)),
|
|
51
57
|
);
|
|
52
58
|
|
|
59
|
+
// `index$` is a node of its own in every row, visited on every update of
|
|
60
|
+
// `items`; a `children` that declares no second parameter is not given
|
|
61
|
+
// one, as Solid's `For` does.
|
|
62
|
+
const usesIndex = children.length >= 2;
|
|
63
|
+
|
|
64
|
+
const callChildren: BivariantHack<
|
|
65
|
+
(
|
|
66
|
+
item$: InitializedObservable<T>,
|
|
67
|
+
index$?: InitializedObservable<number>,
|
|
68
|
+
) => JSX.Element
|
|
69
|
+
> = children;
|
|
70
|
+
|
|
53
71
|
const mut_rows = new Map<unknown, Row>();
|
|
54
72
|
|
|
55
73
|
const rowStarts = new WeakSet<Node>();
|
|
@@ -70,9 +88,15 @@ export const For = <T,>({
|
|
|
70
88
|
const nodes = scope.run(() => {
|
|
71
89
|
const item$ = rowField(entries$, rowKey, entry.item, (e) => e.item);
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
return toNodes(
|
|
92
|
+
(usesIndex
|
|
93
|
+
? callChildren(
|
|
94
|
+
item$,
|
|
95
|
+
rowField(entries$, rowKey, entry.index, (e) => e.index),
|
|
96
|
+
)
|
|
97
|
+
: callChildren(item$)
|
|
98
|
+
).mount(),
|
|
99
|
+
);
|
|
76
100
|
});
|
|
77
101
|
|
|
78
102
|
const row: Row = { scope, start } as const;
|
|
@@ -105,9 +129,45 @@ export const For = <T,>({
|
|
|
105
129
|
return mut_nodes;
|
|
106
130
|
};
|
|
107
131
|
|
|
132
|
+
/**
|
|
133
|
+
* When no key stays, takes every row's nodes out in one range, rather than
|
|
134
|
+
* one by one as each row's scope is disposed: clearing or replacing the
|
|
135
|
+
* whole list is then one DOM operation. The scopes are disposed after,
|
|
136
|
+
* and find their nodes already detached.
|
|
137
|
+
*/
|
|
138
|
+
const removeAllAtOnceIfEveryKeyGoes = (
|
|
139
|
+
previousOrder: readonly unknown[],
|
|
140
|
+
entries: Entries<T>,
|
|
141
|
+
): void => {
|
|
142
|
+
if (
|
|
143
|
+
!Arr.isNonEmpty(previousOrder) ||
|
|
144
|
+
previousOrder.some((rowKey) => entries.byKey.has(rowKey))
|
|
145
|
+
) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const first = mut_rows.get(previousOrder[0]);
|
|
150
|
+
|
|
151
|
+
if (first === undefined) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const range = document.createRange();
|
|
156
|
+
|
|
157
|
+
range.setStartBefore(first.start);
|
|
158
|
+
|
|
159
|
+
range.setEndBefore(anchor);
|
|
160
|
+
|
|
161
|
+
range.deleteContents();
|
|
162
|
+
};
|
|
163
|
+
|
|
108
164
|
bindValue(entries$, (entries) => {
|
|
109
165
|
const previousOrder = Array.from(mut_rows.keys());
|
|
110
166
|
|
|
167
|
+
if (anchor.parentNode !== null) {
|
|
168
|
+
removeAllAtOnceIfEveryKeyGoes(previousOrder, entries);
|
|
169
|
+
}
|
|
170
|
+
|
|
111
171
|
for (const [rowKey, row] of mut_rows) {
|
|
112
172
|
if (entries.byKey.has(rowKey)) {
|
|
113
173
|
continue;
|
|
@@ -128,6 +188,10 @@ export const For = <T,>({
|
|
|
128
188
|
return;
|
|
129
189
|
}
|
|
130
190
|
|
|
191
|
+
if (Arr.eq(previousOrder, entries.order)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
131
195
|
const previousPosition = new Map(
|
|
132
196
|
previousOrder
|
|
133
197
|
.filter((rowKey) => mut_rows.has(rowKey))
|