@uni-store/core
Version:
Unified Store
76 lines (72 loc) • 2.51 kB
JavaScript
/*!
* @uni-store/core v0.3.5
* (c) 2022 dolymood (dolymood@gmail.com)
* @license MIT
*/
import { effectScope, reactive, markRaw } from '@vue/reactivity';
export { computed, customRef, effect, effectScope, getCurrentScope, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, onScopeDispose, proxyRefs, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, stop, toRaw, toRef, toRefs, triggerRef, unref } from '@vue/reactivity';
import { watch } from '@vue/runtime-core';
export { nextTick, watch, watchEffect, watchPostEffect, watchSyncEffect } from '@vue/runtime-core';
function addSubscription(subscriptions, callback) {
subscriptions.push(callback);
const removeSubscription = () => {
const idx = subscriptions.indexOf(callback);
if (idx > -1) {
subscriptions.splice(idx, 1);
}
};
return removeSubscription;
}
function createStore(setup) {
const scope = effectScope(true);
const store = reactive({
$dispose,
$subscribe
});
// watcher options for $subscribe
const subscribeOptions = {
deep: true,
flush: 'post'
};
let subscriptions = markRaw([]);
function $subscribe(callback, options = {}) {
const _removeSubscription = addSubscription(subscriptions, callback);
const stopWatcher = scope.run(() => watch(() => store, (newStore) => {
callback(newStore.$state);
}, Object.assign({}, subscribeOptions, options)));
const removeSubscription = () => {
stopWatcher();
_removeSubscription();
};
return removeSubscription;
}
function $dispose() {
scope.stop();
subscriptions = [];
}
const setupState = scope.run(() => setup());
Object.defineProperty(store, '$state', {
get() {
return setupState;
}
});
Object.assign(store, setupState);
return store;
}
/**
* Create a `useStore` function that retrieves the store instance
*
* @param setup - function that creates the store
* @returns `useStore` function with `reset` param that determines whether create a new store instance
*/
function defineStore(setup) {
let store;
return function useStore(reset = false) {
if (!store || reset) {
store && store.$dispose();
store = createStore(setup);
}
return store;
};
}
export { defineStore };