@coaction/valtio 1.4.1 → 2.0.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/README.md +2 -2
- package/dist/index.d.mts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +222 -80
- package/dist/index.mjs +213 -78
- package/package.json +33 -45
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @coaction/valtio
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
[](https://www.npmjs.com/package/@coaction/valtio)
|
|
5
5
|

|
|
6
6
|
|
|
@@ -40,4 +40,4 @@ store.getState().increment();
|
|
|
40
40
|
|
|
41
41
|
## Documentation
|
|
42
42
|
|
|
43
|
-
You can find the documentation [here](https://github.com/
|
|
43
|
+
You can find the documentation [here](https://github.com/coactionjs/coaction).
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { proxy } from "valtio/vanilla";
|
|
2
|
+
export * from "valtio/vanilla";
|
|
3
3
|
|
|
4
|
+
//#region \0rolldown/runtime.js
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region packages/coaction-valtio/src/index.d.ts
|
|
4
7
|
interface BindValtio {
|
|
5
|
-
|
|
8
|
+
<T extends object>(target: T): T;
|
|
6
9
|
}
|
|
7
10
|
/**
|
|
8
11
|
* Bind a store to Valtio.
|
|
@@ -12,5 +15,8 @@ declare const bindValtio: BindValtio;
|
|
|
12
15
|
* Adapt a Valtio store type to state type.
|
|
13
16
|
*/
|
|
14
17
|
declare const adapt: <T extends object>(store: T) => T;
|
|
15
|
-
|
|
16
|
-
export { adapt, bindValtio };
|
|
18
|
+
declare namespace index_d_exports {
|
|
19
|
+
export { adapt, bindValtio, proxy };
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { adapt, bindValtio, proxy };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { proxy } from "valtio/vanilla";
|
|
2
|
+
export * from "valtio/vanilla";
|
|
3
3
|
|
|
4
|
+
//#region \0rolldown/runtime.js
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region packages/coaction-valtio/src/index.d.ts
|
|
4
7
|
interface BindValtio {
|
|
5
|
-
|
|
8
|
+
<T extends object>(target: T): T;
|
|
6
9
|
}
|
|
7
10
|
/**
|
|
8
11
|
* Bind a store to Valtio.
|
|
@@ -12,5 +15,8 @@ declare const bindValtio: BindValtio;
|
|
|
12
15
|
* Adapt a Valtio store type to state type.
|
|
13
16
|
*/
|
|
14
17
|
declare const adapt: <T extends object>(store: T) => T;
|
|
15
|
-
|
|
16
|
-
export { adapt, bindValtio };
|
|
18
|
+
declare namespace index_d_exports {
|
|
19
|
+
export { adapt, bindValtio, proxy };
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { adapt, bindValtio, proxy };
|
package/dist/index.js
CHANGED
|
@@ -1,85 +1,227 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#endregion
|
|
3
|
+
let mutability = require("mutability");
|
|
4
|
+
let coaction = require("coaction");
|
|
5
|
+
let valtio_vanilla = require("valtio/vanilla");
|
|
6
|
+
//#region packages/coaction-valtio/src/index.ts
|
|
7
|
+
const instancesMap = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
const getOwnEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
9
|
+
const isUnsafeKey = (key) => typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
|
|
10
|
+
const isArrayIndexKey = (key) => {
|
|
11
|
+
if (typeof key !== "string") return false;
|
|
12
|
+
const index = Number(key);
|
|
13
|
+
return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
|
|
9
14
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const isObjectRecord = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
16
|
+
const replaceMutableState = (rawState, mutableState, publicState, source) => {
|
|
17
|
+
const nextKeys = /* @__PURE__ */ new Set();
|
|
18
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
19
|
+
if (isUnsafeKey(key)) continue;
|
|
20
|
+
if (typeof source[key] === "function") continue;
|
|
21
|
+
nextKeys.add(key);
|
|
22
|
+
}
|
|
23
|
+
for (const key of getOwnEnumerableKeys(rawState)) {
|
|
24
|
+
if (isUnsafeKey(key)) {
|
|
25
|
+
delete rawState[key];
|
|
26
|
+
delete mutableState[key];
|
|
27
|
+
delete publicState[key];
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (typeof rawState[key] === "function") continue;
|
|
31
|
+
if (!nextKeys.has(key)) {
|
|
32
|
+
delete rawState[key];
|
|
33
|
+
delete mutableState[key];
|
|
34
|
+
delete publicState[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const rawSeen = /* @__PURE__ */ new WeakMap();
|
|
38
|
+
const mutableSeen = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
const publicSeen = /* @__PURE__ */ new WeakMap();
|
|
40
|
+
rawSeen.set(source, rawState);
|
|
41
|
+
mutableSeen.set(source, mutableState);
|
|
42
|
+
publicSeen.set(source, publicState);
|
|
43
|
+
nextKeys.forEach((key) => {
|
|
44
|
+
rawState[key] = (0, coaction.sanitizeReplacementState)(source[key], rawSeen);
|
|
45
|
+
mutableState[key] = (0, coaction.sanitizeReplacementState)(source[key], mutableSeen);
|
|
46
|
+
publicState[key] = (0, coaction.sanitizeReplacementState)(source[key], publicSeen);
|
|
47
|
+
});
|
|
17
48
|
};
|
|
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
|
-
|
|
49
|
+
const toSnapshot = (value, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
if (visited.has(value)) return visited.get(value);
|
|
52
|
+
const next = [];
|
|
53
|
+
next.length = value.length;
|
|
54
|
+
visited.set(value, next);
|
|
55
|
+
for (let index = 0; index < value.length; index += 1) if (Object.prototype.hasOwnProperty.call(value, index)) next[index] = toSnapshot(value[index], visited);
|
|
56
|
+
const source = value;
|
|
57
|
+
const target = next;
|
|
58
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
59
|
+
if (isArrayIndexKey(key) || isUnsafeKey(key)) continue;
|
|
60
|
+
const child = source[key];
|
|
61
|
+
if (typeof child !== "function") target[key] = toSnapshot(child, visited);
|
|
62
|
+
}
|
|
63
|
+
return next;
|
|
64
|
+
}
|
|
65
|
+
if (typeof value === "object" && value !== null) {
|
|
66
|
+
if (!isObjectRecord(value)) return value;
|
|
67
|
+
if (visited.has(value)) return visited.get(value);
|
|
68
|
+
const next = {};
|
|
69
|
+
visited.set(value, next);
|
|
70
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
71
|
+
if (isUnsafeKey(key)) continue;
|
|
72
|
+
const child = value[key];
|
|
73
|
+
if (typeof child !== "function") next[key] = toSnapshot(child, visited);
|
|
74
|
+
}
|
|
75
|
+
return next;
|
|
76
|
+
}
|
|
77
|
+
return value;
|
|
78
|
+
};
|
|
79
|
+
const snapshotPureState = (store) => toSnapshot(store.getPureState());
|
|
80
|
+
const isEqualSnapshot = (left, right, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
81
|
+
if (Object.is(left, right)) return true;
|
|
82
|
+
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
|
|
83
|
+
const leftIsArray = Array.isArray(left);
|
|
84
|
+
const rightIsArray = Array.isArray(right);
|
|
85
|
+
if (leftIsArray || rightIsArray) {
|
|
86
|
+
if (!leftIsArray || !rightIsArray || left.length !== right.length) return false;
|
|
87
|
+
} else if (!isObjectRecord(left) || !isObjectRecord(right)) return false;
|
|
88
|
+
let seenTargets = visited.get(left);
|
|
89
|
+
if (!seenTargets) {
|
|
90
|
+
seenTargets = /* @__PURE__ */ new WeakSet();
|
|
91
|
+
visited.set(left, seenTargets);
|
|
92
|
+
} else if (seenTargets.has(right)) return true;
|
|
93
|
+
seenTargets.add(right);
|
|
94
|
+
const leftRecord = left;
|
|
95
|
+
const rightRecord = right;
|
|
96
|
+
const leftKeys = getOwnEnumerableKeys(left);
|
|
97
|
+
const rightKeys = getOwnEnumerableKeys(right);
|
|
98
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
99
|
+
for (const key of leftKeys) {
|
|
100
|
+
if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;
|
|
101
|
+
if (!isEqualSnapshot(leftRecord[key], rightRecord[key], visited)) return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
};
|
|
105
|
+
const handleStore = (store, rawState, state, internal) => {
|
|
106
|
+
if (!internal.toMutableRaw) {
|
|
107
|
+
internal.toMutableRaw = (key) => instancesMap.get(key);
|
|
108
|
+
const getMutableState = () => internal.toMutableRaw?.(rawState) ?? rawState;
|
|
109
|
+
let isApplyingCoactionState = false;
|
|
110
|
+
let lastSnapshot;
|
|
111
|
+
const restoreClientState = (snapshot) => {
|
|
112
|
+
isApplyingCoactionState = true;
|
|
113
|
+
try {
|
|
114
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), snapshot);
|
|
115
|
+
} finally {
|
|
116
|
+
lastSnapshot = snapshotPureState(store);
|
|
117
|
+
isApplyingCoactionState = false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const syncSharedExternalChange = () => {
|
|
121
|
+
const currentSnapshot = snapshotPureState(store);
|
|
122
|
+
if (isApplyingCoactionState) {
|
|
123
|
+
lastSnapshot = currentSnapshot;
|
|
124
|
+
return "handled";
|
|
125
|
+
}
|
|
126
|
+
if (store.share === "client" && lastSnapshot) {
|
|
127
|
+
if (!isEqualSnapshot(currentSnapshot, lastSnapshot)) restoreClientState(lastSnapshot);
|
|
128
|
+
return "ignored";
|
|
129
|
+
}
|
|
130
|
+
if (store.share === "main" && lastSnapshot) {
|
|
131
|
+
const rootState = internal.rootState;
|
|
132
|
+
internal.rootState = lastSnapshot;
|
|
133
|
+
try {
|
|
134
|
+
(0, coaction.replaceExternalStoreState)(store, internal, currentSnapshot, { syncImmutable: false });
|
|
135
|
+
} finally {
|
|
136
|
+
internal.rootState = rootState;
|
|
137
|
+
}
|
|
138
|
+
lastSnapshot = currentSnapshot;
|
|
139
|
+
return "handled";
|
|
140
|
+
}
|
|
141
|
+
lastSnapshot = currentSnapshot;
|
|
142
|
+
return "external";
|
|
143
|
+
};
|
|
144
|
+
store._destroyers = /* @__PURE__ */ new Set();
|
|
145
|
+
store._listeners = /* @__PURE__ */ new Set();
|
|
146
|
+
let unsubscribeExternal;
|
|
147
|
+
const cancelReadySubscription = (0, coaction.onStoreReady)(store, () => {
|
|
148
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), (0, coaction.sanitizeInitialStateValue)(snapshotPureState(store)));
|
|
149
|
+
lastSnapshot = snapshotPureState(store);
|
|
150
|
+
unsubscribeExternal = (0, valtio_vanilla.subscribe)(getMutableState(), () => {
|
|
151
|
+
const change = syncSharedExternalChange();
|
|
152
|
+
if (change === "ignored") return;
|
|
153
|
+
if (change === "external") internal.notifyStateChange?.();
|
|
154
|
+
store._listeners?.forEach((listener) => listener());
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
Object.assign(store, { subscribe: (listener) => {
|
|
158
|
+
store._listeners.add(listener);
|
|
159
|
+
return () => {
|
|
160
|
+
store._listeners?.delete(listener);
|
|
161
|
+
};
|
|
162
|
+
} });
|
|
163
|
+
const baseDestroy = store.destroy;
|
|
164
|
+
let destroyed = false;
|
|
165
|
+
store.destroy = () => {
|
|
166
|
+
if (destroyed) return;
|
|
167
|
+
destroyed = true;
|
|
168
|
+
cancelReadySubscription();
|
|
169
|
+
unsubscribeExternal?.();
|
|
170
|
+
unsubscribeExternal = void 0;
|
|
171
|
+
store._listeners?.clear();
|
|
172
|
+
store._listeners = void 0;
|
|
173
|
+
store._destroyers?.forEach((destroy) => destroy());
|
|
174
|
+
store._destroyers?.clear();
|
|
175
|
+
store._destroyers = void 0;
|
|
176
|
+
baseDestroy();
|
|
177
|
+
};
|
|
178
|
+
store.apply = (state = store.getState(), patches) => {
|
|
179
|
+
isApplyingCoactionState = true;
|
|
180
|
+
try {
|
|
181
|
+
if (!patches) {
|
|
182
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), state);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
(0, mutability.apply)(state, patches);
|
|
186
|
+
} finally {
|
|
187
|
+
lastSnapshot = snapshotPureState(store);
|
|
188
|
+
isApplyingCoactionState = false;
|
|
189
|
+
internal.notifyStateChange?.();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
57
193
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Bind a store to Valtio.
|
|
196
|
+
*/
|
|
197
|
+
const bindValtio = (0, coaction.createBinder)({
|
|
198
|
+
handleStore,
|
|
199
|
+
handleState: (options) => {
|
|
200
|
+
const descriptors = Object.getOwnPropertyDescriptors(options);
|
|
201
|
+
const copyState = Object.defineProperties({}, descriptors);
|
|
202
|
+
const rawState = Object.defineProperties({}, descriptors);
|
|
203
|
+
return {
|
|
204
|
+
copyState,
|
|
205
|
+
bind: (state) => {
|
|
206
|
+
instancesMap.set(rawState, state);
|
|
207
|
+
return rawState;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
75
211
|
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Adapt a Valtio store type to state type.
|
|
214
|
+
*/
|
|
215
|
+
const adapt = (store) => store;
|
|
216
|
+
//#endregion
|
|
217
|
+
exports.adapt = adapt;
|
|
218
|
+
exports.bindValtio = bindValtio;
|
|
219
|
+
exports.proxy = valtio_vanilla.proxy;
|
|
220
|
+
Object.keys(valtio_vanilla).forEach(function(k) {
|
|
221
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
222
|
+
enumerable: true,
|
|
223
|
+
get: function() {
|
|
224
|
+
return valtio_vanilla[k];
|
|
225
|
+
}
|
|
226
|
+
});
|
|
85
227
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,82 +1,217 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
|
-
|
|
19
|
-
// index.ts
|
|
20
|
-
var index_exports = {};
|
|
21
|
-
__export(index_exports, {
|
|
22
|
-
adapt: () => adapt,
|
|
23
|
-
bindValtio: () => bindValtio,
|
|
24
|
-
proxy: () => proxy
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// src/index.ts
|
|
28
|
-
var src_exports = {};
|
|
29
|
-
__export(src_exports, {
|
|
30
|
-
adapt: () => adapt,
|
|
31
|
-
bindValtio: () => bindValtio,
|
|
32
|
-
proxy: () => proxy
|
|
33
|
-
});
|
|
34
|
-
__reExport(src_exports, vanilla_star);
|
|
35
1
|
import { apply } from "mutability";
|
|
36
|
-
import { createBinder } from "coaction";
|
|
2
|
+
import { createBinder, onStoreReady, replaceExternalStoreState, sanitizeInitialStateValue, sanitizeReplacementState } from "coaction";
|
|
37
3
|
import { proxy, subscribe } from "valtio/vanilla";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (!patches) {
|
|
49
|
-
Object.assign(store.getState(), state2);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
apply(state2, patches);
|
|
53
|
-
};
|
|
54
|
-
}
|
|
4
|
+
export * from "valtio/vanilla";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region packages/coaction-valtio/src/index.ts
|
|
7
|
+
const instancesMap = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
const getOwnEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
9
|
+
const isUnsafeKey = (key) => typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
|
|
10
|
+
const isArrayIndexKey = (key) => {
|
|
11
|
+
if (typeof key !== "string") return false;
|
|
12
|
+
const index = Number(key);
|
|
13
|
+
return Number.isInteger(index) && index >= 0 && index < 2 ** 32 - 1 && String(index) === key;
|
|
55
14
|
};
|
|
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
|
-
|
|
15
|
+
const isObjectRecord = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
16
|
+
const replaceMutableState = (rawState, mutableState, publicState, source) => {
|
|
17
|
+
const nextKeys = /* @__PURE__ */ new Set();
|
|
18
|
+
for (const key of getOwnEnumerableKeys(source)) {
|
|
19
|
+
if (isUnsafeKey(key)) continue;
|
|
20
|
+
if (typeof source[key] === "function") continue;
|
|
21
|
+
nextKeys.add(key);
|
|
22
|
+
}
|
|
23
|
+
for (const key of getOwnEnumerableKeys(rawState)) {
|
|
24
|
+
if (isUnsafeKey(key)) {
|
|
25
|
+
delete rawState[key];
|
|
26
|
+
delete mutableState[key];
|
|
27
|
+
delete publicState[key];
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (typeof rawState[key] === "function") continue;
|
|
31
|
+
if (!nextKeys.has(key)) {
|
|
32
|
+
delete rawState[key];
|
|
33
|
+
delete mutableState[key];
|
|
34
|
+
delete publicState[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const rawSeen = /* @__PURE__ */ new WeakMap();
|
|
38
|
+
const mutableSeen = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
const publicSeen = /* @__PURE__ */ new WeakMap();
|
|
40
|
+
rawSeen.set(source, rawState);
|
|
41
|
+
mutableSeen.set(source, mutableState);
|
|
42
|
+
publicSeen.set(source, publicState);
|
|
43
|
+
nextKeys.forEach((key) => {
|
|
44
|
+
rawState[key] = sanitizeReplacementState(source[key], rawSeen);
|
|
45
|
+
mutableState[key] = sanitizeReplacementState(source[key], mutableSeen);
|
|
46
|
+
publicState[key] = sanitizeReplacementState(source[key], publicSeen);
|
|
47
|
+
});
|
|
82
48
|
};
|
|
49
|
+
const toSnapshot = (value, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
if (visited.has(value)) return visited.get(value);
|
|
52
|
+
const next = [];
|
|
53
|
+
next.length = value.length;
|
|
54
|
+
visited.set(value, next);
|
|
55
|
+
for (let index = 0; index < value.length; index += 1) if (Object.prototype.hasOwnProperty.call(value, index)) next[index] = toSnapshot(value[index], visited);
|
|
56
|
+
const source = value;
|
|
57
|
+
const target = next;
|
|
58
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
59
|
+
if (isArrayIndexKey(key) || isUnsafeKey(key)) continue;
|
|
60
|
+
const child = source[key];
|
|
61
|
+
if (typeof child !== "function") target[key] = toSnapshot(child, visited);
|
|
62
|
+
}
|
|
63
|
+
return next;
|
|
64
|
+
}
|
|
65
|
+
if (typeof value === "object" && value !== null) {
|
|
66
|
+
if (!isObjectRecord(value)) return value;
|
|
67
|
+
if (visited.has(value)) return visited.get(value);
|
|
68
|
+
const next = {};
|
|
69
|
+
visited.set(value, next);
|
|
70
|
+
for (const key of getOwnEnumerableKeys(value)) {
|
|
71
|
+
if (isUnsafeKey(key)) continue;
|
|
72
|
+
const child = value[key];
|
|
73
|
+
if (typeof child !== "function") next[key] = toSnapshot(child, visited);
|
|
74
|
+
}
|
|
75
|
+
return next;
|
|
76
|
+
}
|
|
77
|
+
return value;
|
|
78
|
+
};
|
|
79
|
+
const snapshotPureState = (store) => toSnapshot(store.getPureState());
|
|
80
|
+
const isEqualSnapshot = (left, right, visited = /* @__PURE__ */ new WeakMap()) => {
|
|
81
|
+
if (Object.is(left, right)) return true;
|
|
82
|
+
if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
|
|
83
|
+
const leftIsArray = Array.isArray(left);
|
|
84
|
+
const rightIsArray = Array.isArray(right);
|
|
85
|
+
if (leftIsArray || rightIsArray) {
|
|
86
|
+
if (!leftIsArray || !rightIsArray || left.length !== right.length) return false;
|
|
87
|
+
} else if (!isObjectRecord(left) || !isObjectRecord(right)) return false;
|
|
88
|
+
let seenTargets = visited.get(left);
|
|
89
|
+
if (!seenTargets) {
|
|
90
|
+
seenTargets = /* @__PURE__ */ new WeakSet();
|
|
91
|
+
visited.set(left, seenTargets);
|
|
92
|
+
} else if (seenTargets.has(right)) return true;
|
|
93
|
+
seenTargets.add(right);
|
|
94
|
+
const leftRecord = left;
|
|
95
|
+
const rightRecord = right;
|
|
96
|
+
const leftKeys = getOwnEnumerableKeys(left);
|
|
97
|
+
const rightKeys = getOwnEnumerableKeys(right);
|
|
98
|
+
if (leftKeys.length !== rightKeys.length) return false;
|
|
99
|
+
for (const key of leftKeys) {
|
|
100
|
+
if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;
|
|
101
|
+
if (!isEqualSnapshot(leftRecord[key], rightRecord[key], visited)) return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
};
|
|
105
|
+
const handleStore = (store, rawState, state, internal) => {
|
|
106
|
+
if (!internal.toMutableRaw) {
|
|
107
|
+
internal.toMutableRaw = (key) => instancesMap.get(key);
|
|
108
|
+
const getMutableState = () => internal.toMutableRaw?.(rawState) ?? rawState;
|
|
109
|
+
let isApplyingCoactionState = false;
|
|
110
|
+
let lastSnapshot;
|
|
111
|
+
const restoreClientState = (snapshot) => {
|
|
112
|
+
isApplyingCoactionState = true;
|
|
113
|
+
try {
|
|
114
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), snapshot);
|
|
115
|
+
} finally {
|
|
116
|
+
lastSnapshot = snapshotPureState(store);
|
|
117
|
+
isApplyingCoactionState = false;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const syncSharedExternalChange = () => {
|
|
121
|
+
const currentSnapshot = snapshotPureState(store);
|
|
122
|
+
if (isApplyingCoactionState) {
|
|
123
|
+
lastSnapshot = currentSnapshot;
|
|
124
|
+
return "handled";
|
|
125
|
+
}
|
|
126
|
+
if (store.share === "client" && lastSnapshot) {
|
|
127
|
+
if (!isEqualSnapshot(currentSnapshot, lastSnapshot)) restoreClientState(lastSnapshot);
|
|
128
|
+
return "ignored";
|
|
129
|
+
}
|
|
130
|
+
if (store.share === "main" && lastSnapshot) {
|
|
131
|
+
const rootState = internal.rootState;
|
|
132
|
+
internal.rootState = lastSnapshot;
|
|
133
|
+
try {
|
|
134
|
+
replaceExternalStoreState(store, internal, currentSnapshot, { syncImmutable: false });
|
|
135
|
+
} finally {
|
|
136
|
+
internal.rootState = rootState;
|
|
137
|
+
}
|
|
138
|
+
lastSnapshot = currentSnapshot;
|
|
139
|
+
return "handled";
|
|
140
|
+
}
|
|
141
|
+
lastSnapshot = currentSnapshot;
|
|
142
|
+
return "external";
|
|
143
|
+
};
|
|
144
|
+
store._destroyers = /* @__PURE__ */ new Set();
|
|
145
|
+
store._listeners = /* @__PURE__ */ new Set();
|
|
146
|
+
let unsubscribeExternal;
|
|
147
|
+
const cancelReadySubscription = onStoreReady(store, () => {
|
|
148
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), sanitizeInitialStateValue(snapshotPureState(store)));
|
|
149
|
+
lastSnapshot = snapshotPureState(store);
|
|
150
|
+
unsubscribeExternal = subscribe(getMutableState(), () => {
|
|
151
|
+
const change = syncSharedExternalChange();
|
|
152
|
+
if (change === "ignored") return;
|
|
153
|
+
if (change === "external") internal.notifyStateChange?.();
|
|
154
|
+
store._listeners?.forEach((listener) => listener());
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
Object.assign(store, { subscribe: (listener) => {
|
|
158
|
+
store._listeners.add(listener);
|
|
159
|
+
return () => {
|
|
160
|
+
store._listeners?.delete(listener);
|
|
161
|
+
};
|
|
162
|
+
} });
|
|
163
|
+
const baseDestroy = store.destroy;
|
|
164
|
+
let destroyed = false;
|
|
165
|
+
store.destroy = () => {
|
|
166
|
+
if (destroyed) return;
|
|
167
|
+
destroyed = true;
|
|
168
|
+
cancelReadySubscription();
|
|
169
|
+
unsubscribeExternal?.();
|
|
170
|
+
unsubscribeExternal = void 0;
|
|
171
|
+
store._listeners?.clear();
|
|
172
|
+
store._listeners = void 0;
|
|
173
|
+
store._destroyers?.forEach((destroy) => destroy());
|
|
174
|
+
store._destroyers?.clear();
|
|
175
|
+
store._destroyers = void 0;
|
|
176
|
+
baseDestroy();
|
|
177
|
+
};
|
|
178
|
+
store.apply = (state = store.getState(), patches) => {
|
|
179
|
+
isApplyingCoactionState = true;
|
|
180
|
+
try {
|
|
181
|
+
if (!patches) {
|
|
182
|
+
replaceMutableState(internal.rootState ?? rawState, getMutableState(), store.getState(), state);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
apply(state, patches);
|
|
186
|
+
} finally {
|
|
187
|
+
lastSnapshot = snapshotPureState(store);
|
|
188
|
+
isApplyingCoactionState = false;
|
|
189
|
+
internal.notifyStateChange?.();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Bind a store to Valtio.
|
|
196
|
+
*/
|
|
197
|
+
const bindValtio = createBinder({
|
|
198
|
+
handleStore,
|
|
199
|
+
handleState: (options) => {
|
|
200
|
+
const descriptors = Object.getOwnPropertyDescriptors(options);
|
|
201
|
+
const copyState = Object.defineProperties({}, descriptors);
|
|
202
|
+
const rawState = Object.defineProperties({}, descriptors);
|
|
203
|
+
return {
|
|
204
|
+
copyState,
|
|
205
|
+
bind: (state) => {
|
|
206
|
+
instancesMap.set(rawState, state);
|
|
207
|
+
return rawState;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
/**
|
|
213
|
+
* Adapt a Valtio store type to state type.
|
|
214
|
+
*/
|
|
215
|
+
const adapt = (store) => store;
|
|
216
|
+
//#endregion
|
|
217
|
+
export { adapt, bindValtio, proxy };
|
package/package.json
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coaction/valtio",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A Coaction integration tool for Valtio",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"state",
|
|
7
6
|
"coaction",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
"authors": [
|
|
12
|
-
"Michael Lin <unadlib@gmail.com> (https://github.com/unadlib)"
|
|
7
|
+
"proxy",
|
|
8
|
+
"state",
|
|
9
|
+
"valtio"
|
|
13
10
|
],
|
|
14
|
-
"homepage": "https://github.com/
|
|
11
|
+
"homepage": "https://github.com/coactionjs/coaction/tree/main/packages/coaction-valtio#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/coactionjs/coaction/issues"
|
|
14
|
+
},
|
|
15
15
|
"license": "MIT",
|
|
16
|
+
"author": "unadlib",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/coactionjs/coaction.git",
|
|
20
|
+
"directory": "packages/coaction-valtio"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": false,
|
|
16
26
|
"main": "dist/index.js",
|
|
17
27
|
"module": "dist/index.mjs",
|
|
28
|
+
"types": "dist/index.d.ts",
|
|
18
29
|
"exports": {
|
|
19
30
|
".": {
|
|
20
31
|
"types": "./dist/index.d.ts",
|
|
@@ -24,52 +35,29 @@
|
|
|
24
35
|
},
|
|
25
36
|
"./package.json": "./package.json"
|
|
26
37
|
},
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"dist"
|
|
31
|
-
],
|
|
32
|
-
"repository": {
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "https://github.com/unadlib/coaction.git",
|
|
35
|
-
"directory": "packages/coaction-valtio"
|
|
36
|
-
},
|
|
37
|
-
"bugs": {
|
|
38
|
-
"url": "https://github.com/unadlib/coaction/issues"
|
|
39
|
-
},
|
|
40
|
-
"peerDependencies": {
|
|
41
|
-
"coaction": "^1.4.1",
|
|
42
|
-
"mutative": "^1.1.0",
|
|
43
|
-
"valtio": "^2.0.0"
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public",
|
|
40
|
+
"provenance": true
|
|
44
41
|
},
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"optional": true
|
|
48
|
-
},
|
|
49
|
-
"mutative": {
|
|
50
|
-
"optional": true
|
|
51
|
-
},
|
|
52
|
-
"valtio": {
|
|
53
|
-
"optional": true
|
|
54
|
-
}
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"mutability": "^1.2.1"
|
|
55
44
|
},
|
|
56
45
|
"devDependencies": {
|
|
57
46
|
"mutative": "^1.3.0",
|
|
58
47
|
"valtio": "^2.3.1",
|
|
59
|
-
"coaction": "
|
|
48
|
+
"coaction": "2.0.0"
|
|
60
49
|
},
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
"publishConfig": {
|
|
65
|
-
"access": "public",
|
|
66
|
-
"provenance": true
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"coaction": "^2.0.0",
|
|
52
|
+
"valtio": "^2.0.0"
|
|
67
53
|
},
|
|
68
|
-
"
|
|
54
|
+
"authors": [
|
|
55
|
+
"Michael Lin <unadlib@gmail.com> (https://github.com/unadlib)"
|
|
56
|
+
],
|
|
69
57
|
"scripts": {
|
|
70
58
|
"clean": "rm -rf dist",
|
|
71
59
|
"test": "vitest run test",
|
|
72
|
-
"build": "
|
|
73
|
-
"dev": "
|
|
60
|
+
"build": "node ../../scripts/build-package.mjs",
|
|
61
|
+
"dev": "node ../../scripts/build-package.mjs --watch"
|
|
74
62
|
}
|
|
75
63
|
}
|