@lapis-notes/api 0.1.4 → 0.2.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.
Files changed (188) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/README.md +19 -0
  3. package/dist/__tests__/fixtures/indexed-mutations.json +6862 -0
  4. package/dist/__tests__/fixtures/memory-storage.json +309 -0
  5. package/dist/__tests__/fixtures/native-facade-contract.json +3224 -0
  6. package/dist/__tests__/fixtures/projection-query.json +195 -0
  7. package/dist/__tests__/fixtures/projection-values.json +60 -0
  8. package/dist/__tests__/fixtures/search-preparation.json +1513 -0
  9. package/dist/__tests__/fixtures/search-retrieval.json +15409 -0
  10. package/dist/__tests__/fixtures/search-semantic-model.json +3691 -0
  11. package/dist/__tests__/fixtures/search-semantic-retrieval.json +6603 -0
  12. package/dist/__tests__/fixtures/search-storage.json +409 -0
  13. package/dist/__tests__/fixtures/task-projection.json +428 -0
  14. package/dist/__tests__/indexed-mutation-support.js +262 -0
  15. package/dist/__tests__/projection-query-support.js +40 -0
  16. package/dist/__tests__/search-retrieval-support.js +47 -0
  17. package/dist/app-database-host.d.ts +1 -0
  18. package/dist/app-shell-plugin-persistence.d.ts +3 -2
  19. package/dist/app-shell-plugin-persistence.js +37 -3
  20. package/dist/cache.svelte.d.ts +8 -1
  21. package/dist/cache.svelte.js +103 -5
  22. package/dist/command.svelte.js +29 -2
  23. package/dist/components/editor/editor.css +4 -0
  24. package/dist/components/editor/editor.svelte +21 -9
  25. package/dist/components/editor/embedded-editor-surface.js +3 -1
  26. package/dist/components/editor/inline-title-alignment.d.ts +3 -0
  27. package/dist/components/editor/inline-title-alignment.js +57 -0
  28. package/dist/configuration.svelte.d.ts +270 -206
  29. package/dist/configuration.svelte.js +161 -86
  30. package/dist/context.svelte.d.ts +21 -3
  31. package/dist/context.svelte.js +63 -20
  32. package/dist/diagnostics.d.ts +8 -0
  33. package/dist/diagnostics.js +6 -0
  34. package/dist/editor-save-context.d.ts +12 -1
  35. package/dist/editor-save-context.js +32 -1
  36. package/dist/editor-view-registry.d.ts +10 -0
  37. package/dist/editor-view-registry.js +44 -4
  38. package/dist/editor.svelte.js +128 -37
  39. package/dist/embed-registry.d.ts +10 -0
  40. package/dist/embed-registry.js +15 -0
  41. package/dist/file-editing-failures.d.ts +2 -0
  42. package/dist/file-editing-failures.js +29 -0
  43. package/dist/file-editing-native-issues.d.ts +19 -0
  44. package/dist/file-editing-native-issues.js +65 -0
  45. package/dist/file-editing-sessions.d.ts +56 -8
  46. package/dist/file-editing-sessions.js +185 -15
  47. package/dist/file-manager.d.ts +8 -1
  48. package/dist/file-manager.js +37 -3
  49. package/dist/file-state-store.d.ts +5 -0
  50. package/dist/file-state-store.js +34 -0
  51. package/dist/file-text-conflicts.d.ts +25 -0
  52. package/dist/file-text-conflicts.js +35 -0
  53. package/dist/file-text-mutation.d.ts +13 -0
  54. package/dist/file-text-mutation.js +100 -0
  55. package/dist/file-text-persistence.d.ts +36 -0
  56. package/dist/file-text-persistence.js +234 -0
  57. package/dist/file-text-state-writer.d.ts +34 -0
  58. package/dist/file-text-state-writer.js +183 -0
  59. package/dist/files-configuration.d.ts +20 -0
  60. package/dist/files-configuration.js +47 -0
  61. package/dist/generated/plugin-host-modules.schema.generated.d.ts +87 -37
  62. package/dist/generated/plugin-host-modules.schema.generated.js +102 -37
  63. package/dist/glob.d.ts +3 -0
  64. package/dist/glob.js +2 -1
  65. package/dist/icons/changes.d.ts +3 -0
  66. package/dist/icons/changes.js +16 -0
  67. package/dist/icons/index.d.ts +5 -1
  68. package/dist/icons/index.js +44 -3
  69. package/dist/icons/registry.d.ts +35 -0
  70. package/dist/icons/registry.js +154 -0
  71. package/dist/icons/safe-svg.d.ts +2 -0
  72. package/dist/icons/safe-svg.js +44 -0
  73. package/dist/index.d.ts +5 -1
  74. package/dist/index.js +3 -1
  75. package/dist/lapis-extension.d.ts +6 -2
  76. package/dist/lapis-extension.js +2 -0
  77. package/dist/metadata.svelte.js +45 -2
  78. package/dist/native-background-indexing.d.ts +48 -0
  79. package/dist/native-background-indexing.js +208 -0
  80. package/dist/native-database-protocol.d.ts +29 -0
  81. package/dist/native-database-protocol.js +1 -0
  82. package/dist/native-editing-intent-lease.d.ts +17 -0
  83. package/dist/native-editing-intent-lease.js +188 -0
  84. package/dist/native-editing-intents-protocol.d.ts +70 -0
  85. package/dist/native-editing-intents-protocol.js +1 -0
  86. package/dist/native-editing-intents.d.ts +8 -0
  87. package/dist/native-editing-intents.js +1 -0
  88. package/dist/native-editing-problems.d.ts +3 -0
  89. package/dist/native-editing-problems.js +180 -0
  90. package/dist/native-editing-recovery.d.ts +24 -0
  91. package/dist/native-editing-recovery.js +198 -0
  92. package/dist/native-editing-session.d.ts +51 -0
  93. package/dist/native-editing-session.js +251 -0
  94. package/dist/native-history-index-protocol.d.ts +80 -0
  95. package/dist/native-history-index-protocol.js +1 -0
  96. package/dist/native-history-index.d.ts +6 -0
  97. package/dist/native-history-index.js +1 -0
  98. package/dist/native-indexing-protocol.d.ts +63 -0
  99. package/dist/native-indexing-protocol.js +1 -0
  100. package/dist/native-participant-protocol.d.ts +67 -0
  101. package/dist/native-participant-protocol.js +3 -0
  102. package/dist/native-queue-protocol.d.ts +73 -0
  103. package/dist/native-queue-protocol.js +3 -0
  104. package/dist/native-tasks-protocol.d.ts +264 -0
  105. package/dist/native-tasks-protocol.js +1 -0
  106. package/dist/native-tasks.d.ts +35 -0
  107. package/dist/native-tasks.js +79 -0
  108. package/dist/native-turn-protocol.d.ts +81 -0
  109. package/dist/native-turn-protocol.js +1 -0
  110. package/dist/native-turns.d.ts +29 -0
  111. package/dist/native-turns.js +2 -0
  112. package/dist/plugin-asset-server.js +3 -2
  113. package/dist/plugin-dependency-resolver.d.ts +1 -1
  114. package/dist/plugin-distribution/compatibility.d.ts +1 -1
  115. package/dist/plugin-distribution/compatibility.js +10 -5
  116. package/dist/plugin-distribution/installed-plugin-state.js +2 -1
  117. package/dist/plugin-distribution/installer.d.ts +6 -0
  118. package/dist/plugin-distribution/installer.js +90 -37
  119. package/dist/plugin-distribution/manager.d.ts +4 -1
  120. package/dist/plugin-distribution/manager.js +12 -5
  121. package/dist/plugin-distribution/registry-cache.js +2 -1
  122. package/dist/plugin-distribution/registry-source-state.js +2 -1
  123. package/dist/plugin-distribution/schemas.d.ts +26 -8
  124. package/dist/plugin-distribution/schemas.js +2 -1
  125. package/dist/plugin-distribution/types.d.ts +4 -0
  126. package/dist/plugin-manager.d.ts +20 -4
  127. package/dist/plugin-manager.js +228 -64
  128. package/dist/plugin-runtime-entry.d.ts +1 -1
  129. package/dist/plugin-runtime-entry.js +16 -0
  130. package/dist/plugin.d.ts +18 -2
  131. package/dist/plugin.js +93 -39
  132. package/dist/registry-schema/catalog-v1.d.ts +60 -9
  133. package/dist/registry-schema/catalog-v1.js +2 -1
  134. package/dist/registry-schema/catalog-v2.d.ts +60 -9
  135. package/dist/registry-schema/catalog-v2.js +1 -1
  136. package/dist/search-result-provider.d.ts +95 -0
  137. package/dist/search-result-provider.js +42 -0
  138. package/dist/status-bar.svelte.d.ts +26 -20
  139. package/dist/status-bar.svelte.js +1 -0
  140. package/dist/storage/app-database.d.ts +6 -2
  141. package/dist/storage/app-database.js +41 -34
  142. package/dist/storage/desktop-native.d.ts +5 -3
  143. package/dist/storage/desktop-native.js +59 -6
  144. package/dist/storage/directory-watcher.d.ts +27 -0
  145. package/dist/storage/directory-watcher.js +201 -0
  146. package/dist/storage/fs.d.ts +14 -27
  147. package/dist/storage/fs.js +2 -168
  148. package/dist/storage/index-projection.js +33 -15
  149. package/dist/storage/memory-vault-adapter.d.ts +2 -0
  150. package/dist/storage/memory-vault-adapter.js +14 -1
  151. package/dist/storage/path.d.ts +6 -2
  152. package/dist/storage/path.js +8 -2
  153. package/dist/storage/projection-query-candidates.d.ts +3 -0
  154. package/dist/storage/projection-query-candidates.js +69 -0
  155. package/dist/storage/remote-app-database.d.ts +2 -2
  156. package/dist/storage/remote-app-database.js +1 -1
  157. package/dist/storage/runtime.d.ts +3 -0
  158. package/dist/storage/runtime.js +3 -0
  159. package/dist/storage/search-embedding-record.d.ts +3 -0
  160. package/dist/storage/search-embedding-record.js +18 -0
  161. package/dist/storage/turso-app-database.d.ts +2 -0
  162. package/dist/storage/turso-app-database.js +67 -30
  163. package/dist/storage/vault-listing.d.ts +3 -0
  164. package/dist/storage/vault-listing.js +36 -0
  165. package/dist/storage/vault-reconciliation.d.ts +19 -0
  166. package/dist/storage/vault-reconciliation.js +137 -0
  167. package/dist/storage/vault-session.d.ts +8 -0
  168. package/dist/storage/vault-session.js +10 -2
  169. package/dist/storage/vault.svelte.d.ts +53 -4
  170. package/dist/storage/vault.svelte.js +223 -87
  171. package/dist/sync-host.d.ts +12 -3
  172. package/dist/sync-host.js +5 -1
  173. package/dist/vault-change-views.d.ts +4 -0
  174. package/dist/vault-change-views.js +43 -0
  175. package/dist/vault-changes.d.ts +37 -0
  176. package/dist/vault-changes.js +228 -0
  177. package/dist/view.svelte.d.ts +182 -149
  178. package/dist/view.svelte.js +11 -2
  179. package/dist/workspace-close-guard.d.ts +3 -0
  180. package/dist/workspace-close-guard.js +35 -0
  181. package/dist/workspace-host-internal.js +10 -2
  182. package/dist/workspace-layout-normalizer.d.ts +4 -2
  183. package/dist/workspace-layout-normalizer.js +5 -5
  184. package/dist/workspace-view-document.d.ts +3 -0
  185. package/dist/workspace-view-document.js +12 -0
  186. package/dist/workspace.svelte.d.ts +13 -2
  187. package/dist/workspace.svelte.js +371 -82
  188. package/package.json +45 -8
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import type { IconLoader } from "./icons";
2
+ import type { ExtensionRegistrationOptions } from "./editor-view-registry";
3
+ import type { SearchResultProvider, SearchResultProviderRegistration } from "./search-result-provider";
1
4
  import type { MetadataProcessor } from "./cache.svelte";
