@yiin/reactive-proxy-state 1.0.35 → 1.0.37
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/index.cjs +60 -34
- package/dist/index.js +60 -34
- package/dist/integrations/vue3.d.ts +17 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4030,7 +4030,7 @@ function markRaw(obj) {
|
|
|
4030
4030
|
var import_vue = require("vue");
|
|
4031
4031
|
var import_reactivity = __toESM(require_reactivity_cjs(), 1);
|
|
4032
4032
|
function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
4033
|
-
const { emitInitialReplace = true } = options;
|
|
4033
|
+
const { emitInitialReplace = true, onDiffError } = options;
|
|
4034
4034
|
if (emitInitialReplace) {
|
|
4035
4035
|
try {
|
|
4036
4036
|
emit({ action: "replace", path: [], newValue: deepClone(vueState) });
|
|
@@ -4039,6 +4039,7 @@ function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
|
4039
4039
|
const prev = {};
|
|
4040
4040
|
const pathStack = [];
|
|
4041
4041
|
const keyStops = new Map;
|
|
4042
|
+
let rootStop = null;
|
|
4042
4043
|
for (const k of Object.keys(vueState)) {
|
|
4043
4044
|
prev[k] = deepClone(vueState[k]);
|
|
4044
4045
|
}
|
|
@@ -4054,50 +4055,75 @@ function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
|
4054
4055
|
prev[k] = result;
|
|
4055
4056
|
}
|
|
4056
4057
|
} catch (e) {
|
|
4057
|
-
|
|
4058
|
+
const errorPath = pathStack.slice();
|
|
4058
4059
|
pathStack.length = 0;
|
|
4059
4060
|
prev[k] = deepClone(vueState[k]);
|
|
4061
|
+
if (onDiffError) {
|
|
4062
|
+
onDiffError({ key: k, path: errorPath, error: e });
|
|
4063
|
+
}
|
|
4060
4064
|
return;
|
|
4061
4065
|
}
|
|
4062
4066
|
pathStack.pop();
|
|
4063
4067
|
}, { flush: "sync" });
|
|
4064
4068
|
keyStops.set(k, stop);
|
|
4065
4069
|
}
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4070
|
+
function createRootEffect() {
|
|
4071
|
+
rootStop = import_vue.watchEffect(() => {
|
|
4072
|
+
const currKeys = Object.keys(vueState);
|
|
4073
|
+
const currKeySet = new Set(currKeys);
|
|
4074
|
+
const prevKeySet = new Set(Object.keys(prev));
|
|
4075
|
+
for (const k of currKeys) {
|
|
4076
|
+
if (!prevKeySet.has(k)) {
|
|
4077
|
+
import_reactivity.pauseTracking();
|
|
4078
|
+
const cloned = deepClone(vueState[k]);
|
|
4079
|
+
import_reactivity.resetTracking();
|
|
4080
|
+
pathStack.push(k);
|
|
4081
|
+
emit({ action: "set", path: pathStack.slice(), newValue: cloned });
|
|
4082
|
+
pathStack.pop();
|
|
4083
|
+
prev[k] = cloned;
|
|
4084
|
+
createKeyEffect(k);
|
|
4085
|
+
}
|
|
4086
|
+
}
|
|
4087
|
+
for (const k of prevKeySet) {
|
|
4088
|
+
if (!currKeySet.has(k)) {
|
|
4089
|
+
pathStack.push(k);
|
|
4090
|
+
emit({ action: "delete", path: pathStack.slice(), oldValue: prev[k] });
|
|
4091
|
+
pathStack.pop();
|
|
4092
|
+
delete prev[k];
|
|
4093
|
+
keyStops.get(k)?.();
|
|
4094
|
+
keyStops.delete(k);
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
}, { flush: "sync" });
|
|
4098
|
+
}
|
|
4099
|
+
function stopAll() {
|
|
4100
|
+
rootStop?.();
|
|
4101
|
+
rootStop = null;
|
|
4098
4102
|
for (const stop of keyStops.values())
|
|
4099
4103
|
stop();
|
|
4100
4104
|
keyStops.clear();
|
|
4105
|
+
}
|
|
4106
|
+
function startAll() {
|
|
4107
|
+
for (const k of Object.keys(prev)) {
|
|
4108
|
+
createKeyEffect(k);
|
|
4109
|
+
}
|
|
4110
|
+
createRootEffect();
|
|
4111
|
+
}
|
|
4112
|
+
startAll();
|
|
4113
|
+
return {
|
|
4114
|
+
stop: stopAll,
|
|
4115
|
+
pause: stopAll,
|
|
4116
|
+
resume() {
|
|
4117
|
+
const currentKeys = new Set(Object.keys(vueState));
|
|
4118
|
+
for (const k of Object.keys(prev)) {
|
|
4119
|
+
if (!currentKeys.has(k))
|
|
4120
|
+
delete prev[k];
|
|
4121
|
+
}
|
|
4122
|
+
for (const k of currentKeys) {
|
|
4123
|
+
prev[k] = deepClone(vueState[k]);
|
|
4124
|
+
}
|
|
4125
|
+
startAll();
|
|
4126
|
+
}
|
|
4101
4127
|
};
|
|
4102
4128
|
}
|
|
4103
4129
|
function typeTag(v) {
|
package/dist/index.js
CHANGED
|
@@ -3970,7 +3970,7 @@ function markRaw(obj) {
|
|
|
3970
3970
|
var import_reactivity = __toESM(require_reactivity_cjs(), 1);
|
|
3971
3971
|
import { watchEffect as watchEffect2 } from "vue";
|
|
3972
3972
|
function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
3973
|
-
const { emitInitialReplace = true } = options;
|
|
3973
|
+
const { emitInitialReplace = true, onDiffError } = options;
|
|
3974
3974
|
if (emitInitialReplace) {
|
|
3975
3975
|
try {
|
|
3976
3976
|
emit({ action: "replace", path: [], newValue: deepClone(vueState) });
|
|
@@ -3979,6 +3979,7 @@ function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
|
3979
3979
|
const prev = {};
|
|
3980
3980
|
const pathStack = [];
|
|
3981
3981
|
const keyStops = new Map;
|
|
3982
|
+
let rootStop = null;
|
|
3982
3983
|
for (const k of Object.keys(vueState)) {
|
|
3983
3984
|
prev[k] = deepClone(vueState[k]);
|
|
3984
3985
|
}
|
|
@@ -3994,50 +3995,75 @@ function trackVueReactiveEvents(vueState, emit, options = {}) {
|
|
|
3994
3995
|
prev[k] = result;
|
|
3995
3996
|
}
|
|
3996
3997
|
} catch (e) {
|
|
3997
|
-
|
|
3998
|
+
const errorPath = pathStack.slice();
|
|
3998
3999
|
pathStack.length = 0;
|
|
3999
4000
|
prev[k] = deepClone(vueState[k]);
|
|
4001
|
+
if (onDiffError) {
|
|
4002
|
+
onDiffError({ key: k, path: errorPath, error: e });
|
|
4003
|
+
}
|
|
4000
4004
|
return;
|
|
4001
4005
|
}
|
|
4002
4006
|
pathStack.pop();
|
|
4003
4007
|
}, { flush: "sync" });
|
|
4004
4008
|
keyStops.set(k, stop);
|
|
4005
4009
|
}
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4010
|
+
function createRootEffect() {
|
|
4011
|
+
rootStop = watchEffect2(() => {
|
|
4012
|
+
const currKeys = Object.keys(vueState);
|
|
4013
|
+
const currKeySet = new Set(currKeys);
|
|
4014
|
+
const prevKeySet = new Set(Object.keys(prev));
|
|
4015
|
+
for (const k of currKeys) {
|
|
4016
|
+
if (!prevKeySet.has(k)) {
|
|
4017
|
+
import_reactivity.pauseTracking();
|
|
4018
|
+
const cloned = deepClone(vueState[k]);
|
|
4019
|
+
import_reactivity.resetTracking();
|
|
4020
|
+
pathStack.push(k);
|
|
4021
|
+
emit({ action: "set", path: pathStack.slice(), newValue: cloned });
|
|
4022
|
+
pathStack.pop();
|
|
4023
|
+
prev[k] = cloned;
|
|
4024
|
+
createKeyEffect(k);
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
for (const k of prevKeySet) {
|
|
4028
|
+
if (!currKeySet.has(k)) {
|
|
4029
|
+
pathStack.push(k);
|
|
4030
|
+
emit({ action: "delete", path: pathStack.slice(), oldValue: prev[k] });
|
|
4031
|
+
pathStack.pop();
|
|
4032
|
+
delete prev[k];
|
|
4033
|
+
keyStops.get(k)?.();
|
|
4034
|
+
keyStops.delete(k);
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
}, { flush: "sync" });
|
|
4038
|
+
}
|
|
4039
|
+
function stopAll() {
|
|
4040
|
+
rootStop?.();
|
|
4041
|
+
rootStop = null;
|
|
4038
4042
|
for (const stop of keyStops.values())
|
|
4039
4043
|
stop();
|
|
4040
4044
|
keyStops.clear();
|
|
4045
|
+
}
|
|
4046
|
+
function startAll() {
|
|
4047
|
+
for (const k of Object.keys(prev)) {
|
|
4048
|
+
createKeyEffect(k);
|
|
4049
|
+
}
|
|
4050
|
+
createRootEffect();
|
|
4051
|
+
}
|
|
4052
|
+
startAll();
|
|
4053
|
+
return {
|
|
4054
|
+
stop: stopAll,
|
|
4055
|
+
pause: stopAll,
|
|
4056
|
+
resume() {
|
|
4057
|
+
const currentKeys = new Set(Object.keys(vueState));
|
|
4058
|
+
for (const k of Object.keys(prev)) {
|
|
4059
|
+
if (!currentKeys.has(k))
|
|
4060
|
+
delete prev[k];
|
|
4061
|
+
}
|
|
4062
|
+
for (const k of currentKeys) {
|
|
4063
|
+
prev[k] = deepClone(vueState[k]);
|
|
4064
|
+
}
|
|
4065
|
+
startAll();
|
|
4066
|
+
}
|
|
4041
4067
|
};
|
|
4042
4068
|
}
|
|
4043
4069
|
function typeTag(v) {
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { StateEvent } from "../types";
|
|
2
|
+
export type DiffErrorContext = {
|
|
3
|
+
key: string;
|
|
4
|
+
path: (string | number | symbol)[];
|
|
5
|
+
error: unknown;
|
|
6
|
+
};
|
|
2
7
|
export type TrackVueReactiveEventsOptions = {
|
|
3
8
|
emitInitialReplace?: boolean;
|
|
9
|
+
onDiffError?: (ctx: DiffErrorContext) => void;
|
|
10
|
+
};
|
|
11
|
+
export type VueTrackingControl = {
|
|
12
|
+
/** Stop all effects permanently. */
|
|
13
|
+
stop: () => void;
|
|
14
|
+
/** Stop all effects temporarily. No diffing overhead while paused. */
|
|
15
|
+
pause: () => void;
|
|
16
|
+
/** Rebuild snapshots from current state and re-create effects. */
|
|
17
|
+
resume: () => void;
|
|
4
18
|
};
|
|
5
19
|
/**
|
|
6
20
|
* Observe a Vue 3 reactive object and emit RPS-compatible StateEvents
|
|
@@ -10,6 +24,7 @@ export type TrackVueReactiveEventsOptions = {
|
|
|
10
24
|
* only the affected subtree is diffed on mutation. A root structural effect
|
|
11
25
|
* tracks Object.keys() for key add/delete at the top level.
|
|
12
26
|
*
|
|
13
|
-
* Returns a
|
|
27
|
+
* Returns a control object with stop/pause/resume. Use pause/resume to
|
|
28
|
+
* suppress diffing while applying external mutations (e.g. server events).
|
|
14
29
|
*/
|
|
15
|
-
export declare function trackVueReactiveEvents<T extends object>(vueState: T, emit: (event: StateEvent) => void, options?: TrackVueReactiveEventsOptions):
|
|
30
|
+
export declare function trackVueReactiveEvents<T extends object>(vueState: T, emit: (event: StateEvent) => void, options?: TrackVueReactiveEventsOptions): VueTrackingControl;
|