diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bc8336c..b3b7cdd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -35,4 +35,6 @@ jobs: run: pnpm build && pnpm publish-package env: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - + TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.event.repository.owner.login }} + REPO: ${{ github.event.repository.name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3158653..7bde1c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,6 +27,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} flags: fork-me - uses: paambaati/codeclimate-action@v5.0.0 + continue-on-error: true env: CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} with: diff --git a/examples/nextjs/CHANGELOG.md b/examples/nextjs/CHANGELOG.md index 30a5210..43e5a3f 100644 --- a/examples/nextjs/CHANGELOG.md +++ b/examples/nextjs/CHANGELOG.md @@ -1,5 +1,12 @@ # nextjs-example +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - persist-and-sync@1.1.1 + ## 1.0.2 ### Patch Changes diff --git a/examples/nextjs/app/store.ts b/examples/nextjs/app/store.ts index cb12379..5d9104e 100644 --- a/examples/nextjs/app/store.ts +++ b/examples/nextjs/app/store.ts @@ -20,6 +20,6 @@ export const useMyStore = create()( set(state => ({ ...state, _count })); }, }), - { name: "example", exclude: ["_count"] }, + { name: "example", exclude: ["_count"], storage: "cookies" }, ), ); diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 4f8b1a0..46bd385 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "nextjs-example", - "version": "1.0.2", + "version": "1.0.3", "private": true, "scripts": { "dev": "next dev --port 3001", @@ -13,12 +13,12 @@ "persist-and-sync": "workspace:*", "react": "^18.2.0", "react-dom": "^18.2.0", - "zustand": "^4.4.6" + "zustand": "^4.4.7" }, "devDependencies": { "@next/eslint-plugin-next": "^14.0.3", - "@types/node": "^20.9.4", - "@types/react": "^18.2.38", + "@types/node": "^20.10.2", + "@types/react": "^18.2.41", "@types/react-dom": "^18.2.17", "eslint-config-custom": "workspace:*", "tsconfig": "workspace:*", diff --git a/package.json b/package.json index 15923e4..4c01df9 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,md,css,scss}\"" }, "devDependencies": { - "@changesets/cli": "^2.26.2", - "eslint": "^8.54.0", + "@changesets/cli": "^2.27.1", + "eslint": "^8.55.0", "prettier": "^3.1.0", "tsconfig": "workspace:*", "turbo": "^1.10.16" diff --git a/packages/persist-and-sync/CHANGELOG.md b/packages/persist-and-sync/CHANGELOG.md index 5bfcba2..b23fc13 100644 --- a/packages/persist-and-sync/CHANGELOG.md +++ b/packages/persist-and-sync/CHANGELOG.md @@ -1,5 +1,11 @@ # persist-and-sync +## 1.1.1 + +### Patch Changes + +- Updated internal sync mechanism + ## 1.1.0 ### Minor Changes diff --git a/packages/persist-and-sync/__tests__/index.test.ts b/packages/persist-and-sync/__tests__/index.test.ts index e01506c..1f16d58 100644 --- a/packages/persist-and-sync/__tests__/index.test.ts +++ b/packages/persist-and-sync/__tests__/index.test.ts @@ -1,7 +1,7 @@ import { act, cleanup, renderHook } from "@testing-library/react"; import { afterEach, describe, test } from "vitest"; -import { useMyStore } from "./store"; +import { useCookieStore, useMyStore } from "./store"; describe.concurrent("Setting state", () => { afterEach(cleanup); @@ -11,7 +11,7 @@ describe.concurrent("Setting state", () => { }); test("test setting state", async ({ expect }) => { - const { result } = renderHook(() => useMyStore()); + const { result } = renderHook(() => useCookieStore()); act(() => result.current.setCount(5)); expect(result.current.count).toBe(5); expect(localStorage.getItem("example")).toBe('{"count":5}'); diff --git a/packages/persist-and-sync/__tests__/store.ts b/packages/persist-and-sync/__tests__/store.ts index 444b9ce..5a41bc7 100644 --- a/packages/persist-and-sync/__tests__/store.ts +++ b/packages/persist-and-sync/__tests__/store.ts @@ -1,4 +1,4 @@ -import { create } from "../vitest-setup"; +import { create } from "../vitest.setup"; import { persistNSync } from "../src"; type MyStoreType = { @@ -16,6 +16,18 @@ export const useMyStore = create( setCount: count => set(state => ({ ...state, count })), set_Count: _count => set(state => ({ ...state, _count })), }), - { name: "example", regExpToIgnore: /^_/ }, + { name: "example", exclude: [/^_/] }, + ), +); + +export const useCookieStore = create( + persistNSync( + set => ({ + count: 0, + _count: 0 /** skipped as it matches the regexp provided */, + setCount: count => set(state => ({ ...state, count })), + set_Count: _count => set(state => ({ ...state, _count })), + }), + { name: "example", include: [/count/], exclude: [/^_/], storage: "cookies" }, ), ); diff --git a/packages/persist-and-sync/createPackageJSON.js b/packages/persist-and-sync/createPackageJSON.js index 3392336..b96a3e0 100644 --- a/packages/persist-and-sync/createPackageJSON.js +++ b/packages/persist-and-sync/createPackageJSON.js @@ -3,12 +3,42 @@ const fs = require("fs"); const path = require("path"); const packageJson = require(path.resolve(__dirname, "package.json")); +if (process.env.TOKEN) { + const { Octokit } = require("octokit"); + // Octokit.js + // https://github.com/octokit/core.js#readme + const octokit = new Octokit({ + auth: process.env.TOKEN, + }); -const { devDependencies, scripts, ...newPackageJSON } = packageJson; -newPackageJSON.main = packageJson.main.split("/")[1]; -newPackageJSON.types = packageJson.types.split("/")[1]; + const octoOptions = { + owner: process.env.OWNER, + repo: process.env.REPO, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + }, + }; + const tagName = `v${packageJson.version}`; + const name = `Release ${tagName}`; + /** Create a release */ + octokit.request("POST /repos/{owner}/{repo}/releases", { + ...octoOptions, + tag_name: tagName, + target_commitish: "main", + name, + draft: false, + prerelease: false, + generate_release_notes: true, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + }, + }); +} +delete packageJson.scripts; +packageJson.main = packageJson.main.split("/")[1]; +packageJson.types = packageJson.types.split("/")[1]; fs.writeFileSync( path.resolve(__dirname, "dist", "package.json"), - JSON.stringify(newPackageJSON, null, 2), + JSON.stringify(packageJson, null, 2), ); diff --git a/packages/persist-and-sync/package.json b/packages/persist-and-sync/package.json index b791b70..7a67e9f 100644 --- a/packages/persist-and-sync/package.json +++ b/packages/persist-and-sync/package.json @@ -1,7 +1,7 @@ { "name": "persist-and-sync", "author": "Mayank Kumar Chaudhari ", - "version": "1.1.0", + "version": "1.1.1", "description": "Zustand middleware to easily persist and sync Zustand state between tabs and windows", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -26,13 +26,14 @@ }, "devDependencies": { "@testing-library/react": "^14.1.2", - "@types/node": "^20.9.4", + "@types/node": "^20.10.2", "@vitejs/plugin-react": "^4.2.0", "@vitest/coverage-v8": "^0.34.6", - "jsdom": "^22.1.0", + "jsdom": "^23.0.1", + "octokit": "^3.1.2", "typescript": "^5.3.2", "vitest": "^0.34.6", - "zustand": "^4.4.6" + "zustand": "^4.4.7" }, "peerDependencies": { "zustand": "^3 || ^4" diff --git a/packages/persist-and-sync/src/index.ts b/packages/persist-and-sync/src/index.ts index 0f77d9b..47dbc94 100644 --- a/packages/persist-and-sync/src/index.ts +++ b/packages/persist-and-sync/src/index.ts @@ -27,7 +27,7 @@ function getItem(options: PersistNSyncOptionsType) { function setItem(options: PersistNSyncOptionsType, value: string) { const { storage } = options; if (storage === "cookies") { - document.cookie = `${options.name}=${value}; max-age=31536000`; + document.cookie = `${options.name}=${value}; max-age=31536000; SameSite=Strict;`; } if (storage === "sessionStorage") sessionStorage.setItem(options.name, value); else localStorage.setItem(options.name, value); @@ -48,27 +48,23 @@ export const persistNSync: PersistNSyncType = (stateCreator, options) => (set, g /** timeout 0 is enough. timeout 100 is added to avoid server and client render content mismatch error */ if (savedState) setTimeout(() => set({ ...get(), ...JSON.parse(savedState) }), 100); - const channel = globalThis.BroadcastChannel ? new BroadcastChannel(name) : undefined; - const set_: typeof set = (newStateOrPartialOrFunction, replace) => { - const prevState = get() as { [k: string]: any }; set(newStateOrPartialOrFunction, replace); const newState = get() as { [k: string]: any }; - saveAndSync({ newState, prevState, channel, options }); + saveAndSync({ newState, options }); }; - if (channel) { - channel.onmessage = e => { - set({ ...get(), ...e.data }); - }; - } + window.addEventListener("storage", e => { + if (e.key === name) { + const newState = JSON.parse(e.newValue || "{}"); + set({ ...get(), ...newState }); + } + }); return stateCreator(set_, get, store); }; interface SaveAndSyncProps { newState: { [k: string]: any }; - prevState: { [k: string]: any }; - channel?: BroadcastChannel; options: PersistNSyncOptionsType; } @@ -107,7 +103,7 @@ const getKeysToPersistAndSyncMemoised = (() => { }; })(); -function saveAndSync({ newState, prevState, channel, options }: SaveAndSyncProps) { +function saveAndSync({ newState, options }: SaveAndSyncProps) { const keysToPersistAndSync = getKeysToPersistAndSyncMemoised(Object.keys(newState), options); if (keysToPersistAndSync.length === 0) return; @@ -115,13 +111,4 @@ function saveAndSync({ newState, prevState, channel, options }: SaveAndSyncProps const stateToStore: { [k: string]: any } = {}; keysToPersistAndSync.forEach(key => (stateToStore[key] = newState[key])); setItem(options, JSON.stringify(stateToStore)); - - if (!channel) return; - const stateUpdates: { [k: string]: any } = {}; - keysToPersistAndSync.forEach(key => { - if (newState[key] !== prevState[key]) stateUpdates[key] = newState[key]; - }); - if (Object.keys(stateUpdates).length) { - channel?.postMessage(stateUpdates); - } } diff --git a/packages/persist-and-sync/vitest.config.ts b/packages/persist-and-sync/vitest.config.ts index 53344af..9055687 100644 --- a/packages/persist-and-sync/vitest.config.ts +++ b/packages/persist-and-sync/vitest.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ test: { environment: "jsdom", globals: true, - setupFiles: ["vitest-setup.ts"], + setupFiles: ["vitest.setup.ts"], coverage: { reporter: ["text", "json", "clover", "html"], }, diff --git a/packages/persist-and-sync/vitest-setup.ts b/packages/persist-and-sync/vitest.setup.ts similarity index 100% rename from packages/persist-and-sync/vitest-setup.ts rename to packages/persist-and-sync/vitest.setup.ts