2
5
  import type { IndexProjectionRegistration, RegisteredIndexProjectionHandle } from "./storage/index-projection";
3
6
  import type { SearchDocumentProvider, SearchDocumentProviderRegistration } from "./search-document-provider";
@@ -5,6 +8,7 @@ import type { Command, KeymapEventHandler } from "./command.svelte";
5
8
  import type { ContextKeyValue, ScopedContextKey } from "./context-keys.svelte";
6
9
  import type { App, ExtType } from "./context.svelte";
7
10
  import type { LapisExtensionContributions, LapisExtensionKind, LapisExtensionManifest, LapisExtensionPermission, LapisExtensionRuntimeHost, LapisPluginClassification, LapisServiceProviderRegistration, LapisSystemExtensionRegistration } from "./lapis-extension";
11
+ import type { MarkdownEmbedder } from "./embed-registry";
8
12
  import type { EditorViewContribution } from "./editor-view-registry";
9
13
  import type { ConfigurationOptionSourceProvider, ConfigurationOptionSourceRegistration } from "./configuration-option-source-registry";
10
14
  import type { HostedPluginCapability } from "./plugin-capability-facade";
@@ -125,6 +129,8 @@ export interface PluginManifest {
125
129
  * @public
126
130
  */
127
131
  requiredCapabilities?: HostedPluginCapability[];
132
+ /** Native host services that must be available before module evaluation. */
133
+ requiredNativeServices?: string[];
128
134
  /**
129
135
  * Optional host-specific execution hints for future sidecar scheduling.
130
136
  *
@@ -150,7 +156,7 @@ export type PluginSource = "core" | "community" | "official" | "system";
150
156
  * Resolve the compatibility data path used by `loadData()` and `saveData()`.
151
157
  *
152
158
  * Community plugins store data beside their manifest folder, while bundled and
153
- * system plugins use the shared `/.obsidian/<id>.json` location.
159
+ * system plugins use the shared `/.lapis/<id>.json` location.
154
160
  *
155
161
  * @public
156
162
  */
@@ -247,6 +253,8 @@ export declare abstract class Plugin extends Component {
247
253
  * @see {@link https://docs.obsidian.md/Plugins/User+interface/Settings}
248
254
  */
249
255
  loadData(): Promise<any>;
256
+ private runDataOperation;
257
+ private loadDataNow;
250
258
  /**
251
259
  * Write settings data to disk. Data is stored in `data.json` in the plugin
252
260
  * folder.
@@ -255,6 +263,7 @@ export declare abstract class Plugin extends Component {
255
263
  * @see {@link https://docs.obsidian.md/Plugins/User+interface/Settings}
256
264
  */
257
265
  saveData(data: any): Promise<void>;
266
+ private saveDataNow;
258
267
  loadGeneratedState<T>(key: string): Promise<T | null>;
259
268
  saveGeneratedState(key: string, value: unknown): Promise<void>;
260
269
  deleteGeneratedState(key: string): Promise<void>;
@@ -280,6 +289,10 @@ export declare abstract class Plugin extends Component {
280
289
  icon?: string;
281
290
  hidden?: boolean;
282
291
  }, access?: ViewAccess): void;
292
+ /** Register an App-owned SVG and dispose it automatically on plugin unload. */
293
+ registerIcon(localId: string, svg: string): string;
294
+ /** Register an owned icon pack; use the returned prefix in `prefix:icon` IDs. */
295
+ registerIconPack(input: IconLoader): string;
283
296
  registerEditorView(contribution: EditorViewContribution): void;
284
297
  registerConfigurationOptionSource(id: string, provider: Omit<ConfigurationOptionSourceProvider, "pluginId">): ConfigurationOptionSourceRegistration;
285
298
  registerHoverLinkSource(id: string, info: any): void;
@@ -291,7 +304,7 @@ export declare abstract class Plugin extends Component {
291
304
  createDiagnosticCollection(id: string, options?: DiagnosticCollectionOptions): DiagnosticCollection;
292
305
  onUserEnable(): Promise<void> | void;
293
306
  onExternalSettingsChange(): Promise<void> | void;
294
- registerExtensions(extensions: string[], viewType?: string): void;
307
+ registerExtensions(extensions: string[], viewType?: string, options?: ExtensionRegistrationOptions): void;
295
308
  registerTypeWidget(widget: TypeWidget): void;
296
309
  /**
297
310
  * Register an EditorSuggest which can provide live suggestions while the user
@@ -326,6 +339,7 @@ export declare abstract class Plugin extends Component {
326
339
  registerMarkdownCodeBlockProcessor(language: string, handler: (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => Promise<any> | void, sortOrder?: number): MarkdownPostProcessor;
327
340
  registerMarkdownDirectiveRenderer(directive: string, renderer: MarkdownDirectiveRenderer): void;
328
341
  registerMarkdownViewMenuItem(provider: MarkdownViewMenuItemProvider): void;
342
+ registerMarkdownEmbedder(embedder: MarkdownEmbedder): void;
329
343
  registerMetadataProcessor(processor: MetadataProcessor, ext?: string): void;
330
344
  registerIndexProjection<T = Record<string, unknown>>(registration: IndexProjectionRegistration): RegisteredIndexProjectionHandle<T>;
331
345
  private backfillIndexProjection;
@@ -334,6 +348,8 @@ export declare abstract class Plugin extends Component {
334
348
  * The local id is namespaced by this plugin's runtime id.
335
349
  */
336
350
  registerSearchDocumentProvider(localId: string, provider: Omit<SearchDocumentProvider, "id">): SearchDocumentProviderRegistration;
351
+ /** Contribute query results whose navigation remains provider-owned. */
352
+ registerSearchResultProvider(localId: string, provider: Omit<SearchResultProvider, "id">): SearchResultProviderRegistration;
337
353
  /** Register an application tool under this plugin's lifecycle and identity. */
338
354
  registerAgentTool<TInput>(tool: AppTool<TInput>): AppToolRegistration;
339
355
  /** Register a directory that contains one skill. */
package/dist/plugin.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { saveFileState } from "./file-state-store";
2
+ import { appStatePath } from "./storage/path";
1
3
  import { matchesProjectionSource } from "./storage/index-projection";
2
4
  import { resolveWorkspaceHostBinding } from "./workspace-host-internal";
3
5
  import { dirname, joinPath } from "./storage";
@@ -9,13 +11,13 @@ function isPromiseLike(value) {
9
11
  * Resolve the compatibility data path used by `loadData()` and `saveData()`.
10
12
  *
11
13
  * Community plugins store data beside their manifest folder, while bundled and
12
- * system plugins use the shared `/.obsidian/<id>.json` location.
14
+ * system plugins use the shared `/.lapis/<id>.json` location.
13
15
  *
14
16
  * @public
15
17
  */
16
18
  export function resolvePluginDataPath(pluginId, source, basePath) {
17
19
  if (source === "core" || source === "system") {
18
- return joinPath("/.obsidian", `${pluginId}.json`);
20
+ return joinPath("/", appStatePath(`${pluginId}.json`));
19
21
  }
20
22
  if (!basePath) {
21
23
  return null;
@@ -122,10 +124,19 @@ export class Plugin extends Component {
122
124
  this.register(() => lease.release());
123
125
  }
124
126
  await this.loadAsync();
127
+ await this.app.metadataCache?.finishNativeContributions?.(this.id);
125
128
  this.#runtimeState = "enabled";
126
129
  this.emit("enable");
127
130
  }
128
131
  catch (error) {
132
+ if (this.app.session?.backgroundIndexing && this.loaded) {
133
+ try {
134
+ await this.unloadAsync();
135
+ }
136
+ catch (cleanupError) {
137
+ console.error("Failed to rollback native plugin activation", cleanupError);
138
+ }
139
+ }
129
140
  this.#runtimeState = "failed";
130
141
  this.#failureMessage = formatPluginError(error);
131
142
  this.#lastFailureMessage = this.#failureMessage;
@@ -200,6 +211,10 @@ export class Plugin extends Component {
200
211
  return;
201
212
  }
202
213
  const payload = JSON.stringify(data, null, 2);
214
+ if (this.app.vault.supportsConditionalTextWrites) {
215
+ await saveFileState(this.app, path, payload);
216
+ return;
217
+ }
203
218
  const file = this.app.vault.getFileByPath(path);
204
219
  if (file) {
205
220
  await this.app.vault.modify(file, payload);
@@ -237,6 +252,7 @@ export class Plugin extends Component {
237
252
  async disable() {
238
253
  if (!this.loaded) {
239
254
  try {
255
+ await this.app.metadataCache?.disableNativeContributions?.(this.id);
240
256
  await this.#revokeSyncHostCapabilities?.();
241
257
  }
242
258
  finally {
@@ -248,6 +264,7 @@ export class Plugin extends Component {
248
264
  }
249
265
  this.#runtimeState = "disabling";
250
266
  try {
267
+ await this.app.metadataCache?.disableNativeContributions?.(this.id);
251
268
  try {
252
269
  await this.unloadAsync();
253
270
  }
@@ -272,27 +289,17 @@ export class Plugin extends Component {
272
289
  }
273
290
  }
274
291
  addStatusBarItem() {
275
- let parent = this.app.workspace.statusCompatEl ??
276
- document.querySelector("#status-bar");
277
- if (!parent) {
278
- parent = document.querySelector("#lapis-status-bar-compat-fallback");
279
- }
280
- if (!parent) {
281
- parent = document.body.createDiv({
282
- attr: {
283
- id: "lapis-status-bar-compat-fallback",
284
- hidden: "true",
285
- "aria-hidden": "true",
286
- },
287
- });
288
- }
289
- this.app.workspace.statusCompatEl = parent;
290
- const statusEl = parent.createDiv({
291
- cls: "status-bar-item plugin-" + this.manifest.id,
292
- });
293
- this.register(() => {
294
- statusEl.detach();
292
+ const statusEl = document.createElement("div");
293
+ statusEl.className = "status-bar-item plugin-" + this.manifest.id;
294
+ const dispose = this.app.statusBar.registerItem({
295
+ id: `${this.manifest.id}:compat-status:${crypto.randomUUID()}`,
296
+ sourcePlugin: this.manifest.id,
297
+ mount: (host) => {
298
+ host.append(statusEl);
299
+ return () => statusEl.remove();
300
+ },
295
301
  });
302
+ this.register(dispose);
296
303
  return statusEl;
297
304
  }
298
305
  /**
@@ -303,6 +310,14 @@ export class Plugin extends Component {
303
310
  * @see {@link https://docs.obsidian.md/Plugins/User+interface/Settings}
304
311
  */
305
312
  loadData() {
313
+ return this.runDataOperation(() => this.loadDataNow());
314
+ }
315
+ runDataOperation(run) {
316
+ return this.app.vault.supportsConditionalTextWrites
317
+ ? this.app.fileEditingSessions.track(run)
318
+ : run();
319
+ }
320
+ loadDataNow() {
306
321
  return this.measureTelemetryAsync("plugin.load_data", async () => {
307
322
  if (this.app.configuration.hasPluginData(this.id)) {
308
323
  const data = this.app.configuration.getPluginData(this.id);
@@ -324,6 +339,9 @@ export class Plugin extends Component {
324
339
  * @see {@link https://docs.obsidian.md/Plugins/User+interface/Settings}
325
340
  */
326
341
  saveData(data) {
342
+ return this.runDataOperation(() => this.saveDataNow(data));
343
+ }
344
+ saveDataNow(data) {
327
345
  return this.measureTelemetryAsync("plugin.save_data", async () => {
328
346
  await this.app.configuration.updatePluginData(this.id, data, {
329
347
  origin: "plugin-save",
@@ -449,6 +467,18 @@ export class Plugin extends Component {
449
467
  this.app.workspace.unregisterSidebarView(type);
450
468
  });
451
469
  }
470
+ /** Register an App-owned SVG and dispose it automatically on plugin unload. */
471
+ registerIcon(localId, svg) {
472
+ const registration = this.app.icons.registerIcon(this.manifest.id, localId, svg);
473
+ this.register(registration.dispose);
474
+ return registration.id;
475
+ }
476
+ /** Register an owned icon pack; use the returned prefix in `prefix:icon` IDs. */
477
+ registerIconPack(input) {
478
+ const registration = this.app.icons.registerIconPack(this.manifest.id, input);
479
+ this.register(registration.dispose);
480
+ return registration.prefix;
481
+ }
452
482
  registerEditorView(contribution) {
453
483
  const dispose = this.app.workspace.registerEditorView({
454
484
  ...contribution,
@@ -503,7 +533,11 @@ export class Plugin extends Component {
503
533
  }
504
534
  onUserEnable() { }
505
535
  onExternalSettingsChange() { }
506
- registerExtensions(extensions, viewType = "markdown") {
536
+ registerExtensions(extensions, viewType = "markdown", options) {
537
+ if (options) {
538
+ this.register(this.app.workspace.registerExtensions(extensions, viewType, options));
539
+ return;
540
+ }
507
541
  this.app.workspace.registerExtensions(extensions, viewType);
508
542
  this.register(() => {
509
543
  this.app.workspace.unregisterExtensions(extensions, viewType);
@@ -619,29 +653,38 @@ export class Plugin extends Component {
619
653
  this.app.unregisterMarkdownViewMenuItem(provider);
620
654
  });
621
655
  }
656
+ registerMarkdownEmbedder(embedder) {
657
+ this.register(this.app.embedRegistry.registerMarkdownEmbedder(embedder));
658
+ }
622
659
  registerMetadataProcessor(processor, ext = "md") {
623
- this.app.metadataCache.addProcessor(ext, processor);
660
+ this.app.metadataCache.addProcessor(ext, processor, this.id);
624
661
  this.register(() => {
625
662
  this.app.metadataCache.removeProcessor(ext, processor);
626
663
  });
627
664
  }
628
665
  registerIndexProjection(registration) {
629
666
  const recorded = this.app.indexProjections.register(this.id, registration);
630
- void this.app.appDatabase.registerProjectionDefinition({
631
- projectionId: recorded.projectionId,
632
- ownerPluginId: this.id,
633
- schemaVersion: registration.version,
634
- configHash: registration.configurationHash ?? "",
635
- visibility: registration.visibility ?? "public",
636
- fields: registration.fields,
637
- active: true,
638
- updatedAt: Date.now(),
639
- });
640
- this.register(() => {
641
- this.app.indexProjections.unregister(recorded.projectionId);
642
- void this.app.appDatabase.unregisterProjectionDefinition(recorded.projectionId);
643
- });
644
- void this.backfillIndexProjection(recorded.projectionId);
667
+ if (this.app.session?.backgroundIndexing) {
668
+ this.app.metadataCache.registerNativeProjection(this.id, recorded.projectionId, registration);
669
+ this.register(() => this.app.indexProjections.unregister(recorded.projectionId));
670
+ }
671
+ else {
672
+ void this.app.appDatabase.registerProjectionDefinition({
673
+ projectionId: recorded.projectionId,
674
+ ownerPluginId: this.id,
675
+ schemaVersion: registration.version,
676
+ configHash: registration.configurationHash ?? "",
677
+ visibility: registration.visibility ?? "public",
678
+ fields: registration.fields,
679
+ active: true,
680
+ updatedAt: Date.now(),
681
+ });
682
+ this.register(() => {
683
+ this.app.indexProjections.unregister(recorded.projectionId);
684
+ void this.app.appDatabase.unregisterProjectionDefinition(recorded.projectionId);
685
+ });
686
+ void this.backfillIndexProjection(recorded.projectionId);
687
+ }
645
688
  return {
646
689
  id: recorded.projectionId,
647
690
  query: (query) => this.app.appDatabase.queryProjection(recorded.projectionId, query, this.id),
@@ -710,6 +753,17 @@ export class Plugin extends Component {
710
753
  this.register(() => registration.dispose());
711
754
  return registration;
712
755
  }
756
+ /** Contribute query results whose navigation remains provider-owned. */
757
+ registerSearchResultProvider(localId, provider) {
758
+ if (!localId.trim())
759
+ throw new Error("Search result provider local id must not be empty.");
760
+ const registration = this.app.searchResultProviders.register({
761
+ ...provider,
762
+ id: `${this.id}:${localId.trim()}`,
763
+ });
764
+ this.register(() => registration.dispose());
765
+ return registration;
766
+ }
713
767
  /** Register an application tool under this plugin's lifecycle and identity. */
714
768
  registerAgentTool(tool) {
715
769
  const registration = this.app.agentTools.register({