obsidian-dev-utils 101.8.0 → 102.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -65,6 +65,111 @@ export declare enum LinkStyle {
65
65
  */
66
66
  Wikilink = "Wikilink"
67
67
  }
68
+ /**
69
+ * Params passed to the link converter of {@link editBacklinksSnapshot}.
70
+ *
71
+ * @typeParam TPayload - The payload recorded for each link when the snapshot was built.
72
+ */
73
+ export interface BacklinkConversionParams<TPayload> {
74
+ /**
75
+ * The link being converted.
76
+ */
77
+ readonly link: Reference;
78
+ /**
79
+ * The payload captured for the link when the snapshot was built.
80
+ *
81
+ * `undefined` when the link is not in the snapshot, which can only happen if
82
+ * {@link EditBacklinksSnapshotParams.shouldVisitUnmatchedLinks} is `true`.
83
+ */
84
+ readonly payload: TPayload | undefined;
85
+ /**
86
+ * The path of the note holding the link.
87
+ */
88
+ readonly sourcePath: string;
89
+ }
90
+ /**
91
+ * The minimal shape {@link buildBacklinksSnapshot} reads a set of backlinks from.
92
+ *
93
+ * Both a `CustomArrayDict<Reference>` — what
94
+ * {@link ../obsidian/metadata-cache!getBacklinksForFileSafe | getBacklinksForFileSafe} returns — and a plain
95
+ * `Map<string, Reference[]>` satisfy it, so a caller can pass either without converting first.
96
+ */
97
+ export interface BacklinksLike {
98
+ /**
99
+ * Returns the links the note at `key` holds, or a nullish value when it holds none.
100
+ *
101
+ * @param key - The path of the backlink-holding note.
102
+ * @returns The links, or a nullish value.
103
+ */
104
+ get(key: string): null | readonly Reference[] | undefined;
105
+ /**
106
+ * Returns the paths of the backlink-holding notes.
107
+ *
108
+ * @returns The paths.
109
+ */
110
+ keys(): Iterable<string>;
111
+ }
112
+ /**
113
+ * A captured snapshot of a set of backlinks: the path of each backlink-holding note, mapped to the identity
114
+ * keys of that note's own links to the target(s), each mapped to the payload recorded for it.
115
+ *
116
+ * The snapshot exists so that the fetch and the rewrite can happen at different moments. A rename invalidates
117
+ * the metadata cache for the old path, so a caller that rewrites links **after** renaming has to capture the
118
+ * backlinks **before** — which is why {@link editBacklinksSnapshot} takes a snapshot rather than a path.
119
+ *
120
+ * The payload is whatever the caller needs to remember per link. It is `undefined` for a single-target
121
+ * rewrite (the target is implied), and the old target's path for a multi-target one, where one note's links
122
+ * may point at several files that all moved and each link has to be resolved to its own new path.
123
+ *
124
+ * @typeParam TPayload - The payload recorded for each link.
125
+ */
126
+ export type BacklinksSnapshot<TPayload> = ReadonlyMap<string, ReadonlyMap<string, TPayload>>;
127
+ /**
128
+ * Params for {@link buildBacklinksSnapshot}.
129
+ *
130
+ * @typeParam TPayload - The payload recorded for each link.
131
+ */
132
+ export interface BuildBacklinksSnapshotParams<TPayload> {
133
+ /**
134
+ * The backlinks to record.
135
+ */
136
+ readonly backlinks: BacklinksLike;
137
+ /**
138
+ * Computes the identity key of a link.
139
+ *
140
+ * Must be the same function passed to {@link editBacklinksSnapshot}, or no link will ever match.
141
+ *
142
+ * @default `JSON.stringify`
143
+ */
144
+ linkIdentityKeyProvider?(this: void, link: Reference): string;
145
+ /**
146
+ * Rewrites the path of a backlink-holding note as it will be **after** the operation.
147
+ *
148
+ * A note that holds a backlink can itself be renamed or moved by the same operation — including the
149
+ * renamed note's own self-links. Remapping here keys the snapshot by the path the rewrite will actually
150
+ * open.
151
+ *
152
+ * @default the identity function
153
+ */
154
+ pathRemapper?(this: void, backlinkPath: string): string;
155
+ /**
156
+ * Produces the payload to record for a link. See {@link BacklinksSnapshot} for what a payload is for.
157
+ *
158
+ * @param link - The link being recorded.
159
+ * @returns The payload.
160
+ */
161
+ payloadProvider(this: void, link: Reference): TPayload;
162
+ /**
163
+ * An existing snapshot to merge into, so several sets of backlinks can be accumulated into one.
164
+ *
165
+ * Merging is what makes a single rewrite pass per note possible when a note links to several moved
166
+ * targets: without it, calling the rewrite once per target would open — and write — the same note
167
+ * repeatedly.
168
+ *
169
+ * When omitted, a new snapshot is created.
170
+ */
171
+ readonly target?: MutableBacklinksSnapshot<TPayload>;
172
+ }
68
173
  /**
69
174
  * Params for {@link convertLink}.
70
175
  */
@@ -198,6 +303,54 @@ export interface EditBacklinksParams extends EditBacklinksOptions {
198
303
  */
199
304
  readonly pathOrFile: PathOrFile;
200
305
  }
