Skip to content

Commit 4f69f3f

Browse files
committed
Improve caching when using local generation (fixes #47)
1 parent 908d6c7 commit 4f69f3f

File tree

5 files changed

+83
-16
lines changed

5 files changed

+83
-16
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Bug Report
22
description: File a bug report
3-
labels: ["bug"]
3+
labels: [ "bug" ]
44
body:
55
- type: markdown
66
attributes:

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@codemirror/search": "6.0.0",
3232
"@codemirror/view": "6.0.0",
3333
"@codemirror/commands": "6.0.0",
34-
"@codemirror/language": "https://github.com/lishid/cm-language"
34+
"@codemirror/language": "https://github.com/lishid/cm-language",
35+
"localforage": "1.10.0"
3536
}
3637
}

src/localProcessors.ts

+26-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import PlantumlPlugin from "./main";
22
import {Processor} from "./processor";
3-
import {MarkdownPostProcessorContext} from "obsidian";
3+
import {MarkdownPostProcessorContext, moment} from "obsidian";
44
import * as plantuml from "plantuml-encoder";
55
import {insertAsciiImage, insertImageWithMap, insertSvgImage} from "./functions";
66
import {OutputType} from "./const";
7+
import * as localforage from "localforage";
78

89
export class LocalProcessors implements Processor {
910

@@ -14,38 +15,52 @@ export class LocalProcessors implements Processor {
1415
}
1516

1617
ascii = async(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
18+
const encodedDiagram = plantuml.encode(source);
19+
const item: string = await localforage.getItem('ascii-' + encodedDiagram);
20+
if(item) {
21+
insertAsciiImage(el, item);
22+
await localforage.setItem('ts-' + encodedDiagram, Date.now());
23+
return;
24+
}
25+
1726
const image = await this.generateLocalImage(source, OutputType.ASCII, this.plugin.replacer.getPath(ctx));
1827
insertAsciiImage(el, image);
28+
await localforage.setItem('ascii-' + encodedDiagram, image);
29+
await localforage.setItem('ts-' + encodedDiagram, Date.now());
1930
}
2031

2132
png = async(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
2233
const encodedDiagram = plantuml.encode(source);
23-
24-
if(localStorage.getItem(encodedDiagram + "-png")) {
25-
const image = localStorage.getItem(encodedDiagram + "-png");
26-
const map = localStorage.getItem(encodedDiagram + "-map");
27-
insertImageWithMap(el,image, map, encodedDiagram);
34+
const item: string = await localforage.getItem('png-' + encodedDiagram);
35+
if(item) {
36+
const map: string = await localforage.getItem('map-' + encodedDiagram);
37+
insertImageWithMap(el, item , map, encodedDiagram);
38+
await localforage.setItem('ts-' + encodedDiagram, Date.now());
2839
return;
2940
}
3041

3142
const path = this.plugin.replacer.getPath(ctx);
3243
const image = await this.generateLocalImage(source, OutputType.PNG, path);
3344
const map = await this.generateLocalMap(source, path);
3445

35-
localStorage.setItem(encodedDiagram + "-png", image);
36-
localStorage.setItem(encodedDiagram + "-map", map);
46+
await localforage.setItem('png-' + encodedDiagram, image);
47+
await localforage.setItem('map-' + encodedDiagram, map);
48+
await localforage.setItem('ts-'+ encodedDiagram, Date.now());
3749

3850
insertImageWithMap(el, image, map, encodedDiagram);
3951
}
4052

4153
svg = async(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
4254
const encodedDiagram = plantuml.encode(source);
43-
if(localStorage.getItem(encodedDiagram + "-svg")) {
44-
insertSvgImage(el, localStorage.getItem(encodedDiagram + "-svg"));
55+
const item: string = await localforage.getItem('svg-' + encodedDiagram);
56+
if(item) {
57+
insertSvgImage(el, item);
58+
await localforage.setItem('ts-' + encodedDiagram, Date.now());
4559
return;
4660
}
47-
4861
const image = await this.generateLocalImage(source, OutputType.SVG, this.plugin.replacer.getPath(ctx));
62+
await localforage.setItem('svg-' + encodedDiagram, image);
63+
await localforage.setItem('ts-' + encodedDiagram, Date.now());
4964
insertSvgImage(el, image);
5065
}
5166

src/main.ts

+33
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {Replacer} from "./functions";
1212
import {VIEW_TYPE} from "./PumlView";
1313
import {Prec} from "@codemirror/state";
1414
import {asyncDecoBuilderExt} from "./decorations/EmbedDecoration";
15+
import localforage from "localforage";
1516

1617
declare module "obsidian" {
1718
interface Workspace {
@@ -83,6 +84,13 @@ export default class PlantumlPlugin extends Plugin {
8384
//keep this processor for backwards compatibility
8485
this.registerMarkdownCodeBlockProcessor("plantuml-map", processor.png);
8586

87+
this.cleanupLocalStorage();
88+
localforage.config({
89+
name: 'puml',
90+
description: 'PlantUML plugin'
91+
});
92+
await this.cleanupCache();
93+
8694

8795
//internal links
8896
this.observer = new MutationObserver(async (mutation) => {
@@ -168,6 +176,31 @@ export default class PlantumlPlugin extends Plugin {
168176
});
169177
}
170178

179+
async cleanupCache() {
180+
await localforage.iterate((value, key) => {
181+
if(key.startsWith('ts-')) {
182+
const encoded = key.split('-')[1];
183+
if(value < new Date().getTime() - (this.settings.cache * 24 * 60 * 60 * 1000)) {
184+
localforage.removeItem('png-' + encoded);
185+
localforage.removeItem('svg-' + encoded);
186+
localforage.removeItem('map-' + encoded);
187+
localforage.removeItem('ascii-' + encoded);
188+
}
189+
}
190+
});
191+
}
192+
193+
/*
194+
* older versions used to store generated images in local storage when using local generation.
195+
* To fix issues with the local storage quota we have to clean this up when upgrading from a version that supported this.
196+
*/
197+
cleanupLocalStorage() {
198+
for (const key of Object.keys(localStorage)) {
199+
if(key.endsWith('-map') || key.endsWith('-png') || key.endsWith('-svg') || key.endsWith('ascii')) {
200+
localStorage.removeItem(key);
201+
}
202+
}
203+
}
171204

172205
async onunload(): Promise<void> {
173206
console.log('unloading plugin plantuml');

src/settings.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface PlantUMLSettings {
99
javaPath: string;
1010
dotPath: string;
1111
defaultProcessor: string;
12+
cache: number;
1213
}
1314

1415
export const DEFAULT_SETTINGS: PlantUMLSettings = {
@@ -19,6 +20,7 @@ export const DEFAULT_SETTINGS: PlantUMLSettings = {
1920
javaPath: 'java',
2021
dotPath: 'dot',
2122
defaultProcessor: "png",
23+
cache: 60,
2224
}
2325

2426
export class PlantUMLSettingsTab extends PluginSettingTab {
@@ -68,7 +70,7 @@ export class PlantUMLSettingsTab extends PluginSettingTab {
6870
);
6971

7072
new Setting(containerEl)
71-
.setName("Java Path")
73+
.setName("Java path")
7274
.setDesc("Path to Java executable")
7375
.addText(text => text.setPlaceholder(DEFAULT_SETTINGS.javaPath)
7476
.setValue(this.plugin.settings.javaPath)
@@ -80,7 +82,7 @@ export class PlantUMLSettingsTab extends PluginSettingTab {
8082
);
8183

8284
new Setting(containerEl)
83-
.setName("Dot Path")
85+
.setName("Dot path")
8486
.setDesc("Path to dot executable")
8587
.addText(text => text.setPlaceholder(DEFAULT_SETTINGS.dotPath)
8688
.setValue(this.plugin.settings.dotPath)
@@ -120,7 +122,23 @@ export class PlantUMLSettingsTab extends PluginSettingTab {
120122
text.inputEl.addClass("puml-settings-area")
121123
}
122124
);
123-
new Setting(containerEl).setName("Debounce")
125+
126+
new Setting(containerEl)
127+
.setName('Cache')
128+
.setDesc('in days. Only applicable when generating diagrams locally')
129+
.addSlider(slider => {
130+
slider
131+
.setLimits(10, 360, 10)
132+
.setValue(this.plugin.settings.cache)
133+
.setDynamicTooltip()
134+
.onChange(async value => {
135+
this.plugin.settings.cache = value;
136+
await this.plugin.saveSettings();
137+
})
138+
});
139+
140+
new Setting(containerEl)
141+
.setName("Debounce")
124142
.setDesc("How often should the diagram refresh in seconds")
125143
.addText(text => text.setPlaceholder(String(DEFAULT_SETTINGS.debounce))
126144
.setValue(String(this.plugin.settings.debounce))

0 commit comments

Comments
 (0)