@mnaoumov/obsidian-lib 10.10.0 → 10.12.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 (133) hide show
  1. package/README.md +26 -0
  2. package/components/all-windows-status-bar-item-component/package.json +6 -0
  3. package/components/shared-component-pool-component/package.json +6 -0
  4. package/components/workspace-layout-state-component/package.json +6 -0
  5. package/dist/lib/cjs/__merged.cjs +90 -1
  6. package/dist/lib/cjs/__merged.d.cts +13 -4
  7. package/dist/lib/cjs/bug-report-diagnostics.cjs +222 -0
  8. package/dist/lib/cjs/bug-report-diagnostics.d.cts +186 -0
  9. package/dist/lib/cjs/bug-report.cjs +36 -10
  10. package/dist/lib/cjs/bug-report.d.cts +65 -0
  11. package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.cjs +93 -2
  12. package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.d.cts +34 -2
  13. package/dist/lib/cjs/components/all-windows-status-bar-item-component.cjs +245 -0
  14. package/dist/lib/cjs/components/all-windows-status-bar-item-component.d.cts +146 -0
  15. package/dist/lib/cjs/components/embed-extensions-component.cjs +20 -3
  16. package/dist/lib/cjs/components/embed-extensions-component.d.cts +8 -0
  17. package/dist/lib/cjs/components/embeddable-markdown-editor-component.cjs +16 -2
  18. package/dist/lib/cjs/components/embeddable-markdown-editor-component.d.cts +9 -0
  19. package/dist/lib/cjs/components/index.cjs +12 -3
  20. package/dist/lib/cjs/components/index.d.cts +3 -0
  21. package/dist/lib/cjs/components/plugin-gate-component.cjs +2 -9
  22. package/dist/lib/cjs/components/plugin-settings-component.cjs +7 -2
  23. package/dist/lib/cjs/components/shared-component-pool-component.cjs +368 -0
  24. package/dist/lib/cjs/components/shared-component-pool-component.d.cts +129 -0
  25. package/dist/lib/cjs/components/workspace-layout-state-component.cjs +495 -0
  26. package/dist/lib/cjs/components/workspace-layout-state-component.d.cts +239 -0
  27. package/dist/lib/cjs/css-class.cjs +5 -1
  28. package/dist/lib/cjs/css-class.d.cts +16 -0
  29. package/dist/lib/cjs/data-handler.cjs +156 -5
  30. package/dist/lib/cjs/data-handler.d.cts +128 -2
  31. package/dist/lib/cjs/desktop-git-runner.cjs +4 -14
  32. package/dist/lib/cjs/desktop-git-runner.d.cts +8 -2
  33. package/dist/lib/cjs/generated-during-build.cjs +2 -2
  34. package/dist/lib/cjs/git-rename-history.cjs +1 -1
  35. package/dist/lib/cjs/git-rename-history.d.cts +2 -2
  36. package/dist/lib/cjs/i18n/locales/en.cjs +29 -1
  37. package/dist/lib/cjs/i18n/locales/en.d.cts +28 -0
  38. package/dist/lib/cjs/i18n/locales/translations-map.d.cts +28 -0
  39. package/dist/lib/cjs/index.cjs +10 -1
  40. package/dist/lib/cjs/index.d.cts +3 -0
  41. package/dist/lib/cjs/link.cjs +40 -1
  42. package/dist/lib/cjs/link.d.cts +37 -1
  43. package/dist/lib/cjs/markdown-view.cjs +191 -3
  44. package/dist/lib/cjs/markdown-view.d.cts +48 -1
  45. package/dist/lib/cjs/modals/copy-text-manually.cjs +181 -0
  46. package/dist/lib/cjs/modals/copy-text-manually.d.cts +38 -0
  47. package/dist/lib/cjs/modals/index.cjs +7 -1
  48. package/dist/lib/cjs/modals/index.d.cts +2 -0
  49. package/dist/lib/cjs/modals/review-bug-report-diagnostics.cjs +202 -0
  50. package/dist/lib/cjs/modals/review-bug-report-diagnostics.d.cts +30 -0
  51. package/dist/lib/cjs/plugin/index.cjs +4 -1
  52. package/dist/lib/cjs/plugin/index.d.cts +1 -0
  53. package/dist/lib/cjs/plugin/plugin-api.cjs +13 -4
  54. package/dist/lib/cjs/plugin/plugin-api.d.cts +5 -1
  55. package/dist/lib/cjs/plugin/plugin-install-state.cjs +46 -1
  56. package/dist/lib/cjs/plugin/plugin-install-state.d.cts +30 -0
  57. package/dist/lib/cjs/plugin/plugin-instance.cjs +448 -0
  58. package/dist/lib/cjs/plugin/plugin-instance.d.cts +251 -0
  59. package/dist/lib/cjs/plugin/plugin.cjs +16 -1
  60. package/dist/lib/cjs/plugin/plugin.d.cts +7 -0
  61. package/dist/lib/cjs/reference-definition.cjs +234 -0
  62. package/dist/lib/cjs/reference-definition.d.cts +47 -0
  63. package/dist/lib/cjs/release-asset.cjs +279 -0
  64. package/dist/lib/cjs/release-asset.d.cts +190 -0
  65. package/dist/lib/cjs/workspace.cjs +3 -2
  66. package/dist/lib/cjs/workspace.d.cts +6 -0
  67. package/dist/lib/esm/__merged.d.mts +13 -4
  68. package/dist/lib/esm/__merged.mjs +97 -3
  69. package/dist/lib/esm/bug-report-diagnostics.d.mts +186 -0
  70. package/dist/lib/esm/bug-report-diagnostics.mjs +127 -0
  71. package/dist/lib/esm/bug-report.d.mts +65 -0
  72. package/dist/lib/esm/bug-report.mjs +33 -10
  73. package/dist/lib/esm/command-handlers/open-bug-report-command-handler.d.mts +34 -2
  74. package/dist/lib/esm/command-handlers/open-bug-report-command-handler.mjs +99 -3
  75. package/dist/lib/esm/components/all-windows-status-bar-item-component.d.mts +146 -0
  76. package/dist/lib/esm/components/all-windows-status-bar-item-component.mjs +154 -0
  77. package/dist/lib/esm/components/embed-extensions-component.d.mts +8 -0
  78. package/dist/lib/esm/components/embed-extensions-component.mjs +20 -3
  79. package/dist/lib/esm/components/embeddable-markdown-editor-component.d.mts +9 -0
  80. package/dist/lib/esm/components/embeddable-markdown-editor-component.mjs +16 -2
  81. package/dist/lib/esm/components/index.d.mts +3 -0
  82. package/dist/lib/esm/components/index.mjs +8 -2
  83. package/dist/lib/esm/components/plugin-gate-component.mjs +5 -13
  84. package/dist/lib/esm/components/plugin-settings-component.mjs +7 -2
  85. package/dist/lib/esm/components/shared-component-pool-component.d.mts +129 -0
  86. package/dist/lib/esm/components/shared-component-pool-component.mjs +280 -0
  87. package/dist/lib/esm/components/workspace-layout-state-component.d.mts +239 -0
  88. package/dist/lib/esm/components/workspace-layout-state-component.mjs +404 -0
  89. package/dist/lib/esm/css-class.d.mts +16 -0
  90. package/dist/lib/esm/css-class.mjs +5 -1
  91. package/dist/lib/esm/data-handler.d.mts +128 -2
  92. package/dist/lib/esm/data-handler.mjs +152 -4
  93. package/dist/lib/esm/desktop-git-runner.d.mts +8 -2
  94. package/dist/lib/esm/desktop-git-runner.mjs +3 -3
  95. package/dist/lib/esm/generated-during-build.mjs +2 -2
  96. package/dist/lib/esm/git-rename-history.d.mts +2 -2
  97. package/dist/lib/esm/git-rename-history.mjs +1 -1
  98. package/dist/lib/esm/i18n/locales/en.d.mts +28 -0
  99. package/dist/lib/esm/i18n/locales/en.mjs +29 -1
  100. package/dist/lib/esm/i18n/locales/translations-map.d.mts +28 -0
  101. package/dist/lib/esm/index.d.mts +3 -0
  102. package/dist/lib/esm/index.mjs +7 -1
  103. package/dist/lib/esm/link.d.mts +37 -1
  104. package/dist/lib/esm/link.mjs +40 -1
  105. package/dist/lib/esm/markdown-view.d.mts +48 -1
  106. package/dist/lib/esm/markdown-view.mjs +192 -2
  107. package/dist/lib/esm/modals/copy-text-manually.d.mts +38 -0
  108. package/dist/lib/esm/modals/copy-text-manually.mjs +99 -0
  109. package/dist/lib/esm/modals/index.d.mts +2 -0
  110. package/dist/lib/esm/modals/index.mjs +5 -1
  111. package/dist/lib/esm/modals/review-bug-report-diagnostics.d.mts +30 -0
  112. package/dist/lib/esm/modals/review-bug-report-diagnostics.mjs +120 -0
  113. package/dist/lib/esm/plugin/index.d.mts +1 -0
  114. package/dist/lib/esm/plugin/index.mjs +3 -1
  115. package/dist/lib/esm/plugin/plugin-api.d.mts +5 -1
  116. package/dist/lib/esm/plugin/plugin-api.mjs +13 -4
  117. package/dist/lib/esm/plugin/plugin-install-state.d.mts +30 -0
  118. package/dist/lib/esm/plugin/plugin-install-state.mjs +44 -1
  119. package/dist/lib/esm/plugin/plugin-instance.d.mts +251 -0
  120. package/dist/lib/esm/plugin/plugin-instance.mjs +366 -0
  121. package/dist/lib/esm/plugin/plugin.d.mts +7 -0
  122. package/dist/lib/esm/plugin/plugin.mjs +16 -1
  123. package/dist/lib/esm/reference-definition.d.mts +47 -0
  124. package/dist/lib/esm/reference-definition.mjs +146 -0
  125. package/dist/lib/esm/release-asset.d.mts +190 -0
  126. package/dist/lib/esm/release-asset.mjs +187 -0
  127. package/dist/lib/esm/workspace.d.mts +6 -0
  128. package/dist/lib/esm/workspace.mjs +3 -2
  129. package/dist/styles.css +16 -1
  130. package/modals/copy-text-manually/package.json +6 -0
  131. package/modals/review-bug-report-diagnostics/package.json +6 -0
  132. package/package.json +2 -1
  133. package/plugin/plugin-instance/package.json +6 -0
