@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
@@ -0,0 +1,37 @@
1
+ import type { App } from "./context.svelte";
2
+ /** One App owns watching, reconciliation and retirement for its live Vault. */
3
+ export declare class VaultChangeService {
4
+ private readonly app;
5
+ private watcher;
6
+ private starting;
7
+ private stopping;
8
+ private processing;
9
+ private timer;
10
+ private generation;
11
+ private active;
12
+ private registered;
13
+ private dirty;
14
+ private uncertain;
15
+ private failures;
16
+ private readonly hints;
17
+ private stopProjection;
18
+ private readonly projections;
19
+ constructor(app: App);
20
+ start(): Promise<void>;
21
+ /**
22
+ * Retire callbacks synchronously, then drain registration, native IO and
23
+ * scans.
24
+ */
25
+ stop(): Promise<void>;
26
+ /**
27
+ * Flush pending hints now; explicit calls also retry a previously failed
28
+ * scan.
29
+ */
30
+ settle(): Promise<void>;
31
+ private live;
32
+ private clearTimer;
33
+ private report;
34
+ private schedule;
35
+ private changed;
36
+ private drain;
37
+ }
@@ -0,0 +1,228 @@
1
+ import { DirectoryWatcher, TFile, } from "./storage/fs";
2
+ import { projectVaultChange } from "./vault-change-views";
3
+ /** One App owns watching, reconciliation and retirement for its live Vault. */
4
+ export class VaultChangeService {
5
+ app;
6
+ watcher;
7
+ starting;
8
+ stopping;
9
+ processing;
10
+ timer;
11
+ generation = 0;
12
+ active = false;
13
+ registered = false;
14
+ dirty = false;
15
+ uncertain = false;
16
+ failures = 0;
17
+ hints = new Map();
18
+ stopProjection;
19
+ projections = new Set();
20
+ constructor(app) {
21
+ this.app = app;
22
+ }
23
+ start() {
24
+ if (this.starting)
25
+ return this.starting;
26
+ if (this.active)
27
+ return this.settle();
28
+ const run = async () => {
29
+ const retiring = this.stop();
30
+ const requested = this.generation;
31
+ await retiring;
32
+ if (this.generation !== requested)
33
+ return;
34
+ const generation = ++this.generation;
35
+ this.active = true;
36
+ this.dirty = true;
37
+ const watcher = new DirectoryWatcher(this.app.vault.adapter);
38
+ this.watcher = watcher;
39
+ const projection = this.app.vault.on("all", (event, file, context) => {
40
+ if (!this.live(generation) || !(file instanceof TFile))
41
+ return;
42
+ const snapshot = file.copy(), details = { ...context };
43
+ const pending = this.app.fileEditingSessions.track(() => this.app.fileEditingSessions.afterMutations(() => projectVaultChange(this.app, event, snapshot, details, () => this.live(generation))));
44
+ this.projections.add(pending);
45
+ void pending
46
+ .catch((error) => this.report(error))
47
+ .finally(() => this.projections.delete(pending));
48
+ });
49
+ this.stopProjection = () => this.app.vault.offref(projection);
50
+ watcher.on("all", (event) => {
51
+ if (this.live(generation))
52
+ this.changed(event, generation);
53
+ });
54
+ const subscription = watcher.watch("/", { recursive: true });
55
+ await subscription.ready;
56
+ if (!this.live(generation))
57
+ return;
58
+ this.registered = true;
59
+ await this.drain(generation);
60
+ };
61
+ const pending = run()
62
+ .catch(async (error) => {
63
+ this.active = false;
64
+ this.registered = false;
65
+ ++this.generation;
66
+ this.clearTimer();
67
+ this.stopProjection?.();
68
+ this.stopProjection = undefined;
69
+ try {
70
+ await this.watcher?.close();
71
+ }
72
+ catch (cleanup) {
73
+ throw new AggregateError([error, cleanup], "Vault watch startup and cleanup failed");
74
+ }
75
+ this.watcher = undefined;
76
+ throw error;
77
+ })
78
+ .finally(() => {
79
+ if (this.starting === pending)
80
+ this.starting = undefined;
81
+ });
82
+ this.starting = pending;
83
+ return pending;
84
+ }
85
+ /**
86
+ * Retire callbacks synchronously, then drain registration, native IO and
87
+ * scans.
88
+ */
89
+ stop() {
90
+ this.active = false;
91
+ this.registered = false;
92
+ ++this.generation;
93
+ this.clearTimer();
94
+ this.stopProjection?.();
95
+ this.stopProjection = undefined;
96
+ this.hints.clear();
97
+ this.dirty = false;
98
+ this.uncertain = false;
99
+ if (this.stopping)
100
+ return this.stopping;
101
+ const watcher = this.watcher;
102
+ const pending = Promise.allSettled([
103
+ watcher?.close(),
104
+ this.processing,
105
+ this.starting,
106
+ ...this.projections,
107
+ ])
108
+ .then((results) => {
109
+ const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
110
+ if (errors.length)
111
+ throw new AggregateError(errors, "Vault watch cleanup failed");
112
+ if (this.watcher === watcher)
113
+ this.watcher = undefined;
114
+ })
115
+ .finally(() => {
116
+ if (this.stopping === pending)
117
+ this.stopping = undefined;
118
+ });
119
+ this.stopping = pending;
120
+ return pending;
121
+ }
122
+ /**
123
+ * Flush pending hints now; explicit calls also retry a previously failed
124
+ * scan.
125
+ */
126
+ async settle() {
127
+ await this.starting;
128
+ this.clearTimer();
129
+ if (this.active && this.registered) {
130
+ await this.drain(this.generation);
131
+ while (this.projections.size)
132
+ await Promise.all([...this.projections]);
133
+ }
134
+ }
135
+ live(generation) {
136
+ return this.active && this.generation === generation;
137
+ }
138
+ clearTimer() {
139
+ if (this.timer)
140
+ clearTimeout(this.timer);
141
+ this.timer = undefined;
142
+ }
143
+ report(error) {
144
+ this.app.notifications.notify({
145
+ id: "vault-watch-reconciliation",
146
+ title: "File changes need attention",
147
+ message: error instanceof Error ? error.message : String(error),
148
+ severity: "error",
149
+ source: "vault",
150
+ });
151
+ }
152
+ schedule(generation, delay = 40) {
153
+ if (!this.registered || this.timer || !this.live(generation))
154
+ return;
155
+ this.timer = setTimeout(() => {
156
+ this.timer = undefined;
157
+ void this.drain(generation).catch(() => { });
158
+ }, delay);
159
+ }
160
+ changed(event, generation) {
161
+ this.dirty = true;
162
+ if (event.type === "error") {
163
+ this.uncertain = true;
164
+ this.hints.clear();
165
+ this.report(event.error);
166
+ }
167
+ else if (!this.uncertain) {
168
+ const previous = event.previousPath
169
+ ? this.hints.get(event.previousPath)
170
+ : this.hints.get(event.path);
171
+ const hint = {
172
+ ...event,
173
+ previousPath: previous?.previousPath ?? event.previousPath,
174
+ };
175
+ if (event.previousPath)
176
+ this.hints.delete(event.previousPath);
177
+ this.hints.set(event.path, hint);
178
+ const bytes = [...this.hints.values()].reduce((sum, value) => sum +
179
+ new TextEncoder().encode(value.path + (value.previousPath ?? ""))
180
+ .byteLength +
181
+ 96, 0);
182
+ if (event.path === "/" ||
183
+ !event.path ||
184
+ this.hints.size > 2048 ||
185
+ bytes > 128 * 1024) {
186
+ this.uncertain = true;
187
+ this.hints.clear();
188
+ }
189
+ }
190
+ this.schedule(generation);
191
+ }
192
+ drain(generation) {
193
+ if (this.processing)
194
+ return this.processing;
195
+ const run = async () => {
196
+ while (this.live(generation) && this.dirty) {
197
+ const hints = this.uncertain ? [] : [...this.hints.values()];
198
+ this.hints.clear();
199
+ this.dirty = false;
200
+ this.uncertain = false;
201
+ try {
202
+ await this.app.vault.reconcile(hints, () => this.live(generation), {
203
+ external: true,
204
+ });
205
+ while (this.projections.size)
206
+ await Promise.all([...this.projections]);
207
+ this.failures = 0;
208
+ }
209
+ catch (error) {
210
+ if (this.live(generation)) {
211
+ this.dirty = true;
212
+ this.uncertain = true;
213
+ this.report(error);
214
+ if (++this.failures <= 4)
215
+ this.schedule(generation, 250 * 2 ** (this.failures - 1));
216
+ }
217
+ throw error;
218
+ }
219
+ }
220
+ };
221
+ const pending = run().finally(() => {
222
+ if (this.processing === pending)
223
+ this.processing = undefined;
224
+ });
225
+ this.processing = pending;
226
+ return pending;
227
+ }
228
+ }
@@ -4,7 +4,12 @@ import type { Menu } from "./menu.svelte";
4
4
  import { Editor } from "./editor.svelte";
