diff --git a/examples/vite/src/App.vue b/examples/vite/src/App.vue
index a0fc5b4..e3394bc 100644
--- a/examples/vite/src/App.vue
+++ b/examples/vite/src/App.vue
@@ -1,13 +1,7 @@
diff --git a/examples/vite/src/store.ts b/examples/vite/src/store.ts
index 96c29c3..8552a57 100644
--- a/examples/vite/src/store.ts
+++ b/examples/vite/src/store.ts
@@ -18,7 +18,7 @@ export const useCounterStore = defineStore('counter', {
},
},
- // share: {
- // enable: true,
- // },
+ share: {
+ enable: true,
+ },
})
diff --git a/src/index.ts b/src/index.ts
index 304234e..c8ac3f0 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,12 +1,19 @@
-import { toRaw } from 'vue-demi'
import type { MethodType } from 'broadcast-channel'
import { BroadcastChannel as BroadcastChannelImpl } from 'broadcast-channel'
import type { PiniaPluginContext } from 'pinia'
+import { serialize, type Serializer } from './utils'
function stateHasKey(key: string, $state: PiniaPluginContext['store']['$state']) {
return Object.keys($state).includes(key)
}
+interface Options {
+ initialize?: boolean
+ enable?: boolean
+ type?: MethodType
+ serializer?: Serializer
+}
+
/**
* Adds a `share` option to your store to share state across browser tabs.
*
@@ -23,8 +30,14 @@ function stateHasKey(key: string, $state: PiniaPluginContext['store']['$state'])
* @param options.enable - Enable/disable sharing of state for all stores.
* @param options.initialize - Immediately recover the shared state from another tab.
* @param options.type - 'native', 'idb', 'localstorage', 'node'.
+ * @param options.serializer - Custom serializer to serialize state before broadcasting.
*/
-export function PiniaSharedState({ enable = true, initialize = true, type }: { initialize?: boolean, enable?: boolean, type?: MethodType }) {
+export function PiniaSharedState({
+ enable = true,
+ initialize = true,
+ type,
+ serializer,
+}: Options) {
return ({ store, options }: PiniaPluginContext) => {
const isEnabled = options?.share?.enable ?? enable
const omittedKeys = options?.share?.omit ?? []
@@ -44,7 +57,7 @@ export function PiniaSharedState({ enable = true, initialize = true, type }: { i
if (newState === undefined) {
channel.postMessage({
timestamp,
- state: toRaw(store.$state),
+ state: serialize(store.$state, serializer),
})
return
}
@@ -71,7 +84,7 @@ export function PiniaSharedState({ enable = true, initialize = true, type }: { i
timestamp = Date.now()
channel.postMessage({
timestamp,
- state: toRaw(state),
+ state: serialize(state, serializer),
})
}
externalUpdate = false
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..aa15d5a
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,11 @@
+export interface Serializer {
+ serialize: (value: any) => string
+ deserialize: (value: string) => any
+}
+
+export function serialize(
+ obj: Record,
+ serializer: Serializer = { serialize: JSON.stringify, deserialize: JSON.parse }
+) {
+ return serializer.deserialize(serializer.serialize(obj))
+}
diff --git a/src/vanilla.ts b/src/vanilla.ts
index cc08884..f39e3ad 100644
--- a/src/vanilla.ts
+++ b/src/vanilla.ts
@@ -1,7 +1,7 @@
-import { toRaw } from 'vue-demi'
import type { MethodType } from 'broadcast-channel'
import { BroadcastChannel as BroadcastChannelImpl } from 'broadcast-channel'
import type { Store } from 'pinia'
+import { Serializer, serialize } from './utils'
/**
* Share state across browser tabs.
@@ -21,11 +21,12 @@ import type { Store } from 'pinia'
* @param options - Share state options.
* @param options.initialize - Immediately recover the shared state from another tab.
* @param options.type - 'native', 'idb', 'localstorage', 'node'.
+ * @param options.serializer - Custom serializer to serialize state before broadcasting.
*/
export function share(
key: K,
store: T,
- { initialize, type }: { initialize: boolean, type?: MethodType },
+ { initialize, serializer, type }: { initialize: boolean, serializer?: Serializer, type?: MethodType },
): { sync: () => void, unshare: () => void } {
const channelName = `${store.$id}-${key.toString()}`
@@ -40,8 +41,7 @@ export function share(
timestamp = Date.now()
channel.postMessage({
timestamp,
- // @ts-expect-error: TODO
- newValue: toRaw(state)[key],
+ newValue: serialize(state, serializer)[key],
})
}
externalUpdate = false
@@ -52,7 +52,7 @@ export function share(
channel.postMessage({
timestamp,
// @ts-expect-error: TODO
- newValue: toRaw(store.$state)[key],
+ newValue: serialize(store.$state, serializer)[key],
})
return
}