Match-id-efec6baa7c4396c9a4dfb7bb733134ca50f5ff34

This commit is contained in:
* 2022-11-12 02:03:04 +08:00
parent f6c6e0db43
commit 5be06f0683
4 changed files with 116 additions and 2 deletions

View File

@ -39,7 +39,7 @@ export const helper = {
return { name: HookName.RefHook, hIndex, value: (state as Ref<any>).current }; return { name: HookName.RefHook, hIndex, value: (state as Ref<any>).current };
} else if (isEffectHook(state)) { } else if (isEffectHook(state)) {
const name = const name =
state.effectConstant == EffectConstant.LayoutEffect || (EffectConstant.LayoutEffect | EffectConstant.DepsChange) state.effectConstant == EffectConstant.LayoutEffect || EffectConstant.LayoutEffect | EffectConstant.DepsChange
? HookName.LayoutEffectHook ? HookName.LayoutEffectHook
: HookName.EffectHook; : HookName.EffectHook;
return { name, hIndex, value: (state as Effect).effect }; return { name, hIndex, value: (state as Effect).effect };

View File

@ -0,0 +1,8 @@
export const INITIALIZED = 'horizonx store initialized';
export const STATE_CHANGE = 'horizonx state change';
export const SUBSCRIBED = 'horizonx subscribed';
export const UNSUBSCRIBED = 'horizonx unsubscribed';
export const ACTION = 'horizonx action';
export const ACTION_QUEUED = 'horizonx action queued';
export const QUEUE_PENDING = 'horizonx queue pending';
export const QUEUE_FINISHED = 'horizonx queue finished';

View File

@ -0,0 +1,51 @@
const sessionId = Date.now();
function makeStoreSnapshot({ type, data }) {
const expanded = {};
Object.keys(data.store.$c).forEach(key => {
expanded[key] = data.store[key];
});
data.store.expanded = expanded;
const snapshot = makeProxySnapshot({
data,
type,
sessionId,
});
return snapshot;
}
function makeProxySnapshot(obj) {
let clone;
try {
if (!obj) {
return obj;
}
if (obj.nativeEvent) return obj.type + 'Event';
if (typeof obj === 'function') {
return obj.toString();
}
if (Array.isArray(obj)) {
clone = [];
obj.forEach(item => clone.push(makeProxySnapshot(item)));
return clone;
} else if (typeof obj === 'object') {
clone = {};
Object.entries(obj).forEach(([id, value]) => (clone[id] = makeProxySnapshot(value)));
return clone;
}
return obj;
} catch (err) {
throw console.log('cannot serialize object. ' + err);
}
}
export const devtools = {
emit: (type, data) => {
console.log('store snapshot:', makeStoreSnapshot({ type, data }));
window.postMessage({
type: 'HORIZON_DEV_TOOLS',
payload: makeStoreSnapshot({ type, data }),
from: 'dev tool hook',
});
},
};

View File

@ -6,6 +6,23 @@ import readonlyProxy from '../proxy/readonlyProxy';
import { Observer } from '../proxy/Observer'; import { Observer } from '../proxy/Observer';
import { FunctionComponent, ClassComponent } from '../Constants'; import { FunctionComponent, ClassComponent } from '../Constants';
import { VNode } from '../../renderer/Types'; import { VNode } from '../../renderer/Types';
import { devtools } from '../devtools';
import {
ACTION,
ACTION_QUEUED,
INITIALIZED,
QUEUE_FINISHED,
STATE_CHANGE,
SUBSCRIBED,
UNSUBSCRIBED,
} from '../devtools/constants';
const idGenerator = {
id: 0,
get: function (prefix) {
return prefix.toString() + this.id++;
},
};
const storeMap = new Map<string, StoreHandler<any, any, any>>(); const storeMap = new Map<string, StoreHandler<any, any, any>>();
@ -73,7 +90,7 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
): () => StoreHandler<S, A, C> { ): () => StoreHandler<S, A, C> {
//create a local shalow copy to ensure consistency (if user would change the config object after store creation) //create a local shalow copy to ensure consistency (if user would change the config object after store creation)
config = { config = {
id: config.id, id: config.id || idGenerator.get('UNKNOWN_STORE_'),
/* @ts-ignore*/ /* @ts-ignore*/
options: config.options, options: config.options,
state: config.state, state: config.state,
@ -92,10 +109,12 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
proxyObj.$pending = false; proxyObj.$pending = false;
const $subscribe = listener => { const $subscribe = listener => {
devtools.emit(SUBSCRIBED, { store: handler, listener });
proxyObj.addListener(listener); proxyObj.addListener(listener);
}; };
const $unsubscribe = listener => { const $unsubscribe = listener => {
devtools.emit(UNSUBSCRIBED, handler);
proxyObj.removeListener(listener); proxyObj.removeListener(listener);
}; };
@ -115,11 +134,13 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
function tryNextAction() { function tryNextAction() {
if (!plannedActions.length) { if (!plannedActions.length) {
devtools.emit(QUEUE_FINISHED, { store: handler });
proxyObj.$pending = false; proxyObj.$pending = false;
return; return;
} }
const nextAction = plannedActions.shift()!; const nextAction = plannedActions.shift()!;
devtools.emit(ACTION, { store: handler, action: nextAction, fromQueue: true });
const result = config.actions const result = config.actions
? config.actions[nextAction.action].bind(handler, proxyObj)(...nextAction.payload) ? config.actions[nextAction.action].bind(handler, proxyObj)(...nextAction.payload)
: undefined; : undefined;
@ -139,6 +160,14 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
if (config.actions) { if (config.actions) {
Object.keys(config.actions).forEach(action => { Object.keys(config.actions).forEach(action => {
($queue as any)[action] = (...payload) => { ($queue as any)[action] = (...payload) => {
devtools.emit(ACTION_QUEUED, {
store: handler,
action: {
action,
payload,
},
fromQueue: true,
});
return new Promise(resolve => { return new Promise(resolve => {
if (!proxyObj.$pending) { if (!proxyObj.$pending) {
proxyObj.$pending = true; proxyObj.$pending = true;
@ -164,6 +193,14 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
}; };
($a as any)[action] = function Wrapped(...payload) { ($a as any)[action] = function Wrapped(...payload) {
devtools.emit(ACTION, {
store: handler,
action: {
action,
payload,
},
fromQueue: false,
});
return config.actions![action].bind(handler, proxyObj)(...payload); return config.actions![action].bind(handler, proxyObj)(...payload);
}; };
@ -171,6 +208,14 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
Object.defineProperty(handler, action, { Object.defineProperty(handler, action, {
writable: false, writable: false,
value: (...payload) => { value: (...payload) => {
devtools.emit(ACTION, {
store: handler,
action: {
action,
payload,
},
fromQueue: false,
});
return config.actions![action].bind(handler, proxyObj)(...payload); return config.actions![action].bind(handler, proxyObj)(...payload);
}, },
}); });
@ -204,6 +249,16 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
storeMap.set(config.id, handler); storeMap.set(config.id, handler);
} }
devtools.emit(INITIALIZED, {
store: handler,
});
handler.$subscribe(() => {
devtools.emit(STATE_CHANGE, {
store: handler,
});
});
return createStoreHook(handler); return createStoreHook(handler);
} }