Skip to content

Commit 9d52dd9

Browse files
committed
fix #185
1 parent 3be4589 commit 9d52dd9

24 files changed

+1395
-640
lines changed

bun.lockb

-2.27 KB
Binary file not shown.

exampleVault/Advanced Examples/PF2e Encounter Calculator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
playerCount: 6
3-
playerLevel: 6
3+
playerLevel: 4
44
enemy:
55
- name: Somthing
66
level: 2

exampleVault/Advanced Examples/Using JS Engine for Complex things.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
text: aaa
2+
text: aasdasd
33
locked: false
44
---
55

@@ -8,23 +8,28 @@ Locked: `INPUT[toggle:locked]`
88
```js-engine
99
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
1010
11-
const signal = mb.createSignal(undefined)
12-
component.register(mb.listenToMetadata(signal, context.file.path, ['locked']))
11+
const signal = mb.createSignal(undefined);
12+
13+
component.register(mb.listenToMetadata(signal, context.file.path, ['locked']));
14+
15+
const comp = new obsidian.Component(component);
1316
1417
function render() {
18+
comp.unload()
19+
comp.load()
1520
container.empty();
1621
if (signal.get()) {
17-
mb.createViewFieldFromString("VIEW[{text}][text]", "INLINE", context.file.path, container, component);
22+
mb.createViewFieldFromString("VIEW[{text}][text]", "inline", context.file.path, container, comp);
1823
} else {
19-
mb.createInputFieldFromString("INPUT[text:text]", "INLINE", context.file.path, container, component);
24+
mb.createInputFieldFromString("INPUT[text:text]", "inline", context.file.path, container, comp);
2025
}
2126
2227
}
2328
24-
const reactive = engine.reactive(render)
29+
const reactive = engine.reactive(render);
2530
signal.registerListener({
2631
callback: () => reactive.refresh(),
27-
})
32+
});
2833
2934
return reactive;
3035
```

exampleVault/Examples.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
slider1: 8
2+
slider1: 7
33
suggest: test
44
toggle1: false
55
Domestic_tasks:
@@ -13,7 +13,7 @@ inlineSelect: 0
1313
nested:
1414
object: test
1515
number1: 2
16-
number2: 16
16+
number2: 14
1717
---
1818

1919
## Fields Work Everywhere

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dev-publish": "bun run esbuild.publish.config.mjs",
1010
"build-publish": "tsc -noEmit -skipLibCheck && node esbuild.publish.config.mjs production",
1111
"tsc": "tsc -noEmit -skipLibCheck",
12-
"test": "bun test",
12+
"test": "LOG_TESTS=false bun test",
1313
"test:log": "LOG_TESTS=true bun test",
1414
"format": "prettier --write --plugin prettier-plugin-svelte .",
1515
"format:check": "prettier --check --plugin prettier-plugin-svelte .",
@@ -28,7 +28,7 @@
2828
"@codemirror/language": "6.9.2",
2929
"@codemirror/state": "6.3.1",
3030
"@codemirror/view": "6.22.0",
31-
"@happy-dom/global-registrator": "^12.10.3",
31+
"@happy-dom/global-registrator": "^13.3.1",
3232
"@tsconfig/svelte": "^5.0.0",
3333
"@types/bun": "^1.0.2",
3434
"@typescript-eslint/eslint-plugin": "^6.0.0",

src/main.ts

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createMarkdownRenderChildWidgetEditorPlugin } from './cm6/Cm6_ViewPlugi
88
import { MDRCManager } from './MDRCManager';
99
import { DEFAULT_SETTINGS, type MetaBindPluginSettings } from './settings/Settings';
1010
import { type IPlugin } from './IPlugin';
11-
import { ObsidianMetadataAdapter } from './metadata/ObsidianMetadataAdapter';
11+
// import { ObsidianMetadataAdapter } from './metadata/ObsidianMetadataAdapter';
1212
import { FaqView, MB_FAQ_VIEW_TYPE } from './faq/FaqView';
1313
import { EMBED_MAX_DEPTH, EmbedMDRC } from './renderChildren/EmbedMDRC';
1414
import { getUUID } from './utils/Utils';
@@ -20,6 +20,9 @@ import { registerCm5HLModes } from './cm6/Cm5_Modes';
2020
import { DependencyManager } from './utils/dependencies/DependencyManager';
2121
import { Version } from './utils/dependencies/Version';
2222
import { createEditorMenu } from './EditorMenu';
23+
import { BindTargetStorageType } from './parsers/bindTargetParser/BindTargetDeclaration';
24+
import { GlobalMetadataSource, InternalMetadataSource } from './metadata/InternalMetadataSources';
25+
import { ObsidianMetadataSource } from './metadata/ObsidianMetadataSource';
2326

