@loomweaver/plugin-sdk 0.7.2

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 (71) hide show
  1. package/README.md +11 -0
  2. package/package.json +45 -0
  3. package/src/index.d.ts +22 -0
  4. package/src/index.js +23 -0
  5. package/src/index.js.map +1 -0
  6. package/src/lib/auth.d.ts +60 -0
  7. package/src/lib/auth.js +35 -0
  8. package/src/lib/auth.js.map +1 -0
  9. package/src/lib/bar-item.d.ts +67 -0
  10. package/src/lib/bar-item.js +2 -0
  11. package/src/lib/bar-item.js.map +1 -0
  12. package/src/lib/button.d.ts +4 -0
  13. package/src/lib/button.js +2 -0
  14. package/src/lib/button.js.map +1 -0
  15. package/src/lib/capability.d.ts +38 -0
  16. package/src/lib/capability.js +32 -0
  17. package/src/lib/capability.js.map +1 -0
  18. package/src/lib/command.d.ts +199 -0
  19. package/src/lib/command.js +2 -0
  20. package/src/lib/command.js.map +1 -0
  21. package/src/lib/container-handle.d.ts +36 -0
  22. package/src/lib/container-handle.js +4 -0
  23. package/src/lib/container-handle.js.map +1 -0
  24. package/src/lib/content-route.d.ts +254 -0
  25. package/src/lib/content-route.js +2 -0
  26. package/src/lib/content-route.js.map +1 -0
  27. package/src/lib/contribution.d.ts +4 -0
  28. package/src/lib/contribution.js +2 -0
  29. package/src/lib/contribution.js.map +1 -0
  30. package/src/lib/dialog-ref.d.ts +25 -0
  31. package/src/lib/dialog-ref.js +37 -0
  32. package/src/lib/dialog-ref.js.map +1 -0
  33. package/src/lib/dialog.d.ts +105 -0
  34. package/src/lib/dialog.js +2 -0
  35. package/src/lib/dialog.js.map +1 -0
  36. package/src/lib/dirty-surface.d.ts +48 -0
  37. package/src/lib/dirty-surface.js +2 -0
  38. package/src/lib/dirty-surface.js.map +1 -0
  39. package/src/lib/menu.d.ts +48 -0
  40. package/src/lib/menu.js +2 -0
  41. package/src/lib/menu.js.map +1 -0
  42. package/src/lib/notification.d.ts +28 -0
  43. package/src/lib/notification.js +2 -0
  44. package/src/lib/notification.js.map +1 -0
  45. package/src/lib/pane-area.d.ts +29 -0
  46. package/src/lib/pane-area.js +2 -0
  47. package/src/lib/pane-area.js.map +1 -0
  48. package/src/lib/plugin-state.d.ts +52 -0
  49. package/src/lib/plugin-state.js +2 -0
  50. package/src/lib/plugin-state.js.map +1 -0
  51. package/src/lib/plugin.d.ts +259 -0
  52. package/src/lib/plugin.js +2 -0
  53. package/src/lib/plugin.js.map +1 -0
  54. package/src/lib/product-identity.d.ts +25 -0
  55. package/src/lib/product-identity.js +17 -0
  56. package/src/lib/product-identity.js.map +1 -0
  57. package/src/lib/rail-item.d.ts +61 -0
  58. package/src/lib/rail-item.js +2 -0
  59. package/src/lib/rail-item.js.map +1 -0
  60. package/src/lib/settings-model.d.ts +164 -0
  61. package/src/lib/settings-model.js +2 -0
  62. package/src/lib/settings-model.js.map +1 -0
  63. package/src/lib/surface.d.ts +220 -0
  64. package/src/lib/surface.js +2 -0
  65. package/src/lib/surface.js.map +1 -0
  66. package/src/lib/view-state.d.ts +38 -0
  67. package/src/lib/view-state.js +9 -0
  68. package/src/lib/view-state.js.map +1 -0
  69. package/src/lib/view.d.ts +103 -0
  70. package/src/lib/view.js +2 -0
  71. package/src/lib/view.js.map +1 -0
