Merge pull request #9132 from streetwriters/fix/themes-not-instaling

Fix themes not installing
This commit is contained in:
Abdullah Atta
2026-01-03 14:40:18 +05:00
committed by GitHub
7 changed files with 41 additions and 25 deletions

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/themes-server",
"version": "1.0.2",
"version": "1.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@notesnook/themes-server",
"version": "1.0.2",
"version": "1.0.3",
"license": "ISC",
"dependencies": {
"@notesnook/theme": "file:../../packages/theme",

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/themes-server",
"version": "1.0.2",
"version": "1.0.3",
"description": "A simple rest api for notesnook themes",
"private": "true",
"main": "src/index.ts",

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { z } from "zod";
import { InstallsCounter } from "./constants";
import { findTheme, getThemes } from "./orama";
import { findTheme, getThemes, updateTotalInstalls } from "./orama";
import { syncThemes } from "./sync";
import { publicProcedure, router } from "./trpc";
import { THEME_COMPATIBILITY_VERSION } from "@notesnook/theme";
@@ -41,7 +41,12 @@ export const ThemesAPI = router({
const theme = await findTheme(id, compatibilityVersion);
if (!theme) return;
if (userId) await InstallsCounter.increment(theme.id, userId);
if (userId) {
updateTotalInstalls(
theme,
await InstallsCounter.increment(theme.id, userId)
);
}
return theme;
}),
updateTheme: publicProcedure

View File

@@ -30,12 +30,13 @@ export class FsCounter {
}
async increment(key: string, uid: string) {
await this.mutex.runExclusive(async () => {
return await this.mutex.runExclusive(async () => {
const counts = await this.all();
counts[key] = counts[key] || [];
if (counts[key].includes(uid)) return;
if (counts[key].includes(uid)) return counts[key].length;
counts[key].push(uid);
await this.save(counts);
return counts[key].length;
});
}

View File

@@ -28,6 +28,7 @@ type WorkersKVRESTConfig = {
export class KVCounter {
private readonly client: Cloudflare;
private readonly mutex: Mutex;
private installs: Record<string, string[]> = {};
constructor(private readonly config: WorkersKVRESTConfig) {
this.mutex = new Mutex();
this.client = new Cloudflare({
@@ -36,15 +37,12 @@ export class KVCounter {
}
async increment(key: string, uid: string) {
await this.mutex.runExclusive(async () => {
const installs = await readMulti(this.client, this.config, [key]);
const existing = installs[key] || [];
await write(
this.client,
this.config,
key,
Array.from(new Set([...existing, uid]))
);
return await this.mutex.runExclusive(async () => {
const existing = this.installs[key] || [];
const installsSet = Array.from(new Set([...existing, uid]));
await write(this.client, this.config, key, installsSet);
this.installs[key] = installsSet;
return installsSet.length;
});
}
@@ -54,6 +52,7 @@ export class KVCounter {
for (const [key, value] of Object.entries(installs)) {
result[key] = value.length;
}
this.installs = installs;
return result;
}
}
@@ -87,13 +86,8 @@ function write<T>(
key: string,
data: T
) {
return client.kv.namespaces.bulkUpdate(config.namespaceId, {
return client.kv.namespaces.values.update(config.namespaceId, key, {
account_id: config.cfAccountId,
body: [
{
key,
value: JSON.stringify(data)
}
]
value: JSON.stringify(data)
});
}

View File

@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Orama, SearchParams, create, search } from "@orama/orama";
import { Orama, SearchParams, create, search, update } from "@orama/orama";
import { CompiledThemeDefinition, ThemeMetadata } from "./sync";
import { ThemeQuerySchema } from "./schemas";
@@ -30,7 +30,8 @@ export async function initializeDatabase(): Promise<Orama> {
colorScheme: "string",
compatibilityVersion: "number",
description: "string",
tags: "string[]"
tags: "string[]",
totalInstalls: "number"
},
id: "notesnook-themes"
});
@@ -53,6 +54,14 @@ export async function findTheme(
return results.hits[0].document as CompiledThemeDefinition;
}
export async function updateTotalInstalls(
theme: CompiledThemeDefinition,
totalInstalls: number
) {
if (!ThemesDatabase) await initializeDatabase();
await update(ThemesDatabase!, theme.id, { ...theme, totalInstalls });
}
export async function getThemes(query: (typeof ThemeQuerySchema)["_type"]) {
if (!ThemesDatabase) await initializeDatabase();
@@ -60,6 +69,10 @@ export async function getThemes(query: (typeof ThemeQuerySchema)["_type"]) {
const count = query.limit;
const searchParams: SearchParams = {
sortBy: {
property: "totalInstalls",
order: "DESC"
},
where: {
compatibilityVersion: {
eq: query.compatibilityVersion

View File

@@ -32,6 +32,9 @@ server.listen(PORT, HOST);
console.log(`Server started successfully on: http://${HOST}:${PORT}/`);
syncThemes();
setInterval(() => {
syncThemes();
}, 1000 * 60 * 60); // every hour
if (import.meta.hot) {
import.meta.hot.on("vite:beforeFullReload", () => {