Files
tome/src/lib/models/config.ts
Matte Noble 366f9f5b97 Back to line length of 100 + some svelte/ts settings
- Goes back to a max line length of 100
- Makes whitespace insignificant in Svelte files (see below)
- Avoids parens around single argument closures, in TS, when unncessary

*Whitespace Significance*

In HTML, `<p><b> 1 </b></p>` and `<p><b>1</b></p>` are not the same
thing. In the former, the "1" has spaces around it. If you were to try
to split this into multiple lines...

```html
<p>
    <b>
        1
    </b>
</p>
```

...you would lose that whitespace. The newlines reset any significance
around individual tokens. This meant prettier would format that code
as...

```html
<p>
    <b
    > 1 </b>
</p>
```

...which is insane and hideous.

We're saying all whitespace is insignificant from now on. Meaning
prettier no longer needs to retain it and can format that code as a sane
person.

This means you need to explicitly use `&nbsp;` characters if you
explicitly need whitespace around things. OR put it in a `span` and use
css.

TL;DR: do not rely on whitespace significance in HTML.
2025-05-27 09:29:57 -07:00

95 lines
2.2 KiB
TypeScript

import { BaseDirectory, exists, readTextFile } from '@tauri-apps/plugin-fs';
import Model, { type ToSqlRow } from '$lib/models/base.svelte';
export interface IConfig {
id?: number;
key: string;
value: unknown;
}
interface Row {
id: number;
key: string;
value: string;
}
type ConfigKey = 'latest-session-id' | 'welcome-agreed' | 'skipped-version' | 'default-model';
export default class Config extends Model<IConfig, Row>('config') {
@getset('latest-session-id')
static latestSessionId: number;
@getset('welcome-agreed')
static agreedToWelcome: boolean;
@getset('skipped-version')
static skippedVersions: string[];
@getset('default-model')
static defaultModel: string;
static get(key: string) {
return this.findBy({ key })?.value;
}
static async set(key: ConfigKey, value: unknown) {
const config = this.findBy({ key }) || this.default({ key });
config.value = value;
await this.save(config);
}
static async migrate() {
const filename = 'tome.conf.json';
const opt = { baseDir: BaseDirectory.AppData };
if (!(await exists(filename, opt))) {
return;
}
try {
Object.entries(JSON.parse(await readTextFile(filename, opt))).forEach(
([key, value]) => {
if (!this.exists({ key })) {
this.create({ key, value });
}
}
);
} catch {
return;
}
}
protected static async fromSql(row: Row): Promise<IConfig> {
return {
id: row.id,
key: row.key,
value: JSON.parse(row.value),
};
}
protected static async toSql(config: IConfig): Promise<ToSqlRow<Row>> {
return {
key: config.key,
value: JSON.stringify(config.value),
};
}
}
function getset(key: ConfigKey) {
return function (target: object, property: string) {
function get() {
return Config.get(key);
}
function set(value: unknown) {
Config.set(key, value);
}
Object.defineProperty(target, property, {
get,
set,
});
};
}