2427
export enum MetaBindBuild {
2528
DEV = 'dev',
@@ -79,22 +82,9 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
7982
this.api = new API(this);
8083
this.internal = new ObsidianAPIAdapter(this);
8184
this.mdrcManager = new MDRCManager();
82-
const metadataAdapter = new ObsidianMetadataAdapter(this);
83-
this.metadataManager = new MetadataManager(metadataAdapter);
85+
// const metadataAdapter = new ObsidianMetadataAdapter(this);
8486

85-
this.registerEvent(
86-
this.app.vault.on('rename', (_file, oldPath) => {
87-
this.mdrcManager.unloadFile(oldPath);
88-
metadataAdapter.onFileRename(oldPath);
89-
}),
90-
);
91-
92-
this.registerEvent(
93-
this.app.vault.on('delete', file => {
94-
this.mdrcManager.unloadFile(file.path);
95-
metadataAdapter.onFileDelete(file.path);
96-
}),
97-
);
87+
this.setUpMetadataManager();
9888

9989
this.loadTemplates();
10090

@@ -121,7 +111,6 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
121111
onunload(): void {
122112
console.log(`meta-bind | Main >> unload`);
123113
this.mdrcManager.unload();
124-
this.metadataManager.unload();
125114
}
126115

127116
// TODO: move to internal API
@@ -135,6 +124,42 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
135124
}
136125
}
137126

