gitmaps 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -122
- package/app/[...slug]/page.client.tsx +1 -0
- package/app/[...slug]/page.tsx +6 -0
- package/app/[owner]/[repo]/page.client.tsx +5 -0
- package/app/[slug]/page.client.tsx +5 -0
- package/app/analytics.db +0 -0
- package/app/api/analytics/route.ts +64 -0
- package/app/api/auth/positions/route.ts +95 -33
- package/app/api/build-info/route.ts +19 -0
- package/app/api/chat/route.ts +13 -2
- package/app/api/manifest.json/route.ts +20 -0
- package/app/api/og-image/route.ts +14 -0
- package/app/api/pwa-icon/route.ts +14 -0
- package/app/api/repo/clone-stream/route.ts +20 -12
- package/app/api/repo/file-content/route.ts +73 -20
- package/app/api/repo/imports/route.ts +21 -3
- package/app/api/repo/list/route.ts +30 -0
- package/app/api/repo/load/route.test.ts +62 -0
- package/app/api/repo/load/route.ts +41 -1
- package/app/api/repo/pdf-thumb/route.ts +127 -0
- package/app/api/repo/resolve-slug/route.ts +51 -0
- package/app/api/repo/tree/route.ts +188 -104
- package/app/api/repo/upload/route.ts +6 -9
- package/app/api/sw.js/route.ts +70 -0
- package/app/api/version/route.ts +26 -0
- package/app/galaxy-canvas/page.client.tsx +2 -0
- package/app/galaxy-canvas/page.tsx +5 -0
- package/app/globals.css +5844 -4694
- package/app/icon.png +0 -0
- package/app/layout.tsx +1284 -467
- package/app/lib/auto-arrange.test.ts +158 -0
- package/app/lib/auto-arrange.ts +147 -0
- package/app/lib/canvas-export.ts +358 -358
- package/app/lib/canvas-text.ts +4 -72
- package/app/lib/canvas.ts +625 -564
- package/app/lib/card-arrangement.ts +21 -7
- package/app/lib/card-context-menu.tsx +2 -2
- package/app/lib/card-groups.ts +9 -2
- package/app/lib/cards.tsx +1361 -914
- package/app/lib/chat.tsx +65 -9
- package/app/lib/code-editor.ts +86 -2
- package/app/lib/connections.tsx +34 -43
- package/app/lib/context.test.ts +32 -0
- package/app/lib/context.ts +19 -3
- package/app/lib/cursor-sharing.ts +34 -0
- package/app/lib/events.tsx +76 -73
- package/app/lib/export-canvas.ts +287 -0
- package/app/lib/file-card-plugin.ts +148 -134
- package/app/lib/file-modal.tsx +49 -0
- package/app/lib/file-preview.ts +486 -400
- package/app/lib/github-import.test.ts +424 -0
- package/app/lib/global-search.ts +48 -27
- package/app/lib/initial-route-hydration.test.ts +283 -0
- package/app/lib/initial-route-hydration.ts +202 -0
- package/app/lib/landing-reset.test.ts +99 -0
- package/app/lib/landing-reset.ts +106 -0
- package/app/lib/landing-shell.test.ts +75 -0
- package/app/lib/large-repo-optimization.ts +37 -0
- package/app/lib/layers.tsx +17 -18
- package/app/lib/layout-snapshots.ts +320 -0
- package/app/lib/loading.test.ts +69 -0
- package/app/lib/loading.tsx +160 -45
- package/app/lib/mount-cleanup.test.ts +52 -0
- package/app/lib/mount-cleanup.ts +34 -0
- package/app/lib/mount-init.test.ts +123 -0
- package/app/lib/mount-init.ts +107 -0
- package/app/lib/mount-lifecycle.test.ts +39 -0
- package/app/lib/mount-lifecycle.ts +12 -0
- package/app/lib/mount-route-wiring.test.ts +87 -0
- package/app/lib/mount-route-wiring.ts +84 -0
- package/app/lib/multi-repo.ts +14 -0
- package/app/lib/onboarding-tutorial.ts +278 -0
- package/app/lib/perf-overlay.ts +78 -0
- package/app/lib/positions.ts +191 -122
- package/app/lib/recent-commits.test.ts +869 -0
- package/app/lib/recent-commits.ts +227 -0
- package/app/lib/repo-handoff.test.ts +23 -0
- package/app/lib/repo-handoff.ts +16 -0
- package/app/lib/repo-progressive.ts +119 -0
- package/app/lib/repo-select.test.ts +61 -0
- package/app/lib/repo-select.ts +74 -0
- package/app/lib/repo.tsx +1383 -977
- package/app/lib/role.ts +228 -0
- package/app/lib/route-catchall.test.ts +27 -0
- package/app/lib/route-repo-entry.test.ts +95 -0
- package/app/lib/route-repo-entry.ts +36 -0
- package/app/lib/router-contract.test.ts +22 -0
- package/app/lib/router-contract.ts +19 -0
- package/app/lib/shared-layout.test.ts +86 -0
- package/app/lib/shared-layout.ts +82 -0
- package/app/lib/shortcuts-panel.ts +2 -0
- package/app/lib/status-bar.test.ts +118 -0
- package/app/lib/status-bar.ts +365 -128
- package/app/lib/sync-controls.test.ts +43 -0
- package/app/lib/sync-controls.tsx +303 -0
- package/app/lib/test-dom.ts +145 -0
- package/app/lib/test-fixtures/router-contract/[...slug]/page.tsx +3 -0
- package/app/lib/test-fixtures/router-contract/api/health/route.ts +3 -0
- package/app/lib/test-fixtures/router-contract/api/version/route.ts +3 -0
- package/app/lib/test-fixtures/router-contract/galaxy-canvas/page.tsx +3 -0
- package/app/lib/test-fixtures/router-contract/page.tsx +3 -0
- package/app/lib/transclusion-smoke.test.ts +163 -0
- package/app/lib/tutorial.ts +301 -0
- package/app/lib/version.ts +93 -0
- package/app/lib/viewport-culling.ts +740 -728
- package/app/lib/virtual-files.ts +456 -0
- package/app/lib/webgl-text.ts +189 -0
- package/app/lib/{galaxydraw-bridge.ts → xydraw-bridge.ts} +485 -477
- package/app/lib/{galaxydraw.test.ts → xydraw.test.ts} +228 -229
- package/app/og-image.png +0 -0
- package/app/page.client.tsx +70 -215
- package/app/page.tsx +27 -92
- package/app/state/machine.js +13 -0
- package/banner.png +0 -0
- package/package.json +17 -8
- package/server.ts +11 -1
- package/app/api/connections/route.ts +0 -72
- package/app/api/positions/route.ts +0 -80
- package/app/api/repo/browse/route.ts +0 -55
- package/app/lib/pr-review.ts +0 -374
- package/packages/galaxydraw/README.md +0 -296
- package/packages/galaxydraw/banner.png +0 -0
- package/packages/galaxydraw/demo/build-static.ts +0 -100
- package/packages/galaxydraw/demo/client.ts +0 -154
- package/packages/galaxydraw/demo/dist/client.js +0 -8
- package/packages/galaxydraw/demo/index.html +0 -256
- package/packages/galaxydraw/demo/server.ts +0 -96
- package/packages/galaxydraw/dist/index.js +0 -984
- package/packages/galaxydraw/dist/index.js.map +0 -16
- package/packages/galaxydraw/node_modules/.bin/tsc.bunx +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsc.exe +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsserver.bunx +0 -0
- package/packages/galaxydraw/node_modules/.bin/tsserver.exe +0 -0
- package/packages/galaxydraw/package.json +0 -49
- package/packages/galaxydraw/perf.test.ts +0 -284
- package/packages/galaxydraw/src/core/cards.ts +0 -435
- package/packages/galaxydraw/src/core/engine.ts +0 -339
- package/packages/galaxydraw/src/core/events.ts +0 -81
- package/packages/galaxydraw/src/core/layout.ts +0 -136
- package/packages/galaxydraw/src/core/minimap.ts +0 -216
- package/packages/galaxydraw/src/core/state.ts +0 -177
- package/packages/galaxydraw/src/core/viewport.ts +0 -106
- package/packages/galaxydraw/src/galaxydraw.css +0 -166
- package/packages/galaxydraw/src/index.ts +0 -40
- package/packages/galaxydraw/tsconfig.json +0 -30
package/app/lib/positions.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
/**
|
|
3
|
-
* Positions — load/save card positions with
|
|
4
|
-
* -
|
|
5
|
-
* -
|
|
3
|
+
* Positions — load/save card positions with role-based storage:
|
|
4
|
+
* - Leader (localhost): SQLite primary + localStorage backup
|
|
5
|
+
* - Follower (remote): Read-only from server
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Leader can push to remote servers for followers to view.
|
|
8
8
|
*/
|
|
9
|
-
import { measure } from
|
|
10
|
-
import type { CanvasContext } from
|
|
11
|
-
import { getUser } from
|
|
9
|
+
import { measure } from "measure-fn";
|
|
10
|
+
import type { CanvasContext } from "./context";
|
|
11
|
+
import { getUser } from "./user";
|
|
12
|
+
import { isLeader, isFollower } from "./role";
|
|
12
13
|
|
|
13
|
-
const STORAGE_PREFIX =
|
|
14
|
+
const STORAGE_PREFIX = "gitcanvas:positions:";
|
|
14
15
|
|
|
15
16
|
/** Debounce timer for batched saves */
|
|
16
17
|
let _saveTimer: any = null;
|
|
@@ -18,159 +19,227 @@ const SAVE_DEBOUNCE_MS = 300;
|
|
|
18
19
|
|
|
19
20
|
// ─── Get the localStorage key for the current repo ───────
|
|
20
21
|
function getStorageKey(ctx: CanvasContext): string | null {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const repoPath = ctx.snap?.()?.context?.repoPath;
|
|
23
|
+
if (!repoPath) return null;
|
|
24
|
+
return `${STORAGE_PREFIX}${repoPath}`;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
function getRepoPath(ctx: CanvasContext): string | null {
|
|
27
|
-
|
|
28
|
+
return ctx.snap?.()?.context?.repoPath || null;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// ─── Load all saved positions ────────────────────────────
|
|
31
32
|
export async function loadSavedPositions(ctx: CanvasContext) {
|
|
32
|
-
|
|
33
|
+
return measure("positions:load", async () => {
|
|
34
|
+
try {
|
|
35
|
+
const repoPath = getRepoPath(ctx);
|
|
36
|
+
if (!repoPath) return;
|
|
37
|
+
|
|
38
|
+
// Clear old positions first to prevent stale data
|
|
39
|
+
ctx.positions = new Map();
|
|
40
|
+
|
|
41
|
+
if (isLeader()) {
|
|
42
|
+
// Leader: Try SQLite first, then localStorage backup
|
|
33
43
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (user) {
|
|
44
|
-
try {
|
|
45
|
-
const res = await fetch(`/api/auth/positions?repo=${encodeURIComponent(repoPath)}`);
|
|
46
|
-
const data = await res.json();
|
|
47
|
-
if (data.positions) {
|
|
48
|
-
ctx.positions = new Map(Object.entries(data.positions));
|
|
49
|
-
// Migrate legacy expanded state from separate localStorage key
|
|
50
|
-
_migrateLegacyExpanded(ctx, repoPath);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
} catch { /* fall through to localStorage */ }
|
|
44
|
+
const res = await fetch(
|
|
45
|
+
`/api/auth/positions?repo=${encodeURIComponent(repoPath)}`,
|
|
46
|
+
);
|
|
47
|
+
if (res.ok) {
|
|
48
|
+
const data = await res.json();
|
|
49
|
+
if (data.positions) {
|
|
50
|
+
ctx.positions = new Map(Object.entries(data.positions));
|
|
51
|
+
_migrateLegacyExpanded(ctx, repoPath);
|
|
52
|
+
return;
|
|
54
53
|
}
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
/* fall through to localStorage */
|
|
57
|
+
}
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
// Fallback: localStorage
|
|
60
|
+
const key = getStorageKey(ctx);
|
|
61
|
+
if (key) {
|
|
62
|
+
const raw = localStorage.getItem(key);
|
|
63
|
+
if (raw) {
|
|
64
|
+
const data = JSON.parse(raw);
|
|
65
|
+
ctx.positions = new Map(Object.entries(data));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
_migrateLegacyExpanded(ctx, repoPath);
|
|
69
|
+
} else {
|
|
70
|
+
// Follower: Read-only from server
|
|
71
|
+
try {
|
|
72
|
+
const res = await fetch(
|
|
73
|
+
`/api/auth/positions?repo=${encodeURIComponent(repoPath)}&readonly=true`,
|
|
74
|
+
);
|
|
75
|
+
if (res.ok) {
|
|
76
|
+
const data = await res.json();
|
|
77
|
+
if (data.positions) {
|
|
78
|
+
ctx.positions = new Map(Object.entries(data.positions));
|
|
63
79
|
}
|
|
64
|
-
|
|
65
|
-
// Migrate legacy expanded state from separate localStorage key
|
|
66
|
-
_migrateLegacyExpanded(ctx, repoPath);
|
|
80
|
+
}
|
|
67
81
|
} catch (e) {
|
|
68
|
-
|
|
82
|
+
console.warn(
|
|
83
|
+
"[positions] Failed to load from server (follower mode)",
|
|
84
|
+
e,
|
|
85
|
+
);
|
|
69
86
|
}
|
|
70
|
-
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
measure("positions:loadError", () => e);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
71
92
|
}
|
|
72
93
|
|
|
73
94
|
// ─── Persist all positions (debounced) ───────────────────
|
|
74
|
-
function flushPositions(ctx: CanvasContext) {
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
export function flushPositions(ctx: CanvasContext) {
|
|
96
|
+
const repoPath = getRepoPath(ctx);
|
|
97
|
+
if (!repoPath) return;
|
|
77
98
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
const obj: Record<string, any> = {};
|
|
100
|
+
for (const [k, v] of ctx.positions) {
|
|
101
|
+
obj[k] = v;
|
|
102
|
+
}
|
|
82
103
|
|
|
83
|
-
|
|
104
|
+
if (isLeader()) {
|
|
105
|
+
// Leader: Save to localStorage + SQLite
|
|
84
106
|
try {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} catch {
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
const key = getStorageKey(ctx);
|
|
108
|
+
if (key) localStorage.setItem(key, JSON.stringify(obj));
|
|
109
|
+
} catch {}
|
|
110
|
+
|
|
111
|
+
// Sync to local server (async, fire-and-forget)
|
|
112
|
+
fetch("/api/auth/positions", {
|
|
113
|
+
method: "POST",
|
|
114
|
+
headers: { "Content-Type": "application/json" },
|
|
115
|
+
body: JSON.stringify({ repoUrl: repoPath, positions: obj }),
|
|
116
|
+
}).catch(() => {
|
|
117
|
+
/* silent — localStorage is the safety net */
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Auto-sync to remote server if enabled
|
|
121
|
+
try {
|
|
122
|
+
const { isAutoSyncEnabled, pushToServer } = require("./sync-controls");
|
|
123
|
+
if (isAutoSyncEnabled()) {
|
|
124
|
+
pushToServer(repoPath, obj).catch(() => {
|
|
125
|
+
/* silent */
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
/* sync-controls not loaded or auto-sync disabled */
|
|
97
130
|
}
|
|
131
|
+
}
|
|
132
|
+
// Follower: No saves allowed (read-only)
|
|
98
133
|
}
|
|
99
134
|
|
|
100
135
|
// ─── Save a single card position (debounced) ─────────────
|
|
101
|
-
export async function savePosition(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
136
|
+
export async function savePosition(
|
|
137
|
+
ctx: CanvasContext,
|
|
138
|
+
commitHash: string,
|
|
139
|
+
filePath: string,
|
|
140
|
+
x?: number,
|
|
141
|
+
y?: number,
|
|
142
|
+
width?: number,
|
|
143
|
+
height?: number,
|
|
144
|
+
immediate = false,
|
|
145
|
+
) {
|
|
146
|
+
// Follower: No saves allowed
|
|
147
|
+
if (isFollower()) {
|
|
148
|
+
console.warn(
|
|
149
|
+
"[positions] Cannot save positions in follower mode (read-only)",
|
|
150
|
+
);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return measure("positions:save", async () => {
|
|
155
|
+
try {
|
|
156
|
+
const posKey = `${commitHash}:${filePath}`;
|
|
157
|
+
const existing = ctx.positions.get(posKey) || {};
|
|
158
|
+
const newPos = {
|
|
159
|
+
x: x !== undefined ? x : existing.x,
|
|
160
|
+
y: y !== undefined ? y : existing.y,
|
|
161
|
+
width: width !== undefined ? width : existing.width,
|
|
162
|
+
height: height !== undefined ? height : existing.height,
|
|
163
|
+
expanded: existing.expanded,
|
|
164
|
+
};
|
|
165
|
+
ctx.positions.set(posKey, newPos);
|
|
166
|
+
|
|
167
|
+
// Debounced persist (or immediate if requested)
|
|
168
|
+
if (_saveTimer) clearTimeout(_saveTimer);
|
|
169
|
+
if (immediate) {
|
|
170
|
+
flushPositions(ctx);
|
|
171
|
+
} else {
|
|
172
|
+
_saveTimer = setTimeout(() => flushPositions(ctx), SAVE_DEBOUNCE_MS);
|
|
173
|
+
}
|
|
174
|
+
} catch (e) {
|
|
175
|
+
measure("positions:saveError", () => e);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ─── Force immediate save (no debounce) ──────────────────
|
|
181
|
+
export function flushPositionsImmediate(ctx: CanvasContext) {
|
|
182
|
+
if (_saveTimer) clearTimeout(_saveTimer);
|
|
183
|
+
flushPositions(ctx);
|
|
122
184
|
}
|
|
123
185
|
|
|
124
186
|
// ─── Position key helper ─────────────────────────────────
|
|
125
187
|
export function getPositionKey(filePath: string, commitHash: string): string {
|
|
126
|
-
|
|
188
|
+
return `${commitHash}:${filePath}`;
|
|
127
189
|
}
|
|
128
190
|
|
|
129
191
|
// ─── Expanded state (unified with positions) ─────────────
|
|
130
192
|
|
|
131
193
|
/** Check if a file path is saved as expanded in positions */
|
|
132
|
-
export function isPathExpandedInPositions(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
194
|
+
export function isPathExpandedInPositions(
|
|
195
|
+
ctx: CanvasContext,
|
|
196
|
+
filePath: string,
|
|
197
|
+
): boolean {
|
|
198
|
+
// Check allfiles key (primary)
|
|
199
|
+
const key = `allfiles:${filePath}`;
|
|
200
|
+
const pos = ctx.positions.get(key);
|
|
201
|
+
return !!(pos && pos.expanded);
|
|
137
202
|
}
|
|
138
203
|
|
|
139
204
|
/** Mark a file path as expanded or collapsed in positions */
|
|
140
|
-
export function setPathExpandedInPositions(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
205
|
+
export function setPathExpandedInPositions(
|
|
206
|
+
ctx: CanvasContext,
|
|
207
|
+
filePath: string,
|
|
208
|
+
expanded: boolean,
|
|
209
|
+
) {
|
|
210
|
+
const key = `allfiles:${filePath}`;
|
|
211
|
+
const existing = ctx.positions.get(key) || {};
|
|
212
|
+
ctx.positions.set(key, { ...existing, expanded });
|
|
213
|
+
// Trigger debounced persist
|
|
214
|
+
if (_saveTimer) clearTimeout(_saveTimer);
|
|
215
|
+
_saveTimer = setTimeout(() => flushPositions(ctx), SAVE_DEBOUNCE_MS);
|
|
147
216
|
}
|
|
148
217
|
|
|
149
218
|
/** Migrate legacy expanded state from separate localStorage key into positions */
|
|
150
219
|
function _migrateLegacyExpanded(ctx: CanvasContext, repoPath: string) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
220
|
+
const legacyKey = `gitcanvas:expanded:${repoPath}`;
|
|
221
|
+
try {
|
|
222
|
+
const raw = localStorage.getItem(legacyKey);
|
|
223
|
+
if (!raw) return;
|
|
224
|
+
const paths: string[] = JSON.parse(raw);
|
|
225
|
+
if (!Array.isArray(paths) || paths.length === 0) return;
|
|
226
|
+
|
|
227
|
+
let migrated = 0;
|
|
228
|
+
for (const filePath of paths) {
|
|
229
|
+
const posKey = `allfiles:${filePath}`;
|
|
230
|
+
const existing = ctx.positions.get(posKey) || {};
|
|
231
|
+
if (!existing.expanded) {
|
|
232
|
+
ctx.positions.set(posKey, { ...existing, expanded: true });
|
|
233
|
+
migrated++;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
167
236
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
237
|
+
if (migrated > 0) {
|
|
238
|
+
// Persist immediately to save the migration
|
|
239
|
+
flushPositions(ctx);
|
|
240
|
+
}
|
|
172
241
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
242
|
+
// Remove the legacy key
|
|
243
|
+
localStorage.removeItem(legacyKey);
|
|
244
|
+
} catch {}
|
|
176
245
|
}
|