sh3-core 0.7.5 → 0.8.1
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.
- package/dist/api.d.ts +12 -2
- package/dist/api.js +13 -1
- package/dist/app/admin/SystemView.svelte +149 -11
- package/dist/app/store/StoreView.svelte +36 -7
- package/dist/app/store/storeShard.svelte.js +9 -3
- package/dist/app/store/verbs.js +8 -2
- package/dist/apps/lifecycle.d.ts +11 -0
- package/dist/apps/lifecycle.js +21 -1
- package/dist/apps/lifecycle.test.js +50 -1
- package/dist/apps/types.d.ts +7 -2
- package/dist/createShell.d.ts +2 -0
- package/dist/createShell.js +9 -7
- package/dist/documents/backends.d.ts +8 -0
- package/dist/documents/backends.js +87 -0
- package/dist/documents/backends.test.d.ts +1 -0
- package/dist/documents/backends.test.js +33 -0
- package/dist/documents/browse.d.ts +12 -0
- package/dist/documents/browse.js +19 -0
- package/dist/documents/browse.test.d.ts +1 -0
- package/dist/documents/browse.test.js +41 -0
- package/dist/documents/handle.js +5 -0
- package/dist/documents/http-backend.d.ts +4 -0
- package/dist/documents/http-backend.js +14 -0
- package/dist/documents/index.d.ts +1 -0
- package/dist/documents/index.js +1 -0
- package/dist/documents/journal-hook.d.ts +6 -0
- package/dist/documents/journal-hook.js +16 -0
- package/dist/documents/sync/activate-integration.test.d.ts +1 -0
- package/dist/documents/sync/activate-integration.test.js +37 -0
- package/dist/documents/sync/components/DocumentSyncExplorer.svelte +99 -0
- package/dist/documents/sync/components/DocumentSyncExplorer.svelte.d.ts +15 -0
- package/dist/documents/sync/components/SyncGrantPicker.svelte +70 -0
- package/dist/documents/sync/components/SyncGrantPicker.svelte.d.ts +12 -0
- package/dist/documents/sync/conflicts.d.ts +30 -0
- package/dist/documents/sync/conflicts.js +77 -0
- package/dist/documents/sync/conflicts.test.d.ts +1 -0
- package/dist/documents/sync/conflicts.test.js +71 -0
- package/dist/documents/sync/engine.d.ts +19 -0
- package/dist/documents/sync/engine.js +188 -0
- package/dist/documents/sync/engine.test.d.ts +1 -0
- package/dist/documents/sync/engine.test.js +169 -0
- package/dist/documents/sync/handle.d.ts +11 -0
- package/dist/documents/sync/handle.js +79 -0
- package/dist/documents/sync/handle.test.d.ts +1 -0
- package/dist/documents/sync/handle.test.js +56 -0
- package/dist/documents/sync/hash.d.ts +1 -0
- package/dist/documents/sync/hash.js +13 -0
- package/dist/documents/sync/hash.test.d.ts +1 -0
- package/dist/documents/sync/hash.test.js +20 -0
- package/dist/documents/sync/index.d.ts +5 -0
- package/dist/documents/sync/index.js +10 -0
- package/dist/documents/sync/journal.d.ts +30 -0
- package/dist/documents/sync/journal.js +179 -0
- package/dist/documents/sync/journal.test.d.ts +1 -0
- package/dist/documents/sync/journal.test.js +87 -0
- package/dist/documents/sync/observer.d.ts +3 -0
- package/dist/documents/sync/observer.js +45 -0
- package/dist/documents/sync/registry.d.ts +13 -0
- package/dist/documents/sync/registry.js +73 -0
- package/dist/documents/sync/registry.test.d.ts +1 -0
- package/dist/documents/sync/registry.test.js +53 -0
- package/dist/documents/sync/serialization.d.ts +5 -0
- package/dist/documents/sync/serialization.js +24 -0
- package/dist/documents/sync/serialization.test.d.ts +1 -0
- package/dist/documents/sync/serialization.test.js +26 -0
- package/dist/documents/sync/singleton.d.ts +11 -0
- package/dist/documents/sync/singleton.js +26 -0
- package/dist/documents/sync/tombstones.d.ts +19 -0
- package/dist/documents/sync/tombstones.js +58 -0
- package/dist/documents/sync/tombstones.test.d.ts +1 -0
- package/dist/documents/sync/tombstones.test.js +37 -0
- package/dist/documents/sync/types.d.ts +116 -0
- package/dist/documents/sync/types.js +27 -0
- package/dist/documents/sync/write-hook.test.d.ts +1 -0
- package/dist/documents/sync/write-hook.test.js +36 -0
- package/dist/documents/types.d.ts +18 -0
- package/dist/documents/types.js +6 -1
- package/dist/env/client.d.ts +10 -5
- package/dist/env/client.js +12 -4
- package/dist/layout/inspection.d.ts +17 -0
- package/dist/layout/inspection.js +53 -0
- package/dist/registry/installer.d.ts +10 -7
- package/dist/registry/installer.js +39 -35
- package/dist/registry/register.d.ts +17 -0
- package/dist/registry/register.js +22 -0
- package/dist/registry/register.test.d.ts +1 -0
- package/dist/registry/register.test.js +28 -0
- package/dist/shards/activate-browse.test.d.ts +1 -0
- package/dist/shards/activate-browse.test.js +36 -0
- package/dist/shards/activate-sync-registry.test.d.ts +1 -0
- package/dist/shards/activate-sync-registry.test.js +42 -0
- package/dist/shards/activate-tenantid.test.d.ts +1 -0
- package/dist/shards/activate-tenantid.test.js +21 -0
- package/dist/shards/activate.svelte.d.ts +12 -0
- package/dist/shards/activate.svelte.js +53 -2
- package/dist/shards/types.d.ts +43 -1
- package/dist/shell-shard/Terminal.svelte +140 -33
- package/dist/shell-shard/Terminal.svelte.d.ts +3 -0
- package/dist/shell-shard/auto-relocate.d.ts +12 -0
- package/dist/shell-shard/auto-relocate.js +20 -0
- package/dist/shell-shard/auto-relocate.test.d.ts +1 -0
- package/dist/shell-shard/auto-relocate.test.js +35 -0
- package/dist/shell-shard/dispatch.d.ts +15 -0
- package/dist/shell-shard/dispatch.js +56 -0
- package/dist/shell-shard/manifest.js +1 -1
- package/dist/shell-shard/modes/builtin.d.ts +5 -0
- package/dist/shell-shard/modes/builtin.js +18 -0
- package/dist/shell-shard/modes/prefs.d.ts +5 -0
- package/dist/shell-shard/modes/prefs.js +31 -0
- package/dist/shell-shard/modes/prefs.test.d.ts +1 -0
- package/dist/shell-shard/modes/prefs.test.js +46 -0
- package/dist/shell-shard/modes/registry.d.ts +7 -0
- package/dist/shell-shard/modes/registry.js +27 -0
- package/dist/shell-shard/modes/registry.test.d.ts +1 -0
- package/dist/shell-shard/modes/registry.test.js +35 -0
- package/dist/shell-shard/modes/types.d.ts +8 -0
- package/dist/shell-shard/modes/types.js +1 -0
- package/dist/shell-shard/protocol.d.ts +6 -0
- package/dist/shell-shard/shellShard.svelte.js +57 -5
- package/dist/shell-shard/tenant-fs-client.d.ts +24 -0
- package/dist/shell-shard/tenant-fs-client.js +44 -0
- package/dist/shell-shard/tenant-fs-client.test.d.ts +1 -0
- package/dist/shell-shard/tenant-fs-client.test.js +49 -0
- package/dist/shell-shard/terminal-dispatch.test.d.ts +1 -0
- package/dist/shell-shard/terminal-dispatch.test.js +53 -0
- package/dist/shell-shard/toolbar/Toolbar.svelte +62 -0
- package/dist/shell-shard/toolbar/Toolbar.svelte.d.ts +11 -0
- package/dist/shell-shard/toolbar/slots/FocusLockSlot.svelte +28 -0
- package/dist/shell-shard/toolbar/slots/FocusLockSlot.svelte.d.ts +7 -0
- package/dist/shell-shard/toolbar/slots/ModeSlot.svelte +102 -0
- package/dist/shell-shard/toolbar/slots/ModeSlot.svelte.d.ts +11 -0
- package/dist/shell-shard/toolbar/slots/TargetShardSlot.svelte +17 -0
- package/dist/shell-shard/toolbar/slots/TargetShardSlot.svelte.d.ts +6 -0
- package/dist/shell-shard/toolbar/slots.d.ts +17 -0
- package/dist/shell-shard/toolbar/slots.js +26 -0
- package/dist/shell-shard/toolbar/slots.test.d.ts +1 -0
- package/dist/shell-shard/toolbar/slots.test.js +28 -0
- package/dist/shell-shard/verbs/cat.d.ts +2 -0
- package/dist/shell-shard/verbs/cat.js +34 -0
- package/dist/shell-shard/verbs/cd.test.d.ts +1 -0
- package/dist/shell-shard/verbs/cd.test.js +56 -0
- package/dist/shell-shard/verbs/env.d.ts +2 -0
- package/dist/shell-shard/verbs/env.js +14 -0
- package/dist/shell-shard/verbs/index.js +9 -2
- package/dist/shell-shard/verbs/ls.d.ts +2 -0
- package/dist/shell-shard/verbs/ls.js +29 -0
- package/dist/shell-shard/verbs/ls.test.d.ts +1 -0
- package/dist/shell-shard/verbs/ls.test.js +49 -0
- package/dist/shell-shard/verbs/session.d.ts +0 -1
- package/dist/shell-shard/verbs/session.js +58 -26
- package/dist/shell-shard/verbs/views.d.ts +2 -0
- package/dist/shell-shard/verbs/views.js +103 -2
- package/dist/verbs/types.d.ts +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -14,9 +14,16 @@ export type { StateZones } from './state/zones.svelte';
|
|
|
14
14
|
export type { EnvState } from './env/types';
|
|
15
15
|
export type { App, AppManifest, SourceApp, SourceAppManifest, AppContext, } from './apps/types';
|
|
16
16
|
export { listRegisteredApps, getActiveApp } from './apps/registry.svelte';
|
|
17
|
-
export { launchApp, returnToHome } from './apps/lifecycle';
|
|
17
|
+
export { launchApp, returnToHome, unregisterApp } from './apps/lifecycle';
|
|
18
18
|
export { inspectActiveLayout, spliceIntoActiveLayout, dockIntoActiveLayout, focusTab, focusView, collapseChild, expandChild, closeTab, } from './layout/inspection';
|
|
19
19
|
export type { DocumentHandle, DocumentHandleOptions, DocumentFormat, DocumentMeta, DocumentChange, AutosaveController, } from './documents/types';
|
|
20
|
+
export { PERMISSION_DOCUMENTS_BROWSE } from './documents/types';
|
|
21
|
+
export type { BrowseCapability } from './documents/browse';
|
|
22
|
+
export type { SyncHandle, SyncScope, ManifestEntry, ApplyEntry, ApplyOpts, ApplyOutcome, ApplyBatchResult, ConflictPolicy, ConflictResolution, ConflictContext, JournalEntry, ChangePage, GrantRecord, } from './documents/sync/types';
|
|
23
|
+
export { PERMISSION_DOCUMENTS_SYNC, ScopeNotGrantedError, ScopeRevokedError, TenantMismatchError, } from './documents/sync/types';
|
|
24
|
+
export type { SyncRegistry } from './documents/sync/registry';
|
|
25
|
+
export { default as SyncGrantPicker } from './documents/sync/components/SyncGrantPicker.svelte';
|
|
26
|
+
export { default as DocumentSyncExplorer } from './documents/sync/components/DocumentSyncExplorer.svelte';
|
|
20
27
|
export { registeredShards, activeShards } from './shards/activate.svelte';
|
|
21
28
|
export type { RegistryIndex, PackageEntry, PackageVersion, RequiredDependency, InstalledPackage, InstallResult, PackageMeta, } from './registry/types';
|
|
22
29
|
export type { ResolvedPackage } from './registry/client';
|
|
@@ -30,7 +37,10 @@ export declare const capabilities: {
|
|
|
30
37
|
readonly hotInstall: boolean;
|
|
31
38
|
};
|
|
32
39
|
export type { ServerShard, ServerShardContext } from './server-shard/types';
|
|
33
|
-
export type { Verb } from './verbs/types';
|
|
40
|
+
export type { Verb, VerbContext, ShellApi } from './verbs/types';
|
|
41
|
+
export type { Scrollback } from './shell-shard/scrollback.svelte';
|
|
42
|
+
export type { SessionClient } from './shell-shard/session-client.svelte';
|
|
34
43
|
export { listVerbs } from './shards/registry';
|
|
35
44
|
export { VERSION } from './version';
|
|
45
|
+
export declare const FRAMEWORK_SHARD_IDS: readonly string[];
|
|
36
46
|
export { setTokenOverrides, clearTokenOverrides, getTokenOverrides, } from './theme';
|
package/dist/api.js
CHANGED
|
@@ -26,9 +26,13 @@ export { shell } from './shellRuntime.svelte';
|
|
|
26
26
|
export { PERMISSION_STATE_MANAGE } from './state/types';
|
|
27
27
|
// Host actions callable from inside views (shell home, status bar, etc.).
|
|
28
28
|
export { listRegisteredApps, getActiveApp } from './apps/registry.svelte';
|
|
29
|
-
export { launchApp, returnToHome } from './apps/lifecycle';
|
|
29
|
+
export { launchApp, returnToHome, unregisterApp } from './apps/lifecycle';
|
|
30
30
|
// Layout inspection / mutation for advanced shards (diagnostic, etc.).
|
|
31
31
|
export { inspectActiveLayout, spliceIntoActiveLayout, dockIntoActiveLayout, focusTab, focusView, collapseChild, expandChild, closeTab, } from './layout/inspection';
|
|
32
|
+
export { PERMISSION_DOCUMENTS_BROWSE } from './documents/types';
|
|
33
|
+
export { PERMISSION_DOCUMENTS_SYNC, ScopeNotGrantedError, ScopeRevokedError, TenantMismatchError, } from './documents/sync/types';
|
|
34
|
+
export { default as SyncGrantPicker } from './documents/sync/components/SyncGrantPicker.svelte';
|
|
35
|
+
export { default as DocumentSyncExplorer } from './documents/sync/components/DocumentSyncExplorer.svelte';
|
|
32
36
|
// Shard introspection — read-only reactive maps exposing which shards are
|
|
33
37
|
// known to the host and which are currently active. Intended for diagnostic
|
|
34
38
|
// and tooling shards that need to visualize framework state. Phase 9
|
|
@@ -47,5 +51,13 @@ export const capabilities = {
|
|
|
47
51
|
export { listVerbs } from './shards/registry';
|
|
48
52
|
// Package version.
|
|
49
53
|
export { VERSION } from './version';
|
|
54
|
+
// Framework shard IDs — shards that are always present (built-in to sh3-core).
|
|
55
|
+
// Used by the store UI to skip dependency checks for these well-known shards.
|
|
56
|
+
export const FRAMEWORK_SHARD_IDS = [
|
|
57
|
+
'__sh3core__',
|
|
58
|
+
'shell',
|
|
59
|
+
'sh3-store',
|
|
60
|
+
'sh3-admin',
|
|
61
|
+
];
|
|
50
62
|
// Theme token override API (shell-level theming support).
|
|
51
63
|
export { setTokenOverrides, clearTokenOverrides, getTokenOverrides, } from './theme';
|
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
* Admin System view — server status and
|
|
3
|
+
* Admin System view — server status, restart, and package-bundle cache policy.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
const SNAP_POINTS: Array<{ value: number; label: string }> = [
|
|
7
|
+
{ value: 0, label: 'Off (no-store)' },
|
|
8
|
+
{ value: 5, label: '5s (dev)' },
|
|
9
|
+
{ value: 60, label: '1 min' },
|
|
10
|
+
{ value: 3600, label: '1 hour' },
|
|
11
|
+
{ value: 86400, label: '1 day' },
|
|
12
|
+
{ value: 31536000, label: '1 year' },
|
|
13
|
+
];
|
|
14
|
+
|
|
6
15
|
let version = $state('...');
|
|
7
16
|
let restarting = $state(false);
|
|
8
17
|
let restartError = $state<string | null>(null);
|
|
9
18
|
|
|
19
|
+
let cacheMaxAge = $state(31536000);
|
|
20
|
+
let loadedMaxAge = $state(31536000);
|
|
21
|
+
let savingCache = $state(false);
|
|
22
|
+
let cacheError = $state<string | null>(null);
|
|
23
|
+
|
|
24
|
+
const dirty = $derived(cacheMaxAge !== loadedMaxAge);
|
|
25
|
+
const humanized = $derived(humanize(cacheMaxAge));
|
|
26
|
+
|
|
27
|
+
function humanize(sec: number): string {
|
|
28
|
+
if (sec === 0) return '0 seconds (off — browsers never cache)';
|
|
29
|
+
if (sec < 60) return `${sec} seconds`;
|
|
30
|
+
if (sec < 3600) return `${Math.round(sec / 60)} minutes`;
|
|
31
|
+
if (sec < 86400) return `${Math.round(sec / 3600)} hours`;
|
|
32
|
+
if (sec < 31536000) return `${Math.round(sec / 86400)} days`;
|
|
33
|
+
return `${Math.round(sec / 31536000)} years`;
|
|
34
|
+
}
|
|
35
|
+
|
|
10
36
|
async function fetchVersion() {
|
|
11
37
|
try {
|
|
12
38
|
const res = await fetch('/api/version');
|
|
@@ -17,6 +43,43 @@
|
|
|
17
43
|
} catch { /* ignore */ }
|
|
18
44
|
}
|
|
19
45
|
|
|
46
|
+
async function fetchSettings() {
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch('/api/admin/settings', { credentials: 'include' });
|
|
49
|
+
if (res.ok) {
|
|
50
|
+
const body = await res.json();
|
|
51
|
+
const age = body.packages?.cacheMaxAge ?? 31536000;
|
|
52
|
+
cacheMaxAge = age;
|
|
53
|
+
loadedMaxAge = age;
|
|
54
|
+
}
|
|
55
|
+
} catch { /* ignore */ }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function saveCache() {
|
|
59
|
+
savingCache = true;
|
|
60
|
+
cacheError = null;
|
|
61
|
+
try {
|
|
62
|
+
const res = await fetch('/api/admin/settings', {
|
|
63
|
+
method: 'PUT',
|
|
64
|
+
credentials: 'include',
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
body: JSON.stringify({ packages: { cacheMaxAge } }),
|
|
67
|
+
});
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
const body = await res.json().catch(() => ({}));
|
|
70
|
+
cacheError = body.error || 'Save failed';
|
|
71
|
+
} else {
|
|
72
|
+
const body = await res.json();
|
|
73
|
+
loadedMaxAge = body.packages?.cacheMaxAge ?? cacheMaxAge;
|
|
74
|
+
cacheMaxAge = loadedMaxAge;
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
cacheError = 'Network error';
|
|
78
|
+
} finally {
|
|
79
|
+
savingCache = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
20
83
|
async function restart() {
|
|
21
84
|
restarting = true;
|
|
22
85
|
restartError = null;
|
|
@@ -38,6 +101,7 @@
|
|
|
38
101
|
}
|
|
39
102
|
|
|
40
103
|
fetchVersion();
|
|
104
|
+
fetchSettings();
|
|
41
105
|
</script>
|
|
42
106
|
|
|
43
107
|
<div class="admin-system">
|
|
@@ -50,24 +114,98 @@
|
|
|
50
114
|
</div>
|
|
51
115
|
</div>
|
|
52
116
|
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
117
|
+
<section class="admin-system-section">
|
|
118
|
+
<h3>Package bundle cache</h3>
|
|
119
|
+
<p class="admin-system-hint">
|
|
120
|
+
Controls the <code>Cache-Control</code> header on <code>/packages/:id/client.js</code>.
|
|
121
|
+
Set to <strong>0</strong> during development so drop-in bundle replacements take effect on F5.
|
|
122
|
+
Use a long value in production.
|
|
123
|
+
</p>
|
|
124
|
+
|
|
125
|
+
<input
|
|
126
|
+
type="range"
|
|
127
|
+
min="0"
|
|
128
|
+
max="31536000"
|
|
129
|
+
step="1"
|
|
130
|
+
bind:value={cacheMaxAge}
|
|
131
|
+
disabled={savingCache}
|
|
132
|
+
/>
|
|
133
|
+
<div class="admin-system-readout">
|
|
134
|
+
<code>{cacheMaxAge}</code> — {humanized}
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<div class="admin-system-snaps">
|
|
138
|
+
{#each SNAP_POINTS as snap (snap.value)}
|
|
139
|
+
<button
|
|
140
|
+
type="button"
|
|
141
|
+
class="admin-snap"
|
|
142
|
+
class:active={cacheMaxAge === snap.value}
|
|
143
|
+
onclick={() => (cacheMaxAge = snap.value)}
|
|
144
|
+
disabled={savingCache}
|
|
145
|
+
>
|
|
146
|
+
{snap.label}
|
|
147
|
+
</button>
|
|
148
|
+
{/each}
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div class="admin-system-actions">
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
class="admin-btn"
|
|
155
|
+
onclick={saveCache}
|
|
156
|
+
disabled={!dirty || savingCache}
|
|
157
|
+
>
|
|
158
|
+
{savingCache ? 'Saving...' : 'Save'}
|
|
159
|
+
</button>
|
|
160
|
+
<button
|
|
161
|
+
type="button"
|
|
162
|
+
class="admin-btn-ghost"
|
|
163
|
+
onclick={() => (cacheMaxAge = loadedMaxAge)}
|
|
164
|
+
disabled={!dirty || savingCache}
|
|
165
|
+
>
|
|
166
|
+
Reset
|
|
167
|
+
</button>
|
|
168
|
+
{#if cacheError}
|
|
169
|
+
<div class="admin-error">{cacheError}</div>
|
|
170
|
+
{/if}
|
|
171
|
+
</div>
|
|
172
|
+
</section>
|
|
173
|
+
|
|
174
|
+
<section class="admin-system-section">
|
|
175
|
+
<h3>Server control</h3>
|
|
176
|
+
<div class="admin-system-actions">
|
|
177
|
+
<button type="button" class="admin-btn-danger" onclick={restart} disabled={restarting}>
|
|
178
|
+
{restarting ? 'Restarting...' : 'Restart server'}
|
|
179
|
+
</button>
|
|
180
|
+
{#if restartError}
|
|
181
|
+
<div class="admin-error">{restartError}</div>
|
|
182
|
+
{/if}
|
|
183
|
+
</div>
|
|
184
|
+
</section>
|
|
61
185
|
</div>
|
|
62
186
|
|
|
63
187
|
<style>
|
|
64
188
|
.admin-system { padding: 24px; font-family: system-ui, sans-serif; color: var(--shell-fg); }
|
|
65
189
|
.admin-system h2 { margin: 0 0 16px; font-size: 18px; }
|
|
190
|
+
.admin-system h3 { margin: 0 0 8px; font-size: 14px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--shell-fg-subtle); }
|
|
66
191
|
.admin-system-info { margin-bottom: 24px; }
|
|
67
192
|
.admin-system-row { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--shell-border, #3a3a5c); font-size: 13px; }
|
|
68
193
|
.admin-system-label { color: var(--shell-fg-subtle); min-width: 140px; }
|
|
69
|
-
.admin-system-
|
|
70
|
-
.admin-
|
|
194
|
+
.admin-system-section { margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid var(--shell-border, #3a3a5c); }
|
|
195
|
+
.admin-system-section:last-child { border-bottom: none; }
|
|
196
|
+
.admin-system-hint { font-size: 13px; color: var(--shell-fg-subtle); margin: 0 0 12px; }
|
|
197
|
+
.admin-system-readout { font-size: 13px; margin: 8px 0 12px; }
|
|
198
|
+
.admin-system-snaps { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
|
|
199
|
+
.admin-snap { padding: 4px 10px; font-size: 12px; background: transparent; border: 1px solid var(--shell-border, #3a3a5c); color: var(--shell-fg); cursor: pointer; border-radius: var(--shell-radius-sm, 3px); }
|
|
200
|
+
.admin-snap.active { background: var(--shell-accent, #4a7bd4); color: var(--shell-bg); border-color: var(--shell-accent, #4a7bd4); }
|
|
201
|
+
.admin-snap:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
202
|
+
.admin-system-actions { display: flex; flex-direction: row; gap: 8px; align-items: center; flex-wrap: wrap; }
|
|
203
|
+
.admin-btn { padding: 8px 16px; background: var(--shell-accent, #4a7bd4); color: var(--shell-bg); border: 1px solid var(--shell-accent, #4a7bd4); font-weight: 600; cursor: pointer; border-radius: var(--shell-radius-sm, 3px); }
|
|
204
|
+
.admin-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
205
|
+
.admin-btn-ghost { padding: 8px 16px; background: transparent; color: var(--shell-fg); border: 1px solid var(--shell-border, #3a3a5c); cursor: pointer; border-radius: var(--shell-radius-sm, 3px); }
|
|
206
|
+
.admin-btn-ghost:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
207
|
+
.admin-btn-danger { padding: 8px 16px; background: transparent; color: var(--shell-error, #d32f2f); border: 1px solid var(--shell-error, #d32f2f); font-weight: 600; cursor: pointer; border-radius: var(--shell-radius-sm, 3px); }
|
|
71
208
|
.admin-btn-danger:disabled { opacity: 0.6; cursor: not-allowed; }
|
|
72
209
|
.admin-error { color: var(--shell-error, #d32f2f); font-size: 13px; }
|
|
210
|
+
input[type="range"] { width: 100%; max-width: 480px; }
|
|
73
211
|
</style>
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { contract } from '../../contract';
|
|
14
14
|
import type { ResolvedPackage } from '../../registry/client';
|
|
15
15
|
import type { InstalledPackage } from '../../registry/types';
|
|
16
|
+
import { FRAMEWORK_SHARD_IDS } from '../../api';
|
|
16
17
|
|
|
17
18
|
let search = $state('');
|
|
18
19
|
let typeFilter = $state<'all' | 'shard' | 'app'>('all');
|
|
@@ -75,6 +76,16 @@
|
|
|
75
76
|
return ctx.state.ephemeral.installed.find((p: InstalledPackage) => p.id === id)?.version ?? '';
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
function missingShards(pkg: ResolvedPackage, installed: InstalledPackage[]): string[] {
|
|
80
|
+
const required = pkg.latest.requires?.map((r) => r.id) ?? [];
|
|
81
|
+
if (required.length === 0) return [];
|
|
82
|
+
const known = new Set<string>(FRAMEWORK_SHARD_IDS);
|
|
83
|
+
for (const p of installed) {
|
|
84
|
+
if (p.type === 'shard' || p.type === 'combo') known.add(p.id);
|
|
85
|
+
}
|
|
86
|
+
return required.filter((id: string) => !known.has(id));
|
|
87
|
+
}
|
|
88
|
+
|
|
78
89
|
async function handleUpdate(id: string) {
|
|
79
90
|
if (updatingIds.has(id)) return;
|
|
80
91
|
|
|
@@ -118,6 +129,7 @@
|
|
|
118
129
|
version: meta.version,
|
|
119
130
|
contractVersion: meta.contractVersion,
|
|
120
131
|
sourceRegistry: meta.sourceRegistry,
|
|
132
|
+
requiredShards: pkg.latest.requires?.map((r) => r.id) ?? [],
|
|
121
133
|
installedAt: new Date().toISOString(),
|
|
122
134
|
};
|
|
123
135
|
const serverResult = await serverInstallPackage(manifest, bundle, serverBundle);
|
|
@@ -215,6 +227,7 @@
|
|
|
215
227
|
{@const installing = installingIds.has(pkg.entry.id)}
|
|
216
228
|
{@const updatable = hasUpdate(pkg.entry.id)}
|
|
217
229
|
{@const updating = updatingIds.has(pkg.entry.id)}
|
|
230
|
+
{@const missing = missingShards(pkg, ctx.state.ephemeral.installed)}
|
|
218
231
|
<div class="store-card">
|
|
219
232
|
<div class="store-card-header">
|
|
220
233
|
<div class="store-card-icon">
|
|
@@ -253,13 +266,19 @@
|
|
|
253
266
|
{:else if installed}
|
|
254
267
|
<span class="store-installed-label">Installed</span>
|
|
255
268
|
{:else}
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
269
|
+
<div class="store-install-wrap">
|
|
270
|
+
<button
|
|
271
|
+
class="store-install-btn"
|
|
272
|
+
onclick={() => handleInstall(pkg)}
|
|
273
|
+
disabled={installing || missing.length > 0}
|
|
274
|
+
title={missing.length > 0 ? `Missing required shards: ${missing.join(', ')}` : undefined}
|
|
275
|
+
>
|
|
276
|
+
{installing ? 'Installing...' : 'Install'}
|
|
277
|
+
</button>
|
|
278
|
+
{#if missing.length > 0}
|
|
279
|
+
<span class="store-card-missing">requires: {missing.join(', ')}</span>
|
|
280
|
+
{/if}
|
|
281
|
+
</div>
|
|
263
282
|
{/if}
|
|
264
283
|
</div>
|
|
265
284
|
</div>
|
|
@@ -449,6 +468,16 @@
|
|
|
449
468
|
color: var(--shell-success, #4caf50);
|
|
450
469
|
font-weight: 600;
|
|
451
470
|
}
|
|
471
|
+
.store-install-wrap {
|
|
472
|
+
display: flex;
|
|
473
|
+
flex-direction: column;
|
|
474
|
+
align-items: flex-end;
|
|
475
|
+
gap: 4px;
|
|
476
|
+
}
|
|
477
|
+
.store-card-missing {
|
|
478
|
+
font-size: 0.75rem;
|
|
479
|
+
color: var(--shell-warning, #ff9800);
|
|
480
|
+
}
|
|
452
481
|
.store-update-btn {
|
|
453
482
|
padding: 5px 14px;
|
|
454
483
|
background: var(--shell-warning, #ff9800);
|
|
@@ -134,7 +134,7 @@ export const storeShard = {
|
|
|
134
134
|
await ctx.envUpdate({ registries });
|
|
135
135
|
}
|
|
136
136
|
async function updatePackage(id) {
|
|
137
|
-
var _a, _b;
|
|
137
|
+
var _a, _b, _c, _d;
|
|
138
138
|
const catalogEntry = state.ephemeral.updatable[id];
|
|
139
139
|
if (!catalogEntry)
|
|
140
140
|
return;
|
|
@@ -160,10 +160,16 @@ export const storeShard = {
|
|
|
160
160
|
contractVersion: meta.contractVersion,
|
|
161
161
|
sourceRegistry: meta.sourceRegistry,
|
|
162
162
|
installedAt: new Date().toISOString(),
|
|
163
|
+
requiredShards: (_b = (_a = catalogEntry.latest.requires) === null || _a === void 0 ? void 0 : _a.map((r) => r.id)) !== null && _b !== void 0 ? _b : [],
|
|
163
164
|
};
|
|
164
165
|
const serverResult = await serverInstallPackage(manifest, bundle, serverBundle);
|
|
165
166
|
if (!serverResult.ok) {
|
|
166
|
-
|
|
167
|
+
let message = (_c = serverResult.error) !== null && _c !== void 0 ? _c : 'Server update failed';
|
|
168
|
+
if (serverResult.code === 'missing-shards' && serverResult.missing) {
|
|
169
|
+
const ids = serverResult.missing.map((m) => m.id).join(', ');
|
|
170
|
+
message = `missing required shard(s): ${ids}`;
|
|
171
|
+
}
|
|
172
|
+
throw new Error(message);
|
|
167
173
|
}
|
|
168
174
|
// 4. Install locally (overwrites IndexedDB + re-registers).
|
|
169
175
|
const result = await installPackage(bundle, meta);
|
|
@@ -177,7 +183,7 @@ export const storeShard = {
|
|
|
177
183
|
console.warn(`[sh3-store] Rollback failed for "${id}":`, rollbackErr instanceof Error ? rollbackErr.message : rollbackErr);
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
|
-
throw new Error((
|
|
186
|
+
throw new Error((_d = result.error) !== null && _d !== void 0 ? _d : 'Local install failed during update');
|
|
181
187
|
}
|
|
182
188
|
await refreshInstalled();
|
|
183
189
|
}
|
package/dist/app/store/verbs.js
CHANGED
|
@@ -19,7 +19,7 @@ export const installVerb = {
|
|
|
19
19
|
name: 'install',
|
|
20
20
|
summary: 'Install a package by id from the catalog.',
|
|
21
21
|
async run(ctx, args) {
|
|
22
|
-
var _a;
|
|
22
|
+
var _a, _b, _c;
|
|
23
23
|
const id = args[0];
|
|
24
24
|
if (!id) {
|
|
25
25
|
ctx.scrollback.push({
|
|
@@ -71,12 +71,18 @@ export const installVerb = {
|
|
|
71
71
|
contractVersion: meta.contractVersion,
|
|
72
72
|
sourceRegistry: meta.sourceRegistry,
|
|
73
73
|
installedAt: new Date().toISOString(),
|
|
74
|
+
requiredShards: (_b = (_a = pkg.latest.requires) === null || _a === void 0 ? void 0 : _a.map((r) => r.id)) !== null && _b !== void 0 ? _b : [],
|
|
74
75
|
};
|
|
75
76
|
const serverResult = await serverInstallPackage(manifest, bundle, serverBundle);
|
|
76
77
|
if (!serverResult.ok) {
|
|
78
|
+
let text = `install failed: ${(_c = serverResult.error) !== null && _c !== void 0 ? _c : 'server error'}`;
|
|
79
|
+
if (serverResult.code === 'missing-shards' && serverResult.missing) {
|
|
80
|
+
const ids = serverResult.missing.map((m) => m.id).join(', ');
|
|
81
|
+
text = `install failed: missing required shard(s): ${ids}`;
|
|
82
|
+
}
|
|
77
83
|
ctx.scrollback.push({
|
|
78
84
|
kind: 'status',
|
|
79
|
-
text
|
|
85
|
+
text,
|
|
80
86
|
level: 'error',
|
|
81
87
|
ts: Date.now(),
|
|
82
88
|
});
|
package/dist/apps/lifecycle.d.ts
CHANGED
|
@@ -25,6 +25,17 @@ export declare function launchApp(id: string): Promise<void>;
|
|
|
25
25
|
* @param id - The `AppManifest.id` of the app to unload.
|
|
26
26
|
*/
|
|
27
27
|
export declare function unloadApp(id: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Unregister an app and remove it from the registry.
|
|
30
|
+
*
|
|
31
|
+
* If the app is currently active, force-closes (android-style): calls
|
|
32
|
+
* `App.deactivate`, detaches the layout, and deactivates required shards,
|
|
33
|
+
* then clears the active-app pointer. Unlike `returnToHome` this does not
|
|
34
|
+
* run suspend hooks and cannot be cancelled.
|
|
35
|
+
*
|
|
36
|
+
* No-op if the id is not registered.
|
|
37
|
+
*/
|
|
38
|
+
export declare function unregisterApp(id: string): void;
|
|
28
39
|
/**
|
|
29
40
|
* Return to the shell home view without unloading the active app. The
|
|
30
41
|
* app's shards stay running, its layout proxy stays attached with its
|
package/dist/apps/lifecycle.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { createStateZones } from '../state/zones.svelte';
|
|
15
15
|
import { activateShard, deactivateShard, getShardContext, registeredShards, } from '../shards/activate.svelte';
|
|
16
16
|
import { attachApp, acquireAppSlotHolds, detachApp, switchToApp, switchToHome, } from '../layout/store.svelte';
|
|
17
|
-
import { activeApp, getRegisteredApp } from './registry.svelte';
|
|
17
|
+
import { activeApp, getRegisteredApp, registeredApps } from './registry.svelte';
|
|
18
18
|
import { createZoneManager } from '../state/manage';
|
|
19
19
|
import { PERMISSION_STATE_MANAGE } from '../state/types';
|
|
20
20
|
// ---------- last-active-app user zone ------------------------------------
|
|
@@ -169,6 +169,26 @@ export function unloadApp(id) {
|
|
|
169
169
|
activeApp.id = null;
|
|
170
170
|
appContexts.delete(id);
|
|
171
171
|
}
|
|
172
|
+
// ---------- unregister -------------------------------------------------------
|
|
173
|
+
/**
|
|
174
|
+
* Unregister an app and remove it from the registry.
|
|
175
|
+
*
|
|
176
|
+
* If the app is currently active, force-closes (android-style): calls
|
|
177
|
+
* `App.deactivate`, detaches the layout, and deactivates required shards,
|
|
178
|
+
* then clears the active-app pointer. Unlike `returnToHome` this does not
|
|
179
|
+
* run suspend hooks and cannot be cancelled.
|
|
180
|
+
*
|
|
181
|
+
* No-op if the id is not registered.
|
|
182
|
+
*/
|
|
183
|
+
export function unregisterApp(id) {
|
|
184
|
+
if (!registeredApps.has(id))
|
|
185
|
+
return;
|
|
186
|
+
if (activeApp.id === id) {
|
|
187
|
+
unloadApp(id);
|
|
188
|
+
writeLastApp(null);
|
|
189
|
+
}
|
|
190
|
+
registeredApps.delete(id);
|
|
191
|
+
}
|
|
172
192
|
// ---------- return to home -----------------------------------------------
|
|
173
193
|
/**
|
|
174
194
|
* Return to the shell home view without unloading the active app. The
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
2
|
import { resetFramework } from '../__test__/reset';
|
|
3
3
|
import { makeApp, makeShard, makeAppManifest, makeShardManifest, makeTabsNode, makeTabEntry, makeSlotNode, makeTree, } from '../__test__/fixtures';
|
|
4
|
-
import { launchApp, returnToHome } from './lifecycle';
|
|
4
|
+
import { launchApp, returnToHome, unregisterApp } from './lifecycle';
|
|
5
5
|
import { registerApp } from './registry.svelte';
|
|
6
6
|
import { registerShard } from '../shards/activate.svelte';
|
|
7
7
|
import { presetManager } from '../overlays/presets';
|
|
@@ -258,3 +258,52 @@ describe('presets — scenario B.5 post-launch switch re-renders', () => {
|
|
|
258
258
|
expect(container.querySelector('[data-view-for="slot-one"]')).toBeNull();
|
|
259
259
|
});
|
|
260
260
|
});
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
// unregisterApp — android-style force-close + removal
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
describe('unregisterApp', () => {
|
|
265
|
+
beforeEach(resetFramework);
|
|
266
|
+
it('removes an inactive app from the registry', async () => {
|
|
267
|
+
const { registeredApps } = await import('./registry.svelte');
|
|
268
|
+
const app = makeApp({ manifest: makeAppManifest({ id: 'app-u1' }) });
|
|
269
|
+
registerApp(app);
|
|
270
|
+
expect(registeredApps.has('app-u1')).toBe(true);
|
|
271
|
+
unregisterApp('app-u1');
|
|
272
|
+
expect(registeredApps.has('app-u1')).toBe(false);
|
|
273
|
+
});
|
|
274
|
+
it('force-closes to home if the app being unregistered is active', async () => {
|
|
275
|
+
const { activeApp, registeredApps } = await import('./registry.svelte');
|
|
276
|
+
const shard = makeShard({ manifest: makeShardManifest({ id: 'shard-U' }) });
|
|
277
|
+
registerShard(shard);
|
|
278
|
+
const app = makeApp({
|
|
279
|
+
manifest: makeAppManifest({ id: 'app-u2', requiredShards: ['shard-U'] }),
|
|
280
|
+
});
|
|
281
|
+
registerApp(app);
|
|
282
|
+
await launchApp('app-u2');
|
|
283
|
+
expect(activeApp.id).toBe('app-u2');
|
|
284
|
+
unregisterApp('app-u2');
|
|
285
|
+
expect(activeApp.id).toBeNull();
|
|
286
|
+
expect(registeredApps.has('app-u2')).toBe(false);
|
|
287
|
+
});
|
|
288
|
+
it('is a no-op for unknown ids', async () => {
|
|
289
|
+
expect(() => unregisterApp('does-not-exist')).not.toThrow();
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// installPackage — evict-before-register (via registerLoadedBundle)
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
describe('installPackage evict-before-register (simulated via registerLoadedBundle)', () => {
|
|
296
|
+
beforeEach(resetFramework);
|
|
297
|
+
it('replaces an existing shard entry when a new version is registered', async () => {
|
|
298
|
+
var _a, _b;
|
|
299
|
+
const { registerLoadedBundle } = await import('../registry/register');
|
|
300
|
+
const { deactivateShard, registeredShards } = await import('../shards/activate.svelte');
|
|
301
|
+
const s1 = makeShard({ manifest: makeShardManifest({ id: 'S', version: '' }) });
|
|
302
|
+
registerLoadedBundle({ shards: [s1], apps: [] }, { version: '1.0.0', sourceRegistry: '', contractVersion: '1' });
|
|
303
|
+
expect((_a = registeredShards.get('S')) === null || _a === void 0 ? void 0 : _a.manifest.version).toBe('1.0.0');
|
|
304
|
+
deactivateShard('S');
|
|
305
|
+
const s2 = makeShard({ manifest: makeShardManifest({ id: 'S', version: '' }) });
|
|
306
|
+
registerLoadedBundle({ shards: [s2], apps: [] }, { version: '1.0.1', sourceRegistry: '', contractVersion: '1' });
|
|
307
|
+
expect((_b = registeredShards.get('S')) === null || _b === void 0 ? void 0 : _b.manifest.version).toBe('1.0.1');
|
|
308
|
+
});
|
|
309
|
+
});
|
package/dist/apps/types.d.ts
CHANGED
|
@@ -39,8 +39,9 @@ export interface AppManifest {
|
|
|
39
39
|
/**
|
|
40
40
|
* Optional permissions this app requests beyond the default sandbox.
|
|
41
41
|
* Declared in the manifest and surfaced to the user at install time
|
|
42
|
-
* by the store app. Currently recognized:
|
|
43
|
-
* shard zone access.
|
|
42
|
+
* by the store app. Currently recognized:
|
|
43
|
+
* - 'state:manage' — cross-shard zone access.
|
|
44
|
+
* - 'documents:sync' — cross-shard document sync API.
|
|
44
45
|
*/
|
|
45
46
|
permissions?: string[];
|
|
46
47
|
}
|
|
@@ -61,6 +62,10 @@ export interface AppContext {
|
|
|
61
62
|
* Cross-shard zone management API. Only present when the app's
|
|
62
63
|
* manifest declares the `'state:manage'` permission. Check with
|
|
63
64
|
* `if (ctx.zones)` before use.
|
|
65
|
+
*
|
|
66
|
+
* Related permissions also recognized by the framework:
|
|
67
|
+
* - 'documents:sync' — cross-shard document sync API (exposed on
|
|
68
|
+
* shard contexts as `ctx.sync()`, not on app contexts).
|
|
64
69
|
*/
|
|
65
70
|
zones?: ZoneManager;
|
|
66
71
|
}
|
package/dist/createShell.d.ts
CHANGED
package/dist/createShell.js
CHANGED
|
@@ -15,8 +15,10 @@ import { __setEnvServerUrl } from './env/index';
|
|
|
15
15
|
import { __setTenantId } from './documents/config';
|
|
16
16
|
import { initFromBoot } from './auth/index';
|
|
17
17
|
import SignInWall from './auth/SignInWall.svelte';
|
|
18
|
+
import { loadBundleModule } from './registry/loader';
|
|
19
|
+
import { registerLoadedBundle } from './registry/register';
|
|
18
20
|
export async function createShell(config) {
|
|
19
|
-
var _a, _b, _c;
|
|
21
|
+
var _a, _b, _c, _d, _e;
|
|
20
22
|
const sUrl = (_a = config === null || config === void 0 ? void 0 : config.serverUrl) !== null && _a !== void 0 ? _a : '';
|
|
21
23
|
// 1. Platform detection
|
|
22
24
|
const platform = await resolvePlatform();
|
|
@@ -45,7 +47,7 @@ export async function createShell(config) {
|
|
|
45
47
|
bootConfig = await res.json();
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
|
-
catch (
|
|
50
|
+
catch (_f) {
|
|
49
51
|
// Server unreachable — boot without auth (offline mode)
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -73,7 +75,6 @@ export async function createShell(config) {
|
|
|
73
75
|
}
|
|
74
76
|
// 5. Load server-discovered packages
|
|
75
77
|
if ((_c = config === null || config === void 0 ? void 0 : config.discoveredPackages) === null || _c === void 0 ? void 0 : _c.length) {
|
|
76
|
-
const { loadBundleModule } = await import('./registry/loader');
|
|
77
78
|
for (const pkg of config.discoveredPackages) {
|
|
78
79
|
try {
|
|
79
80
|
const res = await fetch(pkg.bundleUrl);
|
|
@@ -83,10 +84,11 @@ export async function createShell(config) {
|
|
|
83
84
|
}
|
|
84
85
|
const bytes = await res.arrayBuffer();
|
|
85
86
|
const loaded = await loadBundleModule(bytes);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
registerLoadedBundle(loaded, {
|
|
88
|
+
version: pkg.version,
|
|
89
|
+
sourceRegistry: (_d = pkg.sourceRegistry) !== null && _d !== void 0 ? _d : '',
|
|
90
|
+
contractVersion: (_e = pkg.contractVersion) !== null && _e !== void 0 ? _e : '',
|
|
91
|
+
});
|
|
90
92
|
console.log(`[sh3] Loaded discovered package: ${pkg.id}`);
|
|
91
93
|
}
|
|
92
94
|
catch (err) {
|
|
@@ -6,6 +6,10 @@ export declare class MemoryDocumentBackend implements DocumentBackend {
|
|
|
6
6
|
delete(tenantId: string, shardId: string, path: string): Promise<void>;
|
|
7
7
|
list(tenantId: string, shardId: string): Promise<DocumentMeta[]>;
|
|
8
8
|
exists(tenantId: string, shardId: string, path: string): Promise<boolean>;
|
|
9
|
+
listAllShards(tenantId: string): Promise<string[]>;
|
|
10
|
+
listAllDocuments(tenantId: string): Promise<Array<DocumentMeta & {
|
|
11
|
+
shardId: string;
|
|
12
|
+
}>>;
|
|
9
13
|
}
|
|
10
14
|
export declare class IndexedDBDocumentBackend implements DocumentBackend {
|
|
11
15
|
#private;
|
|
@@ -14,4 +18,8 @@ export declare class IndexedDBDocumentBackend implements DocumentBackend {
|
|
|
14
18
|
delete(tenantId: string, shardId: string, path: string): Promise<void>;
|
|
15
19
|
list(tenantId: string, shardId: string): Promise<DocumentMeta[]>;
|
|
16
20
|
exists(tenantId: string, shardId: string, path: string): Promise<boolean>;
|
|
21
|
+
listAllShards(tenantId: string): Promise<string[]>;
|
|
22
|
+
listAllDocuments(tenantId: string): Promise<Array<DocumentMeta & {
|
|
23
|
+
shardId: string;
|
|
24
|
+
}>>;
|
|
17
25
|
}
|