From dd1990cc8f5fce0f3c9df83b6c18f338a674d93f Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Mon, 29 Sep 2025 11:32:12 +0200 Subject: [PATCH] More dead code elimination --- client/data/datastore.test.ts | 3 +- client/data/mq.datastore.test.ts | 5 +- client/data/mq.datastore.ts | 3 + client/data/prefixed_kv_primitives.ts | 51 ------------ client/plugos/event.ts | 3 + client/space.ts | 23 ++--- .../spaces/asset_bundle_space_primitives.ts | 83 ------------------- client/spaces/sync.ts | 3 + 8 files changed, 24 insertions(+), 150 deletions(-) delete mode 100644 client/data/prefixed_kv_primitives.ts delete mode 100644 client/spaces/asset_bundle_space_primitives.ts diff --git a/client/data/datastore.test.ts b/client/data/datastore.test.ts index 3b1911a9..902966a2 100644 --- a/client/data/datastore.test.ts +++ b/client/data/datastore.test.ts @@ -3,13 +3,12 @@ import { IndexedDBKvPrimitives } from "./indexeddb_kv_primitives.ts"; import { MemoryKvPrimitives } from "./memory_kv_primitives.ts"; import type { KvPrimitives } from "./kv_primitives.ts"; import { assertEquals } from "@std/assert"; -import { PrefixedKvPrimitives } from "./prefixed_kv_primitives.ts"; import { DataStore } from "./datastore.ts"; import { LuaEnv, LuaStackFrame } from "../space_lua/runtime.ts"; import { parseExpressionString } from "../space_lua/parse.ts"; async function test(db: KvPrimitives) { - const datastore = new DataStore(new PrefixedKvPrimitives(db, ["ds"])); + const datastore = new DataStore(db); await datastore.set(["user", "peter"], { name: "Peter" }); await datastore.set(["user", "hank"], { name: "Hank" }); const env = new LuaEnv(); diff --git a/client/data/mq.datastore.test.ts b/client/data/mq.datastore.test.ts index f05a1b10..d779b423 100644 --- a/client/data/mq.datastore.test.ts +++ b/client/data/mq.datastore.test.ts @@ -2,7 +2,6 @@ import { DataStoreMQ } from "./mq.datastore.ts"; import { assertEquals } from "@std/assert"; import { MemoryKvPrimitives } from "./memory_kv_primitives.ts"; import { DataStore } from "./datastore.ts"; -import { PrefixedKvPrimitives } from "./prefixed_kv_primitives.ts"; import { FakeTime } from "@std/testing/time"; import type { MQMessage } from "../../plug-api/types/datastore.ts"; @@ -13,7 +12,7 @@ Deno.test("DataStore MQ", async () => { try { const mq = new DataStoreMQ( - new DataStore(new PrefixedKvPrimitives(db, ["mq"])), + new DataStore(db), ); let messages: MQMessage[]; @@ -81,7 +80,7 @@ Deno.test("DataStore MQ - Scale test with multiple subscribers", async () => { try { const mq = new DataStoreMQ( - new DataStore(new PrefixedKvPrimitives(db, ["mq"])), + new DataStore(db), ); const queueName = "scale-test"; diff --git a/client/data/mq.datastore.ts b/client/data/mq.datastore.ts index 84cb8455..4f76521f 100644 --- a/client/data/mq.datastore.ts +++ b/client/data/mq.datastore.ts @@ -84,6 +84,9 @@ export class QueueWorker { } } +/** + * Basic message queue implementation on top of a DataStore + */ export class DataStoreMQ { // Internal sequencer for messages, only really necessary when batch sending tons of messages within a millisecond seq = 0; diff --git a/client/data/prefixed_kv_primitives.ts b/client/data/prefixed_kv_primitives.ts deleted file mode 100644 index 98f1bcbf..00000000 --- a/client/data/prefixed_kv_primitives.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { KvPrimitives, KvQueryOptions } from "./kv_primitives.ts"; - -import type { KV, KvKey } from "../../plug-api/types/datastore.ts"; - -/** - * Turns any KvPrimitives into a KvPrimitives that automatically prefixes all keys (and removes them again when reading) - */ -export class PrefixedKvPrimitives implements KvPrimitives { - constructor(private wrapped: KvPrimitives, private prefix: KvKey) { - } - - clear(): Promise { - return this.wrapped.clear(); - } - - batchGet(keys: KvKey[]): Promise { - return this.wrapped.batchGet(keys.map((key) => this.applyPrefix(key))); - } - - batchSet(entries: KV[]): Promise { - return this.wrapped.batchSet( - entries.map(({ key, value }) => ({ key: this.applyPrefix(key), value })), - ); - } - - batchDelete(keys: KvKey[]): Promise { - return this.wrapped.batchDelete(keys.map((key) => this.applyPrefix(key))); - } - - async *query(options: KvQueryOptions): AsyncIterableIterator { - for await ( - const result of this.wrapped.query({ - prefix: this.applyPrefix(options.prefix), - }) - ) { - yield { key: this.stripPrefix(result.key), value: result.value }; - } - } - - close(): void { - this.wrapped.close(); - } - - private applyPrefix(key?: KvKey): KvKey { - return [...this.prefix, ...(key ? key : [])]; - } - - private stripPrefix(key: KvKey): KvKey { - return key.slice(this.prefix.length); - } -} diff --git a/client/plugos/event.ts b/client/plugos/event.ts index 3049eede..84ddc70e 100644 --- a/client/plugos/event.ts +++ b/client/plugos/event.ts @@ -1,3 +1,6 @@ +/** + * EventEmitter implementation, similar to the one used in CodeMirror + */ export abstract class EventEmitter { private handlers: Partial[] = []; diff --git a/client/space.ts b/client/space.ts index 6dc53def..fc6c620e 100644 --- a/client/space.ts +++ b/client/space.ts @@ -16,6 +16,12 @@ import { const pageWatchInterval = 3000; // + jitter +/** + * Wrapper around space primitives (see spaces/) for Client use + * Adds: + * - Concept of a page (on top of files) + * - Page watchers + */ export class Space { // We do watch files in the background to detect changes // This set of pages should only ever contain 1 page @@ -31,21 +37,15 @@ export class Space { ) { eventHook.addLocalListener("file:deleted", (fileName: string) => { if (this.watchedFiles.has(fileName)) { - // Stop watching deleted files already this.watchedFiles.delete(fileName); } }); - setTimeout(() => { - // Next tick, to ensure that the space is initialized - this.updatePageList().catch(console.error); + setTimeout(async () => { + // The only reason to do this is to trigger events + await this.spacePrimitives.fetchFileList(); }); } - public async updatePageList() { - // The only reason to do this is to trigger events - await this.spacePrimitives.fetchFileList(); - } - async deletePage(name: string): Promise { await this.getPageMeta(name); // Check if page exists, if not throws Error await this.spacePrimitives.deleteFile(`${name}.md`); @@ -160,8 +160,9 @@ export class Space { return this.spacePrimitives.deleteFile(name); } - // Even though changes coming from a sync cycle will immediately trigger a reload - // there are scenarios in which other tabs run the sync, so we have to poll for changes + /** + * Polls for changes in the watched files. + */ watch() { if (this.watchInterval) { clearInterval(this.watchInterval); diff --git a/client/spaces/asset_bundle_space_primitives.ts b/client/spaces/asset_bundle_space_primitives.ts deleted file mode 100644 index 9529e230..00000000 --- a/client/spaces/asset_bundle_space_primitives.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { SpacePrimitives } from "./space_primitives.ts"; -import type { AssetBundle } from "../asset_bundle/bundle.ts"; - -import type { FileMeta } from "@silverbulletmd/silverbullet/type/index"; - -export class AssetBundlePlugSpacePrimitives implements SpacePrimitives { - constructor( - private wrapped: SpacePrimitives, - private assetBundle: AssetBundle, - ) { - } - - async fetchFileList(): Promise { - const files = await this.wrapped.fetchFileList(); - return this.assetBundle.listFiles() - .map((p) => ({ - name: p, - contentType: this.assetBundle.getMimeType(p), - created: this.assetBundle.getMtime(p), - lastModified: this.assetBundle.getMtime(p), - perm: "ro", - size: -1, - } as FileMeta)).concat(files); - } - - readFile( - path: string, - ): Promise<{ data: Uint8Array; meta: FileMeta }> { - if (this.assetBundle.has(path)) { - const data = this.assetBundle.readFileSync(path); - // console.log("Requested encoding", encoding); - return Promise.resolve({ - data, - meta: { - contentType: this.assetBundle.getMimeType(path), - created: this.assetBundle.getMtime(path), - lastModified: this.assetBundle.getMtime(path), - size: data.byteLength, - perm: "ro", - } as FileMeta, - }); - } - return this.wrapped.readFile(path); - } - - getFileMeta(path: string, observing?: boolean): Promise { - if (this.assetBundle.has(path)) { - const data = this.assetBundle.readFileSync(path); - return Promise.resolve({ - contentType: this.assetBundle.getMimeType(path), - created: this.assetBundle.getMtime(path), - lastModified: this.assetBundle.getMtime(path), - size: data.byteLength, - perm: "ro", - } as FileMeta); - } - return this.wrapped.getFileMeta(path, observing); - } - - writeFile( - path: string, - data: Uint8Array, - meta?: FileMeta, - ): Promise { - if (this.assetBundle.has(path)) { - console.warn("Attempted to write to read-only asset file", path); - return this.getFileMeta(path); - } - return this.wrapped.writeFile( - path, - data, - meta, - ); - } - - deleteFile(path: string): Promise { - if (this.assetBundle.has(path)) { - // Quietly ignore - return Promise.resolve(); - } - return this.wrapped.deleteFile(path); - } -} diff --git a/client/spaces/sync.ts b/client/spaces/sync.ts index 9c832de5..1b0f2660 100644 --- a/client/spaces/sync.ts +++ b/client/spaces/sync.ts @@ -1,3 +1,6 @@ +/** + * This is where the sync magic happens + */ import type { SpacePrimitives } from "./space_primitives.ts"; import { EventEmitter } from "../plugos/event.ts"; import { plugPrefix } from "./constants.ts";