@@ -0,0 +1,129 @@
1
+ /// <reference path="../library-references.d.mts" />
2
+ /// <reference lib="dom" />
3
+ /**
4
+ * @file
5
+ *
6
+ * A pool that shares one loaded component per caller-defined key among several consumers, and unloads it when the
7
+ * last consumer releases it.
8
+ */
9
+ import type { DisposableEx } from '@mnaoumov/typescript-lib/disposable';
10
+ import { Component } from 'obsidian';
11
+ import { ComponentEx } from './component-ex.mjs';
12
+ /**
13
+ * One consumer's hold on a shared component.
14
+ *
15
+ * Releasing it is idempotent: the first call drops the hold, and every later call — including the one the consumer
16
+ * link makes when the consumer unloads — does nothing.
17
+ *
18
+ * @typeParam TComponent - The type of the shared component.
19
+ */
20
+ export interface SharedComponentAcquisition<TComponent extends Component> extends DisposableEx {
21
+ /**
22
+ * The shared component, loaded. Every consumer of the same key receives the same instance.
23
+ */
24
+ readonly component: TComponent;
25
+ /**
26
+ * Whether this acquisition has been released.
27
+ */
28
+ readonly isReleased: boolean;
29
+ /**
30
+ * Releases this acquisition. The shared component is unloaded when its last acquisition is released.
31
+ */
32
+ readonly release: () => void;
33
+ }
34
+ /**
35
+ * Options of {@link SharedComponentPoolComponent.acquire}.
36
+ */
37
+ export interface SharedComponentPoolComponentAcquireOptions {
38
+ /**
39
+ * Cancels the acquisition while the shared component is still loading. An abort after the acquisition resolved does
40
+ * nothing; release the acquisition instead.
41
+ */
42
+ readonly abortSignal?: AbortSignal;
43
+ /**
44
+ * A component whose unload releases the acquisition automatically.
45
+ *
46
+ * The link is a child component added to the consumer, so it follows Obsidian's own rules: a consumer that is not
47
+ * loaded yet starts holding the link when it loads, and a {@link ComponentEx} consumer that is already unloaded
48
+ * refuses it with a {@link SilentError}. Releasing the acquisition by hand removes the link again, so a long-lived
49
+ * consumer that acquires and releases many times accumulates nothing.
50
+ */
51
+ readonly consumer?: Component;
52
+ }
53
+ /**
54
+ * Parameters of {@link SharedComponentPoolComponent}.
55
+ *
56
+ * @typeParam TKey - The type of the resource key.
57
+ * @typeParam TComponent - The type of the shared component.
58
+ */
59
+ export interface SharedComponentPoolComponentConstructorParams<TKey, TComponent extends Component> {
60
+ /**
61
+ * Creates the component shared under a key. Called once per key each time the key goes from no consumer to one; the
62
+ * pool loads the component itself, so the factory must return it unloaded.
63
+ *
64
+ * @param key - The resource key.
65
+ * @returns The new, not yet loaded component.
66
+ */
67
+ readonly createComponent: (key: TKey) => TComponent;
68
+ }
69
+ /**
70
+ * Shares one loaded component per caller-defined key among several consumers.
71
+ *
72
+ * The first {@link acquire} of a key creates the component through the factory and loads it; every further acquire of
73
+ * the same key, concurrent or later, receives the same instance; the release of the last acquisition unloads it, and
74
+ * the next acquire creates a fresh one. A {@link ComponentEx} is loaded through {@link ComponentEx.loadWithPromises}, so
75
+ * an acquire resolves only once its `onloadAsync` and children have settled, and a failed load rejects every waiting
76
+ * acquire, unloads the component and leaves the key free for a fresh attempt.
77
+ *
78
+ * The pool is itself a component, and its parent is the owner of every shared instance: add it with `addChild` to the
79
+ * plugin (or any longer-lived component). Unloading the owner unloads every shared component still held, rejects
80
+ * every acquire still waiting with a {@link SilentError}, and refuses later acquires. Keys are compared the way a
81
+ * {@link Map} compares them, so two equal-looking object keys are two resources. The instances live on the pool
82
+ * object only, never in the shared-state bag, so two plugins — or two pools of one plugin — never share anything.
83
+ *
84
+ * Reach for it only when SEVERAL independent consumers want the same expensive component and none of them owns it.
85
+ * A component with a single owner is that owner's child: `addChild` is simpler and already unloads it with its owner.
86
+ *
87
+ * @typeParam TKey - The type of the resource key.
88
+ * @typeParam TComponent - The type of the shared component.
89
+ */
90
+ export declare class SharedComponentPoolComponent<TKey, TComponent extends Component> extends ComponentEx {
91
+ /**
92
+ * Creates the component shared under a key; see {@link SharedComponentPoolComponentConstructorParams.createComponent}.
93
+ */
94
+ protected readonly createComponent: (key: TKey) => TComponent;
95
+ private readonly creatingKeys;
96
+ private readonly entries;
97
+ /**
98
+ * Creates a new pool.
99
+ *
100
+ * @param params - The pool parameters.
101
+ */
102
+ constructor(params: SharedComponentPoolComponentConstructorParams<TKey, TComponent>);
103
+ /**
104
+ * Acquires the component shared under a key, creating and loading it when the key has no consumer yet.
105
+ *
106
+ * @param key - The resource key.
107
+ * @param options - The acquisition options.
108
+ * @returns The acquisition, once the shared component has loaded.
109
+ * @throws An {@link Error} when the pool was never loaded, when the factory or the load fails, or when called for a
110
+ * key from inside that key's own factory or synchronous load; a {@link SilentError} when the pool is unloaded, or
111
+ * when the consumer unloads or the acquisition is released before the load completes; the abort reason when
112
+ * `abortSignal` aborts first.
113
+ */
114
+ acquire(key: TKey, options?: SharedComponentPoolComponentAcquireOptions): Promise<SharedComponentAcquisition<TComponent>>;
115
+ /**
116
+ * Returns how many acquisitions currently hold the component shared under a key, pending ones included.
117
+ *
118
+ * @param key - The resource key.
119
+ * @returns The number of consumers, `0` when the key has no shared component.
120
+ */
121
+ getConsumerCount(key: TKey): number;
122
+ /**
123
+ * Registers the teardown that unloads every shared component when the pool unloads.
124
+ */
125
+ onload(): void;
126
+ private createEntry;
127
+ private releaseReference;
128
+ private unloadEntry;
129
+ }
@@ -0,0 +1,280 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+ (function () {
6
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
7
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
8
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
9
+ }
10
+
11
+ function ensureBrowserProcess() {
12
+ const browserProcess = {
13
+ browser: true,
14
+ cwd() {
15
+ return "/";
16
+ },
17
+ env: {},
18
+ platform: "android"
19
+ };
20
+ const existingProcess = globalThis.process;
21
+ if (!existingProcess) {
22
+ globalThis.process = browserProcess;
23
+ return;
24
+ }
25
+ if (existingProcess.versions?.node) {
26
+ return;
27
+ }
28
+ const existingProcessRecord = existingProcess;
29
+ for (const [key, value] of Object.entries(browserProcess)) {
30
+ existingProcessRecord[key] ??= value;
31
+ }
32
+ existingProcessRecord["browser"] = true;
33
+ }
34
+
35
+ ensureDisposeSymbols();
36
+ ensureBrowserProcess();
37
+ })();
38
+
39
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
40
+ var __typeError = (msg) => {
41
+ throw TypeError(msg);
42
+ };
43
+ var __using = (stack, value, async) => {
44
+ if (value != null) {
45
+ if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
46
+ var dispose, inner;
47
+ if (async) dispose = value[__knownSymbol("asyncDispose")];
48
+ if (dispose === void 0) {
49
+ dispose = value[__knownSymbol("dispose")];
50
+ if (async) inner = dispose;
51
+ }
52
+ if (typeof dispose !== "function") __typeError("Object not disposable");
53
+ if (inner) dispose = function() {
54
+ try {
55
+ inner.call(this);
56
+ } catch (e) {
57
+ return Promise.reject(e);
58
+ }
59
+ };
60
+ stack.push([async, dispose, value]);
61
+ } else if (async) {
62
+ stack.push([async]);
63
+ }
64
+ return value;
65
+ };
66
+ var __callDispose = (stack, error, hasError) => {
67
+ var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
68
+ return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
69
+ };
70
+ var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
71
+ var next = (it) => {
72
+ while (it = stack.pop()) {
73
+ try {
74
+ var result = it[1] && it[1].call(it[2]);
75
+ if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
76
+ } catch (e) {
77
+ fail(e);
78
+ }
79
+ }
80
+ if (hasError) throw error;
81
+ };
82
+ return next();
83
+ };
84
+ import { onAbort } from "@mnaoumov/typescript-lib/abort-controller";
85
+ import { snapshot } from "@mnaoumov/typescript-lib/array";
86
+ import { SilentError } from "@mnaoumov/typescript-lib/error";
87
+ import { noop } from "@mnaoumov/typescript-lib/function";
88
+ import { Component } from "obsidian";
89
+ import { ComponentEx } from "./component-ex.mjs";
90
+ class SharedComponentAcquisitionImpl {
91
+ constructor(component, onRelease) {
92
+ this.component = component;
93
+ this.onRelease = onRelease;
94
+ }
95
+ component;
96
+ onRelease;
97
+ get isReleased() {
98
+ return this._isReleased;
99
+ }
100
+ _isReleased = false;
101
+ unlinkConsumer = null;
102
+ dispose() {
103
+ this.release();
104
+ }
105
+ linkConsumer(consumer) {
106
+ const consumerLink = new Component();
107
+ consumerLink.register(() => {
108
+ this.unlinkConsumer = null;
109
+ this.release();
110
+ });
111
+ consumer.addChild(consumerLink);
112
+ this.unlinkConsumer = () => {
113
+ consumer.removeChild(consumerLink);
114
+ };
115
+ }
116
+ release() {
117
+ if (this._isReleased) {
118
+ return;
119
+ }
120
+ this._isReleased = true;
121
+ const unlinkConsumer = this.unlinkConsumer;
122
+ this.unlinkConsumer = null;
123
+ unlinkConsumer?.();
124
+ this.onRelease();
125
+ }
126
+ [Symbol.dispose]() {
127
+ this.release();
128
+ }
129
+ }
130
+ class SharedComponentPoolComponent extends ComponentEx {
131
+ /**
132
+ * Creates the component shared under a key; see {@link SharedComponentPoolComponentConstructorParams.createComponent}.
133
+ */
134
+ createComponent;
135
+ creatingKeys = /* @__PURE__ */ new Set();
136
+ entries = /* @__PURE__ */ new Map();
137
+ /**
138
+ * Creates a new pool.
139
+ *
140
+ * @param params - The pool parameters.
141
+ */
142
+ constructor(params) {
143
+ super();
144
+ this.createComponent = params.createComponent;
145
+ }
146
+ /**
147
+ * Acquires the component shared under a key, creating and loading it when the key has no consumer yet.
148
+ *
149
+ * @param key - The resource key.
150
+ * @param options - The acquisition options.
151
+ * @returns The acquisition, once the shared component has loaded.
152
+ * @throws An {@link Error} when the pool was never loaded, when the factory or the load fails, or when called for a
153
+ * key from inside that key's own factory or synchronous load; a {@link SilentError} when the pool is unloaded, or
154
+ * when the consumer unloads or the acquisition is released before the load completes; the abort reason when
155
+ * `abortSignal` aborts first.
156
+ */
157
+ async acquire(key, options = {}) {
158
+ var _stack = [];
159
+ try {
160
+ this.ensureLoaded();
161
+ options.abortSignal?.throwIfAborted();
162
+ if (this.creatingKeys.has(key)) {
163
+ throw new Error("A shared component cannot be acquired from inside its own creation");
164
+ }
165
+ const entry = this.entries.get(key) ?? this.createEntry(key);
166
+ entry.consumerCount++;
167
+ const cancellation = createDeferred();
168
+ const acquisition = new SharedComponentAcquisitionImpl(entry.component, () => {
169
+ cancellation.reject(new SilentError("The shared component acquisition was released"));
170
+ this.releaseReference(entry);
171
+ });
172
+ const _abortListener = __using(_stack, options.abortSignal ? onAbort(options.abortSignal, (abortSignal) => {
173
+ cancellation.reject(abortSignal.reason);
174
+ acquisition.release();
175
+ }) : null);
176
+ try {
177
+ if (options.consumer) {
178
+ acquisition.linkConsumer(options.consumer);
179
+ }
180
+ await Promise.race([entry.ready.promise, cancellation.promise]);
181
+ } catch (error) {
182
+ acquisition.release();
183
+ throw error;
184
+ }
185
+ if (acquisition.isReleased) {
186
+ throw new SilentError("The shared component acquisition was released");
187
+ }
188
+ return acquisition;
189
+ } catch (_) {
190
+ var _error = _, _hasError = true;
191
+ } finally {
192
+ __callDispose(_stack, _error, _hasError);
193
+ }
194
+ }
195
+ /**
196
+ * Returns how many acquisitions currently hold the component shared under a key, pending ones included.
197
+ *
198
+ * @param key - The resource key.
199
+ * @returns The number of consumers, `0` when the key has no shared component.
200
+ */
201
+ getConsumerCount(key) {
202
+ return this.entries.get(key)?.consumerCount ?? 0;
203
+ }
204
+ /**
205
+ * Registers the teardown that unloads every shared component when the pool unloads.
206
+ */
207
+ onload() {
208
+ this.register(() => {
209
+ for (const entry of snapshot([...this.entries.values()])) {
210
+ this.unloadEntry(entry, new SilentError("The shared component pool is unloaded"));
211
+ }
212
+ });
213
+ }
214
+ createEntry(key) {
215
+ this.creatingKeys.add(key);
216
+ try {
217
+ const component = this.createComponent(key);
218
+ const entry = {
219
+ component,
220
+ consumerCount: 0,
221
+ isUnloaded: false,
222
+ key,
223
+ ready: createDeferred()
224
+ };
225
+ this.entries.set(key, entry);
226
+ let loadPromise = null;
227
+ try {
228
+ if (component instanceof ComponentEx) {
229
+ loadPromise = component.loadWithPromises();
230
+ } else {
231
+ component.load();
232
+ }
233
+ } catch (error) {
234
+ this.unloadEntry(entry, error);
235
+ throw error;
236
+ }
237
+ if (loadPromise) {
238
+ loadPromise.then(() => {
239
+ entry.ready.resolve();
240
+ }).catch((error) => {
241
+ this.unloadEntry(entry, error);
242
+ });
243
+ } else {
244
+ entry.ready.resolve();
245
+ }
246
+ return entry;
247
+ } finally {
248
+ this.creatingKeys.delete(key);
249
+ }
250
+ }
251
+ releaseReference(entry) {
252
+ entry.consumerCount--;
253
+ if (entry.consumerCount <= 0) {
254
+ this.unloadEntry(entry, new SilentError("The last consumer released the shared component before it loaded"));
255
+ }
256
+ }
257
+ unloadEntry(entry, reason) {
258
+ if (entry.isUnloaded) {
259
+ return;
260
+ }
261
+ entry.isUnloaded = true;
262
+ this.entries.delete(entry.key);
263
+ entry.ready.reject(reason);
264
+ entry.component.unload();
265
+ }
266
+ }
267
+ function createDeferred() {
268
+ let resolve = noop;
269
+ let reject = noop;
270
+ const promise = new Promise((resolvePromise, rejectPromise) => {
271
+ resolve = resolvePromise;
272
+ reject = rejectPromise;
273
+ });
274
+ promise.catch(noop);
275
+ return { promise, reject, resolve };
276
+ }
277
+ export {
278
+ SharedComponentPoolComponent
279
+ };
280
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3NoYXJlZC1jb21wb25lbnQtcG9vbC1jb21wb25lbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEEgcG9vbCB0aGF0IHNoYXJlcyBvbmUgbG9hZGVkIGNvbXBvbmVudCBwZXIgY2FsbGVyLWRlZmluZWQga2V5IGFtb25nIHNldmVyYWwgY29uc3VtZXJzLCBhbmQgdW5sb2FkcyBpdCB3aGVuIHRoZVxuICogbGFzdCBjb25zdW1lciByZWxlYXNlcyBpdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IERpc3Bvc2FibGVFeCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9kaXNwb3NhYmxlJztcblxuaW1wb3J0IHsgb25BYm9ydCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9hYm9ydC1jb250cm9sbGVyJztcbmltcG9ydCB7IHNuYXBzaG90IH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FycmF5JztcbmltcG9ydCB7IFNpbGVudEVycm9yIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2Vycm9yJztcbmltcG9ydCB7IG5vb3AgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvZnVuY3Rpb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgeyBDb21wb25lbnRFeCB9IGZyb20gJy4vY29tcG9uZW50LWV4LnRzJztcblxuLyoqXG4gKiBPbmUgY29uc3VtZXIncyBob2xkIG9uIGEgc2hhcmVkIGNvbXBvbmVudC5cbiAqXG4gKiBSZWxlYXNpbmcgaXQgaXMgaWRlbXBvdGVudDogdGhlIGZpcnN0IGNhbGwgZHJvcHMgdGhlIGhvbGQsIGFuZCBldmVyeSBsYXRlciBjYWxsIOKAlCBpbmNsdWRpbmcgdGhlIG9uZSB0aGUgY29uc3VtZXJcbiAqIGxpbmsgbWFrZXMgd2hlbiB0aGUgY29uc3VtZXIgdW5sb2FkcyDigJQgZG9lcyBub3RoaW5nLlxuICpcbiAqIEB0eXBlUGFyYW0gVENvbXBvbmVudCAtIFRoZSB0eXBlIG9mIHRoZSBzaGFyZWQgY29tcG9uZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJlZENvbXBvbmVudEFjcXVpc2l0aW9uPFRDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQ+IGV4dGVuZHMgRGlzcG9zYWJsZUV4IHtcbiAgLyoqXG4gICAqIFRoZSBzaGFyZWQgY29tcG9uZW50LCBsb2FkZWQuIEV2ZXJ5IGNvbnN1bWVyIG9mIHRoZSBzYW1lIGtleSByZWNlaXZlcyB0aGUgc2FtZSBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbXBvbmVudDogVENvbXBvbmVudDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGFjcXVpc2l0aW9uIGhhcyBiZWVuIHJlbGVhc2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNSZWxlYXNlZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogUmVsZWFzZXMgdGhpcyBhY3F1aXNpdGlvbi4gVGhlIHNoYXJlZCBjb21wb25lbnQgaXMgdW5sb2FkZWQgd2hlbiBpdHMgbGFzdCBhY3F1aXNpdGlvbiBpcyByZWxlYXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHJlbGVhc2U6ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogT3B0aW9ucyBvZiB7QGxpbmsgU2hhcmVkQ29tcG9uZW50UG9vbENvbXBvbmVudC5hY3F1aXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTaGFyZWRDb21wb25lbnRQb29sQ29tcG9uZW50QWNxdWlyZU9wdGlvbnMge1xuICAvKipcbiAgICogQ2FuY2VscyB0aGUgYWNxdWlzaXRpb24gd2hpbGUgdGhlIHNoYXJlZCBjb21wb25lbnQgaXMgc3RpbGwgbG9hZGluZy4gQW4gYWJvcnQgYWZ0ZXIgdGhlIGFjcXVpc2l0aW9uIHJlc29sdmVkIGRvZXNcbiAgICogbm90aGluZzsgcmVsZWFzZSB0aGUgYWNxdWlzaXRpb24gaW5zdGVhZC5cbiAgICovXG4gIHJlYWRvbmx5IGFib3J0U2lnbmFsPzogQWJvcnRTaWduYWw7XG5cbiAgLyoqXG4gICAqIEEgY29tcG9uZW50IHdob3NlIHVubG9hZCByZWxlYXNlcyB0aGUgYWNxdWlzaXRpb24gYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogVGhlIGxpbmsgaXMgYSBjaGlsZCBjb21wb25lbnQgYWRkZWQgdG8gdGhlIGNvbnN1bWVyLCBzbyBpdCBmb2xsb3dzIE9ic2lkaWFuJ3Mgb3duIHJ1bGVzOiBhIGNvbnN1bWVyIHRoYXQgaXMgbm90XG4gICAqIGxvYWRlZCB5ZXQgc3RhcnRzIGhvbGRpbmcgdGhlIGxpbmsgd2hlbiBpdCBsb2FkcywgYW5kIGEge0BsaW5rIENvbXBvbmVudEV4fSBjb25zdW1lciB0aGF0IGlzIGFscmVhZHkgdW5sb2FkZWRcbiAgICogcmVmdXNlcyBpdCB3aXRoIGEge0BsaW5rIFNpbGVudEVycm9yfS4gUmVsZWFzaW5nIHRoZSBhY3F1aXNpdGlvbiBieSBoYW5kIHJlbW92ZXMgdGhlIGxpbmsgYWdhaW4sIHNvIGEgbG9uZy1saXZlZFxuICAgKiBjb25zdW1lciB0aGF0IGFjcXVpcmVzIGFuZCByZWxlYXNlcyBtYW55IHRpbWVzIGFjY3VtdWxhdGVzIG5vdGhpbmcuXG4gICAqL1xuICByZWFkb25seSBjb25zdW1lcj86IENvbXBvbmVudDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIG9mIHtAbGluayBTaGFyZWRDb21wb25lbnRQb29sQ29tcG9uZW50fS5cbiAqXG4gKiBAdHlwZVBhcmFtIFRLZXkgLSBUaGUgdHlwZSBvZiB0aGUgcmVzb3VyY2Uga2V5LlxuICogQHR5cGVQYXJhbSBUQ29tcG9uZW50IC0gVGhlIHR5cGUgb2YgdGhlIHNoYXJlZCBjb21wb25lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcmVkQ29tcG9uZW50UG9vbENvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zPFRLZXksIFRDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQ+IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGNvbXBvbmVudCBzaGFyZWQgdW5kZXIgYSBrZXkuIENhbGxlZCBvbmNlIHBlciBrZXkgZWFjaCB0aW1lIHRoZSBrZXkgZ29lcyBmcm9tIG5vIGNvbnN1bWVyIHRvIG9uZTsgdGhlXG4gICAqIHBvb2wgbG9hZHMgdGhlIGNvbXBvbmVudCBpdHNlbGYsIHNvIHRoZSBmYWN0b3J5IG11c3QgcmV0dXJuIGl0IHVubG9hZGVkLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIHJlc291cmNlIGtleS5cbiAgICogQHJldHVybnMgVGhlIG5ldywgbm90IHlldCBsb2FkZWQgY29tcG9uZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlQ29tcG9uZW50OiAoa2V5OiBUS2V5KSA9PiBUQ29tcG9uZW50O1xufVxuXG5pbnRlcmZhY2UgRGVmZXJyZWQge1xuICByZWFkb25seSBwcm9taXNlOiBQcm9taXNlPHZvaWQ+O1xuICByZWFkb25seSByZWplY3Q6IChyZWFzb246IHVua25vd24pID0+IHZvaWQ7XG4gIHJlYWRvbmx5IHJlc29sdmU6ICgpID0+IHZvaWQ7XG59XG5cbmludGVyZmFjZSBQb29sRW50cnk8VEtleSwgVENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudD4ge1xuICByZWFkb25seSBjb21wb25lbnQ6IFRDb21wb25lbnQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB0eXBlc2NyaXB0LWRldi10b29sa2l0L3JlYWRvbmx5LWludGVyZmFjZS1tZW1iZXJzIC0tIE11dGFibGUgYm9va2tlZXBpbmcgb2YgdGhlIHBvb2wuXG4gIGNvbnN1bWVyQ291bnQ6IG51bWJlcjtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHR5cGVzY3JpcHQtZGV2LXRvb2xraXQvcmVhZG9ubHktaW50ZXJmYWNlLW1lbWJlcnMgLS0gTXV0YWJsZSBib29ra2VlcGluZyBvZiB0aGUgcG9vbC5cbiAgaXNVbmxvYWRlZDogYm9vbGVhbjtcbiAgcmVhZG9ubHkga2V5OiBUS2V5O1xuICByZWFkb25seSByZWFkeTogRGVmZXJyZWQ7XG59XG5cbmNsYXNzIFNoYXJlZENvbXBvbmVudEFjcXVpc2l0aW9uSW1wbDxUQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50PiBpbXBsZW1lbnRzIFNoYXJlZENvbXBvbmVudEFjcXVpc2l0aW9uPFRDb21wb25lbnQ+IHtcbiAgcHVibGljIGdldCBpc1JlbGVhc2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pc1JlbGVhc2VkO1xuICB9XG5cbiAgcHJpdmF0ZSBfaXNSZWxlYXNlZCA9IGZhbHNlO1xuICBwcml2YXRlIHVubGlua0NvbnN1bWVyOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IGNvbXBvbmVudDogVENvbXBvbmVudCwgcHJpdmF0ZSByZWFkb25seSBvblJlbGVhc2U6ICgpID0+IHZvaWQpIHt9XG5cbiAgcHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gIH1cblxuICBwdWJsaWMgbGlua0NvbnN1bWVyKGNvbnN1bWVyOiBDb21wb25lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBjb25zdW1lckxpbmsgPSBuZXcgQ29tcG9uZW50KCk7XG4gICAgY29uc3VtZXJMaW5rLnJlZ2lzdGVyKCgpID0+IHtcbiAgICAgIHRoaXMudW5saW5rQ29uc3VtZXIgPSBudWxsO1xuICAgICAgdGhpcy5yZWxlYXNlKCk7XG4gICAgfSk7XG4gICAgY29uc3VtZXIuYWRkQ2hpbGQoY29uc3VtZXJMaW5rKTtcbiAgICB0aGlzLnVubGlua0NvbnN1bWVyID0gKCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3VtZXIucmVtb3ZlQ2hpbGQoY29uc3VtZXJMaW5rKTtcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHJlbGVhc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2lzUmVsZWFzZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1JlbGVhc2VkID0gdHJ1ZTtcbiAgICBjb25zdCB1bmxpbmtDb25zdW1lciA9IHRoaXMudW5saW5rQ29uc3VtZXI7XG4gICAgdGhpcy51bmxpbmtDb25zdW1lciA9IG51bGw7XG4gICAgdW5saW5rQ29uc3VtZXI/LigpO1xuICAgIHRoaXMub25SZWxlYXNlKCk7XG4gIH1cblxuICBwdWJsaWMgW1N5bWJvbC5kaXNwb3NlXSgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbGVhc2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIFNoYXJlcyBvbmUgbG9hZGVkIGNvbXBvbmVudCBwZXIgY2FsbGVyLWRlZmluZWQga2V5IGFtb25nIHNldmVyYWwgY29uc3VtZXJzLlxuICpcbiAqIFRoZSBmaXJzdCB7QGxpbmsgYWNxdWlyZX0gb2YgYSBrZXkgY3JlYXRlcyB0aGUgY29tcG9uZW50IHRocm91Z2ggdGhlIGZhY3RvcnkgYW5kIGxvYWRzIGl0OyBldmVyeSBmdXJ0aGVyIGFjcXVpcmUgb2ZcbiAqIHRoZSBzYW1lIGtleSwgY29uY3VycmVudCBvciBsYXRlciwgcmVjZWl2ZXMgdGhlIHNhbWUgaW5zdGFuY2U7IHRoZSByZWxlYXNlIG9mIHRoZSBsYXN0IGFjcXVpc2l0aW9uIHVubG9hZHMgaXQsIGFuZFxuICogdGhlIG5leHQgYWNxdWlyZSBjcmVhdGVzIGEgZnJlc2ggb25lLiBBIHtAbGluayBDb21wb25lbnRFeH0gaXMgbG9hZGVkIHRocm91Z2gge0BsaW5rIENvbXBvbmVudEV4LmxvYWRXaXRoUHJvbWlzZXN9LCBzb1xuICogYW4gYWNxdWlyZSByZXNvbHZlcyBvbmx5IG9uY2UgaXRzIGBvbmxvYWRBc3luY2AgYW5kIGNoaWxkcmVuIGhhdmUgc2V0dGxlZCwgYW5kIGEgZmFpbGVkIGxvYWQgcmVqZWN0cyBldmVyeSB3YWl0aW5nXG4gKiBhY3F1aXJlLCB1bmxvYWRzIHRoZSBjb21wb25lbnQgYW5kIGxlYXZlcyB0aGUga2V5IGZyZWUgZm9yIGEgZnJlc2ggYXR0ZW1wdC5cbiAqXG4gKiBUaGUgcG9vbCBpcyBpdHNlbGYgYSBjb21wb25lbnQsIGFuZCBpdHMgcGFyZW50IGlzIHRoZSBvd25lciBvZiBldmVyeSBzaGFyZWQgaW5zdGFuY2U6IGFkZCBpdCB3aXRoIGBhZGRDaGlsZGAgdG8gdGhlXG4gKiBwbHVnaW4gKG9yIGFueSBsb25nZXItbGl2ZWQgY29tcG9uZW50KS4gVW5sb2FkaW5nIHRoZSBvd25lciB1bmxvYWRzIGV2ZXJ5IHNoYXJlZCBjb21wb25lbnQgc3RpbGwgaGVsZCwgcmVqZWN0c1xuICogZXZlcnkgYWNxdWlyZSBzdGlsbCB3YWl0aW5nIHdpdGggYSB7QGxpbmsgU2lsZW50RXJyb3J9LCBhbmQgcmVmdXNlcyBsYXRlciBhY3F1aXJlcy4gS2V5cyBhcmUgY29tcGFyZWQgdGhlIHdheSBhXG4gKiB7QGxpbmsgTWFwfSBjb21wYXJlcyB0aGVtLCBzbyB0d28gZXF1YWwtbG9va2luZyBvYmplY3Qga2V5cyBhcmUgdHdvIHJlc291cmNlcy4gVGhlIGluc3RhbmNlcyBsaXZlIG9uIHRoZSBwb29sXG4gKiBvYmplY3Qgb25seSwgbmV2ZXIgaW4gdGhlIHNoYXJlZC1zdGF0ZSBiYWcsIHNvIHR3byBwbHVnaW5zIOKAlCBvciB0d28gcG9vbHMgb2Ygb25lIHBsdWdpbiDigJQgbmV2ZXIgc2hhcmUgYW55dGhpbmcuXG4gKlxuICogUmVhY2ggZm9yIGl0IG9ubHkgd2hlbiBTRVZFUkFMIGluZGVwZW5kZW50IGNvbnN1bWVycyB3YW50IHRoZSBzYW1lIGV4cGVuc2l2ZSBjb21wb25lbnQgYW5kIG5vbmUgb2YgdGhlbSBvd25zIGl0LlxuICogQSBjb21wb25lbnQgd2l0aCBhIHNpbmdsZSBvd25lciBpcyB0aGF0IG93bmVyJ3MgY2hpbGQ6IGBhZGRDaGlsZGAgaXMgc2ltcGxlciBhbmQgYWxyZWFkeSB1bmxvYWRzIGl0IHdpdGggaXRzIG93bmVyLlxuICpcbiAqIEB0eXBlUGFyYW0gVEtleSAtIFRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSBrZXkuXG4gKiBAdHlwZVBhcmFtIFRDb21wb25lbnQgLSBUaGUgdHlwZSBvZiB0aGUgc2hhcmVkIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNoYXJlZENvbXBvbmVudFBvb2xDb21wb25lbnQ8VEtleSwgVENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudD4gZXh0ZW5kcyBDb21wb25lbnRFeCB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBjb21wb25lbnQgc2hhcmVkIHVuZGVyIGEga2V5OyBzZWUge0BsaW5rIFNoYXJlZENvbXBvbmVudFBvb2xDb21wb25lbnRDb25zdHJ1Y3RvclBhcmFtcy5jcmVhdGVDb21wb25lbnR9LlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNyZWF0ZUNvbXBvbmVudDogKGtleTogVEtleSkgPT4gVENvbXBvbmVudDtcblxuICBwcml2YXRlIHJlYWRvbmx5IGNyZWF0aW5nS2V5cyA9IG5ldyBTZXQ8VEtleT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbnRyaWVzID0gbmV3IE1hcDxUS2V5LCBQb29sRW50cnk8VEtleSwgVENvbXBvbmVudD4+KCk7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcG9vbC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwb29sIHBhcmFtZXRlcnMuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBTaGFyZWRDb21wb25lbnRQb29sQ29tcG9uZW50Q29uc3RydWN0b3JQYXJhbXM8VEtleSwgVENvbXBvbmVudD4pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuY3JlYXRlQ29tcG9uZW50ID0gcGFyYW1zLmNyZWF0ZUNvbXBvbmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3F1aXJlcyB0aGUgY29tcG9uZW50IHNoYXJlZCB1bmRlciBhIGtleSwgY3JlYXRpbmcgYW5kIGxvYWRpbmcgaXQgd2hlbiB0aGUga2V5IGhhcyBubyBjb25zdW1lciB5ZXQuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBUaGUgcmVzb3VyY2Uga2V5LlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBhY3F1aXNpdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBUaGUgYWNxdWlzaXRpb24sIG9uY2UgdGhlIHNoYXJlZCBjb21wb25lbnQgaGFzIGxvYWRlZC5cbiAgICogQHRocm93cyBBbiB7QGxpbmsgRXJyb3J9IHdoZW4gdGhlIHBvb2wgd2FzIG5ldmVyIGxvYWRlZCwgd2hlbiB0aGUgZmFjdG9yeSBvciB0aGUgbG9hZCBmYWlscywgb3Igd2hlbiBjYWxsZWQgZm9yIGFcbiAgICogICBrZXkgZnJvbSBpbnNpZGUgdGhhdCBrZXkncyBvd24gZmFjdG9yeSBvciBzeW5jaHJvbm91cyBsb2FkOyBhIHtAbGluayBTaWxlbnRFcnJvcn0gd2hlbiB0aGUgcG9vbCBpcyB1bmxvYWRlZCwgb3JcbiAgICogICB3aGVuIHRoZSBjb25zdW1lciB1bmxvYWRzIG9yIHRoZSBhY3F1aXNpdGlvbiBpcyByZWxlYXNlZCBiZWZvcmUgdGhlIGxvYWQgY29tcGxldGVzOyB0aGUgYWJvcnQgcmVhc29uIHdoZW5cbiAgICogICBgYWJvcnRTaWduYWxgIGFib3J0cyBmaXJzdC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBhY3F1aXJlKGtleTogVEtleSwgb3B0aW9uczogU2hhcmVkQ29tcG9uZW50UG9vbENvbXBvbmVudEFjcXVpcmVPcHRpb25zID0ge30pOiBQcm9taXNlPFNoYXJlZENvbXBvbmVudEFjcXVpc2l0aW9uPFRDb21wb25lbnQ+PiB7XG4gICAgdGhpcy5lbnN1cmVMb2FkZWQoKTtcbiAgICBvcHRpb25zLmFib3J0U2lnbmFsPy50aHJvd0lmQWJvcnRlZCgpO1xuXG4gICAgaWYgKHRoaXMuY3JlYXRpbmdLZXlzLmhhcyhrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Egc2hhcmVkIGNvbXBvbmVudCBjYW5ub3QgYmUgYWNxdWlyZWQgZnJvbSBpbnNpZGUgaXRzIG93biBjcmVhdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5lbnRyaWVzLmdldChrZXkpID8/IHRoaXMuY3JlYXRlRW50cnkoa2V5KTtcbiAgICBlbnRyeS5jb25zdW1lckNvdW50Kys7XG5cbiAgICBjb25zdCBjYW5jZWxsYXRpb24gPSBjcmVhdGVEZWZlcnJlZCgpO1xuICAgIGNvbnN0IGFjcXVpc2l0aW9uID0gbmV3IFNoYXJlZENvbXBvbmVudEFjcXVpc2l0aW9uSW1wbChlbnRyeS5jb21wb25lbnQsICgpID0+IHtcbiAgICAgIGNhbmNlbGxhdGlvbi5yZWplY3QobmV3IFNpbGVudEVycm9yKCdUaGUgc2hhcmVkIGNvbXBvbmVudCBhY3F1aXNpdGlvbiB3YXMgcmVsZWFzZWQnKSk7XG4gICAgICB0aGlzLnJlbGVhc2VSZWZlcmVuY2UoZW50cnkpO1xuICAgIH0pO1xuXG4gICAgdXNpbmcgX2Fib3J0TGlzdGVuZXIgPSBvcHRpb25zLmFib3J0U2lnbmFsXG4gICAgICA/IG9uQWJvcnQob3B0aW9ucy5hYm9ydFNpZ25hbCwgKGFib3J0U2lnbmFsKSA9PiB7XG4gICAgICAgIGNhbmNlbGxhdGlvbi5yZWplY3QoYWJvcnRTaWduYWwucmVhc29uKTtcbiAgICAgICAgYWNxdWlzaXRpb24ucmVsZWFzZSgpO1xuICAgICAgfSlcbiAgICAgIDogbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBpZiAob3B0aW9ucy5jb25zdW1lcikge1xuICAgICAgICBhY3F1aXNpdGlvbi5saW5rQ29uc3VtZXIob3B0aW9ucy5jb25zdW1lcik7XG4gICAgICB9XG4gICAgICBhd2FpdCBQcm9taXNlLnJhY2UoW2VudHJ5LnJlYWR5LnByb21pc2UsIGNhbmNlbGxhdGlvbi5wcm9taXNlXSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGFjcXVpc2l0aW9uLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGlmIChhY3F1aXNpdGlvbi5pc1JlbGVhc2VkKSB7XG4gICAgICB0aHJvdyBuZXcgU2lsZW50RXJyb3IoJ1RoZSBzaGFyZWQgY29tcG9uZW50IGFjcXVpc2l0aW9uIHdhcyByZWxlYXNlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBhY3F1aXNpdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGhvdyBtYW55IGFjcXVpc2l0aW9ucyBjdXJyZW50bHkgaG9sZCB0aGUgY29tcG9uZW50IHNoYXJlZCB1bmRlciBhIGtleSwgcGVuZGluZyBvbmVzIGluY2x1ZGVkLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIHJlc291cmNlIGtleS5cbiAgICogQHJldHVybnMgVGhlIG51bWJlciBvZiBjb25zdW1lcnMsIGAwYCB3aGVuIHRoZSBrZXkgaGFzIG5vIHNoYXJlZCBjb21wb25lbnQuXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29uc3VtZXJDb3VudChrZXk6IFRLZXkpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmVudHJpZXMuZ2V0KGtleSk/LmNvbnN1bWVyQ291bnQgPz8gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhlIHRlYXJkb3duIHRoYXQgdW5sb2FkcyBldmVyeSBzaGFyZWQgY29tcG9uZW50IHdoZW4gdGhlIHBvb2wgdW5sb2Fkcy5cbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBvbmxvYWQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpc3RlcigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNuYXBzaG90KFsuLi50aGlzLmVudHJpZXMudmFsdWVzKCldKSkge1xuICAgICAgICB0aGlzLnVubG9hZEVudHJ5KGVudHJ5LCBuZXcgU2lsZW50RXJyb3IoJ1RoZSBzaGFyZWQgY29tcG9uZW50IHBvb2wgaXMgdW5sb2FkZWQnKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUVudHJ5KGtleTogVEtleSk6IFBvb2xFbnRyeTxUS2V5LCBUQ29tcG9uZW50PiB7XG4gICAgdGhpcy5jcmVhdGluZ0tleXMuYWRkKGtleSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY3JlYXRlQ29tcG9uZW50KGtleSk7XG4gICAgICBjb25zdCBlbnRyeTogUG9vbEVudHJ5PFRLZXksIFRDb21wb25lbnQ+ID0ge1xuICAgICAgICBjb21wb25lbnQsXG4gICAgICAgIGNvbnN1bWVyQ291bnQ6IDAsXG4gICAgICAgIGlzVW5sb2FkZWQ6IGZhbHNlLFxuICAgICAgICBrZXksXG4gICAgICAgIHJlYWR5OiBjcmVhdGVEZWZlcnJlZCgpXG4gICAgICB9O1xuICAgICAgdGhpcy5lbnRyaWVzLnNldChrZXksIGVudHJ5KTtcblxuICAgICAgbGV0IGxvYWRQcm9taXNlOiBudWxsIHwgUHJvbWlzZTx2b2lkPiA9IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoY29tcG9uZW50IGluc3RhbmNlb2YgQ29tcG9uZW50RXgpIHtcbiAgICAgICAgICBsb2FkUHJvbWlzZSA9IGNvbXBvbmVudC5sb2FkV2l0aFByb21pc2VzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29tcG9uZW50LmxvYWQoKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy51bmxvYWRFbnRyeShlbnRyeSwgZXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGxvYWRQcm9taXNlKSB7XG4gICAgICAgIGxvYWRQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGVudHJ5LnJlYWR5LnJlc29sdmUoKTtcbiAgICAgICAgfSkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgdGhpcy51bmxvYWRFbnRyeShlbnRyeSwgZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudHJ5LnJlYWR5LnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVudHJ5O1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmNyZWF0aW5nS2V5cy5kZWxldGUoa2V5KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbGVhc2VSZWZlcmVuY2UoZW50cnk6IFBvb2xFbnRyeTxUS2V5LCBUQ29tcG9uZW50Pik6IHZvaWQge1xuICAgIGVudHJ5LmNvbnN1bWVyQ291bnQtLTtcbiAgICBpZiAoZW50cnkuY29uc3VtZXJDb3VudCA8PSAwKSB7XG4gICAgICB0aGlzLnVubG9hZEVudHJ5KGVudHJ5LCBuZXcgU2lsZW50RXJyb3IoJ1RoZSBsYXN0IGNvbnN1bWVyIHJlbGVhc2VkIHRoZSBzaGFyZWQgY29tcG9uZW50IGJlZm9yZSBpdCBsb2FkZWQnKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1bmxvYWRFbnRyeShlbnRyeTogUG9vbEVudHJ5PFRLZXksIFRDb21wb25lbnQ+LCByZWFzb246IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoZW50cnkuaXNVbmxvYWRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVudHJ5LmlzVW5sb2FkZWQgPSB0cnVlO1xuICAgIC8vIEFuIGVudHJ5IHN0YXlzIGluIHRoZSBtYXAgdW50aWwgaXQgaXMgdW5sb2FkZWQsIGFuZCBvbmx5IG9uY2UsIHNvIHRoZSBrZXkgc3RpbGwgbWFwcyB0byB0aGlzIGVudHJ5LlxuICAgIHRoaXMuZW50cmllcy5kZWxldGUoZW50cnkua2V5KTtcbiAgICBlbnRyeS5yZWFkeS5yZWplY3QocmVhc29uKTtcbiAgICBlbnRyeS5jb21wb25lbnQudW5sb2FkKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVmZXJyZWQoKTogRGVmZXJyZWQge1xuICBsZXQgcmVzb2x2ZTogKCkgPT4gdm9pZCA9IG5vb3A7XG4gIGxldCByZWplY3Q6IChyZWFzb246IHVua25vd24pID0+IHZvaWQgPSBub29wO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmVQcm9taXNlLCByZWplY3RQcm9taXNlKSA9PiB7XG4gICAgcmVzb2x2ZSA9IHJlc29sdmVQcm9taXNlO1xuICAgIHJlamVjdCA9IHJlamVjdFByb21pc2U7XG4gIH0pO1xuICAvLyBBIGRlZmVycmVkIG1heSBiZSByZWplY3RlZCB3aGlsZSBub2JvZHkgYXdhaXRzIGl0OyBtYXJrIGl0IGhhbmRsZWQgc28gdGhhdCBpcyBub3QgYW4gdW5oYW5kbGVkIHJlamVjdGlvbi5cbiAgcHJvbWlzZS5jYXRjaChub29wKTtcbiAgcmV0dXJuIHsgcHJvbWlzZSwgcmVqZWN0LCByZXNvbHZlIH07XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBU0EsU0FBUyxlQUFlO0FBQ3hCLFNBQVMsZ0JBQWdCO0FBQ3pCLFNBQVMsbUJBQW1CO0FBQzVCLFNBQVMsWUFBWTtBQUNyQixTQUFTLGlCQUFpQjtBQUUxQixTQUFTLG1CQUFtQjtBQWlGNUIsTUFBTSwrQkFBK0c7QUFBQSxFQVE1RyxZQUE0QixXQUF3QyxXQUF1QjtBQUEvRDtBQUF3QztBQUFBLEVBQXdCO0FBQUEsRUFBaEU7QUFBQSxFQUF3QztBQUFBLEVBUDNFLElBQVcsYUFBc0I7QUFDL0IsV0FBTyxLQUFLO0FBQUEsRUFDZDtBQUFBLEVBRVEsY0FBYztBQUFBLEVBQ2QsaUJBQXNDO0FBQUEsRUFJdkMsVUFBZ0I7QUFDckIsU0FBSyxRQUFRO0FBQUEsRUFDZjtBQUFBLEVBRU8sYUFBYSxVQUEyQjtBQUM3QyxVQUFNLGVBQWUsSUFBSSxVQUFVO0FBQ25DLGlCQUFhLFNBQVMsTUFBTTtBQUMxQixXQUFLLGlCQUFpQjtBQUN0QixXQUFLLFFBQVE7QUFBQSxJQUNmLENBQUM7QUFDRCxhQUFTLFNBQVMsWUFBWTtBQUM5QixTQUFLLGlCQUFpQixNQUFZO0FBQ2hDLGVBQVMsWUFBWSxZQUFZO0FBQUEsSUFDbkM7QUFBQSxFQUNGO0FBQUEsRUFFTyxVQUFnQjtBQUNyQixRQUFJLEtBQUssYUFBYTtBQUNwQjtBQUFBLElBQ0Y7QUFF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
@@ -0,0 +1,239 @@
1
+ /// <reference path="../library-references.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Keeps a plugin's layout-scoped state in the workspace layout itself, so each saved workspace remembers its own value
6
+ * and switching workspaces restores it, instead of one global value in `data.json`.
7
+ *
8
+ * Read from Obsidian `1.15.1`: `Workspace.getLayout()` builds a fresh object (`main`, `left`, `right`, `left-ribbon`,
9
+ * `floating`, `active`) and `Workspace.setLayout()` ignores every other top-level key. `deserializeLayout` keeps each
10
+ * item's `id`, popout leaves included. The Workspaces core plugin saves through `getLayout()` and loads through
11
+ * `changeLayout()`, which calls `setLayout()`. Startup goes through `loadLayout()`, `readWorkspaceFile()` and
12
+ * `setLayout()`, after the plugins enabled at startup have loaded. So two patches on the `app.workspace` instance carry
13
+ * the whole thing: `getLayout` writes the records under {@link WORKSPACE_LAYOUT_STATE_LAYOUT_KEY}, and `setLayout`
14
+ * replaces them from the layout it is handed before any view is restored. Per-leaf state is keyed by leaf id at the
15
+ * layout level, so no `WorkspaceItem.serialize` or `deserializeLayout` patch is needed.
16
+ *
17
+ * A view the plugin owns needs none of this: `View.getState` / `setState` already ride in each leaf's state. This
18
+ * component is for the scope those methods cannot represent: the whole layout, and leaves of views the plugin does not
19
+ * own.
20
+ *
21
+ * Every plugin bundles its own copy of this library, so the records, the subscriptions and ONE installation of the
22
+ * patches live in the shared-state bag under a versioned key, owned by one subscriber. When the owner unloads while
23
+ * others remain, the next subscriber installs again from its own copy. What crosses that boundary is a wire format
24
+ * between copies of different versions: plain objects and plain functions only, fields only ever added, and a change of
25
+ * meaning moves to a new key. The layout record is a wire format too, persisted in `workspace.json` and in every saved
26
+ * workspace.
27
+ */
28
+ import type { App, WorkspaceLeaf } from 'obsidian';
29
+ import type { JsonValue } from 'type-fest';
30
+ import { ComponentEx } from './component-ex.mjs';
31
+ /**
32
+ * The top-level key of a serialized layout that holds the records.
33
+ */
34
+ export declare const WORKSPACE_LAYOUT_STATE_LAYOUT_KEY = "obsidianLibLayoutStateV1";
35
+ /**
36
+ * A change of one key's value, in one scope.
37
+ *
38
+ * @typeParam T - The value type.
39
+ */
40
+ export interface WorkspaceLayoutStateChange<T> {
41
+ /**
42
+ * The leaf whose value changed, or `null` for the workspace scope or a leaf no longer in the layout.
43
+ */
44
+ readonly leaf: null | WorkspaceLeaf;
45
+ /**
46
+ * The id of the leaf whose value changed, or `null` for the workspace scope.
47
+ */
48
+ readonly leafId: null | string;
49
+ /**
50
+ * The value before the change, as {@link WorkspaceLayoutStateKey.get} read it.
51
+ */
52
+ readonly oldValue: T;
53
+ /**
54
+ * The value after the change, as {@link WorkspaceLayoutStateKey.get} reads it.
55
+ */
56
+ readonly value: T;
57
+ }
58
+ /**
59
+ * Parameters for {@link WorkspaceLayoutStateComponent}.
60
+ */
61
+ export interface WorkspaceLayoutStateComponentConstructorParams {
62
+ /**
63
+ * The Obsidian app instance.
64
+ */
65
+ readonly app: App;
66
+ /**
67
+ * The id of the plugin the values belong to. Every value is namespaced by it.
68
+ */
69
+ readonly pluginId: string;
70
+ }
71
+ /**
72
+ * A typed handle to one layout-scoped key.
73
+ *
74
+ * Every method takes an optional leaf. Without one, the value belongs to the whole layout (the workspace scope).
75
+ *
76
+ * @typeParam T - The value type.
77
+ */
78
+ export interface WorkspaceLayoutStateKey<T> {
79
+ /**
80
+ * Reads the value: a clone of the stored one, or of the default when nothing is stored or the stored value fails the
81
+ * key's guard.
82
+ *
83
+ * @param leaf - The leaf, or nothing for the workspace scope.
84
+ * @returns The value.
85
+ */
86
+ readonly get: (leaf?: WorkspaceLeaf) => T;
87
+ /**
88
+ * Checks whether a value is stored, valid or not.
89
+ *
90
+ * @param leaf - The leaf, or nothing for the workspace scope.
91
+ * @returns Whether a value is stored.
92
+ */
93
+ readonly has: (leaf?: WorkspaceLeaf) => boolean;
94
+ /**
95
+ * The key name, unique within the plugin.
96
+ */
97
+ readonly key: string;
98
+ /**
99
+ * Subscribes to changes of this key made through `set` or `unset`, in any scope and from any copy of the library. A
100
+ * layout load is reported through {@link WorkspaceLayoutStateComponent.onLayoutLoad} instead.
101
+ *
102
+ * @param callback - Called after each change.
103
+ * @returns A function that unsubscribes. Unloading the component unsubscribes too.
104
+ */
105
+ readonly onChange: (callback: (change: WorkspaceLayoutStateChange<T>) => void) => () => void;
106
+ /**
107
+ * Stores a clone of the value and requests a layout save. Storing a value equal to the stored one does nothing.
108
+ *
109
+ * @param value - The value. It must be JSON-safe; `null` is stored as `null`.
110
+ * @param leaf - The leaf, or nothing for the workspace scope.
111
+ * @throws A `TypeError` if the value is not JSON-safe.
112
+ */
113
+ readonly set: (value: T, leaf?: WorkspaceLeaf) => void;
114
+ /**
115
+ * Removes the stored value, so `get` reads the default again, and requests a layout save.
116
+ *
117
+ * @param leaf - The leaf, or nothing for the workspace scope.
118
+ */
119
+ readonly unset: (leaf?: WorkspaceLeaf) => void;
120
+ }
121
+ /**
122
+ * Defines a layout-scoped key.
123
+ *
124
+ * @typeParam T - The value type.
125
+ */
126
+ export interface WorkspaceLayoutStateKeyDefinition<T> {
127
+ /**
128
+ * The value read when nothing valid is stored.
129
+ */
130
+ readonly defaultValue: T;
131
+ /**
132
+ * Checks a stored value. A value that fails reads as the default and stays stored until it is replaced or unset.
133
+ *
134
+ * @default Accepts every JSON value.
135
+ */
136
+ readonly isValid?: (value: unknown) => value is T;
137
+ /**
138
+ * The key name, unique within the plugin.
139
+ */
140
+ readonly key: string;
141
+ }
142
+ /**
143
+ * One plugin's records. Fields a newer copy adds are preserved.
144
+ */
145
+ export interface WorkspaceLayoutStatePluginRecord {
146
+ /**
147
+ * The values by leaf id, then by key.
148
+ */
149
+ readonly leaves: Record<string, JsonRecord>;
150
+ /**
151
+ * Fields a newer copy of the library added.
152
+ */
153
+ readonly [field: string]: unknown;
154
+ /**
155
+ * The workspace-scope values by key.
156
+ */
157
+ readonly workspace: JsonRecord;
158
+ }
159
+ /**
160
+ * The record persisted under {@link WORKSPACE_LAYOUT_STATE_LAYOUT_KEY}. Fields a newer copy adds are preserved.
161
+ */
162
+ export interface WorkspaceLayoutStateRecord {
163
+ /**
164
+ * The records by plugin id.
165
+ */
166
+ readonly plugins: Record<string, WorkspaceLayoutStatePluginRecord>;
167
+ /**
168
+ * Fields a newer copy of the library added.
169
+ */
170
+ readonly [field: string]: unknown;
171
+ }
172
+ type JsonRecord = Record<string, JsonValue>;
173
+ /**
174
+ * Keeps a plugin's layout-scoped values in the workspace layout, so saved workspaces each restore their own.
175
+ *
176
+ * Any number of these, in any number of plugins, share one installation per {@link App}. Values are restored when a
177
+ * layout loads, which REPLACES every value: write them after {@link Workspace.onLayoutReady}, and re-read them in
178
+ * {@link onLayoutLoad}.
179
+ */
180
+ export declare class WorkspaceLayoutStateComponent extends ComponentEx {
181
+ /**
182
+ * The Obsidian app instance.
183
+ */
184
+ protected readonly app: App;
185
+ /**
186
+ * The id of the plugin the values belong to.
187
+ */
188
+ protected readonly pluginId: string;
189
+ private readonly layoutLoadListeners;
190
+ private readonly recordChangeListeners;
191
+ /**
192
+ * Creates a new workspace layout state component.
193
+ *
194
+ * @param params - The parameters.
195
+ * @throws A `TypeError` if the plugin id is empty.
196
+ */
197
+ constructor(params: WorkspaceLayoutStateComponentConstructorParams);
198
+ /**
199
+ * Defines a typed key.
200
+ *
201
+ * @typeParam T - The value type.
202
+ * @param definition - The key definition.
203
+ * @returns The key handle.
204
+ * @throws A `TypeError` if the key is empty or the default value is not JSON-safe.
205
+ */
206
+ defineKey<T>(definition: WorkspaceLayoutStateKeyDefinition<T>): WorkspaceLayoutStateKey<T>;
207
+ /**
208
+ * Subscribes to layout loads: a saved workspace loaded, the layout restored at startup, or the saved layout read when
209
+ * the component is first loaded after layout-ready. Every value may have changed.
210
+ *
211
+ * @param callback - Called after the layout is loaded, once its leaves exist.
212
+ * @returns A function that unsubscribes. Unloading the component unsubscribes too.
213
+ */
214
+ onLayoutLoad(callback: () => void): () => void;
215
+ /**
216
+ * Subscribes to the shared installation, installing it when nobody has yet.
217
+ */
218
+ onload(): void;
219
+ private subscribeToRecordChanges;
220
+ }
221
+ /**
222
+ * Parses a persisted record. A part that is malformed is dropped one level at a time: a malformed record reads as
223
+ * empty, a malformed plugin record drops only that plugin, and a malformed leaf bucket drops only that leaf. Fields this
224
+ * copy does not know are kept.
225
+ *
226
+ * @param value - The value found under {@link WORKSPACE_LAYOUT_STATE_LAYOUT_KEY}.
227
+ * @returns The parsed record, sharing nothing with the input.
228
+ */
229
+ export declare function parseWorkspaceLayoutStateRecord(value: unknown): WorkspaceLayoutStateRecord;
230
+ /**
231
+ * Builds the record to persist into a serialized layout: leaf buckets for leaves absent from the layout are left out,
232
+ * and so are plugins with nothing left.
233
+ *
234
+ * @param record - The current record.
235
+ * @param layout - The serialized layout.
236
+ * @returns The record to persist, or `null` when there is nothing to persist.
237
+ */
238
+ export declare function serializeWorkspaceLayoutStateRecord(record: WorkspaceLayoutStateRecord, layout: unknown): null | WorkspaceLayoutStateRecord;
239
+ export {};