Comparing version 0.1.0-alpha.1 to 0.1.0
/*! | ||
* pinia v0.1.0-alpha.1 | ||
* pinia v0.1.0 | ||
* (c) 2020 Eduardo San Martin Morote | ||
@@ -10,17 +10,17 @@ * @license MIT | ||
var vue = require('vue'); | ||
var compositionApi = require('@vue/composition-api'); | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Copyright (c) Microsoft Corporation. | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
@@ -48,2 +48,55 @@ | ||
var target = typeof window !== 'undefined' | ||
? window | ||
: typeof global !== 'undefined' | ||
? global | ||
: { __VUE_DEVTOOLS_GLOBAL_HOOK__: undefined }; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
var devtoolHook = target.__VUE_DEVTOOLS_GLOBAL_HOOK__; | ||
var rootStore; | ||
function useStoreDevtools(store) { | ||
if (!devtoolHook) | ||
return; | ||
if (!rootStore) { | ||
rootStore = { | ||
_devtoolHook: devtoolHook, | ||
_vm: { $options: { computed: {} } }, | ||
_mutations: {}, | ||
// we neeed to store modules names | ||
_modulesNamespaceMap: {}, | ||
_modules: { | ||
// we only need this specific method to let devtools retrieve the module name | ||
get: function (name) { | ||
return name in rootStore._modulesNamespaceMap; | ||
}, | ||
}, | ||
state: {}, | ||
replaceState: function () { | ||
// we handle replacing per store so we do nothing here | ||
}, | ||
// these are used by the devtools | ||
registerModule: function () { }, | ||
unregisterModule: function () { }, | ||
}; | ||
devtoolHook.emit('vuex:init', rootStore); | ||
} | ||
rootStore.state[store.id] = store.state; | ||
// tell the devtools we added a module | ||
rootStore.registerModule(store.id, store); | ||
Object.defineProperty(rootStore.state, store.id, { | ||
get: function () { return store.state; }, | ||
set: function (state) { return (store.state = state); }, | ||
}); | ||
// Vue.set(rootStore.state, store.name, store.state) | ||
// the trailing slash is removed by the devtools | ||
rootStore._modulesNamespaceMap[store.id + '/'] = true; | ||
devtoolHook.on('vuex:travel-to-state', function (targetState) { | ||
store.state = targetState[store.id]; | ||
}); | ||
store.subscribe(function (mutation, state) { | ||
rootStore.state[store.id] = state; | ||
devtoolHook.emit('vuex:mutation', __assign(__assign({}, mutation), { type: "[" + mutation.storeName + "] " + mutation.type }), rootStore.state); | ||
}); | ||
} | ||
/** | ||
@@ -91,2 +144,3 @@ * setActiveReq must be called to handle SSR at the top of functions like `fetch`, `setup`, `serverPrefetch` and others | ||
var isClient = typeof window != 'undefined'; | ||
function innerPatch(target, patchToApply) { | ||
@@ -107,2 +161,17 @@ // TODO: get all keys like symbols as well | ||
} | ||
function toComputed(refObject) { | ||
// let asComputed = computed<T>() | ||
var reactiveObject = {}; | ||
var _loop_1 = function (key) { | ||
// @ts-ignore: the key matches | ||
reactiveObject[key] = compositionApi.computed({ | ||
get: function () { return refObject.value[key]; }, | ||
set: function (value) { return (refObject.value[key] = value); }, | ||
}); | ||
}; | ||
for (var key in refObject.value) { | ||
_loop_1(key); | ||
} | ||
return reactiveObject; | ||
} | ||
/** | ||
@@ -117,11 +186,9 @@ * Creates a store instance | ||
if (actions === void 0) { actions = {}; } | ||
var state = vue.ref(initialState || buildState()); | ||
// TODO: remove req part? | ||
var state = compositionApi.ref(initialState || buildState()); | ||
var _r = getActiveReq(); | ||
var isListening = true; | ||
var subscriptions = []; | ||
vue.watch(function () { return state.value; }, function (state) { | ||
compositionApi.watch(function () { return state.value; }, function (state) { | ||
if (isListening) { | ||
subscriptions.forEach(function (callback) { | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
callback({ storeName: id, type: '🧩 in place', payload: {} }, state); | ||
@@ -136,9 +203,7 @@ }); | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
innerPatch(state.value, partialState); | ||
isListening = true; | ||
// because we paused the watcher, we need to manually call the subscriptions | ||
subscriptions.forEach(function (callback) { | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value); | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, state.value); | ||
}); | ||
@@ -157,3 +222,2 @@ } | ||
subscriptions = []; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = buildState(); | ||
@@ -164,5 +228,11 @@ } | ||
_r: _r, | ||
// it is replaced below by a getter | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state: state.value, | ||
// @ts-ignore, `reactive` unwraps this making it of type S | ||
state: compositionApi.computed({ | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}), | ||
patch: patch, | ||
@@ -173,15 +243,15 @@ subscribe: subscribe, | ||
var computedGetters = {}; | ||
var _loop_1 = function (getterName) { | ||
computedGetters[getterName] = vue.computed(function () { | ||
var _loop_2 = function (getterName) { | ||
computedGetters[getterName] = compositionApi.computed(function () { | ||
setActiveReq(_r); | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
return getters[getterName](state.value, computedGetters); | ||
return getters[getterName].call(store, store); | ||
}); | ||
}; | ||
for (var getterName in getters) { | ||
_loop_1(getterName); | ||
_loop_2(getterName); | ||
} | ||
// const reactiveGetters = reactive(computedGetters) | ||
var wrappedActions = {}; | ||
var _loop_2 = function (actionName) { | ||
var _loop_3 = function (actionName) { | ||
wrappedActions[actionName] = function () { | ||
@@ -194,15 +264,5 @@ setActiveReq(_r); | ||
for (var actionName in actions) { | ||
_loop_2(actionName); | ||
_loop_3(actionName); | ||
} | ||
var store = __assign(__assign(__assign({}, storeWithState), computedGetters), wrappedActions); | ||
// make state access invisible | ||
Object.defineProperty(store, 'state', { | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}); | ||
var store = compositionApi.reactive(__assign(__assign(__assign(__assign({}, storeWithState), toComputed(state)), computedGetters), wrappedActions)); | ||
return store; | ||
@@ -225,5 +285,7 @@ } | ||
if (!store) { | ||
stores.set(id, (store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
// TODO: client devtools when availables | ||
// if (isClient) useStoreDevtools(store) | ||
stores.set(id, | ||
// @ts-ignore | ||
(store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
if (isClient) | ||
useStoreDevtools(store); | ||
} | ||
@@ -234,2 +296,47 @@ return store; | ||
var PiniaSsr = function (_Vue) { | ||
var isServer = typeof window === 'undefined'; | ||
if (!isServer) { | ||
console.warn('`PiniaSsrPlugin` seems to be used in the client bundle. You should only call it on the server entry: https://github.com/posva/pinia#raw-vue-ssr'); | ||
return; | ||
} | ||
_Vue.mixin({ | ||
beforeCreate: function () { | ||
// @ts-ignore | ||
var _a = this.$options, setup = _a.setup, serverPrefetch = _a.serverPrefetch; | ||
if (setup) { | ||
// @ts-ignore | ||
this.$options.setup = function (props, context) { | ||
// @ts-ignore TODO: fix usage with nuxt-composition-api https://github.com/posva/pinia/issues/179 | ||
if (context.ssrContext) | ||
setActiveReq(context.ssrContext.req); | ||
return setup(props, context); | ||
}; | ||
} | ||
if (serverPrefetch) { | ||
var patchedServerPrefetch = Array.isArray(serverPrefetch) | ||
? serverPrefetch.slice() | ||
: // serverPrefetch not being an array cannot be triggered due to options merge | ||
// https://github.com/vuejs/vue/blob/7912f75c5eb09e0aef3e4bfd8a3bb78cad7540d7/src/core/util/options.js#L149 | ||
/* istanbul ignore next */ | ||
[serverPrefetch]; | ||
var _loop_1 = function (i) { | ||
var original = patchedServerPrefetch[i]; | ||
patchedServerPrefetch[i] = function () { | ||
// @ts-ignore | ||
setActiveReq(this.$ssrContext.req); | ||
return original.call(this); | ||
}; | ||
}; | ||
for (var i = 0; i < patchedServerPrefetch.length; i++) { | ||
_loop_1(i); | ||
} | ||
// @ts-ignore | ||
this.$options.serverPrefetch = patchedServerPrefetch; | ||
} | ||
}, | ||
}); | ||
}; | ||
exports.PiniaSsr = PiniaSsr; | ||
exports.createStore = createStore; | ||
@@ -236,0 +343,0 @@ exports.getRootState = getRootState; |
/*! | ||
* pinia v0.1.0-alpha.1 | ||
* pinia v0.1.0 | ||
* (c) 2020 Eduardo San Martin Morote | ||
* @license MIT | ||
*/ | ||
import { ref, watch, computed } from 'vue'; | ||
import { ref, watch, computed, reactive } from '@vue/composition-api'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Copyright (c) Microsoft Corporation. | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
@@ -43,2 +43,55 @@ | ||
var target = typeof window !== 'undefined' | ||
? window | ||
: typeof global !== 'undefined' | ||
? global | ||
: { __VUE_DEVTOOLS_GLOBAL_HOOK__: undefined }; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
var devtoolHook = target.__VUE_DEVTOOLS_GLOBAL_HOOK__; | ||
var rootStore; | ||
function useStoreDevtools(store) { | ||
if (!devtoolHook) | ||
return; | ||
if (!rootStore) { | ||
rootStore = { | ||
_devtoolHook: devtoolHook, | ||
_vm: { $options: { computed: {} } }, | ||
_mutations: {}, | ||
// we neeed to store modules names | ||
_modulesNamespaceMap: {}, | ||
_modules: { | ||
// we only need this specific method to let devtools retrieve the module name | ||
get: function (name) { | ||
return name in rootStore._modulesNamespaceMap; | ||
}, | ||
}, | ||
state: {}, | ||
replaceState: function () { | ||
// we handle replacing per store so we do nothing here | ||
}, | ||
// these are used by the devtools | ||
registerModule: function () { }, | ||
unregisterModule: function () { }, | ||
}; | ||
devtoolHook.emit('vuex:init', rootStore); | ||
} | ||
rootStore.state[store.id] = store.state; | ||
// tell the devtools we added a module | ||
rootStore.registerModule(store.id, store); | ||
Object.defineProperty(rootStore.state, store.id, { | ||
get: function () { return store.state; }, | ||
set: function (state) { return (store.state = state); }, | ||
}); | ||
// Vue.set(rootStore.state, store.name, store.state) | ||
// the trailing slash is removed by the devtools | ||
rootStore._modulesNamespaceMap[store.id + '/'] = true; | ||
devtoolHook.on('vuex:travel-to-state', function (targetState) { | ||
store.state = targetState[store.id]; | ||
}); | ||
store.subscribe(function (mutation, state) { | ||
rootStore.state[store.id] = state; | ||
devtoolHook.emit('vuex:mutation', __assign(__assign({}, mutation), { type: "[" + mutation.storeName + "] " + mutation.type }), rootStore.state); | ||
}); | ||
} | ||
/** | ||
@@ -86,2 +139,3 @@ * setActiveReq must be called to handle SSR at the top of functions like `fetch`, `setup`, `serverPrefetch` and others | ||
var isClient = typeof window != 'undefined'; | ||
function innerPatch(target, patchToApply) { | ||
@@ -102,2 +156,17 @@ // TODO: get all keys like symbols as well | ||
} | ||
function toComputed(refObject) { | ||
// let asComputed = computed<T>() | ||
var reactiveObject = {}; | ||
var _loop_1 = function (key) { | ||
// @ts-ignore: the key matches | ||
reactiveObject[key] = computed({ | ||
get: function () { return refObject.value[key]; }, | ||
set: function (value) { return (refObject.value[key] = value); }, | ||
}); | ||
}; | ||
for (var key in refObject.value) { | ||
_loop_1(key); | ||
} | ||
return reactiveObject; | ||
} | ||
/** | ||
@@ -113,3 +182,2 @@ * Creates a store instance | ||
var state = ref(initialState || buildState()); | ||
// TODO: remove req part? | ||
var _r = getActiveReq(); | ||
@@ -121,3 +189,2 @@ var isListening = true; | ||
subscriptions.forEach(function (callback) { | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
callback({ storeName: id, type: '🧩 in place', payload: {} }, state); | ||
@@ -132,9 +199,7 @@ }); | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
innerPatch(state.value, partialState); | ||
isListening = true; | ||
// because we paused the watcher, we need to manually call the subscriptions | ||
subscriptions.forEach(function (callback) { | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value); | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, state.value); | ||
}); | ||
@@ -153,3 +218,2 @@ } | ||
subscriptions = []; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = buildState(); | ||
@@ -160,5 +224,11 @@ } | ||
_r: _r, | ||
// it is replaced below by a getter | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state: state.value, | ||
// @ts-ignore, `reactive` unwraps this making it of type S | ||
state: computed({ | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}), | ||
patch: patch, | ||
@@ -169,15 +239,15 @@ subscribe: subscribe, | ||
var computedGetters = {}; | ||
var _loop_1 = function (getterName) { | ||
var _loop_2 = function (getterName) { | ||
computedGetters[getterName] = computed(function () { | ||
setActiveReq(_r); | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
return getters[getterName](state.value, computedGetters); | ||
return getters[getterName].call(store, store); | ||
}); | ||
}; | ||
for (var getterName in getters) { | ||
_loop_1(getterName); | ||
_loop_2(getterName); | ||
} | ||
// const reactiveGetters = reactive(computedGetters) | ||
var wrappedActions = {}; | ||
var _loop_2 = function (actionName) { | ||
var _loop_3 = function (actionName) { | ||
wrappedActions[actionName] = function () { | ||
@@ -190,15 +260,5 @@ setActiveReq(_r); | ||
for (var actionName in actions) { | ||
_loop_2(actionName); | ||
_loop_3(actionName); | ||
} | ||
var store = __assign(__assign(__assign({}, storeWithState), computedGetters), wrappedActions); | ||
// make state access invisible | ||
Object.defineProperty(store, 'state', { | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}); | ||
var store = reactive(__assign(__assign(__assign(__assign({}, storeWithState), toComputed(state)), computedGetters), wrappedActions)); | ||
return store; | ||
@@ -221,5 +281,7 @@ } | ||
if (!store) { | ||
stores.set(id, (store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
// TODO: client devtools when availables | ||
// if (isClient) useStoreDevtools(store) | ||
stores.set(id, | ||
// @ts-ignore | ||
(store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
if (isClient) | ||
useStoreDevtools(store); | ||
} | ||
@@ -230,2 +292,46 @@ return store; | ||
export { createStore, getRootState, setActiveReq, setStateProvider }; | ||
var PiniaSsr = function (_Vue) { | ||
var isServer = typeof window === 'undefined'; | ||
if (!isServer) { | ||
console.warn('`PiniaSsrPlugin` seems to be used in the client bundle. You should only call it on the server entry: https://github.com/posva/pinia#raw-vue-ssr'); | ||
return; | ||
} | ||
_Vue.mixin({ | ||
beforeCreate: function () { | ||
// @ts-ignore | ||
var _a = this.$options, setup = _a.setup, serverPrefetch = _a.serverPrefetch; | ||
if (setup) { | ||
// @ts-ignore | ||
this.$options.setup = function (props, context) { | ||
// @ts-ignore TODO: fix usage with nuxt-composition-api https://github.com/posva/pinia/issues/179 | ||
if (context.ssrContext) | ||
setActiveReq(context.ssrContext.req); | ||
return setup(props, context); | ||
}; | ||
} | ||
if (serverPrefetch) { | ||
var patchedServerPrefetch = Array.isArray(serverPrefetch) | ||
? serverPrefetch.slice() | ||
: // serverPrefetch not being an array cannot be triggered due to options merge | ||
// https://github.com/vuejs/vue/blob/7912f75c5eb09e0aef3e4bfd8a3bb78cad7540d7/src/core/util/options.js#L149 | ||
/* istanbul ignore next */ | ||
[serverPrefetch]; | ||
var _loop_1 = function (i) { | ||
var original = patchedServerPrefetch[i]; | ||
patchedServerPrefetch[i] = function () { | ||
// @ts-ignore | ||
setActiveReq(this.$ssrContext.req); | ||
return original.call(this); | ||
}; | ||
}; | ||
for (var i = 0; i < patchedServerPrefetch.length; i++) { | ||
_loop_1(i); | ||
} | ||
// @ts-ignore | ||
this.$options.serverPrefetch = patchedServerPrefetch; | ||
} | ||
}, | ||
}); | ||
}; | ||
export { PiniaSsr, createStore, getRootState, setActiveReq, setStateProvider }; |
/*! | ||
* pinia v0.1.0-alpha.1 | ||
* pinia v0.1.0 | ||
* (c) 2020 Eduardo San Martin Morote | ||
* @license MIT | ||
*/ | ||
import{ref as t,watch as n,computed as r}from"vue"; | ||
import{ref as t,watch as e,computed as n,reactive as r}from"@vue/composition-api"; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Copyright (c) Microsoft Corporation. | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */var e=function(){return(e=Object.assign||function(t){for(var n,r=1,e=arguments.length;r<e;r++)for(var o in n=arguments[r])Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o]);return t}).apply(this,arguments)};function o(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var u={},a=function(t){return t&&(u=t)},i=function(){return u},c=new WeakMap,f=new WeakMap;function v(t){f.set(i(),t)}function p(t){var n=c.get(t);if(!n)return{};var r={};return n.forEach((function(t){r[t.id]=t.state})),r}function s(u,c,f,v,p){void 0===c&&(c=function(){return{}}),void 0===f&&(f={}),void 0===v&&(v={});var s=t(p||c()),l=i(),y=!0,d=[];n((function(){return s.value}),(function(t){y&&d.forEach((function(n){n({storeName:u,type:"🧩 in place",payload:{}},t)}))}),{deep:!0,flush:"sync"});var h={id:u,_r:l,state:s.value,patch:function(t){y=!1,function t(n,r){for(var e in r){var u=r[e],a=n[e];o(a)&&o(u)?n[e]=t(a,u):n[e]=u}return n}(s.value,t),y=!0,d.forEach((function(n){n({storeName:u,type:"⤵️ patch",payload:t},s.value)}))},subscribe:function(t){return d.push(t),function(){var n=d.indexOf(t);n>-1&&d.splice(n,1)}},reset:function(){d=[],s.value=c()}},b={},g=function(t){b[t]=r((function(){return a(l),f[t](s.value,b)}))};for(var O in f)g(O);var j={},m=function(t){j[t]=function(){return a(l),v[t].apply(E,arguments)}};for(var w in v)m(w);var E=e(e(e({},h),b),j);return Object.defineProperty(E,"state",{get:function(){return s.value},set:function(t){y=!1,s.value=t,y=!0}}),E}function l(t){var n=t.id,r=t.state,e=t.getters,o=t.actions;return function(t){t&&a(t);var u=i(),v=c.get(u);v||c.set(u,v=new Map);var p=v.get(n);return p||v.set(n,p=s(n,r,e,o,function(t){var n=f.get(i());return n&&n()[t]}(n))),p}}export{l as createStore,p as getRootState,a as setActiveReq,v as setStateProvider}; | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */var o=function(){return(o=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)};function i(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var u,a=("undefined"!=typeof window?window:"undefined"!=typeof global?global:{__VUE_DEVTOOLS_GLOBAL_HOOK__:void 0}).__VUE_DEVTOOLS_GLOBAL_HOOK__;var c={},s=function(t){return t&&(c=t)},f=function(){return c},p=new WeakMap,v=new WeakMap;function l(t){v.set(f(),t)}function d(t){var e=p.get(t);if(!e)return{};var n={};return e.forEach((function(t){n[t.id]=t.state})),n}var h="undefined"!=typeof window;function y(u,a,c,p,v){void 0===a&&(a=function(){return{}}),void 0===c&&(c={}),void 0===p&&(p={});var l=t(v||a()),d=f(),h=!0,y=[];e((function(){return l.value}),(function(t){h&&y.forEach((function(e){e({storeName:u,type:"🧩 in place",payload:{}},t)}))}),{deep:!0,flush:"sync"});var m={id:u,_r:d,state:n({get:function(){return l.value},set:function(t){h=!1,l.value=t,h=!0}}),patch:function(t){h=!1,function t(e,n){for(var r in n){var o=n[r],u=e[r];i(u)&&i(o)?e[r]=t(u,o):e[r]=o}return e}(l.value,t),h=!0,y.forEach((function(e){e({storeName:u,type:"⤵️ patch",payload:t},l.value)}))},subscribe:function(t){return y.push(t),function(){var e=y.indexOf(t);e>-1&&y.splice(e,1)}},reset:function(){y=[],l.value=a()}},_={},g=function(t){_[t]=n((function(){return s(d),c[t].call(M,M)}))};for(var O in c)g(O);var b={},w=function(t){b[t]=function(){return s(d),p[t].apply(M,arguments)}};for(var x in p)w(x);var M=r(o(o(o(o({},m),function(t){var e={},r=function(r){e[r]=n({get:function(){return t.value[r]},set:function(e){return t.value[r]=e}})};for(var o in t.value)r(o);return e}(l)),_),b));return M}function m(t){var e=t.id,n=t.state,r=t.getters,i=t.actions;return function(t){t&&s(t);var c=f(),l=p.get(c);l||p.set(c,l=new Map);var d=l.get(e);return d||(l.set(e,d=y(e,n,r,i,function(t){var e=v.get(f());return e&&e()[t]}(e))),h&&function(t){a&&(u||(u={_devtoolHook:a,_vm:{$options:{computed:{}}},_mutations:{},_modulesNamespaceMap:{},_modules:{get:function(t){return t in u._modulesNamespaceMap}},state:{},replaceState:function(){},registerModule:function(){},unregisterModule:function(){}},a.emit("vuex:init",u)),u.state[t.id]=t.state,u.registerModule(t.id,t),Object.defineProperty(u.state,t.id,{get:function(){return t.state},set:function(e){return t.state=e}}),u._modulesNamespaceMap[t.id+"/"]=!0,a.on("vuex:travel-to-state",(function(e){t.state=e[t.id]})),t.subscribe((function(e,n){u.state[t.id]=n,a.emit("vuex:mutation",o(o({},e),{type:"["+e.storeName+"] "+e.type}),u.state)})))}(d)),d}}var _=function(t){"undefined"==typeof window?t.mixin({beforeCreate:function(){var t=this.$options,e=t.setup,n=t.serverPrefetch;if(e&&(this.$options.setup=function(t,n){return n.ssrContext&&s(n.ssrContext.req),e(t,n)}),n){for(var r=Array.isArray(n)?n.slice():[n],o=function(t){var e=r[t];r[t]=function(){return s(this.$ssrContext.req),e.call(this)}},i=0;i<r.length;i++)o(i);this.$options.serverPrefetch=r}}}):console.warn("`PiniaSsrPlugin` seems to be used in the client bundle. You should only call it on the server entry: https://github.com/posva/pinia#raw-vue-ssr")};export{_ as PiniaSsr,m as createStore,d as getRootState,s as setActiveReq,l as setStateProvider}; |
/*! | ||
* pinia v0.1.0-alpha.1 | ||
* pinia v0.1.0 | ||
* (c) 2020 Eduardo San Martin Morote | ||
* @license MIT | ||
*/ | ||
var Pinia = (function (exports, vue) { | ||
var Pinia = (function (exports, compositionApi) { | ||
'use strict'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Copyright (c) Microsoft Corporation. | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
@@ -44,2 +44,55 @@ | ||
var target = typeof window !== 'undefined' | ||
? window | ||
: typeof global !== 'undefined' | ||
? global | ||
: { __VUE_DEVTOOLS_GLOBAL_HOOK__: undefined }; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
var devtoolHook = target.__VUE_DEVTOOLS_GLOBAL_HOOK__; | ||
var rootStore; | ||
function useStoreDevtools(store) { | ||
if (!devtoolHook) | ||
return; | ||
if (!rootStore) { | ||
rootStore = { | ||
_devtoolHook: devtoolHook, | ||
_vm: { $options: { computed: {} } }, | ||
_mutations: {}, | ||
// we neeed to store modules names | ||
_modulesNamespaceMap: {}, | ||
_modules: { | ||
// we only need this specific method to let devtools retrieve the module name | ||
get: function (name) { | ||
return name in rootStore._modulesNamespaceMap; | ||
}, | ||
}, | ||
state: {}, | ||
replaceState: function () { | ||
// we handle replacing per store so we do nothing here | ||
}, | ||
// these are used by the devtools | ||
registerModule: function () { }, | ||
unregisterModule: function () { }, | ||
}; | ||
devtoolHook.emit('vuex:init', rootStore); | ||
} | ||
rootStore.state[store.id] = store.state; | ||
// tell the devtools we added a module | ||
rootStore.registerModule(store.id, store); | ||
Object.defineProperty(rootStore.state, store.id, { | ||
get: function () { return store.state; }, | ||
set: function (state) { return (store.state = state); }, | ||
}); | ||
// Vue.set(rootStore.state, store.name, store.state) | ||
// the trailing slash is removed by the devtools | ||
rootStore._modulesNamespaceMap[store.id + '/'] = true; | ||
devtoolHook.on('vuex:travel-to-state', function (targetState) { | ||
store.state = targetState[store.id]; | ||
}); | ||
store.subscribe(function (mutation, state) { | ||
rootStore.state[store.id] = state; | ||
devtoolHook.emit('vuex:mutation', __assign(__assign({}, mutation), { type: "[" + mutation.storeName + "] " + mutation.type }), rootStore.state); | ||
}); | ||
} | ||
/** | ||
@@ -87,2 +140,3 @@ * setActiveReq must be called to handle SSR at the top of functions like `fetch`, `setup`, `serverPrefetch` and others | ||
var isClient = typeof window != 'undefined'; | ||
function innerPatch(target, patchToApply) { | ||
@@ -103,2 +157,17 @@ // TODO: get all keys like symbols as well | ||
} | ||
function toComputed(refObject) { | ||
// let asComputed = computed<T>() | ||
var reactiveObject = {}; | ||
var _loop_1 = function (key) { | ||
// @ts-ignore: the key matches | ||
reactiveObject[key] = compositionApi.computed({ | ||
get: function () { return refObject.value[key]; }, | ||
set: function (value) { return (refObject.value[key] = value); }, | ||
}); | ||
}; | ||
for (var key in refObject.value) { | ||
_loop_1(key); | ||
} | ||
return reactiveObject; | ||
} | ||
/** | ||
@@ -113,11 +182,9 @@ * Creates a store instance | ||
if (actions === void 0) { actions = {}; } | ||
var state = vue.ref(initialState || buildState()); | ||
// TODO: remove req part? | ||
var state = compositionApi.ref(initialState || buildState()); | ||
var _r = getActiveReq(); | ||
var isListening = true; | ||
var subscriptions = []; | ||
vue.watch(function () { return state.value; }, function (state) { | ||
compositionApi.watch(function () { return state.value; }, function (state) { | ||
if (isListening) { | ||
subscriptions.forEach(function (callback) { | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
callback({ storeName: id, type: '🧩 in place', payload: {} }, state); | ||
@@ -132,9 +199,7 @@ }); | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
innerPatch(state.value, partialState); | ||
isListening = true; | ||
// because we paused the watcher, we need to manually call the subscriptions | ||
subscriptions.forEach(function (callback) { | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value); | ||
callback({ storeName: id, type: '⤵️ patch', payload: partialState }, state.value); | ||
}); | ||
@@ -153,3 +218,2 @@ } | ||
subscriptions = []; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = buildState(); | ||
@@ -160,5 +224,11 @@ } | ||
_r: _r, | ||
// it is replaced below by a getter | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state: state.value, | ||
// @ts-ignore, `reactive` unwraps this making it of type S | ||
state: compositionApi.computed({ | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}), | ||
patch: patch, | ||
@@ -169,15 +239,15 @@ subscribe: subscribe, | ||
var computedGetters = {}; | ||
var _loop_1 = function (getterName) { | ||
computedGetters[getterName] = vue.computed(function () { | ||
var _loop_2 = function (getterName) { | ||
computedGetters[getterName] = compositionApi.computed(function () { | ||
setActiveReq(_r); | ||
// eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
return getters[getterName](state.value, computedGetters); | ||
return getters[getterName].call(store, store); | ||
}); | ||
}; | ||
for (var getterName in getters) { | ||
_loop_1(getterName); | ||
_loop_2(getterName); | ||
} | ||
// const reactiveGetters = reactive(computedGetters) | ||
var wrappedActions = {}; | ||
var _loop_2 = function (actionName) { | ||
var _loop_3 = function (actionName) { | ||
wrappedActions[actionName] = function () { | ||
@@ -190,15 +260,5 @@ setActiveReq(_r); | ||
for (var actionName in actions) { | ||
_loop_2(actionName); | ||
_loop_3(actionName); | ||
} | ||
var store = __assign(__assign(__assign({}, storeWithState), computedGetters), wrappedActions); | ||
// make state access invisible | ||
Object.defineProperty(store, 'state', { | ||
get: function () { return state.value; }, | ||
set: function (newState) { | ||
isListening = false; | ||
// @ts-ignore FIXME: why is this even failing on TS | ||
state.value = newState; | ||
isListening = true; | ||
}, | ||
}); | ||
var store = compositionApi.reactive(__assign(__assign(__assign(__assign({}, storeWithState), toComputed(state)), computedGetters), wrappedActions)); | ||
return store; | ||
@@ -221,5 +281,7 @@ } | ||
if (!store) { | ||
stores.set(id, (store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
// TODO: client devtools when availables | ||
// if (isClient) useStoreDevtools(store) | ||
stores.set(id, | ||
// @ts-ignore | ||
(store = buildStore(id, state, getters, actions, getInitialState(id)))); | ||
if (isClient) | ||
useStoreDevtools(store); | ||
} | ||
@@ -230,2 +292,47 @@ return store; | ||
var PiniaSsr = function (_Vue) { | ||
var isServer = typeof window === 'undefined'; | ||
if (!isServer) { | ||
console.warn('`PiniaSsrPlugin` seems to be used in the client bundle. You should only call it on the server entry: https://github.com/posva/pinia#raw-vue-ssr'); | ||
return; | ||
} | ||
_Vue.mixin({ | ||
beforeCreate: function () { | ||
// @ts-ignore | ||
var _a = this.$options, setup = _a.setup, serverPrefetch = _a.serverPrefetch; | ||
if (setup) { | ||
// @ts-ignore | ||
this.$options.setup = function (props, context) { | ||
// @ts-ignore TODO: fix usage with nuxt-composition-api https://github.com/posva/pinia/issues/179 | ||
if (context.ssrContext) | ||
setActiveReq(context.ssrContext.req); | ||
return setup(props, context); | ||
}; | ||
} | ||
if (serverPrefetch) { | ||
var patchedServerPrefetch = Array.isArray(serverPrefetch) | ||
? serverPrefetch.slice() | ||
: // serverPrefetch not being an array cannot be triggered due to options merge | ||
// https://github.com/vuejs/vue/blob/7912f75c5eb09e0aef3e4bfd8a3bb78cad7540d7/src/core/util/options.js#L149 | ||
/* istanbul ignore next */ | ||
[serverPrefetch]; | ||
var _loop_1 = function (i) { | ||
var original = patchedServerPrefetch[i]; | ||
patchedServerPrefetch[i] = function () { | ||
// @ts-ignore | ||
setActiveReq(this.$ssrContext.req); | ||
return original.call(this); | ||
}; | ||
}; | ||
for (var i = 0; i < patchedServerPrefetch.length; i++) { | ||
_loop_1(i); | ||
} | ||
// @ts-ignore | ||
this.$options.serverPrefetch = patchedServerPrefetch; | ||
} | ||
}, | ||
}); | ||
}; | ||
exports.PiniaSsr = PiniaSsr; | ||
exports.createStore = createStore; | ||
@@ -238,2 +345,2 @@ exports.getRootState = getRootState; | ||
}({}, vue)); | ||
}({}, vueCompositionApi)); |
/*! | ||
* pinia v0.1.0-alpha.1 | ||
* pinia v0.1.0 | ||
* (c) 2020 Eduardo San Martin Morote | ||
* @license MIT | ||
*/ | ||
var Pinia=function(t,n){"use strict"; | ||
var Pinia=function(t,e){"use strict"; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
Copyright (c) Microsoft Corporation. | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */var e=function(){return(e=Object.assign||function(t){for(var n,e=1,r=arguments.length;e<r;e++)for(var o in n=arguments[e])Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o]);return t}).apply(this,arguments)};function r(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var o={},u=function(t){return t&&(o=t)},a=function(){return o},i=new WeakMap,c=new WeakMap;function f(t,o,i,c,f){void 0===o&&(o=function(){return{}}),void 0===i&&(i={}),void 0===c&&(c={});var v=n.ref(f||o()),s=a(),p=!0,l=[];n.watch((function(){return v.value}),(function(n){p&&l.forEach((function(e){e({storeName:t,type:"🧩 in place",payload:{}},n)}))}),{deep:!0,flush:"sync"});var d={id:t,_r:s,state:v.value,patch:function(n){p=!1,function t(n,e){for(var o in e){var u=e[o],a=n[o];r(a)&&r(u)?n[o]=t(a,u):n[o]=u}return n}(v.value,n),p=!0,l.forEach((function(e){e({storeName:t,type:"⤵️ patch",payload:n},v.value)}))},subscribe:function(t){return l.push(t),function(){var n=l.indexOf(t);n>-1&&l.splice(n,1)}},reset:function(){l=[],v.value=o()}},y={},h=function(t){y[t]=n.computed((function(){return u(s),i[t](v.value,y)}))};for(var g in i)h(g);var b={},O=function(t){b[t]=function(){return u(s),c[t].apply(w,arguments)}};for(var j in c)O(j);var w=e(e(e({},d),y),b);return Object.defineProperty(w,"state",{get:function(){return v.value},set:function(t){p=!1,v.value=t,p=!0}}),w}return t.createStore=function(t){var n=t.id,e=t.state,r=t.getters,o=t.actions;return function(t){t&&u(t);var v=a(),s=i.get(v);s||i.set(v,s=new Map);var p=s.get(n);return p||s.set(n,p=f(n,e,r,o,function(t){var n=c.get(a());return n&&n()[t]}(n))),p}},t.getRootState=function(t){var n=i.get(t);if(!n)return{};var e={};return n.forEach((function(t){e[t.id]=t.state})),e},t.setActiveReq=u,t.setStateProvider=function(t){c.set(a(),t)},t}({},vue); | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */var n=function(){return(n=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)};function r(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var o,i=("undefined"!=typeof window?window:"undefined"!=typeof global?global:{__VUE_DEVTOOLS_GLOBAL_HOOK__:void 0}).__VUE_DEVTOOLS_GLOBAL_HOOK__;var u={},a=function(t){return t&&(u=t)},c=function(){return u},s=new WeakMap,f=new WeakMap;var v="undefined"!=typeof window;function p(t,o,i,u,s){void 0===o&&(o=function(){return{}}),void 0===i&&(i={}),void 0===u&&(u={});var f=e.ref(s||o()),v=c(),p=!0,l=[];e.watch((function(){return f.value}),(function(e){p&&l.forEach((function(n){n({storeName:t,type:"🧩 in place",payload:{}},e)}))}),{deep:!0,flush:"sync"});var d={id:t,_r:v,state:e.computed({get:function(){return f.value},set:function(t){p=!1,f.value=t,p=!0}}),patch:function(e){p=!1,function t(e,n){for(var o in n){var i=n[o],u=e[o];r(u)&&r(i)?e[o]=t(u,i):e[o]=i}return e}(f.value,e),p=!0,l.forEach((function(n){n({storeName:t,type:"⤵️ patch",payload:e},f.value)}))},subscribe:function(t){return l.push(t),function(){var e=l.indexOf(t);e>-1&&l.splice(e,1)}},reset:function(){l=[],f.value=o()}},h={},m=function(t){h[t]=e.computed((function(){return a(v),i[t].call(b,b)}))};for(var y in i)m(y);var _={},g=function(t){_[t]=function(){return a(v),u[t].apply(b,arguments)}};for(var O in u)g(O);var b=e.reactive(n(n(n(n({},d),function(t){var n={},r=function(r){n[r]=e.computed({get:function(){return t.value[r]},set:function(e){return t.value[r]=e}})};for(var o in t.value)r(o);return n}(f)),h),_));return b}return t.PiniaSsr=function(t){"undefined"==typeof window?t.mixin({beforeCreate:function(){var t=this.$options,e=t.setup,n=t.serverPrefetch;if(e&&(this.$options.setup=function(t,n){return n.ssrContext&&a(n.ssrContext.req),e(t,n)}),n){for(var r=Array.isArray(n)?n.slice():[n],o=function(t){var e=r[t];r[t]=function(){return a(this.$ssrContext.req),e.call(this)}},i=0;i<r.length;i++)o(i);this.$options.serverPrefetch=r}}}):console.warn("`PiniaSsrPlugin` seems to be used in the client bundle. You should only call it on the server entry: https://github.com/posva/pinia#raw-vue-ssr")},t.createStore=function(t){var e=t.id,r=t.state,u=t.getters,l=t.actions;return function(t){t&&a(t);var d=c(),h=s.get(d);h||s.set(d,h=new Map);var m=h.get(e);return m||(h.set(e,m=p(e,r,u,l,function(t){var e=f.get(c());return e&&e()[t]}(e))),v&&function(t){i&&(o||(o={_devtoolHook:i,_vm:{$options:{computed:{}}},_mutations:{},_modulesNamespaceMap:{},_modules:{get:function(t){return t in o._modulesNamespaceMap}},state:{},replaceState:function(){},registerModule:function(){},unregisterModule:function(){}},i.emit("vuex:init",o)),o.state[t.id]=t.state,o.registerModule(t.id,t),Object.defineProperty(o.state,t.id,{get:function(){return t.state},set:function(e){return t.state=e}}),o._modulesNamespaceMap[t.id+"/"]=!0,i.on("vuex:travel-to-state",(function(e){t.state=e[t.id]})),t.subscribe((function(e,r){o.state[t.id]=r,i.emit("vuex:mutation",n(n({},e),{type:"["+e.storeName+"] "+e.type}),o.state)})))}(m)),m}},t.getRootState=function(t){var e=s.get(t);if(!e)return{};var n={};return e.forEach((function(t){n[t.id]=t.state})),n},t.setActiveReq=a,t.setStateProvider=function(t){f.set(c(),t)},t}({},vueCompositionApi); |
export { createStore } from './store'; | ||
export { setActiveReq, setStateProvider, getRootState } from './rootStore'; | ||
export { StateTree, StoreGetter, Store } from './types'; | ||
export { StateTree, Store } from './types'; | ||
export { PiniaSsr } from './ssrPlugin'; |
@@ -6,3 +6,3 @@ import { NonNullObject, StateTree } from './types'; | ||
export declare let activeReq: NonNullObject; | ||
export declare const setActiveReq: (req: Record<any, any> | undefined) => Record<any, any> | undefined; | ||
export declare const setActiveReq: (req: NonNullObject | undefined) => Record<any, any> | undefined; | ||
export declare const getActiveReq: () => Record<any, any>; | ||
@@ -14,3 +14,3 @@ /** | ||
*/ | ||
export declare const storesMap: WeakMap<Record<any, any>, Map<string, import("./types").Store<string, Record<string | number | symbol, any>, Record<string, import("./types").StoreGetter<Record<string | number | symbol, any>, any>>, Record<string, import("./types").StoreAction>>>>; | ||
export declare const storesMap: WeakMap<Record<any, any>, Map<string, import("./types").Store<string, Record<string | number | symbol, any>, Record<string, import("./types").Method>, Record<string, import("./types").Method>>>>; | ||
/** | ||
@@ -17,0 +17,0 @@ * A state provider allows to set how states are stored for hydration. e.g. setting a property on a context, getting a property from window |
@@ -1,2 +0,2 @@ | ||
import { StateTree, StoreWithState, StoreWithGetters, StoreGetter, StoreAction, Store } from './types'; | ||
import { StateTree, StoreWithState, StoreWithGetters, Store, Method } from './types'; | ||
/** | ||
@@ -7,3 +7,3 @@ * Creates a store instance | ||
*/ | ||
export declare function buildStore<Id extends string, S extends StateTree, G extends Record<string, StoreGetter<S>>, A extends Record<string, StoreAction>>(id: Id, buildState?: () => S, getters?: G, actions?: A, initialState?: S | undefined): Store<Id, S, G, A>; | ||
export declare function buildStore<Id extends string, S extends StateTree, G extends Record<string, Method>, A extends Record<string, Method>>(id: Id, buildState?: () => S, getters?: G, actions?: A, initialState?: S | undefined): Store<Id, S, G, A>; | ||
/** | ||
@@ -13,7 +13,7 @@ * Creates a `useStore` function that retrieves the store instance | ||
*/ | ||
export declare function createStore<Id extends string, S extends StateTree, G extends Record<string, StoreGetter<S>>, A extends Record<string, StoreAction>>(options: { | ||
export declare function createStore<Id extends string, S extends StateTree, G, A>(options: { | ||
id: Id; | ||
state?: () => S; | ||
getters?: G; | ||
actions?: A & ThisType<A & StoreWithState<Id, S> & StoreWithGetters<S, G>>; | ||
getters?: G & ThisType<S & StoreWithGetters<G>>; | ||
actions?: A & ThisType<A & S & StoreWithState<Id, S> & StoreWithGetters<G>>; | ||
}): (reqKey?: object | undefined) => Store<Id, S, G, A>; |
@@ -1,8 +0,4 @@ | ||
import { Ref } from 'vue'; | ||
export declare type StateTree = Record<string | number | symbol, any>; | ||
export declare function isPlainObject(o: any): o is StateTree; | ||
export declare type NonNullObject = Record<any, any>; | ||
export interface StoreGetter<S extends StateTree, T = any> { | ||
(state: S, getters: Record<string, Ref<any>>): T; | ||
} | ||
export declare type DeepPartial<T> = { | ||
@@ -16,5 +12,2 @@ [K in keyof T]?: DeepPartial<T[K]>; | ||
}, state: S) => void; | ||
export declare type StoreWithGetters<S extends StateTree, G extends Record<string, StoreGetter<S>>> = { | ||
[k in keyof G]: G[k] extends StoreGetter<S, infer V> ? Ref<V> : never; | ||
}; | ||
export interface StoreWithState<Id extends string, S extends StateTree> { | ||
@@ -26,3 +19,3 @@ /** | ||
/** | ||
* State of the Store | ||
* State of the Store. Setting it will replace the whole state. | ||
*/ | ||
@@ -51,10 +44,11 @@ state: S; | ||
} | ||
export interface StoreAction { | ||
(...args: any[]): any; | ||
} | ||
export declare type StoreWithActions<A extends Record<string, StoreAction>> = { | ||
[k in keyof A]: A[k] extends (this: infer This, ...args: infer P) => infer R ? (this: This, ...args: P) => R : never; | ||
export declare type Method = (...args: any[]) => any; | ||
export declare type StoreWithActions<A> = { | ||
[k in keyof A]: A[k] extends (...args: infer P) => infer R ? (...args: P) => R : never; | ||
}; | ||
export declare type Store<Id extends string, S extends StateTree, G extends Record<string, StoreGetter<S>>, A extends Record<string, StoreAction>> = StoreWithState<Id, S> & StoreWithGetters<S, G> & StoreWithActions<A>; | ||
export declare type GenericStore = Store<string, StateTree, Record<string, StoreGetter<StateTree>>, Record<string, StoreAction>>; | ||
export declare type StoreWithGetters<G> = { | ||
[k in keyof G]: G[k] extends (this: infer This, store?: any) => infer R ? R : never; | ||
}; | ||
export declare type Store<Id extends string, S extends StateTree, G, A> = StoreWithState<Id, S> & S & StoreWithGetters<G> & StoreWithActions<A>; | ||
export declare type GenericStore = Store<string, StateTree, Record<string, Method>, Record<string, Method>>; | ||
export interface DevtoolHook { | ||
@@ -61,0 +55,0 @@ on(event: string, callback: (targetState: Record<string, StateTree>) => void): void; |
{ | ||
"name": "pinia", | ||
"version": "0.1.0-alpha.1", | ||
"version": "0.1.0", | ||
"description": "Some awesome description", | ||
@@ -26,2 +26,3 @@ "main": "dist/pinia.common.js", | ||
"files": [ | ||
"nuxt", | ||
"dist", | ||
@@ -35,24 +36,12 @@ "dist/src", | ||
}, | ||
"keywords": [ | ||
"vue", | ||
"vuex", | ||
"store", | ||
"pina", | ||
"composition", | ||
"api", | ||
"setup", | ||
"typed", | ||
"typescript", | ||
"ts", | ||
"type", | ||
"safe" | ||
], | ||
"keywords": [], | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@nuxt/types": "^0.6.1", | ||
"@nuxt/types": "^2.13.0", | ||
"@rollup/plugin-alias": "^3.0.0", | ||
"@rollup/plugin-replace": "^2.2.1", | ||
"@types/jest": "^25.1.1", | ||
"@typescript-eslint/eslint-plugin": "^2.18.0", | ||
"@typescript-eslint/parser": "^2.18.0", | ||
"@types/jest": "^26.0.0", | ||
"@typescript-eslint/eslint-plugin": "^2.20.0", | ||
"@typescript-eslint/parser": "^2.20.0", | ||
"@vue/composition-api": "^0.6.3", | ||
"codecov": "^3.6.1", | ||
@@ -63,14 +52,16 @@ "eslint": "^6.4.0", | ||
"jest": "^25.1.0", | ||
"jest-mock-warn": "^1.1.0", | ||
"pascalcase": "^1.0.0", | ||
"prettier": "^1.18.2", | ||
"rimraf": "^3.0.1", | ||
"rollup": "^1.30.1", | ||
"rollup": "^2.7.2", | ||
"rollup-plugin-commonjs": "^10.1.0", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"rollup-plugin-terser": "^5.1.2", | ||
"rollup-plugin-typescript2": "^0.25.2", | ||
"ts-jest": "^25.1.0", | ||
"tsd": "^0.11.0", | ||
"typescript": "^3.7.4", | ||
"vue": "next" | ||
"rollup-plugin-terser": "^7.0.0", | ||
"rollup-plugin-typescript2": "^0.27.0", | ||
"ts-jest": "^25.2.1", | ||
"tsd": "^0.13.1", | ||
"typescript": "^3.8.2", | ||
"vue": "^2.6.11", | ||
"vue-server-renderer": "^2.6.11" | ||
}, | ||
@@ -77,0 +68,0 @@ "repository": { |
282
README.md
@@ -1,2 +0,2 @@ | ||
# Pinia [![Build Status](https://badgen.net/circleci/github/posva/pinia/next)](https://circleci.com/gh/posva/pinia) [![npm package](https://badgen.net/npm/v/pinia/next)](https://www.npmjs.com/package/pinia) [![coverage](https://badgen.net/codecov/c/github/posva/pinia/next)](https://codecov.io/github/posva/pinia) [![thanks](https://badgen.net/badge/thanks/♥/pink)](https://github.com/posva/thanks) | ||
# Pinia [![Build Status](https://badgen.net/circleci/github/posva/pinia/master)](https://circleci.com/gh/posva/pinia) [![npm package](https://badgen.net/npm/v/pinia)](https://www.npmjs.com/package/pinia) [![coverage](https://badgen.net/codecov/c/github/posva/pinia/master)](https://codecov.io/github/posva/pinia) [![thanks](https://badgen.net/badge/thanks/♥/pink)](https://github.com/posva/thanks) | ||
@@ -7,10 +7,12 @@ > Pronounced like the fruit in Spanish, _Piña_ | ||
🍍Automatically Typed, Modular and lightweight (but **Experimental**) Store for Vue 3.x based on the composition api with devtools support | ||
🍍Automatically Typed, Modular and lightweight (but **Experimental**) Store for Vue based on the composition api with devtools support | ||
## 👉 [Demo](https://github.com/posva/vue-next-pinia) | ||
## 👉 [Demo](https://vcuiu.csb.app/) | ||
⚠️⚠️⚠️ This project is experimental, it's an exploration of what a _Store_ could be like using [the composition api](https://vue-composition-api-rfc.netlify.com). It works both for Vue 2.x and Vue 3.x and you are currently on the branch that supports Vue 3.x. [Go here for the Vue 2.x compatible version](https://github.com/posva/pinia/tree/master). | ||
⚠️⚠️⚠️ This project is experimental, it's an exploration of what a _Store_ could be like using [the composition api](https://vue-composition-api-rfc.netlify.com). It works for Vue 2 by using the [official library](https://github.com/vuejs/composition-api). | ||
What I want is to inspire others to think about ways to improve Vuex and come up with something that works very well with the composition api. Ideally it could also be used without it. | ||
**If you are looking for the version compatible with Vue 3.x, check the [`next` branch](https://github.com/posva/pinia/tree/next)** | ||
What I want is to inspire others to think about ways to improve Vuex and come up with something that works very well with the composition api. Ideally it could also be used without it. **@vue/composition-api is necessary**. | ||
There are the core principles that I try to achieve with this experiment: | ||
@@ -20,3 +22,4 @@ | ||
- Light layer on top of Vue 💨 keep it very lightweight | ||
- Only `state`, `getters` 👐 `patch` is the new _mutation_ | ||
- Only `state`, `getters` | ||
- No more verbose mutations, 👐 `patch` is _the mutation_ | ||
- Actions are like _methods_ ⚗️ Group your business there | ||
@@ -37,10 +40,15 @@ - Import what you need, let webpack code split 📦 No need for dynamically registered modules | ||
<p align="center"> | ||
<a href="https://vuetifyjs.com" target="_blank" title="Vuetify"> | ||
<img src="https://vuejs.org/images/vuetify.png" alt="Vuetify logo" height="48px"> | ||
</a> | ||
</p> | ||
<h3 align="center">Bronze Sponsors</h3> | ||
<p align="center"> | ||
<a href="https://vuetifyjs.com" target="_blank" title="Vuetify"> | ||
<img src="https://vuejs.org/images/vuetify.png" height="32px"> | ||
<a href="https://www.storyblok.com" target="_blank" title="Storyblok"> | ||
<img src="https://a.storyblok.com/f/51376/3856x824/fea44d52a9/colored-full.png" alt="Storyblok logo" height="32px"> | ||
</a> | ||
</p> | ||
--- | ||
@@ -62,5 +70,8 @@ | ||
- [ ] Should the state be merged at the same level as actions and getters? | ||
- [ ] List Getters on DevTools | ||
- [x] Nuxt Module | ||
- [x] Should the state be merged at the same level as actions and getters? | ||
- [ ] Flag to remove devtools support (for very light production apps) | ||
- [ ] Allow grouping stores together into a similar structure and allow defining new getters (`pinia`) | ||
- [ ] Getter with params that act like computed properties (@ktsn) | ||
- ~~Getter with params that act like computed properties (@ktsn)~~ | ||
- [ ] Passing all getters to a getter (need Typing support) | ||
@@ -71,7 +82,9 @@ | ||
```sh | ||
yarn add pinia@next | ||
yarn add pinia @vue/composition-api | ||
# or with npm | ||
npm install pinia@next | ||
npm install pinia @vue/composition-api | ||
``` | ||
Note: **The Vue Composition API plugin must be installed for Pinia to work** | ||
## Usage | ||
@@ -97,5 +110,9 @@ | ||
getters: { | ||
doubleCount: (state, getters) => state.counter * 2, | ||
doubleCount() { | ||
return this.counter * 2, | ||
}, | ||
// use getters in other getters | ||
doubleCountPlusOne: (state, { doubleCount }) => doubleCount.value * 2, | ||
doubleCountPlusOne() { | ||
return this.doubleCount * 2 | ||
} | ||
}, | ||
@@ -106,3 +123,3 @@ // optional actions | ||
// `this` is the store instance | ||
this.state.counter = 0 | ||
this.counter = 0 | ||
}, | ||
@@ -125,5 +142,6 @@ }, | ||
main, | ||
// gives access to the state | ||
state: main.state, | ||
// gives access to specific getter, | ||
// gives access only to specific state | ||
state: computed(() => main.counter), | ||
// gives access to specific getter; like `computed` properties | ||
doubleCount: computed(() => main.doubleCount), | ||
} | ||
@@ -134,19 +152,85 @@ }, | ||
Note: the SSR implementation is yet to be decided on Pinia, but if you intend having SSR on your application, you should avoid using `useStore` functions at the root level of a file to make sure the correct store is retrieved for your request. | ||
**There is one important rule for this to work**: the `useMainStore` (or any other _useStore_ function) must be called inside of deferred functions. This is to allow the **Vue Composition API plugin to be installed**. **Never, ever call `useStore`** like this: | ||
Once you have access to the store, you can access the `state` through `store.state` and any getter directly on the `store` itself as a _computed_ property (meaning you need to use `.value` to read the actual value on the JavaScript but not in the template): | ||
```ts | ||
import { useMainStore } from '@/stores/main' | ||
// ❌ Depending on where you do this it will fail | ||
// so just don't do it | ||
const main = useMainStore() | ||
export default defineComponent({ | ||
setup() { | ||
return {} | ||
}, | ||
}) | ||
``` | ||
Or: | ||
```ts | ||
import Router from 'vue-router' | ||
const router = new Router({ | ||
// ... | ||
}) | ||
// ❌ Depending on where you do this it will fail | ||
const main = useMainStore() | ||
router.beforeEach((to, from, next) => { | ||
if (main.state.isLoggedIn) next() | ||
else next('/login') | ||
}) | ||
``` | ||
It must be called **after the Composition API plugin is installed**. That's why calling `useStore` inside functions is usually safe, because they are called after the plugin being installed: | ||
```ts | ||
export default defineComponent({ | ||
setup() { | ||
// ✅ This will work | ||
const main = useMainStore() | ||
const text = main.state.name | ||
const doubleCount = main.doubleCount.value // notice the `.value` at the end | ||
return {} | ||
}, | ||
}) | ||
// In a different file... | ||
router.beforeEach((to, from, next) => { | ||
// ✅ This will work (requires an extra param for SSR, see below) | ||
const main = useMainStore() | ||
if (main.state.isLoggedIn) next() | ||
else next('/login') | ||
}) | ||
``` | ||
`state` is the result of a `ref` while every getter is the result of a `computed`. | ||
⚠️: Note that if you are developing an SSR application, [you will need to do a bit more](#ssr). | ||
You can access any property defined in `state` and `getters` directly on the store, similar to `data` and `computed` properties in a Vue component. | ||
```ts | ||
export default defineComponent({ | ||
setup() { | ||
const main = useMainStore() | ||
const text = main.name | ||
const doubleCount = main.doubleCount | ||
return {} | ||
}, | ||
}) | ||
``` | ||
The `main` store in an object wrapped with `reactive`, meaning there is no need to write `.value` after getters but, like `props` in `setup`, we cannot destructure it: | ||
```ts | ||
export default defineComponent({ | ||
setup() { | ||
// ❌ This won't work because it breaks reactivity | ||
// it's the same as destructuring from `props` | ||
const { name, doubleCount } = useMainStore() | ||
return { name, doubleCount } | ||
}, | ||
}) | ||
``` | ||
Actions are invoked like methods: | ||
@@ -171,3 +255,3 @@ | ||
```ts | ||
main.state.counter++ | ||
main.counter++ | ||
``` | ||
@@ -184,3 +268,3 @@ | ||
The main difference here is that `patch` allows you to group multiple changes into one single entry in the devtools (which are not yet available for Vue 3.x). | ||
The main difference here is that `patch` allows you to group multiple changes into one single entry in the devtools. | ||
@@ -197,4 +281,112 @@ ### Replacing the `state` | ||
To be decided once SSR is implemented on Vue 3 | ||
When writing a Single Page Application, there always only one instance of the store, but on the server, each request will create new store instances. For Pinia to track which one should be used, we rely on the _Request_ object (usually named `req`). Pinia makes this automatic in a few places: | ||
- actions | ||
- getters | ||
- `setup` | ||
- `serverPrefetch` | ||
Meaning that you can call `useMainStore` at the top of these functions and it will retrieve the correct store. **Calling it anywhere else requires you to pass the current `req` to `useMainStore`**. | ||
#### Nuxt Plugin | ||
SSR is much easier with Nuxt, and so is for Pinia: include the Pinia module in your `buildModules` in your `nuxt.config.js`: | ||
```js | ||
export default { | ||
// ... | ||
// rest of the nuxt config | ||
// ... | ||
buildModules: ['pinia/nuxt'], | ||
} | ||
``` | ||
By default, it will also disable Vuex so you can directly use the `store` folder for pinia. If you want to keep using Vuex, you need to provide an option in `nuxt.config.js`: | ||
```js | ||
export default { | ||
disableVuex: false, | ||
} | ||
``` | ||
If you are dealing with SSR, in order to make sure the correct store is retrieved by `useStore` functions, pass the current `req` to `useStore`. **This is necessary anywhere not in the list above**: | ||
```js | ||
export default { | ||
async fetch({ req }) { | ||
const store = useStore(req) | ||
}, | ||
} | ||
``` | ||
Note: **This is necessary in middlewares and other asynchronous methods**. | ||
It may look like things are working even if you don't pass `req` to `useStore` **but multiple concurrent requests to the server could end up sharing state between different users**. | ||
#### Raw Vue SSR | ||
In a Raw Vue SSR application you have to modify a few files to enable hydration and to tell requests apart. | ||
```js | ||
// entry-server.js | ||
import { getRootState, PiniaSsr } from 'pinia' | ||
// install plugin to automatically use correct context in setup and onServerPrefetch | ||
Vue.use(PiniaSsr) | ||
export default context => { | ||
/* ... */ | ||
context.rendered = () => { | ||
// pass state to context | ||
context.piniaState = getRootState(context.req) | ||
} | ||
/* ... */ | ||
} | ||
``` | ||
```html | ||
<!-- index.html --> | ||
<body> | ||
<!-- pass state from context to client --> | ||
{{{ renderState({ contextKey: 'piniaState', windowKey: '__PINIA_STATE__' }) | ||
}}} | ||
</body> | ||
``` | ||
```js | ||
// entry-client.js | ||
import { setStateProvider } from 'pinia' | ||
// inject ssr-state | ||
setStateProvider(() => window.__PINIA_STATE__) | ||
``` | ||
### Accessing other Stores | ||
You can `useOtherStore` inside a store `actions` and `getters`: | ||
Actions are simply function that contain business logic. As with components, they **must call `useStore`** to retrieve the store: | ||
```ts | ||
createStore({ | ||
id: 'cart', | ||
state: () => ({ items: [] }), | ||
getters: { | ||
message() { | ||
const user = useUserStore() | ||
return `Hi ${user.name}, you have ${this.items.length} items in the cart` | ||
}, | ||
}, | ||
actions: { | ||
async purchase() { | ||
const user = useUserStore() | ||
await apiBuy(user.token, this.items) | ||
this.items = [] | ||
}, | ||
}, | ||
}) | ||
``` | ||
### Composing Stores | ||
@@ -225,3 +417,3 @@ | ||
return `Hi ${user.state.name}, you have ${cart.state.list.length} items in your cart. It costs ${cart.price}.` | ||
return `Hi ${user.name}, you have ${cart.list.length} items in your cart. It costs ${cart.price}.` | ||
}, | ||
@@ -250,3 +442,3 @@ }, | ||
try { | ||
await apiOrderCart(user.state.token, cart.state.items) | ||
await apiOrderCart(user.token, cart.items) | ||
cart.emptyCart() | ||
@@ -279,4 +471,5 @@ } catch (err) { | ||
getters: { | ||
combinedGetter: ({ user, cart }) => | ||
`Hi ${user.state.name}, you have ${cart.state.list.length} items in your cart. It costs ${cart.price}.`, | ||
combinedGetter () { | ||
return `Hi ${this.user.name}, you have ${this.cart.list.length} items in your cart. It costs ${this.cart.price}.`, | ||
} | ||
}, | ||
@@ -286,3 +479,3 @@ actions: { | ||
try { | ||
await apiOrderCart(this.user.state.token, this.cart.state.items) | ||
await apiOrderCart(this.user.token, this.cart.items) | ||
this.cart.emptyCart() | ||
@@ -298,6 +491,31 @@ } catch (err) { | ||
## TypeScript | ||
Pinia is conceived to make typing automatic, benefiting both, JS and, TS users. There are however different ways of handling types when using TS | ||
### Using an interface to type the `state` | ||
If you want to define your own interface to type the _state_, explicitly type the return type of the `state` function: | ||
```ts | ||
interface MainState { | ||
counter: number | ||
name: string | ||
} | ||
export const useMainStore = createStore({ | ||
id: 'main', | ||
state: (): MainState => ({ | ||
counter: 0, | ||
name: 'Paimon', | ||
}), | ||
}) | ||
``` | ||
## Related | ||
- Vuex 5 | ||
## License | ||
[MIT](http://opensource.org/licenses/MIT) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
71332
18
0
1177
505
26