Skip to content

Commit 73750d0

Browse files
committed
svelte 5 and query api
1 parent e8a39f3 commit 73750d0

File tree

16 files changed

+199
-75
lines changed

16 files changed

+199
-75
lines changed

automation/build/esbuild.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import builtins from 'builtin-modules';
22
import esbuild from 'esbuild';
33
import esbuildSvelte from 'esbuild-svelte';
4-
import sveltePreprocess from 'svelte-preprocess';
4+
import { sveltePreprocess } from 'svelte-preprocess';
55
import { getBuildBanner } from 'build/buildBanner';
66

77
const banner = getBuildBanner('Release Build', version => version);
@@ -41,7 +41,7 @@ const build = await esbuild.build({
4141
},
4242
plugins: [
4343
esbuildSvelte({
44-
compilerOptions: { css: 'injected', dev: false, sveltePath: 'svelte' },
44+
compilerOptions: { css: 'injected', dev: false },
4545
preprocess: sveltePreprocess(),
4646
filterWarnings: warning => {
4747
// we don't want warnings from node modules that we can do nothing about

automation/build/esbuild.dev.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import esbuild from 'esbuild';
22
import copy from 'esbuild-plugin-copy-watch';
33
import esbuildSvelte from 'esbuild-svelte';
4-
import sveltePreprocess from 'svelte-preprocess';
4+
import { sveltePreprocess } from 'svelte-preprocess';
55
import manifest from '../../manifest.json' assert { type: 'json' };
66
import { getBuildBanner } from 'build/buildBanner';
77

@@ -49,7 +49,7 @@ const context = await esbuild.context({
4949
],
5050
}),
5151
esbuildSvelte({
52-
compilerOptions: { css: 'injected', dev: true, sveltePath: 'svelte' },
52+
compilerOptions: { css: 'injected', dev: true },
5353
preprocess: sveltePreprocess(),
5454
filterWarnings: warning => {
5555
// we don't want warnings from node modules that we can do nothing about

bun.lockb

12.7 KB
Binary file not shown.

jsEngine/JsMDRC.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class JsMDRC extends MarkdownRenderChild {
3939
const file = this.getExecutionFile();
4040
return {
4141
file: file,
42-
metadata: file === undefined ? undefined : this.plugin.app.metadataCache.getFileCache(file) ?? undefined,
42+
metadata: file === undefined ? undefined : (this.plugin.app.metadataCache.getFileCache(file) ?? undefined),
4343
block: undefined,
4444
};
4545
}
@@ -102,7 +102,7 @@ export class JsMDRC extends MarkdownRenderChild {
102102
await this.renderResults(this.containerEl);
103103
this.renderExecutionStats(this.containerEl);
104104
} catch (e) {
105-
this.containerEl.innerText = e instanceof Error ? e.stack?.toString() ?? '' : (e as string);
105+
this.containerEl.innerText = e instanceof Error ? (e.stack?.toString() ?? '') : (e as string);
106106
this.containerEl.addClass('mod-warning');
107107
}
108108
}

jsEngine/api/API.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { MarkdownAPI } from 'jsEngine/api/MarkdownAPI';
2-
import { type CachedMetadata, type TFile, type App, type Plugin } from 'obsidian';
2+
import { type App, type Plugin } from 'obsidian';
33
import type JsEnginePlugin from 'jsEngine/main';
44
import { type InstanceId } from 'jsEngine/api/InstanceId';
55
import { MessageAPI } from 'jsEngine/api/MessageAPI';
66
import { ReactiveComponent } from 'jsEngine/api/reactive/ReactiveComponent';
77
import { LibAPI } from 'jsEngine/api/LibAPI';
88
import { type JsFunc } from 'jsEngine/engine/JsExecution';
99
import { InternalAPI } from 'jsEngine/api/Internal';
10+
import { QueryAPI } from 'jsEngine/api/QueryAPI';
1011

1112
export class API {
1213
/**
@@ -30,6 +31,10 @@ export class API {
3031
* API to interact with packaged libraries.
3132
*/
3233
readonly lib: LibAPI;
34+
/**
35+
* API to query your vault with simple javascript functions.
36+
*/
37+
readonly query: QueryAPI;
3338
/**
3439
* API to interact with js engines internals.
3540
*/
@@ -43,6 +48,7 @@ export class API {
4348
this.markdown = new MarkdownAPI(this);
4449
this.message = new MessageAPI(this);
4550
this.lib = new LibAPI(this);
51+
this.query = new QueryAPI(this);
4652
this.internal = new InternalAPI(this);
4753
}
4854

@@ -81,8 +87,4 @@ export class API {
8187
public reactive(fn: JsFunc, ...initialArgs: unknown[]): ReactiveComponent {
8288
return new ReactiveComponent(this, fn, initialArgs);
8389
}
84-
85-
public queryVault(query: (file: TFile, cache: CachedMetadata | null) => boolean): TFile[] {
86-
return this.app.vault.getMarkdownFiles().filter(file => query(file, this.app.metadataCache.getFileCache(file)));
87-
}
8890
}

jsEngine/api/QueryAPI.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { getAllTags, type CachedMetadata, type TFile } from 'obsidian';
2+
import type { API } from 'jsEngine/api/API';
3+
4+
export class QueryAPI {
5+
readonly apiInstance: API;
6+
7+
constructor(apiInstance: API) {
8+
this.apiInstance = apiInstance;
9+
}
10+
11+
/**
12+
* This function will run the `query` callback on every markdown file in the vault and then return a list of the results, with `undefined` filtered out.
13+
*
14+
* @example Find all markdown `TFiles` that start with the word "Foo":
15+
* ```typescript
16+
* const files = engine.query.files(file => file.name.startsWith("Foo") ? file : undefined);
17+
* ```
18+
*
19+
* @example Find all the names of all markdown files that are in the "Foo" folder:
20+
* ```typescript
21+
* const fileNames = engine.query.files(file => file.path.startsWith("Foo/") ? file.name : undefined);
22+
* ```
23+
*/
24+
public files<T>(query: (file: TFile) => T | undefined): T[] {
25+
return this.apiInstance.app.vault
26+
.getMarkdownFiles()
27+
.map(file => query(file))
28+
.filter(x => x !== undefined);
29+
}
30+
31+
/**
32+
* This function functions similarly tp {@link QueryAPI.files}, but also provides the cache and tags of each file to the `query` callback.
33+
*
34+
* @example Find the paths of all markdown files that have the tag "Foo":
35+
* ```typescript
36+
* const paths = engine.query.filesWithMetadata((file, cache, tags) => tags.includes("Foo") ? file.path : undefined);
37+
* ```
38+
*/
39+
public filesWithMetadata<T>(query: (file: TFile, cache: CachedMetadata | null, tags: string[]) => T | undefined): T[] {
40+
return this.apiInstance.app.vault
41+
.getMarkdownFiles()
42+
.map(file => {
43+
const cache = this.apiInstance.app.metadataCache.getFileCache(file);
44+
const tags = cache ? (getAllTags(cache) ?? []) : [];
45+
return query(file, cache, tags);
46+
})
47+
.filter(x => x !== undefined);
48+
}
49+
}

jsEngine/engine/ExecutionStatsComponent.svelte

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
import { JsExecution } from './JsExecution';
33
import MessageComponent from '../messages/MessageComponent.svelte';
44
5-
export let execution: JsExecution;
6-
let messages = execution.getMessages();
5+
const {
6+
execution,
7+
}: {
8+
execution: JsExecution;
9+
} = $props();
710
811
function highlightCode(code: string): string {
12+
// @ts-expect-error
913
const prism = window.Prism;
1014
try {
1115
return prism.highlight(code, prism.languages.javascript, 'javascript');
@@ -55,7 +59,7 @@
5559

5660
<h3>Messages</h3>
5761
<div>
58-
{#each messages as messageWrapper}
62+
{#each execution.getMessages() as messageWrapper}
5963
<MessageComponent
6064
messageWrapper={messageWrapper}
6165
messageManager={execution.plugin.messageManager}

jsEngine/engine/JsExecution.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ export class JsExecution {
7979
readonly app: App;
8080
readonly plugin: JsEnginePlugin;
8181

82-
private readonly globals: JsExecutionGlobals;
8382
private readonly context: (JsExecutionContext | undefined) & Record<string, unknown>;
8483
private readonly apiInstance: API;
8584
private messages: MessageWrapper[];
8685
private func: JsFunc | undefined;
8786

87+
readonly globals: JsExecutionGlobals;
8888
readonly uuid: string;
8989
readonly code: string;
9090
result: unknown;

jsEngine/engine/ResultRenderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class ResultRenderer {
4545
}
4646

4747
if (value instanceof MarkdownString) {
48-
console.log('js-engine | Rendering Markdown String\n', value.content);
48+
// console.log('js-engine | Rendering Markdown String\n', value.content);
4949
await value.render(this.plugin.app, this.container, this.sourcePath, this.component);
5050
return;
5151
}

jsEngine/messages/MessageComponent.svelte

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
import { useIcon } from 'jsEngine/utils/UseIcon';
44
import { slide } from 'svelte/transition';
55
6-
export let messageWrapper: MessageWrapper;
7-
export let messageManager: MessageManager;
8-
export let showDeleteButton: boolean = true;
9-
export let showMessageSource: boolean = true;
6+
const {
7+
messageWrapper,
8+
messageManager,
9+
showDeleteButton = true,
10+
showMessageSource = true,
11+
}: {
12+
messageWrapper: MessageWrapper;
13+
messageManager: MessageManager;
14+
showDeleteButton?: boolean;
15+
showMessageSource?: boolean;
16+
} = $props();
1017
11-
let showMore: boolean = false;
18+
let showMore: boolean = $state(false);
1219
</script>
1320

1421
<div class="js-engine-message callout {mapMessageTypeToClass(messageWrapper.message.type)}" data-callout={messageWrapper.message.type}>
@@ -18,8 +25,8 @@
1825
{#if showDeleteButton}
1926
<div
2027
class="js-engine-message-delete-icon callout-icon"
21-
on:click={() => messageManager.removeMessage(messageWrapper.uuid)}
22-
on:keydown={e => (e.key === ' ' ? messageManager.removeMessage(messageWrapper.uuid) : undefined)}
28+
onclick={() => messageManager.removeMessage(messageWrapper.uuid)}
29+
onkeydown={e => (e.key === ' ' ? messageManager.removeMessage(messageWrapper.uuid) : undefined)}
2330
use:useIcon={'x'}
2431
aria-label="remove"
2532
role="button"
@@ -40,9 +47,9 @@
4047
<div class="js-engine-message-detail">
4148
<div
4249
class="js-engine-message-detail-row"
43-
on:click={() => (showMore = !showMore)}
50+
onclick={() => (showMore = !showMore)}
4451
aria-expanded={showMore ? 'true' : 'false'}
45-
on:keydown={e => (e.key === ' ' ? (showMore = !showMore) : undefined)}
52+
onkeydown={e => (e.key === ' ' ? (showMore = !showMore) : undefined)}
4653
role="button"
4754
tabindex="0"
4855
>

0 commit comments

Comments
 (0)