diff --git a/package-lock.json b/package-lock.json index ef625b11..be821471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2351,19 +2351,6 @@ "resolved": "packages/sdk", "link": true }, - "node_modules/@gristlabs/moment-guess": { - "version": "1.2.4-grist.1", - "resolved": "https://registry.npmjs.org/@gristlabs/moment-guess/-/moment-guess-1.2.4-grist.1.tgz", - "integrity": "sha512-emosrHFak1JYEjZmZoeLO+sjTD48Amx2NH/BRCmiCwH50fcK1VvfwrWHjRu2oQ5p8+yuZxHRxsm0+2KANaNLdg==", - "license": "MIT", - "dependencies": { - "arg": "^4.1.3", - "chalk": "^4.1.0" - }, - "bin": { - "moment-guess": "bin/bundle.cmd.js" - } - }, "node_modules/@humanfs/core": { "version": "0.19.1", "dev": true, @@ -5315,13 +5302,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/moment-guess": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/moment-guess/-/moment-guess-1.2.2.tgz", - "integrity": "sha512-6mM8NKyCB4HnLqoNdfAqpHu98VVwMCle+Dtz5dQs1G1AXIQaBMDX7JM52NTMMTIm6NatgJG+gB7TdrbmyVrCyA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -5429,6 +5409,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/statuses": { "version": "2.0.5", "dev": true, @@ -6012,6 +5999,7 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6042,6 +6030,7 @@ }, "node_modules/arg": { "version": "4.1.3", + "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -6808,6 +6797,7 @@ }, "node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -11333,6 +11323,7 @@ }, "node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17401,7 +17392,6 @@ }, "node_modules/semver": { "version": "6.3.1", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -18052,6 +18042,7 @@ }, "node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -20070,7 +20061,6 @@ "@datapunt/matomo-tracker-react": "^0.5.1", "@gephi/gephi-lite-broadcast": "^0.6.2", "@gephi/gephi-lite-sdk": "^0.6.2", - "@gristlabs/moment-guess": "^1.2.4-grist.1", "@monaco-editor/react": "^4.6.0", "@octokit/auth-oauth-device": "^7.1.2", "@octokit/core": "^6.1.3", @@ -20130,6 +20120,7 @@ "react-tether": "^3.0.3", "react-use-konami": "^1.1.0", "seedrandom": "^3.0.5", + "semver": "^6.3.1", "sigma": "^3.0.0", "tlds": "^1.260.0" }, @@ -20143,7 +20134,6 @@ "@types/is-url": "^1.2.32", "@types/linkify-it": "^5.0.0", "@types/lodash": "^4.17.15", - "@types/moment-guess": "^1.2.2", "@types/node": "^22.12.0", "@types/react": "^18.3.18", "@types/react-color": "^3.0.13", @@ -20152,6 +20142,7 @@ "@types/react-linkify": "^1.0.4", "@types/react-slider": "^1.3.6", "@types/seedrandom": "^3.0.8", + "@types/semver": "^7.7.1", "@types/tether": "^1.4.9", "@vitejs/plugin-react-swc": "^3.7.2", "http-proxy-middleware": "^3.0.3", diff --git a/packages/gephi-lite/package.json b/packages/gephi-lite/package.json index a6a97d9c..dde551d9 100644 --- a/packages/gephi-lite/package.json +++ b/packages/gephi-lite/package.json @@ -93,6 +93,7 @@ "react-tether": "^3.0.3", "react-use-konami": "^1.1.0", "seedrandom": "^3.0.5", + "semver": "^6.3.1", "sigma": "^3.0.0", "tlds": "^1.260.0" }, @@ -114,6 +115,7 @@ "@types/react-linkify": "^1.0.4", "@types/react-slider": "^1.3.6", "@types/seedrandom": "^3.0.8", + "@types/semver": "^7.7.1", "@types/tether": "^1.4.9", "@vitejs/plugin-react-swc": "^3.7.2", "http-proxy-middleware": "^3.0.3", diff --git a/packages/gephi-lite/src/config.ts b/packages/gephi-lite/src/config.ts index 26aae0cf..1e6c36c3 100644 --- a/packages/gephi-lite/src/config.ts +++ b/packages/gephi-lite/src/config.ts @@ -1,7 +1,9 @@ +import { parse } from "semver"; + import { version } from "../package.json"; export const config = { - version, + version: parse(version)!, website_url: "https://github.com/gephi/gephi-lite#readme", notificationTimeoutMs: 3000, github_proxy: import.meta.env.VITE_GITHUB_PROXY || "/_github", diff --git a/packages/gephi-lite/src/core/Initialize.tsx b/packages/gephi-lite/src/core/Initialize.tsx index 2997febf..d6e16b56 100644 --- a/packages/gephi-lite/src/core/Initialize.tsx +++ b/packages/gephi-lite/src/core/Initialize.tsx @@ -5,6 +5,7 @@ import useKonami from "react-use-konami"; import { WelcomeModal } from "../components/modals/WelcomeModal"; import { I18n } from "../locales/provider"; +import { sessionStorage } from "../utils/storage"; import { extractFilename } from "../utils/url"; import { appearanceAtom } from "./appearance"; import { useBroadcast } from "./broadcast/useBroadcast"; diff --git a/packages/gephi-lite/src/core/appearance/index.ts b/packages/gephi-lite/src/core/appearance/index.ts index 7cfd6f9e..19239051 100644 --- a/packages/gephi-lite/src/core/appearance/index.ts +++ b/packages/gephi-lite/src/core/appearance/index.ts @@ -1,6 +1,7 @@ import { getEmptyAppearanceState, serializeAppearanceState } from "@gephi/gephi-lite-sdk"; import { Producer, atom, producerToAction } from "@ouestware/atoms"; +import { sessionStorage } from "../../utils/storage"; import { ItemType } from "../types"; import { AppearanceState, diff --git a/packages/gephi-lite/src/core/broadcast/client.ts b/packages/gephi-lite/src/core/broadcast/client.ts index cc375a01..a5f1c95f 100644 --- a/packages/gephi-lite/src/core/broadcast/client.ts +++ b/packages/gephi-lite/src/core/broadcast/client.ts @@ -39,7 +39,7 @@ const BROADCAST_METHODS: { return; }, getVersion: async () => { - return config.version; + return config.version.toString(); }, importGraph: async (data) => { if (fileAtom.get().status.type === "loading") throw new Error("A file is already being loaded"); diff --git a/packages/gephi-lite/src/core/file/index.ts b/packages/gephi-lite/src/core/file/index.ts index 88ec080f..3b419b05 100644 --- a/packages/gephi-lite/src/core/file/index.ts +++ b/packages/gephi-lite/src/core/file/index.ts @@ -5,6 +5,7 @@ import { write } from "graphology-gexf"; import { isEmpty, isEqual } from "lodash"; import { config } from "../../config"; +import { localStorage } from "../../utils/storage"; import { appearanceActions, appearanceAtom } from "../appearance"; import { applyVisualProperties, inferAppearanceState } from "../appearance/utils"; import { resetStates } from "../context/dataContexts"; @@ -132,7 +133,7 @@ export const exportAsGephiLite = asyncAction(async (callback: (data: string) => try { const data: GephiLiteFileFormat = { type: "gephi-lite", - version: config.version, + version: config.version.toString(), graphDataset: graphDatasetAtom.get(), filters: filtersAtom.get(), appearance: appearanceAtom.get(), diff --git a/packages/gephi-lite/src/core/filters/index.ts b/packages/gephi-lite/src/core/filters/index.ts index 7c8777a2..2d50dcec 100644 --- a/packages/gephi-lite/src/core/filters/index.ts +++ b/packages/gephi-lite/src/core/filters/index.ts @@ -1,6 +1,7 @@ import { Producer, atom, producerToAction } from "@ouestware/atoms"; import { dropRight, inRange } from "lodash"; +import { sessionStorage } from "../../utils/storage"; import { FilterType, FiltersState } from "./types"; import { getEmptyFiltersState, serializeFiltersState } from "./utils"; diff --git a/packages/gephi-lite/src/core/graph/index.ts b/packages/gephi-lite/src/core/graph/index.ts index ac22d117..a298aba9 100644 --- a/packages/gephi-lite/src/core/graph/index.ts +++ b/packages/gephi-lite/src/core/graph/index.ts @@ -23,6 +23,7 @@ import { clamp, forEach, isNil, isString, keyBy, keys, last, map, mapValues, omi import { Coordinates } from "sigma/types"; import { getPalette } from "../../components/GraphAppearance/color/utils"; +import { sessionStorage } from "../../utils/storage"; import { appearanceAtom } from "../appearance"; import { applyVisualProperties, getAllVisualGetters } from "../appearance/utils"; import { useGraphDataset } from "../context/dataContexts"; diff --git a/packages/gephi-lite/src/core/layouts/index.ts b/packages/gephi-lite/src/core/layouts/index.ts index a2002ee7..a0a65a47 100644 --- a/packages/gephi-lite/src/core/layouts/index.ts +++ b/packages/gephi-lite/src/core/layouts/index.ts @@ -3,6 +3,7 @@ import { connectedCloseness } from "graphology-metrics/layout-quality"; import { debounce, identity, pick } from "lodash"; import seedRandom from "seedrandom"; +import { localStorage } from "../../utils/storage"; import { EVENTS, emitter } from "../context/eventsContext"; import { graphDatasetActions, graphDatasetAtom, sigmaGraphAtom } from "../graph"; import { dataGraphToFullGraph } from "../graph/utils"; diff --git a/packages/gephi-lite/src/core/preferences/index.ts b/packages/gephi-lite/src/core/preferences/index.ts index d1d79f28..581b74a6 100644 --- a/packages/gephi-lite/src/core/preferences/index.ts +++ b/packages/gephi-lite/src/core/preferences/index.ts @@ -1,5 +1,6 @@ import { Producer, atom, producerToAction } from "@ouestware/atoms"; +import { localStorage } from "../../utils/storage"; import { Preferences } from "./types"; import { getAppliedTheme, getCurrentPreferences, serializePreferences } from "./utils"; diff --git a/packages/gephi-lite/src/core/preferences/utils.ts b/packages/gephi-lite/src/core/preferences/utils.ts index f8f6fb5e..238e0388 100644 --- a/packages/gephi-lite/src/core/preferences/utils.ts +++ b/packages/gephi-lite/src/core/preferences/utils.ts @@ -1,6 +1,7 @@ import { gephiLiteParse, gephiLiteStringify } from "@gephi/gephi-lite-sdk"; import { i18n } from "../../locales/provider"; +import { localStorage } from "../../utils/storage"; import { Preferences } from "./types"; export function getEmptyPreferences(): Preferences { diff --git a/packages/gephi-lite/src/core/session/index.ts b/packages/gephi-lite/src/core/session/index.ts index b0cbea4c..a0e625b1 100644 --- a/packages/gephi-lite/src/core/session/index.ts +++ b/packages/gephi-lite/src/core/session/index.ts @@ -1,5 +1,6 @@ import { Producer, atom, producerToAction } from "@ouestware/atoms"; +import { sessionStorage } from "../../utils/storage"; import { Session } from "./types"; import { getEmptySession, serializeSession } from "./utils"; diff --git a/packages/gephi-lite/src/core/user/AuthInit.tsx b/packages/gephi-lite/src/core/user/AuthInit.tsx index 21d8e3a8..37f9147d 100644 --- a/packages/gephi-lite/src/core/user/AuthInit.tsx +++ b/packages/gephi-lite/src/core/user/AuthInit.tsx @@ -2,6 +2,7 @@ import { isNil } from "lodash"; import { FC, useEffect } from "react"; import { useTranslation } from "react-i18next"; +import { localStorage } from "../../utils/storage"; import { ghProviderDeserialize } from "../cloud/github/provider"; import { useNotifications } from "../notifications"; import { LS_USER_KEY, useConnectedUser } from "./index"; diff --git a/packages/gephi-lite/src/core/user/index.tsx b/packages/gephi-lite/src/core/user/index.tsx index d6214007..3e50c4ef 100644 --- a/packages/gephi-lite/src/core/user/index.tsx +++ b/packages/gephi-lite/src/core/user/index.tsx @@ -1,6 +1,7 @@ import { Producer, atom, producerToAction, useAtom } from "@ouestware/atoms"; import { isNil } from "lodash"; +import { localStorage } from "../../utils/storage"; import { User } from "./types"; export const LS_USER_KEY = "user"; diff --git a/packages/gephi-lite/src/utils/storage.ts b/packages/gephi-lite/src/utils/storage.ts new file mode 100644 index 00000000..ab9df582 --- /dev/null +++ b/packages/gephi-lite/src/utils/storage.ts @@ -0,0 +1,16 @@ +import { config } from "../config"; + +function getPrefixedKey(key: string) { + return `${config.version.major}.${config.version.minor}_${key}`; +} +export const localStorage = { + getItem: (key: string): string | null => window.localStorage.getItem(getPrefixedKey(key)), + setItem: (key: string, data: string): void => window.localStorage.setItem(getPrefixedKey(key), data), + removeItem: (key: string): void => window.localStorage.removeItem(getPrefixedKey(key)), +}; + +export const sessionStorage = { + getItem: (key: string): string | null => window.sessionStorage.getItem(getPrefixedKey(key)), + setItem: (key: string, data: string): void => window.sessionStorage.setItem(getPrefixedKey(key), data), + removeItem: (key: string): void => window.sessionStorage.removeItem(getPrefixedKey(key)), +};