@@ -0,0 +1,220 @@
1
+ import { Type } from '@angular/core';
2
+ import { AccessRequirement } from './auth.js';
3
+ import { ContainerSpec } from './content-route.js';
4
+ import { ViewAction } from './view.js';
5
+ /**
6
+ * How a surface is presented (the UI-boundary form). Exactly one is set:
7
+ *
8
+ * - `component` — an Angular class rendered in-process (trusted rung; the default today). Cannot
9
+ * cross an RPC boundary, so a **sandboxed** plugin never uses this form.
10
+ * - `loadComponent` — the same thing, **deferred**: a loader the host calls the first time the surface is
11
+ * actually shown, mirroring Angular's `Route.loadComponent`. Use it when a surface drags a heavy
12
+ * dependency tree behind it (a chart engine, a graph layout), so that code lands in its own chunk and a
13
+ * user who never opens the surface never downloads it. Routable surfaces hand it straight to the router;
14
+ * host-mounted ones render nothing until it resolves.
15
+ * - `iframe` — a URL the host mounts as an **isolated** `<iframe sandbox>` surface. A plain string, so it
16
+ * serialises over the `ctx`-RPC boundary — which is why it is the form a **sandboxed** plugin uses
17
+ * (the first untrusted rung). A **trusted** plugin may use it too, to embed a foreign origin on purpose
18
+ * (a dashboard, a docs site, a video): a sandboxed plugin is confined to same-origin URLs at the RPC
19
+ * seam, whereas for a trusted one the distribution's CSP `frame-src` decides what may be framed.
20
+ * - `container` — the surface hosts a **nested pane tree** of child surfaces
21
+ * ("workspace-in-a-tab"): the host draws the inner drag/split/tab mechanics, the surface only declares
22
+ * which children it offers. Must be combined with `routable` (the container tab holds its own `:id`).
23
+ *
24
+ * Mirrors the {@link ContentSurface} union so a {@link Surface} and a {@link ContentRoute}
25
+ * present identically, deliberately: `ContentRoute`
26
+ * remains the host's internal storage shape, `Surface` the one authoring contract.
27
+ */
28
+ export type SurfacePresentation = {
29
+ readonly component: Type<unknown>;
30
+ readonly loadComponent?: never;
31
+ readonly iframe?: never;
32
+ readonly container?: never;
33
+ } | {
34
+ readonly loadComponent: () => Promise<Type<unknown>>;
35
+ readonly component?: never;
36
+ readonly iframe?: never;
37
+ readonly container?: never;
38
+ } | {
39
+ readonly iframe: string;
40
+ readonly component?: never;
41
+ readonly loadComponent?: never;
42
+ readonly container?: never;
43
+ } | {
44
+ readonly container: ContainerSpec;
45
+ readonly component?: never;
46
+ readonly loadComponent?: never;
47
+ readonly iframe?: never;
48
+ };
49
+ /**
50
+ * The **routable** capability of a {@link Surface}: the surface is URL-addressable, so it
51
+ * can hold the one URL pane (deep-link, browser back/forward, `RouteReuseStrategy`). Carries the former
52
+ * {@link ContentRoute} route fields. Omit for a surface that only ever lives as host-rendered workspace
53
+ * state (a classic sidebar view).
54
+ */
55
+ export interface SurfaceRoutable {
56
+ /** Route path (Angular syntax), e.g. `'reports'`, `'doc/:id'`, `'dashboard'`. */
57
+ readonly path: string;
58
+ /**
59
+ * A **chromeless** surface owns the whole content area while active: no tab strip, never a tab,
60
+ * excluded from splits, drags and the new-tab picker — the full-area screen that login and
61
+ * onboarding need. Every other routable surface lives in the tab area: navigating to it opens (or
62
+ * re-uses) a tab, in whatever workspace the user is standing in. (This flag replaces the retired
63
+ * `group` concept, whose only remaining meaning had been "lives in the tab area".)
64
+ */
65
+ readonly chromeless?: boolean;
66
+ /**
67
+ * Default title for the tab the host opens when navigation lands on this route (a deep link,
68
+ * browser history, `navigateContent`). Falls back to {@link Surface.title} when omitted.
69
+ */
70
+ readonly title?: string;
71
+ /** Default icon for that dynamic tab; falls back to {@link Surface.icon}. */
72
+ readonly icon?: string;
73
+ /** Whether the routable {@link title} is a literal rather than a Transloco key. */
74
+ readonly titleIsLiteral?: boolean;
75
+ /**
76
+ * Nested sub-route segments — the surface's own level-2 tabs, reflected in the URL.
77
+ * Angular syntax, so a segment may carry a value (`'structure/:structureId'`); the bare tab root is a
78
+ * valid address with no forced redirect to the first entry.
79
+ */
80
+ readonly subRoutes?: readonly string[];
81
+ /**
82
+ * Keep this surface's **permanent tab pointing at the current selection**. Its siblings are facets of
83
+ * one choice rather than independent documents: pick a program on one tab and the others should show
84
+ * that program.
85
+ *
86
+ * The host knows the parameter values of the address it is on, because it knows which pattern matched.
87
+ * For a following tab it substitutes those values **by name** into this surface's pattern, and where a
88
+ * value is unknown it truncates the address before it:
89
+ *
90
+ * ```
91
+ * on cedents/US003950/programs/205470/pricing
92
+ * cedents/:cedentId/programs/:programId/treaties → cedents/US003950/programs/205470/treaties
93
+ * cedents/:cedentId/programs/:programId/:reportId → cedents/US003950/programs/205470
94
+ * ```
95
+ *
96
+ * **Off by default**, because the opposite is right for a tab showing one specific document: nobody
97
+ * wants an open quote rewritten because a parameter changed elsewhere. A following surface is drawn
98
+ * as a **permanent facet tab** (labelled by {@link SurfaceBase.title}/`icon`, ordered by
99
+ * {@link SurfaceBase.order}) whenever its computed address leads somewhere — it does not open
100
+ * dynamic tabs. A dynamically opened tab keeps the address it was opened with,
101
+ * and a tab dragged out of the group that carries the browser address freezes where it is — which is
102
+ * what lets a user park one program beside another.
103
+ *
104
+ * Two following surfaces may use the same parameter name only when the pattern **before** it is
105
+ * identical; otherwise the name means two different things and the host would fill one surface's
106
+ * address with the other's value. A collision refuses that one registration with a message.
107
+ */
108
+ readonly follows?: boolean;
109
+ /**
110
+ * Own **everything below** {@link path}: the longest registered prefix wins, and whatever no more
111
+ * specific surface claims is handed to this one as **the rest** — verbatim, **including the query
112
+ * string**. Without it a deeper address matches no route at all and the navigation fails; with it
113
+ * `programs/US003950/pricing?t=886320` reaches the surface registered on `programs` and hands over
114
+ * `US003950/pricing?t=886320`.
115
+ *
116
+ * The prefix stays the **tab root**, so the whole subtree is one tab whose state survives every move
117
+ * within it. That is the trade the flag buys you: what you put *in the rest* changes without
118
+ * rebuilding the surface, what you put *in the pattern* is a parameter change and may rebuild it.
119
+ *
120
+ * How the rest reaches you depends on the rung. A **sandboxed** surface receives it over its channel
121
+ * (`state.rest`) and sets its own with the channel's `navigate` — both confined to this prefix. A
122
+ * **trusted** component reads it the ordinary Angular way (its child `ActivatedRoute`/the router) and
123
+ * navigates with the router.
124
+ *
125
+ * A prefix of **fewer than two segments** owns most of the address space, which is where the surface
126
+ * channel's "confined to your own territory" guarantee stops meaning anything — declaring it there
127
+ * additionally requires the `navigation` capability.
128
+ */
129
+ readonly rest?: boolean;
130
+ }
131
+ /** The metadata every surface form shares, independent of its presentation. */
132
+ export interface SurfaceBase {
133
+ /** Stable id (ordering, active selection, override/removal, per-instance `VIEW_STATE` key). */
134
+ readonly id: string;
135
+ /** Transloco key (or literal) for the surface title (its tab label + panel header). */
136
+ readonly title: string;
137
+ /** Icon name — resolved by the host icon registry (a plain string). */
138
+ readonly icon?: string;
139
+ /** Lower renders first among sibling surfaces in a dock (default 0). */
140
+ readonly order?: number;
141
+ /** The surface's own header actions, shown in the pane header while active (ex `View.actions`). */
142
+ readonly actions?: readonly ViewAction[];
143
+ /**
144
+ * Declarative auth gating: the host hides/disables/placeholders the surface when the current
145
+ * session does not meet the requirement. Presentation only — real enforcement is server-side. Omit for a
146
+ * surface everyone sees.
147
+ */
148
+ readonly access?: AccessRequirement;
149
+ /**
150
+ * Opt in to **named saved instances**: the host shows a switcher so the user can save,
151
+ * name, rename and delete several configurations of this surface, each with its own `VIEW_STATE` blob.
152
+ */
153
+ readonly instanceable?: boolean;
154
+ /**
155
+ * The **routable** capability — provide to let this surface hold the URL pane. A surface
156
+ * with `routable` is reached by its `path`; one without is host-rendered workspace state only.
157
+ */
158
+ readonly routable?: SurfaceRoutable;
159
+ /**
160
+ * Retention when the surface is **hidden** — rendered by no pane of this window: a tab switch, a
161
+ * minimised or closed pane, a collapsed sidebar, the closed compact drawer. The default is
162
+ * the distribution's retention default (`provideShell({ retention })`), which itself
163
+ * defaults to **destroy**: a hidden, clean surface is destroyed and rebuilt on return — state that
164
+ * must survive belongs in `VIEW_STATE`. Declare `'always'` to keep the instance alive while hidden
165
+ * (an expensive rebuild, a live connection); `'never'` to opt back into destruction when the
166
+ * distribution flipped the default. The declaration wins over the distribution default. A retained
167
+ * **`iframe` surface is hidden in place** rather than destroyed (no reload, no new Penpal
168
+ * handshake) but is still rebuilt whenever it would have to *move* — a split, a drag into another
169
+ * pane, a minimise — because moving an `<iframe>` element in the DOM reloads it. `container`
170
+ * surfaces are always rebuilt.
171
+ */
172
+ readonly retain?: 'always' | 'never';
173
+ /**
174
+ * Auto-save on hiding: when an instance of this surface becomes hidden while its
175
+ * {@link DirtySurface.surfaceDirty} reports unsaved changes, the host calls its
176
+ * {@link DirtySurface.surfaceSave} fire-and-forget — the gesture stays instant. Safe by
177
+ * construction: while the save is in flight the instance is still dirty and therefore still
178
+ * alive; a failure keeps it dirty and surfaces as an error, never as silent loss. Only
179
+ * meaningful for a surface whose component implements {@link DirtySurface} with a save.
180
+ */
181
+ readonly saveOn?: 'hide';
182
+ /**
183
+ * Whether a tab of this surface may be closed by the user — the × affordance, the `Delete` key and
184
+ * the close entries of the tab menu. Defaults to `true`; declare `false` for the overview screen a
185
+ * product wants to keep open while its other tabs come and go.
186
+ *
187
+ * It applies to **every** tab of this surface, so it fits a parameterless route like `dashboard`
188
+ * and is almost always wrong for `doc/:id`, where it would make no document closable at all. The
189
+ * user can still move such a tab, split it and drag it elsewhere; only closing is refused.
190
+ */
191
+ readonly closable?: boolean;
192
+ /**
193
+ * Whether the host insets this surface from its pane edges. Defaults to `true` — comfortable for the
194
+ * prose, forms and lists most surfaces are. Declare `false` for a surface that **is** the content and
195
+ * owns its own edges: a viewer, a canvas, a map, an edge-to-edge table. It travels with the surface,
196
+ * so it holds wherever the user puts it — the URL pane, a split, a sidebar, a pop-out window.
197
+ *
198
+ * Only the inset is yours to switch off; how wide it is stays a styling question, so a product that
199
+ * wants a different amount everywhere writes plain unlayered CSS rather than asking for a token.
200
+ */
201
+ readonly padded?: boolean;
202
+ /**
203
+ * Which docks (region ids, e.g. `'primary'`/`'secondary'`, or `'content'`) this surface may be hosted in
204
+ * — capabilities, not location: the *user* decides where a surface finally lands. The first
205
+ * entry is the surface's **home** dock (where a non-routable surface first appears). Omit only for a
206
+ * routable surface (its home is the content area); a non-routable surface **must** declare `docks` —
207
+ * the host fails fast at registration otherwise. A non-routable surface with an **empty** `docks: []`
208
+ * is a **container-only child**: it is never seeded into a panel and exists only to be
209
+ * mounted inside a container's nested pane tree by id.
210
+ */
211
+ readonly docks?: readonly string[];
212
+ }
213
+ /**
214
+ * The **one author contract**: a plugin contributes a `Surface` and declares *what it can do*
215
+ * (routable · instanceable · which docks) rather than *where it lives* — the user decides placement.
216
+ * This is the convergence of the two older contracts, {@link View} (a component docked in a Panel region)
217
+ * and {@link ContentRoute} (a URL-addressed content view), which the host still uses internally as its
218
+ * storage shapes. Register it with `ctx.registerSurface`.
219
+ */
220
+ export type Surface = SurfaceBase & SurfacePresentation;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.js","sourceRoot":"","sources":["../../../../../../libs/core/plugin-sdk/src/lib/surface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ /**
3
+ * An instance-scoped handle a mounted view uses to read and persist its **own** serialisable state — the
4
+ * chosen view + filters, scroll position, expanded nodes. The platform stays
5
+ * domain-pure: it stores an opaque blob and only this view interprets it.
6
+ *
7
+ * Since a hidden surface is destroyed as soon as it is clean, this is the survival path:
8
+ * anything that must outlive a tab switch, a collapsed sidebar or an F5 belongs here — the rule to author
9
+ * by is *evictable = reload-safe*.
10
+ *
11
+ * Reads are Signal-shaped (`() => T`) so a template re-reads reactively (the same convention as
12
+ * `PluginSession`); writes are auto-saved by the host (debounced) — the view never touches storage, and
13
+ * a fresh instance simply reads `undefined` and applies its own default.
14
+ *
15
+ * The host provides one handle per mounted **docked** surface instance. A **routable** surface has none:
16
+ * its shareable state belongs in the URL it already owns (route params, `subRoutes`), and unsaved work is
17
+ * carried by `DirtySurface` or a `retain` declaration. A **sandboxed** surface has none either — nothing
18
+ * of this shape crosses the RPC boundary; it declares `retain: 'always'` instead, and the host hides the
19
+ * iframe in place rather than destroying it, so the document keeps its own state.
20
+ */
21
+ export interface ViewState<T = unknown> {
22
+ /** The instance's saved state, reactive; `undefined` for a fresh instance (apply your own default). */
23
+ readonly value: () => T | undefined;
24
+ /**
25
+ * Replace the state; the host auto-saves it to the active instance. Call it freely — writes are
26
+ * debounced. It replaces the **whole** blob, so spread the current value when you change one field.
27
+ */
28
+ set(next: T): void;
29
+ /** The id of the instance this view is bound to. */
30
+ readonly instanceId: string;
31
+ }
32
+ /**
33
+ * DI token for the mounted view's {@link ViewState}. A docked view injects it, typing the state to its
34
+ * own shape: `const vs = inject(VIEW_STATE) as ViewState<MyState>`. The host provides one per instance.
35
+ * Injecting it from a routable or sandboxed surface throws — see {@link ViewState} for what those do
36
+ * instead.
37
+ */
38
+ export declare const VIEW_STATE: InjectionToken<ViewState<unknown>>;
@@ -0,0 +1,9 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ /**
3
+ * DI token for the mounted view's {@link ViewState}. A docked view injects it, typing the state to its
4
+ * own shape: `const vs = inject(VIEW_STATE) as ViewState<MyState>`. The host provides one per instance.
5
+ * Injecting it from a routable or sandboxed surface throws — see {@link ViewState} for what those do
6
+ * instead.
7
+ */
8
+ export const VIEW_STATE = new InjectionToken('lw.view-state');
9
+ //# sourceMappingURL=view-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-state.js","sourceRoot":"","sources":["../../../../../../libs/core/plugin-sdk/src/lib/view-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAiC/C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,cAAc,CAAY,eAAe,CAAC,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { Type } from '@angular/core';
2
+ import { AccessRequirement } from './auth.js';
3
+ /**
4
+ * A view's own header action (`header.actions`) — an independent function
5
+ * of that view (e.g. "new", "sort"), shown in the panel header while the view is
6
+ * active. Not a view switcher (that is the Rail). Mirrors Obsidian's view actions.
7
+ */
8
+ export interface ViewAction {
9
+ readonly id: string;
10
+ /** Icon name — resolved by the host icon registry (a plain string). */
11
+ readonly icon: string;
12
+ /** Transloco key (or literal) for the tooltip/label. */
13
+ readonly title: string;
14
+ /** Lower renders first (default 0). */
15
+ readonly order?: number;
16
+ /**
17
+ * Id of a menu slot to open as this action's **context menu** on right-click — region-agnostic:
18
+ * the host wires the right-click uniformly and passes a serialisable context (`{ targetKind, id, region }`).
19
+ * Contribute items to the slot with `ctx.registerMenuItem({ menu, … })`. Omit for no context menu.
20
+ */
21
+ readonly menu?: string;
22
+ /**
23
+ * Id of a registered {@link Command} this action triggers. Provide this **or** {@link run}; when
24
+ * set, the host runs that command (so a keybinding/palette can share the same behaviour).
25
+ */
26
+ readonly command?: string;
27
+ /**
28
+ * Declarative auth gating: the host hides (default) or disables this action when the
29
+ * current session does not meet the requirement. Presentation only — real enforcement is
30
+ * server-side. Omit for an action everyone sees.
31
+ */
32
+ readonly access?: AccessRequirement;
33
+ /**
34
+ * Inline behaviour, for an action that is not backed by a registered command. May be async; the
35
+ * host fires it fire-and-forget. Typed `() => void` so a one-expression arrow whose handler
36
+ * happens to return a value (e.g. `() => ctx.ui.openSettings()`) still assigns — the return is
37
+ * ignored either way.
38
+ */
39
+ run?(): void;
40
+ }
41
+ /**
42
+ * A view docked into a **Panel** region (chrome-local, auto-tabbed by the host) — the host's internal
43
+ * shape for a **non-routable** {@link Surface}. Authors do not build one directly: contribute a
44
+ * `Surface` via `ctx.registerSurface` and the host normalises it into this.
45
+ */
46
+ export interface View {
47
+ /** Stable id (ordering, active-view selection, future removal). */
48
+ readonly id: string;
49
+ /** Target region id this view docks into. */
50
+ readonly region: string;
51
+ /** Transloco key (or literal) for the view title. */
52
+ readonly title: string;
53
+ /** Lower renders/launchers first within a region (default 0). */
54
+ readonly order?: number;
55
+ /** Icon name for this view's tab in the panel's tab bar. */
56
+ readonly icon?: string;
57
+ /** The view's own header actions, shown in the panel header while active. */
58
+ readonly actions?: readonly ViewAction[];
59
+ /**
60
+ * Declarative auth gating: the host **hides** the whole view (its tab and body) when
61
+ * the current session does not meet the requirement. A view is present or not, so `mode` is
62
+ * ignored here (unlike a button, a disabled tab is not a useful state). Presentation only — real
63
+ * enforcement is server-side. Omit for a view everyone sees.
64
+ */
65
+ readonly access?: AccessRequirement;
66
+ /**
67
+ * Opt in to **named saved instances**: the host shows a switcher in the view
68
+ * header so the user can save, name, rename and delete several configurations of this view, each with
69
+ * its own `VIEW_STATE` blob (auto-saved). The non-deletable *default* instance carries the view's
70
+ * baseline state. Omit for a single implicit instance (the view's own `VIEW_STATE`).
71
+ */
72
+ readonly instanceable?: boolean;
73
+ /**
74
+ * Retention when the view is hidden — carried through from {@link Surface.retain}.
75
+ * `'always'` keeps the instance alive while hidden; `'never'` forces destruction; omitted falls back
76
+ * to the distribution's retention default (destroy).
77
+ */
78
+ readonly retain?: 'always' | 'never';
79
+ /**
80
+ * Auto-save on hiding — carried through from {@link Surface.saveOn}: a hidden dirty
81
+ * instance's `surfaceSave` is called fire-and-forget.
82
+ */
83
+ readonly saveOn?: 'hide';
84
+ /** Whether the user may close a tab of this view — carried through from {@link Surface.closable}. */
85
+ readonly closable?: boolean;
86
+ /**
87
+ * Whether the host insets this surface from its pane edges (default `true`). Declare `false` for a
88
+ * surface that owns its own edges — a viewer, a canvas, a map, an edge-to-edge table. See
89
+ * `SurfaceBase.padded`.
90
+ */
91
+ readonly padded?: boolean;
92
+ /** Component the host renders as the view body. */
93
+ readonly component?: Type<unknown>;
94
+ /** Deferred alternative to {@link component} — the host calls it the first time the view is shown. */
95
+ readonly loadComponent?: () => Promise<Type<unknown>>;
96
+ /**
97
+ * A URL the host mounts as an **isolated** `<iframe sandbox>` view body — the same presentation form a
98
+ * routable surface may take, now valid at a dock too. A docked surface has no address, so
99
+ * its channel's `navigate` is a no-op with a development warning and it is told no tab or sub-route;
100
+ * everything else it receives (locale, theme, tokens, text size, session, its instance id) is unchanged.
101
+ */
102
+ readonly iframe?: string;
103
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../../../../../../libs/core/plugin-sdk/src/lib/view.ts"],"names":[],"mappings":""}