From 4c45ec0e784e53d726ff71618f8af1efd76804cc Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Sat, 25 Jun 2022 02:31:03 +0400 Subject: [PATCH 1/2] fix: install plugins after app is set (#1063) --- packages/pinia/src/createPinia.ts | 26 +++++++++++++++-- packages/pinia/src/rootStore.ts | 8 ++++++ packages/pinia/src/store.ts | 46 ++++++++++++++++--------------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/packages/pinia/src/createPinia.ts b/packages/pinia/src/createPinia.ts index f105460e5..796d1c706 100644 --- a/packages/pinia/src/createPinia.ts +++ b/packages/pinia/src/createPinia.ts @@ -18,6 +18,8 @@ export function createPinia(): Pinia { let _p: Pinia['_p'] = [] // plugins added before calling app.use(pinia) let toBeInstalled: PiniaPlugin[] = [] + let afterInitializeCallbacks: ((app: App) => void)[] = [] + let _a: App | null = null const pinia: Pinia = markRaw({ install(app: App) { @@ -47,9 +49,27 @@ export function createPinia(): Pinia { }, _p, - // it's actually undefined here - // @ts-expect-error - _a: null, + + get _a() { + return _a! + }, + set _a(app) { + _a = app + + if (app) { + afterInitializeCallbacks.forEach((cb) => cb(app)) + afterInitializeCallbacks = [] + } + }, + + afterAppInit(cb: (app: App) => void) { + if (_a) { + cb(_a) + } else { + afterInitializeCallbacks.push(cb) + } + }, + _e: scope, _s: new Map(), state, diff --git a/packages/pinia/src/rootStore.ts b/packages/pinia/src/rootStore.ts index 0509a5c8e..d5ec8f8fe 100644 --- a/packages/pinia/src/rootStore.ts +++ b/packages/pinia/src/rootStore.ts @@ -57,6 +57,14 @@ export interface Pinia { */ use(plugin: PiniaPlugin): Pinia + /** + * Executes callback after pinia._a is set, or immediately, if it is set already + * + * @internal + * @param cb - callback to execute + */ + afterAppInit(cb: (app: App) => void): void + /** * Installed store plugins * diff --git a/packages/pinia/src/store.ts b/packages/pinia/src/store.ts index d7156a0ea..1df275aca 100644 --- a/packages/pinia/src/store.ts +++ b/packages/pinia/src/store.ts @@ -676,34 +676,36 @@ function createSetupStore< } // apply all plugins - pinia._p.forEach((extender) => { - /* istanbul ignore else */ - if (__DEV__ && IS_CLIENT) { - const extensions = scope.run(() => - extender({ - store, - app: pinia._a, - pinia, - options: optionsForPlugin, - }) - )! - Object.keys(extensions || {}).forEach((key) => - store._customProperties.add(key) - ) - assign(store, extensions) - } else { - assign( - store, - scope.run(() => + pinia.afterAppInit((app) => { + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if (__DEV__ && IS_CLIENT) { + const extensions = scope.run(() => extender({ store, - app: pinia._a, + app, pinia, options: optionsForPlugin, }) )! - ) - } + Object.keys(extensions || {}).forEach((key) => + store._customProperties.add(key) + ) + assign(store, extensions) + } else { + assign( + store, + scope.run(() => + extender({ + store, + app, + pinia, + options: optionsForPlugin, + }) + )! + ) + } + }) }) if ( From 9ea96a4cef2d9fb38d5656b4fc534eb8141a6996 Mon Sep 17 00:00:00 2001 From: Alex Popov Date: Sat, 25 Jun 2022 23:52:42 +0400 Subject: [PATCH 2/2] fix: install devtools plugin after app is set, but revert change for other plugins --- packages/pinia/src/createPinia.ts | 10 +++--- packages/pinia/src/devtools/plugin.ts | 12 ++++--- packages/pinia/src/rootStore.ts | 4 +-- packages/pinia/src/store.ts | 46 +++++++++++++-------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/pinia/src/createPinia.ts b/packages/pinia/src/createPinia.ts index 796d1c706..342a88d94 100644 --- a/packages/pinia/src/createPinia.ts +++ b/packages/pinia/src/createPinia.ts @@ -18,7 +18,7 @@ export function createPinia(): Pinia { let _p: Pinia['_p'] = [] // plugins added before calling app.use(pinia) let toBeInstalled: PiniaPlugin[] = [] - let afterInitializeCallbacks: ((app: App) => void)[] = [] + let onInstallCallbacks: ((app: App) => void)[] = [] let _a: App | null = null const pinia: Pinia = markRaw({ @@ -57,16 +57,16 @@ export function createPinia(): Pinia { _a = app if (app) { - afterInitializeCallbacks.forEach((cb) => cb(app)) - afterInitializeCallbacks = [] + onInstallCallbacks.forEach((cb) => cb(app)) + onInstallCallbacks = [] } }, - afterAppInit(cb: (app: App) => void) { + onInstall(cb: (app: App) => void) { if (_a) { cb(_a) } else { - afterInitializeCallbacks.push(cb) + onInstallCallbacks.push(cb) } }, diff --git a/packages/pinia/src/devtools/plugin.ts b/packages/pinia/src/devtools/plugin.ts index 04e4abdc5..327f237fb 100644 --- a/packages/pinia/src/devtools/plugin.ts +++ b/packages/pinia/src/devtools/plugin.ts @@ -521,7 +521,7 @@ export function devtoolsPlugin< S extends StateTree = StateTree, G /* extends GettersTree */ = _GettersTree, A /* extends ActionsTree */ = _ActionsTree ->({ app, store, options }: PiniaPluginContext) { +>({ store, options, pinia }: PiniaPluginContext) { // HMR module if (store.$id.startsWith('__hot:')) { return @@ -553,9 +553,11 @@ export function devtoolsPlugin< } } - addStoreToDevtools( - app, - // FIXME: is there a way to allow the assignment from Store to StoreGeneric? - store as StoreGeneric + pinia.onInstall((app) => + addStoreToDevtools( + app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store as StoreGeneric + ) ) } diff --git a/packages/pinia/src/rootStore.ts b/packages/pinia/src/rootStore.ts index d5ec8f8fe..359ea0a6b 100644 --- a/packages/pinia/src/rootStore.ts +++ b/packages/pinia/src/rootStore.ts @@ -58,12 +58,12 @@ export interface Pinia { use(plugin: PiniaPlugin): Pinia /** - * Executes callback after pinia._a is set, or immediately, if it is set already + * Executes callback after Pinia is installed into Vue app * * @internal * @param cb - callback to execute */ - afterAppInit(cb: (app: App) => void): void + onInstall(cb: (app: App) => void): void /** * Installed store plugins diff --git a/packages/pinia/src/store.ts b/packages/pinia/src/store.ts index 1df275aca..d7156a0ea 100644 --- a/packages/pinia/src/store.ts +++ b/packages/pinia/src/store.ts @@ -676,36 +676,34 @@ function createSetupStore< } // apply all plugins - pinia.afterAppInit((app) => { - pinia._p.forEach((extender) => { - /* istanbul ignore else */ - if (__DEV__ && IS_CLIENT) { - const extensions = scope.run(() => + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if (__DEV__ && IS_CLIENT) { + const extensions = scope.run(() => + extender({ + store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }) + )! + Object.keys(extensions || {}).forEach((key) => + store._customProperties.add(key) + ) + assign(store, extensions) + } else { + assign( + store, + scope.run(() => extender({ store, - app, + app: pinia._a, pinia, options: optionsForPlugin, }) )! - Object.keys(extensions || {}).forEach((key) => - store._customProperties.add(key) - ) - assign(store, extensions) - } else { - assign( - store, - scope.run(() => - extender({ - store, - app, - pinia, - options: optionsForPlugin, - }) - )! - ) - } - }) + ) + } }) if (