127+
setUpMetadataManager(): void {
128+
this.metadataManager = new MetadataManager();
129+
130+
const obsidianMetadataSource = new ObsidianMetadataSource(
131+
this,
132+
BindTargetStorageType.FRONTMATTER,
133+
this.metadataManager,
134+
);
135+
this.metadataManager.registerSource(obsidianMetadataSource);
136+
137+
const memoryMetadataSource = new InternalMetadataSource(BindTargetStorageType.MEMORY, this.metadataManager);
138+
this.metadataManager.registerSource(memoryMetadataSource);
139+
140+
const globalMemoryMetadataSource = new GlobalMetadataSource(
141+
BindTargetStorageType.GLOBAL_MEMORY,
142+
this.metadataManager,
143+
);
144+
this.metadataManager.registerSource(globalMemoryMetadataSource);
145+
146+
this.registerEvent(
147+
this.app.vault.on('rename', (file, oldPath) => {
148+
this.mdrcManager.unloadFile(oldPath);
149+
this.metadataManager.onStoragePathRenamed(oldPath, file.path);
150+
}),
151+
);
152+
153+
this.registerEvent(
154+
this.app.vault.on('delete', file => {
155+
this.mdrcManager.unloadFile(file.path);
156+
this.metadataManager.onStoragePathDeleted(file.path);
157+
}),
158+
);
159+
160+
this.registerInterval(window.setInterval(() => this.metadataManager.cycle(), this.settings.syncInterval));
161+
}
162+
138163
addPostProcessors(): void {
139164
this.registerMarkdownPostProcessor((el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
140165
const codeBlocks = el.querySelectorAll('code');

src/metadata/ComputedMetadataSubscription.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class ComputedMetadataSubscription implements IMetadataSubscription {
7676
const values = this.dependencySubscriptions.map(x => x.callbackSignal.get());
7777
const value = await this.computeFunction(values);
7878
this.callbackSignal.set(value);
79-
this.metadataManager.updateCache(value, this);
79+
this.metadataManager.update(value, this);
8080
}
8181

8282
/**

src/metadata/IMetadataAdapter.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { type IMetadataSource, MapMetadataSource, type Metadata } from './MetadataSource';
2+
import { type GlobalMetadataCacheItem, type MapMetadataCacheItem } from './MetadataCacheItem';
3+
import { type MetadataManager } from './MetadataManager';
4+
import { type BindTargetDeclaration } from '../parsers/bindTargetParser/BindTargetDeclaration';
5+
import { type PropPath } from '../utils/prop/PropPath';
6+
import { type IMetadataSubscription } from './IMetadataSubscription';
7+
import { PropUtils } from '../utils/prop/PropUtils';
8+
import { ErrorLevel, MetaBindInternalError } from '../utils/errors/MetaBindErrors';
9+
10+
export class InternalMetadataSource extends MapMetadataSource<MapMetadataCacheItem> {
11+
public getDefaultCacheItem(storagePath: string): MapMetadataCacheItem {
12+
return {
13+
data: {},
14+
storagePath: storagePath,
15+
...this.manager.getDefaultCacheItem(),
16+
};
17+
}
18+
19+
public async syncExternal(_cacheItem: MapMetadataCacheItem): Promise<void> {
20+
// Do nothing
21+
}
22+
}
23+
24+
export class GlobalMetadataSource implements IMetadataSource<GlobalMetadataCacheItem> {
25+
public readonly id: string;
26+
public readonly manager: MetadataManager;
27+
public readonly cache: GlobalMetadataCacheItem;
28+
29+
constructor(id: string, manager: MetadataManager) {
30+
this.id = id;
31+
this.manager = manager;
32+
33+
this.cache = {
34+
data: {},
35+
...this.manager.getDefaultCacheItem(),
36+
};
37+
}
38+
39+
public delete(_cacheItem: GlobalMetadataCacheItem): void {
40+
// noop
41+
}
42+
43+
public getCacheItemForStoragePath(_storagePath: string): GlobalMetadataCacheItem | undefined {
44+
return this.cache;
45+
}
46+
47+
public iterateCacheItems(): IterableIterator<GlobalMetadataCacheItem> {
48+
return [this.cache][Symbol.iterator]();
49+
}
50+
51+
public onCycle(_cacheItem: GlobalMetadataCacheItem): void {
52+
// noop
53+
}
54+
55+
public readCache(_bindTarget: BindTargetDeclaration): unknown {
56+
return this.readCacheItem(this.cache, _bindTarget.storageProp);
57+
}
58+
59+
public readCacheItem(cacheItem: GlobalMetadataCacheItem, propPath: PropPath): unknown {
60+
return PropUtils.tryGet(cacheItem.data, propPath);
61+
}
62+
63+
public shouldDelete(_cacheItem: GlobalMetadataCacheItem): boolean {
64+
return false;
65+
}
66+
67+
public subscribe(subscription: IMetadataSubscription): GlobalMetadataCacheItem {
68+
this.cache.subscriptions.push(subscription);
69+
return this.cache;
70+
}
71+
72+
public syncExternal(_cacheItem: GlobalMetadataCacheItem): void {
73+
// noop
74+
}
75+
76+
public unsubscribe(subscription: IMetadataSubscription): GlobalMetadataCacheItem {
77+
this.cache.subscriptions = this.cache.subscriptions.filter(x => x.uuid !== subscription.uuid);
78+
79+
return this.cache;
80+
}
81+
82+
public update(value: unknown, subscription: IMetadataSubscription): GlobalMetadataCacheItem {
83+
if (subscription.bindTarget === undefined) {
84+
throw new MetaBindInternalError({
85+
errorLevel: ErrorLevel.CRITICAL,
86+
effect: 'can not update metadata',
87+
cause: 'subscription bind target undefined',
88+
});
89+
}
90+
91+
PropUtils.setAndCreate(this.cache.data, subscription.bindTarget.storageProp, value);
92+
93+
return this.cache;
94+
}
95+
96+
public updateEntireCache(value: Metadata, cacheItem: GlobalMetadataCacheItem): void {
97+
cacheItem.data = value;
98+
}
99+
100+
public readEntireCacheItem(cacheItem: GlobalMetadataCacheItem): Metadata {
101+
return cacheItem.data;
102+
}
103+
}

src/metadata/MetadataCacheItem.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { type IMetadataSubscription } from './IMetadataSubscription';
2+
3+
import { type Metadata } from './MetadataSource';
4+
5+
export interface IMetadataCacheItem {
6+
subscriptions: IMetadataSubscription[];
7+
8+
/**
9+
* The cycles since the last change to the cache by the plugin.
10+
*/
11+
cyclesSinceInternalChange: number;
12+
/**
13+
* Whether the cache was changed by the plugin. If this is true, the frontmatter should be updated.
14+
*/
15+
pendingInternalChange: boolean;
16+
/**
17+
* The cycles that the cache has been inactive, meaning no listener registered to it.
18+
*/
19+
cyclesSinceInactive: number;
20+
/**
21+
* Whether the there are no subscribers to the cache.
22+
*/
23+
inactive: boolean;
24+
}
25+
26+
export interface MapMetadataCacheItem extends IMetadataCacheItem {
27+
storagePath: string;
28+
data: Metadata;
29+
}
30+
31+
export interface GlobalMetadataCacheItem extends IMetadataCacheItem {
32+
data: Metadata;
33+
}

0 commit comments

Comments
 (0)