306
+ /**
307
+ * Options for {@link editBacklinksSnapshot}.
308
+ */
309
+ export type EditBacklinksSnapshotOptions = ProcessOptions;
310
+ /**
311
+ * Parameters for {@link editBacklinksSnapshot}.
312
+ *
313
+ * @typeParam TPayload - The payload recorded for each link when the snapshot was built.
314
+ */
315
+ export interface EditBacklinksSnapshotParams<TPayload> extends EditBacklinksSnapshotOptions {
316
+ /**
317
+ * The Obsidian application instance.
318
+ */
319
+ readonly app: App;
320
+ /**
321
+ * The function that converts each link.
322
+ */
323
+ linkConverter(this: void, params: BacklinkConversionParams<TPayload>): Promisable<MaybeReturn<string>>;
324
+ /**
325
+ * Computes the identity key of a link.
326
+ *
327
+ * Must be the same function passed to {@link buildBacklinksSnapshot}, or no link will ever match.
328
+ *
329
+ * @default `JSON.stringify`
330
+ */
331
+ linkIdentityKeyProvider?(this: void, link: Reference): string;
332
+ /**
333
+ * An optional reporter invoked once per backlink file after its links are updated, with the running
334
+ * count of processed files and the total. When omitted, no progress is reported.
335
+ */
336
+ readonly linkUpdateProgressReporter?: LinkUpdateProgressReporter;
337
+ /**
338
+ * Whether the converter is also shown links that are **not** in the snapshot, with an `undefined`
339
+ * {@link BacklinkConversionParams.payload}.
340
+ *
341
+ * The default filters them out, which is what a plain rename wants: a link absent from the snapshot was
342
+ * either never the caller's to rewrite, or has already been rewritten by someone else. Set this to `true`
343
+ * only when the caller has its own reason to look at them — a widened match of its own, or logging a skip
344
+ * that would otherwise be silent.
345
+ *
346
+ * @default `false`
347
+ */
348
+ readonly shouldVisitUnmatchedLinks?: boolean;
349
+ /**
350
+ * The captured backlinks to edit.
351
+ */
352
+ readonly snapshot: BacklinksSnapshot<TPayload>;
353
+ }
201
354
  /**
202
355
  * Parameters for {@link editLinksInContent}.
203
356
  */
@@ -537,6 +690,12 @@ export interface GenerateRawMarkdownLinkParams {
537
690
  */
538
691
  readonly url: string;
539
692
  }
693
+ /**
694
+ * A {@link BacklinksSnapshot} while it is still being accumulated by {@link buildBacklinksSnapshot}.
695
+ *
696
+ * @typeParam TPayload - The payload recorded for each link.
697
+ */
698
+ export type MutableBacklinksSnapshot<TPayload> = Map<string, Map<string, TPayload>>;
540
699
  /**
541
700
  * Params for {@link shouldResetAlias}.
542
701
  */
@@ -958,6 +1117,17 @@ interface UpdateLinksInContentParams {
958
1117
  */
959
1118
  readonly shouldUseLeadingSlashForAbsolutePaths?: boolean;
960
1119
  }
1120
+ /**
1121
+ * Records a set of backlinks into a snapshot that {@link editBacklinksSnapshot} can rewrite later.
1122
+ *
1123
+ * Call it once per target and pass {@link BuildBacklinksSnapshotParams.target} to accumulate several targets
1124
+ * into one snapshot, so that a note linking to several of them is still rewritten exactly once.
1125
+ *
1126
+ * @typeParam TPayload - The payload recorded for each link.
1127
+ * @param params - The parameters for building the snapshot.
1128
+ * @returns The snapshot — {@link BuildBacklinksSnapshotParams.target} itself when one was passed.
1129
+ */
1130
+ export declare function buildBacklinksSnapshot<TPayload>(params: BuildBacklinksSnapshotParams<TPayload>): MutableBacklinksSnapshot<TPayload>;
961
1131
  /**
962
1132
  * Converts a link to a new path.
963
1133
  *
@@ -972,6 +1142,18 @@ export declare function convertLink(params: ConvertLinkParams): string;
972
1142
  * @returns A {@link Promise} that resolves when the backlinks have been edited.
973
1143
  */
974
1144
  export declare function editBacklinks(params: EditBacklinksParams): Promise<void>;
1145
+ /**
1146
+ * Edits a captured snapshot of backlinks, rewriting each backlink-holding note exactly once.
1147
+ *
1148
+ * The counterpart of {@link editBacklinks} for callers that cannot fetch the backlinks at rewrite time —
1149
+ * because the rename that invalidated them has already happened — or that rewrite links to several targets
1150
+ * at once. See {@link BacklinksSnapshot} for both cases.
1151
+ *
1152
+ * @typeParam TPayload - The payload recorded for each link when the snapshot was built.
1153
+ * @param params - The parameters for editing the backlinks.
1154
+ * @returns A {@link Promise} that resolves when the backlinks have been edited.
1155
+ */
1156
+ export declare function editBacklinksSnapshot<TPayload>(params: EditBacklinksSnapshotParams<TPayload>): Promise<void>;
975
1157
  /**
976
1158
  * Edits the links for a file or path.
977
1159
  *