Skip to content

Commit 3f7fcf9

Browse files
trueadmRich-Harris
andauthored
feat: add reactive Set class to svelte/reactivity (#10781)
* feat: add reactive Set class to svelte/reactivity * add some type safety * simplify, read entries lazily * failing unit test * fix deletions * minor tweaks * work around effect ordering bug * simplify, make entries lazy * small tweak * use var, minor tweaks --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent eb40417 commit 3f7fcf9

File tree

10 files changed

+400
-105
lines changed

10 files changed

+400
-105
lines changed

.changeset/calm-ravens-sneeze.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
feat: add reactive Set class to svelte/reactivity

packages/svelte/src/internal/client/proxy.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ export function unstate(value) {
147147
* @param {1 | -1} [d]
148148
*/
149149
function update_version(signal, d = 1) {
150-
const value = untrack(() => get(signal));
151-
set(signal, value + d);
150+
set(signal, signal.v + d);
152151
}
153152

154153
/** @type {ProxyHandler<import('./types.js').ProxyStateObject<any>>} */
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { source, set } from '../internal/client/reactivity/sources.js';
2+
import { get } from '../internal/client/runtime.js';
3+
4+
/** @type {Array<keyof Date>} */
5+
const read = [
6+
'getDate',
7+
'getDay',
8+
'getFullYear',
9+
'getHours',
10+
'getMilliseconds',
11+
'getMinutes',
12+
'getMonth',
13+
'getSeconds',
14+
'getTime',
15+
'getTimezoneOffset',
16+
'getUTCDate',
17+
'getUTCDay',
18+
'getUTCFullYear',
19+
'getUTCHours',
20+
'getUTCMilliseconds',
21+
'getUTCMinutes',
22+
'getUTCMonth',
23+
'getUTCSeconds',
24+
// @ts-expect-error this is deprecated
25+
'getYear',
26+
'toDateString',
27+
'toISOString',
28+
'toJSON',
29+
'toLocaleDateString',
30+
'toLocaleString',
31+
'toLocaleTimeString',
32+
'toString',
33+
'toTimeString',
34+
'toUTCString'
35+
];
36+
37+
/** @type {Array<keyof Date>} */
38+
const write = [
39+
'setDate',
40+
'setFullYear',
41+
'setHours',
42+
'setMilliseconds',
43+
'setMinutes',
44+
'setMonth',
45+
'setSeconds',
46+
'setTime',
47+
'setUTCDate',
48+
'setUTCFullYear',
49+
'setUTCHours',
50+
'setUTCMilliseconds',
51+
'setUTCMinutes',
52+
'setUTCMonth',
53+
'setUTCSeconds',
54+
// @ts-expect-error this is deprecated
55+
'setYear'
56+
];
57+
58+
export class ReactiveDate extends Date {
59+
#raw_time = source(super.getTime());
60+
static #inited = false;
61+
62+
// We init as part of the first instance so that we can treeshake this class
63+
#init() {
64+
if (!ReactiveDate.#inited) {
65+
ReactiveDate.#inited = true;
66+
const proto = ReactiveDate.prototype;
67+
const date_proto = Date.prototype;
68+
69+
for (const method of read) {
70+
// @ts-ignore
71+
proto[method] = function () {
72+
get(this.#raw_time);
73+
// @ts-ignore
74+
return date_proto[method].call(this);
75+
};
76+
}
77+
78+
for (const method of write) {
79+
// @ts-ignore
80+
proto[method] = function (/** @type {any} */ ...args) {
81+
// @ts-ignore
82+
const v = date_proto[method].apply(this, args);
83+
const time = date_proto.getTime.call(this);
84+
if (time !== this.#raw_time.v) {
85+
set(this.#raw_time, time);
86+
}
87+
return v;
88+
};
89+
}
90+
}
91+
}
92+
93+
/**
94+
* @param {any[]} values
95+
*/
96+
constructor(...values) {
97+
// @ts-ignore
98+
super(...values);
99+
this.#init();
100+
}
101+
}
Lines changed: 2 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,2 @@
1-
import { source, set } from '../internal/client/reactivity/sources.js';
2-
import { get } from '../internal/client/runtime.js';
3-
4-
/** @type {Array<keyof Date>} */
5-
const read = [
6-
'getDate',
7-
'getDay',
8-
'getFullYear',
9-
'getHours',
10-
'getMilliseconds',
11-
'getMinutes',
12-
'getMonth',
13-
'getSeconds',
14-
'getTime',
15-
'getTimezoneOffset',
16-
'getUTCDate',
17-
'getUTCDay',
18-
'getUTCFullYear',
19-
'getUTCHours',
20-
'getUTCMilliseconds',
21-
'getUTCMinutes',
22-
'getUTCMonth',
23-
'getUTCSeconds',
24-
// @ts-expect-error this is deprecated
25-
'getYear',
26-
'toDateString',
27-
'toISOString',
28-
'toJSON',
29-
'toLocaleDateString',
30-
'toLocaleString',
31-
'toLocaleTimeString',
32-
'toString',
33-
'toTimeString',
34-
'toUTCString'
35-
];
36-
37-
/** @type {Array<keyof Date>} */
38-
const write = [
39-
'setDate',
40-
'setFullYear',
41-
'setHours',
42-
'setMilliseconds',
43-
'setMinutes',
44-
'setMonth',
45-
'setSeconds',
46-
'setTime',
47-
'setUTCDate',
48-
'setUTCFullYear',
49-
'setUTCHours',
50-
'setUTCMilliseconds',
51-
'setUTCMinutes',
52-
'setUTCMonth',
53-
'setUTCSeconds',
54-
// @ts-expect-error this is deprecated
55-
'setYear'
56-
];
57-
58-
class ReactiveDate extends Date {
59-
#raw_time = source(super.getTime());
60-
static #inited = false;
61-
62-
// We init as part of the first instance so that we can treeshake this class
63-
#init() {
64-
if (!ReactiveDate.#inited) {
65-
ReactiveDate.#inited = true;
66-
const proto = ReactiveDate.prototype;
67-
const date_proto = Date.prototype;
68-
69-
for (const method of read) {
70-
// @ts-ignore
71-
proto[method] = function () {
72-
get(this.#raw_time);
73-
// @ts-ignore
74-
return date_proto[method].call(this);
75-
};
76-
}
77-
78-
for (const method of write) {
79-
// @ts-ignore
80-
proto[method] = function (/** @type {any} */ ...args) {
81-
// @ts-ignore
82-
const v = date_proto[method].apply(this, args);
83-
const time = date_proto.getTime.call(this);
84-
if (time !== this.#raw_time.v) {
85-
set(this.#raw_time, time);
86-
}
87-
return v;
88-
};
89-
}
90-
}
91-
}
92-
93-
/**
94-
* @param {any[]} values
95-
*/
96-
constructor(...values) {
97-
// @ts-ignore
98-
super(...values);
99-
this.#init();
100-
}
101-
}
102-
103-
export { ReactiveDate as Date };
1+
export { ReactiveDate as Date } from './date.js';
2+
export { ReactiveSet as Set } from './set.js';

0 commit comments

Comments
 (0)