Remove [[wiki-links]], backlinks and the graph
CI & Build / Build now, or wait for Android? (push) Successful in 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Failing after 6s
CI & Build / Build & push image (push) Skipped
CI & Build / Python tests (push) Successful in 8s
Desktop (Tauri) / Tauri desktop (Linux) (push) Failing after 31s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Failing after 37s
Desktop (Tauri) / Update manifest (push) Skipped
Android / Kotlin + Rust (APK) (push) Failing after 1m56s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Failing after 6s
CI & Build / Build & push image (push) Skipped
CI & Build / Python tests (push) Successful in 8s
Desktop (Tauri) / Tauri desktop (Linux) (push) Failing after 31s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Failing after 37s
Desktop (Tauri) / Update manifest (push) Skipped
Android / Kotlin + Rust (APK) (push) Failing after 1m56s
Operator, 2026-08-22 (note 2897): ThoughtSync is an intermediary surface. You
write here because it's easy — a notebook in your pocket — and later you recall
the thing and go finish it somewhere else. Recall is the product; organization
is secondary. A linking system is organization, and it isn't what this is for.
So: `[[wiki-links]]`, backlinks, the `[[` autocomplete, the note_links table,
`/api/notes/link-search`, `/api/notes/<id>/backlinks`, the whole graph blueprint
and GraphView. Rust core loses `extract_links`, `backlinks`, `link_search` and
`create_titled`; the desktop loses the three Tauri commands that exposed them.
This subsumes 982d24c rather than reverting it. That commit bound links to a
note id so a rename would stop rewriting other notes' bodies — real infra, but
infra for a feature that is now gone, and nothing it added survives. Alembic
0023 stays in the chain anyway: it shipped in an image and may already be
applied, and deleting an applied revision strands a database's version pointer.
0024 drops the table and takes the column with it. The history stays honest
about the fact that it existed for a day.
Two things deliberately kept, because they were serving recall and only
incidentally serving links:
- `/api/notes/titles` and the titles store. The command palette lists them so
you can jump to a note by name. `resolve()` — the name→note lookup that only
linking needed — is gone.
- `display_title`. Every note still has a name for search results and export
filenames. What that name is FOR changed; that it exists did not.
`notes/links.py` is now `notes/tags.py`, holding the #tag→label reconciliation
it always also owned. A file called links.py with no links in it would have been
exactly the drift this removal is meant to end.
Also swept out on the way: `_escape_like`, whose only caller was link-search,
and the `graph` icon. Nothing lost that a person typed — note_links was always
derived, and the `[[text]]` is still sitting in every body it was written in.
This commit is contained in:
@@ -1,65 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useNotesStore, type NoteLinkRef } from "../stores/notes";
|
||||
import { useTitlesStore } from "../stores/titles";
|
||||
import type { InlineToken } from "../notes/markdown";
|
||||
|
||||
const props = defineProps<{ tokens: InlineToken[]; links?: NoteLinkRef[] }>();
|
||||
|
||||
const router = useRouter();
|
||||
const notes = useNotesStore();
|
||||
const titles = useTitlesStore();
|
||||
|
||||
/**
|
||||
* Where a [[link]] token actually points, according to the server.
|
||||
*
|
||||
* Keyed on the normalized written text, which is what survives in the body — the
|
||||
* server resolved it to an id when the link was saved, so this keeps working after
|
||||
* the target has been renamed and the written text has gone stale.
|
||||
*/
|
||||
const bound = computed(() => {
|
||||
const map = new Map<string, NoteLinkRef>();
|
||||
for (const l of props.links ?? []) map.set(l.norm, l);
|
||||
return map;
|
||||
});
|
||||
|
||||
/** What to SHOW for a link: the target's current name, else the text as written. */
|
||||
function label(token: string): string {
|
||||
return bound.value.get(token.trim().toLowerCase())?.title ?? token;
|
||||
}
|
||||
|
||||
// Open the target via the board's ?open=<id> mechanism, creating the note first if
|
||||
// the link names one that doesn't exist — which is a supported way to make a note.
|
||||
async function follow(token: string) {
|
||||
const hit = bound.value.get(token.trim().toLowerCase());
|
||||
if (hit) {
|
||||
void router.push({ path: "/", query: { open: hit.id } });
|
||||
return;
|
||||
}
|
||||
// No server binding: either this is running offline against the local store, or
|
||||
// the link genuinely resolves to nothing. The name index answers the first case.
|
||||
await titles.load();
|
||||
const byName = titles.resolve(token);
|
||||
const id = byName ? byName.id : (await notes.createTitled(token)).id;
|
||||
if (!byName) await titles.reload();
|
||||
void router.push({ path: "/", query: { open: id } });
|
||||
}
|
||||
// Emphasis and code only. `[[wiki-links]]` were the one token type that needed a
|
||||
// router, a store and a resolver behind it; they are gone (note 2897), and so is all
|
||||
// of that.
|
||||
defineProps<{ tokens: InlineToken[] }>();
|
||||
</script>
|
||||
|
||||
<!-- Rendered tightly (no whitespace between tokens) so a token's own leading/trailing
|
||||
spaces are preserved and no extra spaces are introduced. -->
|
||||
<template
|
||||
><template v-for="(t, i) in tokens" :key="i"
|
||||
><span
|
||||
v-if="t.type === 'link'"
|
||||
role="link"
|
||||
tabindex="0"
|
||||
class="cursor-pointer font-medium text-brand-700 underline-offset-2 hover:underline dark:text-brand"
|
||||
@click.stop="follow(t.value)"
|
||||
@keydown.enter.stop.prevent="follow(t.value)"
|
||||
>{{ label(t.value) }}</span
|
||||
><strong v-else-if="t.type === 'bold'" class="font-semibold">{{ t.value }}</strong
|
||||
><strong v-if="t.type === 'bold'" class="font-semibold">{{ t.value }}</strong
|
||||
><em v-else-if="t.type === 'italic'">{{ t.value }}</em
|
||||
><code
|
||||
v-else-if="t.type === 'code'"
|
||||
|
||||
Reference in New Issue
Block a user