overmind-vue
Version:
Functional actions
117 lines • 4.54 kB
JavaScript
import { ENVIRONMENT, EventType, MODE_SSR, } from 'overmind';
import { inject, ref, onBeforeUpdate, onRenderTracked, onMounted, onBeforeUnmount, defineComponent, provide, h, } from 'vue';
const IS_PRODUCTION = ENVIRONMENT === 'production';
let nextComponentId = 0;
export const withOvermind = (instance, Component) => {
return defineComponent({
setup() {
provide('overmind', instance);
},
render() {
return h(Component);
},
});
};
export function createStateHook() {
const componentId = nextComponentId++;
let componentInstanceId = 0;
return ((cb) => {
const overmindInstance = inject('overmind');
if (overmindInstance.mode.mode === MODE_SSR) {
return cb ? cb(overmindInstance.state) : overmindInstance.state;
}
else {
const overmindRef = ref({});
const flushIds = ref(-1);
const { value } = overmindRef;
const state = ref(cb ? cb(overmindInstance.state) : overmindInstance.state);
if (!value.tree) {
value.tree = overmindInstance.proxyStateTreeInstance.getTrackStateTree();
value.componentInstanceId = componentInstanceId++;
value.onUpdate = (_, __, flushId) => {
value.currentFlushId = flushId;
value.isUpdating = true;
flushIds.value = flushId;
state.value = {
...(cb ? cb(overmindInstance.state) : overmindInstance.state),
};
// this.$forceUpdate()
};
value.isUpdating = false;
}
onBeforeUpdate(function () {
if (overmindInstance.mode.mode === MODE_SSR)
return;
value.tree.track(value.onUpdate);
});
onRenderTracked(function () {
if (IS_PRODUCTION) {
return;
}
if (overmindInstance.isUpdating) {
overmindInstance.eventHub.emitAsync(EventType.COMPONENT_UPDATE, {
componentId,
componentInstanceId: value.componentInstanceId,
name: '', // this.$options.name || '',
flushId: value.currentFlushId,
paths: Array.from(value.tree.pathDependencies),
});
value.isUpdating = false;
}
});
onMounted(() => {
if (IS_PRODUCTION || overmindInstance.mode.mode === MODE_SSR)
return;
value.tree.stopTracking();
overmindInstance.eventHub.emitAsync(EventType.COMPONENT_ADD, {
componentId,
componentInstanceId: value.componentInstanceId,
name: '', // this.$options.name || '',
paths: Array.from(value.tree.pathDependencies),
});
});
onBeforeUnmount(() => {
if (overmindInstance.mode.mode === MODE_SSR)
return;
overmindInstance.proxyStateTreeInstance.disposeTree(value.tree);
if (IS_PRODUCTION) {
return;
}
overmindInstance.eventHub.emitAsync(EventType.COMPONENT_REMOVE, {
componentId,
componentInstanceId: value.componentInstanceId,
name: '', // this.$options.name || '',
});
});
value.tree.track(value.onUpdate);
return state;
}
});
}
export function createActionsHook() {
return ((cb) => {
const overmindInstance = inject('overmind');
return cb ? cb(overmindInstance.actions) : overmindInstance.actions;
});
}
export function createEffectsHook() {
return ((cb) => {
const overmindInstance = inject('overmind');
return cb ? cb(overmindInstance.effects) : overmindInstance.effects;
});
}
export function createReactionHook() {
return () => {
const overmindInstance = inject('overmind');
return overmindInstance.reaction;
};
}
export function createHooks() {
return {
state: createStateHook(),
actions: createActionsHook(),
effects: createEffectsHook(),
reaction: createReactionHook(),
};
}
//# sourceMappingURL=vue3.js.map