-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
109 lines (109 loc) · 4.08 KB
/
index.js
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
/**
* Mixin to attach an Effector Store to a lit-element web-component. On store change the element will be
* automatically updated. The store is reflected in the property `$`.
* @param BaseClass Class inheriting from LitElement
* @param EffectorStore Store
* @param effectAPI Optional event/effect interface that will be injected in property `dispatch`. It must be an obect whose values are functions or effetcs.
*/
export function EffectorMxn(BaseClass, EffectorStore, effectAPI = undefined) {
return class extends BaseClass {
constructor() {
super();
this.$ = undefined;
this._watcherPointer = undefined;
// @ts-ignore
this._apiCopy = Object.assign({}, effectAPI, super.dispatch);
this._storePointer = EffectorStore;
}
static get properties() {
return { $: { attribute: false, reflect: false } };
}
/**
* Getter that returns a pointer to the associated effector store
*/
get store() {
return this._storePointer;
}
/**
* Getter that returns a shallow copy of the injected effect/event API
*/
get dispatch() {
return this._apiCopy;
}
/**
* Replace the store with another one and subscribes to it. If `store` is not provided it will unsubscribe
* from the current store. Usefull during testing, in case one wants to swapp with a fake store or simply detach from it.
* @param store new Store
*/
replaceStore(store = undefined) {
var _a;
(_a = this._watcherPointer) === null || _a === void 0 ? void 0 : _a.unsubscribe();
this._storePointer = store;
this.useStore();
}
connectedCallback() {
if (super.connectedCallback)
super.connectedCallback();
this.useStore();
}
/**
* Subscribes to the store.
*/
useStore() {
var _a;
this._watcherPointer = (_a = this.store) === null || _a === void 0 ? void 0 : _a.watch(this.store_update_handler.bind(this));
if (typeof this.store === "undefined")
this.store_update_handler(undefined);
}
disconnectedCallback() {
var _a;
if (super.disconnectedCallback)
super.disconnectedCallback();
(_a = this._watcherPointer) === null || _a === void 0 ? void 0 : _a.unsubscribe();
}
/**
* Actual function that is subscribed to store chages. Call this
* function if you want to simulate a store update.
* @param currentState
*/
store_update_handler(currentState) {
var stateCopy = this._deepCopyObject(currentState);
this._reflectStoreToProperty(stateCopy);
this._userReactionToStoreUpdate(stateCopy);
}
/**
* Calls the user defined update function on store trigger.
* @param current_data
*/
_userReactionToStoreUpdate(current_data) {
//@ts-ignore
if (this.on_store_update) {
//@ts-ignore
this.on_store_update(current_data);
this.requestUpdate();
}
}
_reflectStoreToProperty(current_data) {
this.$ = current_data;
}
/**
* Does a deep copy of the provided object. Used to copy the store state.
* @param data data to be copied
*/
_deepCopyObject(data) {
let cases = ["number", "boolean", "string", "null", "undefined"];
if (cases.includes(typeof data))
return data;
var copy = {};
for (const [key, value] of Object.entries(data)) {
if (cases.includes(typeof value)) {
copy[key] = value;
}
else if (typeof value === "object") {
copy[key] = JSON.parse(JSON.stringify(value));
}
}
return copy;
}
};
}