Skip to content

Commit

Permalink
Added source reordering support (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
6XGate authored Nov 27, 2024
1 parent af78c51 commit eab8115
Show file tree
Hide file tree
Showing 25 changed files with 1,299 additions and 792 deletions.
6 changes: 6 additions & 0 deletions electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ export default defineConfig({
stream: fileURLToPath(new URL('./node_modules/stream-browserify', import.meta.url)),
util: fileURLToPath(new URL('./node_modules/util', import.meta.url))
}
},
css: {
preprocessorOptions: {
sass: { api: 'modern-compiler' },
scss: { api: 'modern-compiler' }
}
}
}
})
56 changes: 29 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,27 @@
"@types/ini": "^4.1.1",
"@types/leveldown": "^4.0.6",
"@types/levelup": "^5.1.5",
"@types/node": "^20.17.6",
"@types/node": "^20.17.7",
"@types/pouchdb-core": "^7.0.15",
"@types/pouchdb-find": "^7.3.3",
"@types/ws": "^8.5.13",
"@typescript-eslint/eslint-plugin": "^8.12.2",
"@typescript-eslint/parser": "^8.12.2",
"@vitejs/plugin-vue": "^5.1.4",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"@vitest/coverage-v8": "^2.1.4",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",
"@vitejs/plugin-vue": "^5.2.0",
"@vitejs/plugin-vue-jsx": "^4.1.0",
"@vitest/coverage-v8": "^2.1.5",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/tsconfig": "^0.5.1",
"@vue/tsconfig": "^0.6.0",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"@vueuse/core": "^11.2.0",
"@vueuse/shared": "^11.2.0",
"@vueuse/core": "^11.3.0",
"@vueuse/shared": "^11.3.0",
"@zip.js/zip.js": "^2.7.53",
"assert": "^2.1.0",
"auto-bind": "^5.0.1",
"bufferutil": "^4.0.8",
"electron": "^31.7.3",
"electron": "^31.7.5",
"electron-builder": "^24.13.3",
"electron-unhandled": "^5.0.0",
"electron-updater": "^6.3.9",
Expand All @@ -102,49 +102,51 @@
"eslint-import-resolver-node": "^0.3.9",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-n": "^17.12.0",
"eslint-plugin-n": "^17.14.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-promise": "^7.1.0",
"eslint-plugin-vue": "^9.30.0",
"eslint-plugin-promise": "^7.2.0",
"eslint-plugin-vue": "^9.31.0",
"execa": "^9.5.1",
"husky": "^9.1.6",
"husky": "^9.1.7",
"ini": "^5.0.0",
"levelup": "^5.1.1",
"mime": "^4.0.4",
"npm-check-updates": "^17.1.10",
"npm-check-updates": "^17.1.11",
"npm-run-all2": "^7.0.1",
"pinia": "^2.2.6",
"pouchdb-adapter-leveldb-core": "^9.0.0",
"pouchdb-core": "^9.0.0",
"pouchdb-find": "^9.0.0",
"prettier": "^3.3.3",
"radash": "^12.1.0",
"sass": "^1.80.6",
"sass-embedded": "^1.81.0",
"superjson": "^2.2.1",
"tslib": "^2.8.1",
"type-fest": "^4.26.1",
"typescript": "^5.6.3",
"type-fest": "^4.28.0",
"typescript": "5.6.3",
"typescript-eslint-parser-for-extra-files": "^0.7.0",
"utf-8-validate": "^6.0.5",
"vite": "^5.4.10",
"vite-plugin-vue-devtools": "^7.6.2",
"vite": "^5.4.11",
"vite-plugin-vue-devtools": "^7.6.4",
"vite-plugin-vuetify": "^2.0.4",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.1.4",
"vue": "^3.5.12",
"vite-tsconfig-paths": "^5.1.3",
"vitest": "^2.1.5",
"vue": "^3.5.13",
"vue-eslint-parser": "^9.4.3",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5",
"vue-tsc": "^2.1.10",
"vuetify": "^3.7.3",
"vue-router": "^4.5.0",
"vue-tsc": "2.1.10",
"vuetify": "^3.7.4",
"ws": "^8.18.0",
"xdg-basedir": "^5.1.0",
"zod": "^3.23.8"
},
"dependencies": {
"@electron-toolkit/utils": "^3.0.0",
"electron-log": "^5.2.0",
"@types/pouchdb-mapreduce": "^6.1.10",
"electron-log": "^5.2.3",
"leveldown": "^6.1.1",
"pouchdb-mapreduce": "^9.0.0",
"serialport": "^12.0.0"
}
}
16 changes: 0 additions & 16 deletions src/core/error-handling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,3 @@ export function isNodeError(value: unknown, type: new (...args: any[]) => Error
export function raiseError(factory: () => Error): never {
throw factory()
}

export function warnPromiseFailures<T>(msg: string, results: PromiseSettledResult<T>[]) {
for (const result of results) {
if (result.status === 'rejected') {
console.warn(msg, result.reason)
}
}
}

export function logPromiseFailures<T>(msg: string, results: PromiseSettledResult<T>[]) {
for (const result of results) {
if (result.status === 'rejected') {
console.error(msg, result.reason)
}
}
}
6 changes: 6 additions & 0 deletions src/main/boot/01-normalize-source-order.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import useSourcesDatabase from '../dao/sources'

export async function boot() {
const sourcesDb = useSourcesDatabase()
await sourcesDb.normalizeOrder()
}
31 changes: 31 additions & 0 deletions src/main/dao/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import useTiesDatabase from './ties'
import type { DocumentId, RevisionId } from '../services/database'

export const SourceModel = z.object({
order: z.number().nonnegative().finite(),
title: z.string().min(1),
image: z.string().min(1).nullable()
})
Expand All @@ -14,6 +15,36 @@ const useSourcesDatabase = memo(
new (class extends Database.of('sources', SourceModel) {
readonly #ties = useTiesDatabase()

async getNextOrderValue() {
return await this.run(async function getNextOrderValue(db) {
const mapped = await db.query<number>({
/* v8 ignore next 2 */ // Not executed in a way V8 can see.
map: (doc, emit) => emit?.(doc.order, doc.order),
reduce: (_, values) => 1 + Math.max(...values.map(Number))
})

const row = mapped.rows[0]
if (row == null) return 0

return row.value as number
})
}

async normalizeOrder() {
const sources = await this.all()
let i = 0
for (const source of sources.toSorted((a, b) => a.order - b.order)) {
source.order = i
i += 1
}

await Promise.all(
sources.map(async (source) => {
await this.update(source)
})
)
}

override async remove(id: DocumentId, rev?: RevisionId) {
await super.remove(id, rev)

Expand Down
4 changes: 4 additions & 0 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Logger from 'electron-log'
import { sleep } from 'radash'
import appIcon from '../../resources/icon.png?asset&asarUnpack'
import { useAppRouter } from './routes/router'
import useBootOperations from './services/boot'
import useMigrations from './services/migration'
import { createIpcHandler } from './services/rpc/ipc'
import { logError } from './utilities'
Expand Down Expand Up @@ -131,6 +132,9 @@ await migrate().catch((cause: unknown) => {
Logger.error(cause)
})

const boot = useBootOperations()
await boot()

// Set app user model id for windows
electronApp.setAppUserModelId('org.sleepingcats.BridgeCmdr')

Expand Down
20 changes: 20 additions & 0 deletions src/main/migrations/20241124121000-add-source-order.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { z } from 'zod'
import { Database } from '../services/database'

export async function migrate() {
const OldModel = z.object({
order: z.number().nonnegative().finite().optional(),
title: z.string().min(1),
image: z.string().min(1).nullable()
})

const sourcesDb = new Database('sources', OldModel)
const sources = await sourcesDb.all()
await Promise.all(
sources.map(async (source, order) => {
await sourcesDb.update({ order, ...source })
})
)

await sourcesDb.close()
}
5 changes: 5 additions & 0 deletions src/main/routes/data/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export default function useSourcesRouter() {
}),
clear: procedure.mutation(async () => {
await sources.clear()
}),
// Utilities
getNextOrderValue: procedure.query(async () => await sources.getNextOrderValue()),
normalizeOrder: procedure.mutation(async () => {
await sources.normalizeOrder()
})
})
}
21 changes: 21 additions & 0 deletions src/main/services/boot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { basename } from 'node:path'
import Logger from 'electron-log'
import { z } from 'zod'

const BootModule = z.object({
boot: z.function(z.tuple([]), z.unknown())
})

export default function useBootOperations() {
Logger.debug('Loading boot modules')
const bootModules = import.meta.glob('../boot/**/*', { eager: true })
return async function boot() {
Logger.debug('Starting boot up')
for (const [name, module] of Object.entries(bootModules)) {
const bootable = BootModule.parse(module)
Logger.debug(`Attempting boot: ${basename(name, '.ts')}`)
// eslint-disable-next-line no-await-in-loop -- Design to allow serialization.
await bootable.boot()
}
}
}
3 changes: 3 additions & 0 deletions src/main/services/database.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { randomUUID } from 'node:crypto'
import PouchDb from 'pouchdb-core'
import find from 'pouchdb-find'
import mapReduce from 'pouchdb-mapreduce'
import { map } from 'radash'
import { z } from 'zod'
import { useLevelAdapter } from './level'
Expand Down Expand Up @@ -95,6 +96,7 @@ export function inferUpsertOf<Schema extends z.AnyZodObject>(schema: Schema) {

PouchDb.plugin(useLevelAdapter())
PouchDb.plugin(find)
PouchDb.plugin(mapReduce)

/** The basis of a database. */
export class Database<RawSchema extends z.AnyZodObject> {
Expand Down Expand Up @@ -208,6 +210,7 @@ export class Database<RawSchema extends z.AnyZodObject> {
})
}

/** Prepares the document. */
protected async prepare<T extends typeof this.__raw__>(doc: T) {
const { _attachments, _conflicts, _revs_info, _revisions, ...document } = doc
const result = { ...document, _attachments: await prepareAttachments(_attachments as never) }
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/assets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ $widthspx: 50 75 100 125 150 175 200 250 300 400 500 600 700 800 900;
width: string.unquote('#{$width}%') !important;
}
}

@each $width in $widthspx {
.minw-#{$width}px {
min-width: string.unquote('#{$width}px') !important;
Expand All @@ -61,9 +62,11 @@ $widthspx: 50 75 100 125 150 175 200 250 300 400 500 600 700 800 900;
width: string.unquote('#{$width}px') !important;
}
}

.colg {
column-gap: settings.$grid-gutter;
}

.rowg {
row-gap: settings.$grid-gutter;
}
Loading

0 comments on commit eab8115

Please sign in to comment.