-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.mjs
136 lines (132 loc) · 4.06 KB
/
index.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { derived, get } from "svelte/store";
/**
* @external Store
* @see [Svelte stores](https://svelte.dev/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values-store-contract)
*/
/**
* Create a store similar to [Svelte's `derived`](https://svelte.dev/docs#run-time-svelte-store-writable),
* but which has its own `set` and `update` methods and can send values back to the origin stores.
* [Read more...](https://github.com/PixievoltNo1/svelte-writable-derived#default-export-writablederived)
*
* @param {Store|Store[]} origins One or more stores to derive from. Same as
* [`derived`](https://svelte.dev/docs#run-time-svelte-store-writable)'s 1st parameter.
* @param {!Function} derive The callback to determine the derived value. Same as
* [`derived`](https://svelte.dev/docs#run-time-svelte-store-writable)'s 2nd parameter.
* @param {!Function} reflect Called when the derived store gets a new value via its `set` or
* `update` methods, and determines new values for the origin stores.
* [Read more...](https://github.com/PixievoltNo1/svelte-writable-derived#new-parameter-reflect)
* @param [initial] The new store's initial value. Same as
* [`derived`](https://svelte.dev/docs#run-time-svelte-store-writable)'s 3rd parameter.
*
* @returns {Store} A writable store.
*/
export default function writableDerived(origins, derive, reflect, initial) {
var childDerivedSetter, originValues, blockNextDerive = false;
var reflectOldValues = reflect.length >= 2;
var wrappedDerive = (got, set, update) => {
childDerivedSetter = set;
if (reflectOldValues) {
originValues = got;
}
if (!blockNextDerive) {
let returned = derive(got, set, update);
if (derive.length < 2) {
set(returned);
} else {
return returned;
}
}
blockNextDerive = false;
};
var childDerived = derived(origins, wrappedDerive, initial);
var singleOrigin = !Array.isArray(origins);
function doReflect(reflecting) {
var setWith = reflect(reflecting, originValues);
if (singleOrigin) {
blockNextDerive = true;
origins.set(setWith);
} else {
setWith.forEach( (value, i) => {
blockNextDerive = true;
origins[i].set(value);
} );
}
blockNextDerive = false;
}
var tryingSet = false;
function update(fn) {
var isUpdated, mutatedBySubscriptions, oldValue, newValue;
if (tryingSet) {
newValue = fn( get(childDerived) );
childDerivedSetter(newValue);
return;
}
var unsubscribe = childDerived.subscribe( (value) => {
if (!tryingSet) {
oldValue = value;
} else if (!isUpdated) {
isUpdated = true;
} else {
mutatedBySubscriptions = true;
}
} );
newValue = fn(oldValue);
tryingSet = true;
childDerivedSetter(newValue);
unsubscribe();
tryingSet = false;
if (mutatedBySubscriptions) {
newValue = get(childDerived);
}
if (isUpdated) {
doReflect(newValue);
}
}
return {
subscribe: childDerived.subscribe,
set(value) { update( () => value ); },
update,
};
}
export { writableDerived };
/**
* Create a store for a property value in an object contained in another store.
* [Read more...](https://github.com/PixievoltNo1/svelte-writable-derived#named-export-propertystore)
*
* @param {Store} origin The store containing the object to get/set from.
* @param {string|number|symbol|Array<string|number|symbol>} propName The property to get/set, or a path of
* properties in nested objects.
*
* @returns {Store} A writable store.
*/
export function propertyStore(origin, propName) {
if (!Array.isArray(propName)) {
return writableDerived(
origin,
(object) => object[propName],
(reflecting, object) => {
object[propName] = reflecting;
return object;
},
);
} else {
let props = propName.concat();
return writableDerived(
origin,
(value) => {
for (let i = 0; i < props.length; ++i) {
value = value[ props[i] ];
}
return value;
},
(reflecting, object) => {
let target = object;
for (let i = 0; i < props.length - 1; ++i) {
target = target[ props[i] ];
}
target[ props[props.length - 1] ] = reflecting;
return object;
},
);
}
}