5
5
  import type { App } from "./context.svelte";
6
6
  import "./enhance";
7
- import { EventDispatcher, type EventNames, type EventRef, type ValidEventTypes } from "./events";
7
+ import {
8
+ EventDispatcher,
9
+ type EventNames,
10
+ type EventRef,
11
+ type ValidEventTypes,
12
+ } from "./events";
8
13
  import type { Scope } from "./command.svelte";
9
14
  /**
10
15
  * Base lifecycle helper used throughout the public API.
@@ -14,70 +19,89 @@ import type { Scope } from "./command.svelte";
14
19
  *
15
20
  * @public
16
21
  */
17
- export declare abstract class Component<Events extends ValidEventTypes = Record<string, any>> extends EventDispatcher<Events> {
18
- children: Component[];
19
- private unloaders;
20
- loaded: boolean;
21
- protected _containerEl: HTMLElement;
22
- get containerEl(): HTMLElement;
23
- set containerEl(el: HTMLElement);
24
- /**
25
- * Load this component and its children
26
- *
27
- * @public
28
- */
29
- load(): void;
30
- /**
31
- * Override this to load your component
32
- *
33
- * @abstract
34
- * @public
35
- */
36
- onload(): Promise<void> | void;
37
- protected loadAsync(): Promise<void>;
38
- /**
39
- * Unload this component and its children
40
- *
41
- * @public
42
- */
43
- unload(): void;
44
- protected unloadAsync(): Promise<void>;
45
- /**
46
- * Override this to unload your component
47
- *
48
- * @abstract
49
- * @public
50
- */
51
- onunload(): void;
52
- private cleanupAsync;
53
- /**
54
- * Adds a child component, loading it if this component is loaded
55
- *
56
- * @public
57
- */
58
- addChild<T extends Component>(component: T): T;
59
- /**
60
- * Removes a child component, unloading it
61
- *
62
- * @public
63
- */
64
- removeChild<T extends Component>(component: T): T;
65
- /**
66
- * Registers a callback to be called when unloading
67
- *
68
- * @public
69
- */
70
- register(cb: () => any): void;
71
- registerEvent<T extends ValidEventTypes, K extends EventNames<T>>(eventRef: EventRef<T, K, any>): void;
72
- registerInterval(id: ReturnType<typeof setInterval>): void;
73
- /**
74
- * Registers an DOM event to be detached when unloading
75
- *
76
- * @public
77
- */
78
- registerDomEvent<K extends keyof HTMLElementEventMap>(el: HTMLElement, type: K, callback: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
79
- registerDomEvent<K extends keyof DocumentEventMap>(el: Document, type: K, callback: (this: HTMLElement, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
80
- registerDomEvent<K extends keyof WindowEventMap>(el: Window, type: K, callback: (this: HTMLElement, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
22
+ export declare abstract class Component<
23
+ Events extends ValidEventTypes = Record<string, any>,
24
+ > extends EventDispatcher<Events> {
25
+ children: Component[];
26
+ private unloaders;
27
+ loaded: boolean;
28
+ protected _containerEl: HTMLElement;
29
+ get containerEl(): HTMLElement;
30
+ set containerEl(el: HTMLElement);
31
+ /**
32
+ * Load this component and its children
33
+ *
34
+ * @public
35
+ */
36
+ load(): void;
37
+ /**
38
+ * Override this to load your component
39
+ *
40
+ * @abstract
41
+ * @public
42
+ */
43
+ onload(): Promise<void> | void;
44
+ protected loadAsync(): Promise<void>;
45
+ /**
46
+ * Unload this component and its children
47
+ *
48
+ * @public
49
+ */
50
+ unload(): void;
51
+ protected unloadAsync(): Promise<void>;
52
+ /**
53
+ * Override this to unload your component
54
+ *
55
+ * @abstract
56
+ * @public
57
+ */
58
+ onunload(): void;
59
+ private cleanupAsync;
60
+ /**
61
+ * Adds a child component, loading it if this component is loaded
62
+ *
63
+ * @public
64
+ */
65
+ addChild<T extends Component>(component: T): T;
66
+ /**
67
+ * Removes a child component, unloading it
68
+ *
69
+ * @public
70
+ */
71
+ removeChild<T extends Component>(component: T): T;
72
+ /**
73
+ * Registers a callback to be called when unloading
74
+ *
75
+ * @public
76
+ */
77
+ register(cb: () => any): void;
78
+ registerEvent<T extends ValidEventTypes, K extends EventNames<T>>(
79
+ eventRef: EventRef<T, K, any>,
80
+ ): void;
81
+ registerInterval(id: ReturnType<typeof setInterval>): void;
82
+ /**
83
+ * Registers an DOM event to be detached when unloading
84
+ *
85
+ * @public
86
+ */
87
+ registerDomEvent<K extends keyof HTMLElementEventMap>(
88
+ el: HTMLElement,
89
+ type: K,
90
+ callback: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any,
91
+ options?: boolean | AddEventListenerOptions,
92
+ ): void;
93
+ registerDomEvent<K extends keyof DocumentEventMap>(
94
+ el: Document,
95
+ type: K,
96
+ callback: (this: HTMLElement, ev: DocumentEventMap[K]) => any,
97
+ options?: boolean | AddEventListenerOptions,
98
+ ): void;
99
+ registerDomEvent<K extends keyof WindowEventMap>(
100
+ el: Window,
101
+ type: K,
102
+ callback: (this: HTMLElement, ev: WindowEventMap[K]) => any,
103
+ options?: boolean | AddEventListenerOptions,
104
+ ): void;
81
105
  }
82
106
  /**
83
107
  * Additional metadata returned from view-state transitions.
@@ -85,13 +109,13 @@ export declare abstract class Component<Events extends ValidEventTypes = Record<
85
109
  * @public
86
110
  */
87
111
  export interface ViewStateResult {
88
- /**
89
- * Set this to true to indicate that there is a state change which should be
90
- * recorded in the navigation history.
91
- *
92
- * @public
93
- */
94
- history: boolean;
112
+ /**
113
+ * Set this to true to indicate that there is a state change which should be
114
+ * recorded in the navigation history.
115
+ *
116
+ * @public
117
+ */
118
+ history: boolean;
95
119
  }
96
120
  /**
97
121
  * Serialized workspace state for a single leaf.
@@ -99,27 +123,27 @@ export interface ViewStateResult {
99
123
  * @public
100
124
  */
101
125
  export interface ViewState {
102
- /** @public */
103
- type: string;
104
- /** @public */
105
- state?: Record<string, unknown>;
106
- /** @public */
107
- active?: boolean;
108
- /** @public */
109
- pinned?: boolean;
110
- /** @public */
111
- group?: WorkspaceLeaf;
126
+ /** @public */
127
+ type: string;
128
+ /** @public */
129
+ state?: Record<string, unknown>;
130
+ /** @public */
131
+ active?: boolean;
132
+ /** @public */
133
+ pinned?: boolean;
134
+ /** @public */
135
+ group?: WorkspaceLeaf;
112
136
  }
113
137
  /**
114
- * Header breadcrumb contributed by a view. Keep the leaf filename in the
115
- * header title rather than this list.
138
+ * Header breadcrumb contributed by a view. Keep the leaf filename in the header
139
+ * title rather than this list.
116
140
  *
117
141
  * @public
118
142
  */
119
143
  export interface ViewBreadcrumb {
120
- id: string;
121
- label: string;
122
- onSelect?: () => void;
144
+ id: string;
145
+ label: string;
146
+ onSelect?: () => void;
123
147
  }
124
148
  /**
125
149
  * Base class for anything that can be mounted inside a workspace leaf.
@@ -127,37 +151,41 @@ export interface ViewBreadcrumb {
127
151
  * @public
128
152
  */
129
153
  export declare abstract class View extends Component {
130
- icon: string;
131
- leaf: WorkspaceLeaf;
132
- scope: Scope | null;
133
- protected state: Record<string, unknown>;
134
- constructor(leaf?: WorkspaceLeaf);
135
- get containerEl(): HTMLElement;
136
- get app(): App;
137
- /** @public */
138
- protected abstract onOpen(): Promise<void>;
139
- /** @public */
140
- protected abstract onClose(): Promise<void>;
141
- /** @public */
142
- abstract getViewType(): string;
143
- getState(): Record<string, unknown>;
144
- setState(state: Record<string, unknown>, result?: ViewStateResult): Promise<void>;
145
- getIcon(): string;
146
- abstract getDisplayText(): string;
147
- getBreadcrumbFilePath(): string | null;
148
- getBreadcrumbs(): ViewBreadcrumb[];
149
- onPaneMenu(menu: Menu, source: "more-options" | "tab-header" | string): void;
154
+ icon: string;
155
+ leaf: WorkspaceLeaf;
156
+ scope: Scope | null;
157
+ protected state: Record<string, unknown>;
158
+ constructor(leaf?: WorkspaceLeaf);
159
+ get containerEl(): HTMLElement;
160
+ get app(): App;
161
+ /** @public */
162
+ protected abstract onOpen(): Promise<void>;
163
+ /** @public */
164
+ protected abstract onClose(): Promise<void>;
165
+ /** @public */
166
+ abstract getViewType(): string;
167
+ getState(): Record<string, unknown>;
168
+ setState(
169
+ state: Record<string, unknown>,
170
+ result?: ViewStateResult,
171
+ ): Promise<void>;
172
+ getIcon(): string;
173
+ abstract getDisplayText(): string;
174
+ getClosePersistenceScope(): "application" | "layout";
175
+ getBreadcrumbFilePath(): string | null;
176
+ getBreadcrumbs(): ViewBreadcrumb[];
177
+ onPaneMenu(menu: Menu, source: "more-options" | "tab-header" | string): void;
150
178
  }
151
179
  export declare class EmptyView extends View {
152
- private component;
153
- constructor(leaf?: WorkspaceLeaf);
154
- protected onOpen(): Promise<void>;
155
- protected onClose(): Promise<void>;
156
- load(): void;
157
- unload(): void;
158
- getViewType(): string;
159
- getDisplayText(): string;
160
- getIcon(): string;
180
+ private component;
181
+ constructor(leaf?: WorkspaceLeaf);
182
+ protected onOpen(): Promise<void>;
183
+ protected onClose(): Promise<void>;
184
+ load(): void;
185
+ unload(): void;
186
+ getViewType(): string;
187
+ getDisplayText(): string;
188
+ getIcon(): string;
161
189
  }
162
190
  /**
163
191
  * View base class with an action bar and content area.
@@ -165,20 +193,25 @@ export declare class EmptyView extends View {
165
193
  * @public
166
194
  */
167
195
  export declare abstract class ItemView extends View {
168
- actions: Array<{
169
- icon: string;
170
- title: string;
171
- callback: (evt: MouseEvent) => any;
172
- disabled?: boolean;
173
- }>;
174
- constructor(leaf?: WorkspaceLeaf);
175
- get contentEl(): HTMLElement;
176
- unload(): void;
177
- addAction(icon: string, title: string, callback: (evt: MouseEvent) => any, options?: {
178
- disabled?: boolean;
179
- }): void;
180
- protected onOpen(): Promise<void>;
181
- protected onClose(): Promise<void>;
196
+ actions: Array<{
197
+ icon: string;
198
+ title: string;
199
+ callback: (evt: MouseEvent) => any;
200
+ disabled?: boolean;
201
+ }>;
202
+ constructor(leaf?: WorkspaceLeaf);
203
+ get contentEl(): HTMLElement;
204
+ unload(): void;
205
+ addAction(
206
+ icon: string,
207
+ title: string,
208
+ callback: (evt: MouseEvent) => any,
209
+ options?: {
210
+ disabled?: boolean;
211
+ },
212
+ ): void;
213
+ protected onOpen(): Promise<void>;
214
+ protected onClose(): Promise<void>;
182
215
  }
183
216
  /**
184
217
  * Item view base class that is backed by a vault file.
@@ -186,13 +219,13 @@ export declare abstract class ItemView extends View {
186
219
  * @public
187
220
  */
188
221
  export declare abstract class FileView extends ItemView {
189
- file: TFile | null;
190
- constructor(leaf?: WorkspaceLeaf);
191
- getBreadcrumbFilePath(): string | null;
192
- abstract onLoadFile(file: TFile): Promise<void>;
193
- abstract onUnloadFile(file: TFile): Promise<void>;
194
- abstract onRename(file: TFile): Promise<void>;
195
- abstract canAcceptExtension(extension: string): boolean;
222
+ file: TFile | null;
223
+ constructor(leaf?: WorkspaceLeaf);
224
+ getBreadcrumbFilePath(): string | null;
225
+ abstract onLoadFile(file: TFile): Promise<void>;
226
+ abstract onUnloadFile(file: TFile): Promise<void>;
227
+ abstract onRename(file: TFile): Promise<void>;
228
+ abstract canAcceptExtension(extension: string): boolean;
196
229
  }
197
230
  /**
198
231
  * File view base class for text-backed editors.
@@ -200,16 +233,16 @@ export declare abstract class FileView extends ItemView {
200
233
  * @public
201
234
  */
202
235
  export declare abstract class TextFileView extends FileView {
203
- editor: Editor;
204
- data: string;
205
- constructor(leaf?: WorkspaceLeaf);
206
- get adapter(): DataAdapter;
207
- abstract getViewData(): string;
208
- abstract setViewData(data: string, clear?: boolean): void;
209
- abstract clear(): void;
210
- onLoadFile(file: TFile): Promise<void>;
211
- getIcon(): string;
212
- onRename(file: TFile): Promise<void>;
213
- onUnloadFile(file: TFile): Promise<void>;
214
- save(clear?: boolean): Promise<void>;
236
+ editor: Editor;
237
+ data: string;
238
+ constructor(leaf?: WorkspaceLeaf);
239
+ get adapter(): DataAdapter;
240
+ abstract getViewData(): string;
241
+ abstract setViewData(data: string, clear?: boolean): void;
242
+ abstract clear(): void;
243
+ onLoadFile(file: TFile): Promise<void>;
244
+ getIcon(): string;
245
+ onRename(file: TFile): Promise<void>;
246
+ onUnloadFile(file: TFile): Promise<void>;
247
+ save(clear?: boolean): Promise<void>;
215
248
  }
@@ -208,8 +208,17 @@ export class View extends Component {
208
208
  return this.icon;
209
209
  }
210
210
  /**
211
- * Vault path used for parent-path header breadcrumbs. File views return
212
- * the open file; other views MAY return a related path or null.
211
+ * Layout-only views own no file writers and retain staged state outside their
212
+ * UI. Every other view keeps the complete application writer close guard.
213
+ *
214
+ * @public
215
+ */
216
+ getClosePersistenceScope() {
217
+ return "application";
218
+ }
219
+ /**
220
+ * Vault path used for parent-path header breadcrumbs. File views return the
221
+ * open file; other views MAY return a related path or null.
213
222
  *
214
223
  * @public
215
224
  */
@@ -0,0 +1,3 @@
1
+ import type { Workspace } from "./workspace.svelte";
2
+ /** Keep the App's persistence barrier held through destructive shell changes. */
3
+ export declare function workspaceCloseGuard(workspace: Workspace, hostDocuments?: () => Document[]): (ids: string[], remove: () => void) => Promise<void>;