sh3-core 0.8.0 → 0.8.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 (78) hide show
  1. package/dist/Shell.svelte +19 -0
  2. package/dist/api.d.ts +5 -1
  3. package/dist/api.js +6 -1
  4. package/dist/app/admin/ApiKeysView.svelte +16 -27
  5. package/dist/app/admin/SystemView.svelte +149 -11
  6. package/dist/documents/backends.d.ts +8 -0
  7. package/dist/documents/backends.js +87 -0
  8. package/dist/documents/backends.test.d.ts +1 -0
  9. package/dist/documents/backends.test.js +33 -0
  10. package/dist/documents/browse.d.ts +12 -0
  11. package/dist/documents/browse.js +19 -0
  12. package/dist/documents/browse.test.d.ts +1 -0
  13. package/dist/documents/browse.test.js +41 -0
  14. package/dist/documents/http-backend.d.ts +4 -0
  15. package/dist/documents/http-backend.js +14 -0
  16. package/dist/documents/sync/index.d.ts +1 -2
  17. package/dist/documents/sync/index.js +0 -2
  18. package/dist/documents/sync/observer.d.ts +3 -0
  19. package/dist/documents/sync/observer.js +45 -0
  20. package/dist/documents/sync/registry.d.ts +3 -0
  21. package/dist/documents/sync/registry.js +8 -1
  22. package/dist/documents/sync/registry.test.js +11 -0
  23. package/dist/documents/types.d.ts +18 -0
  24. package/dist/documents/types.js +6 -1
  25. package/dist/keys/ConsentDialog.svelte +176 -0
  26. package/dist/keys/ConsentDialog.svelte.d.ts +3 -0
  27. package/dist/keys/client.d.ts +13 -0
  28. package/dist/keys/client.js +65 -0
  29. package/dist/keys/client.test.d.ts +1 -0
  30. package/dist/keys/client.test.js +44 -0
  31. package/dist/keys/consent.svelte.d.ts +16 -0
  32. package/dist/keys/consent.svelte.js +29 -0
  33. package/dist/keys/consent.test.d.ts +1 -0
  34. package/dist/keys/consent.test.js +53 -0
  35. package/dist/keys/revocation-bus.svelte.d.ts +35 -0
  36. package/dist/keys/revocation-bus.svelte.js +92 -0
  37. package/dist/keys/revocation-bus.test.d.ts +1 -0
  38. package/dist/keys/revocation-bus.test.js +95 -0
  39. package/dist/keys/types.d.ts +32 -0
  40. package/dist/keys/types.js +13 -0
  41. package/dist/layout/inspection.d.ts +17 -0
  42. package/dist/layout/inspection.js +53 -0
  43. package/dist/server-shard/types.d.ts +21 -2
  44. package/dist/server-sync.d.ts +6 -0
  45. package/dist/server-sync.js +634 -0
  46. package/dist/server-sync.js.map +7 -0
  47. package/dist/sh3core-shard/ShellHome.svelte +140 -63
  48. package/dist/sh3core-shard/sh3coreShard.svelte.js +12 -1
  49. package/dist/shards/activate-browse.test.d.ts +1 -0
  50. package/dist/shards/activate-browse.test.js +36 -0
  51. package/dist/shards/activate-on-key-revoked.test.d.ts +1 -0
  52. package/dist/shards/activate-on-key-revoked.test.js +60 -0
  53. package/dist/shards/activate-sync-registry.test.d.ts +1 -0
  54. package/dist/shards/activate-sync-registry.test.js +42 -0
  55. package/dist/shards/activate-tenantid.test.d.ts +1 -0
  56. package/dist/shards/activate-tenantid.test.js +21 -0
  57. package/dist/shards/activate.svelte.d.ts +12 -0
  58. package/dist/shards/activate.svelte.js +55 -3
  59. package/dist/shards/types.d.ts +42 -0
  60. package/dist/shards/types.js +1 -1
  61. package/dist/shell/views/KeysAndPeers.svelte +110 -0
  62. package/dist/shell/views/KeysAndPeers.svelte.d.ts +3 -0
  63. package/dist/shell-shard/Terminal.svelte +0 -11
  64. package/dist/shell-shard/manifest.js +1 -1
  65. package/dist/shell-shard/shellShard.svelte.js +52 -4
  66. package/dist/shell-shard/toolbar/Toolbar.svelte +11 -32
  67. package/dist/shell-shard/toolbar/Toolbar.svelte.d.ts +0 -2
  68. package/dist/shell-shard/toolbar/slots/ModeSlot.svelte +29 -62
  69. package/dist/shell-shard/verbs/index.js +3 -1
  70. package/dist/shell-shard/verbs/views.d.ts +2 -0
  71. package/dist/shell-shard/verbs/views.js +103 -2
  72. package/dist/testing.d.ts +3 -0
  73. package/dist/testing.js +77 -0
  74. package/dist/testing.js.map +7 -0
  75. package/dist/verbs/types.d.ts +19 -0
  76. package/dist/version.d.ts +1 -1
  77. package/dist/version.js +1 -1
  78. package/package.json +10 -2
@@ -1,8 +1,29 @@
1
1
  import ViewsTable from '../rich/ViewsTable.svelte';
2
2
  export const viewsVerb = {
3
3
  name: 'views',
4
- summary: 'List views currently mounted in the active layout.',
5
- async run(ctx) {
4
+ summary: 'List views currently mounted. Pass --standalone to list summonable views instead.',
5
+ async run(ctx, args) {
6
+ if (args.includes('--standalone')) {
7
+ const standalones = ctx.shell.listStandaloneViews();
8
+ if (standalones.length === 0) {
9
+ ctx.scrollback.push({
10
+ kind: 'status',
11
+ text: 'shell: no standalone views are currently available.',
12
+ level: 'info',
13
+ ts: Date.now(),
14
+ });
15
+ return;
16
+ }
17
+ ctx.scrollback.push({
18
+ kind: 'status',
19
+ text: standalones
20
+ .map((v) => ` ${v.viewId.padEnd(32)} ${v.label}`)
21
+ .join('\n'),
22
+ level: 'info',
23
+ ts: Date.now(),
24
+ });
25
+ return;
26
+ }
6
27
  const views = ctx.shell.listViewsInCurrentLayout();
7
28
  ctx.scrollback.push({
8
29
  kind: 'rich',
@@ -62,6 +83,86 @@ export const openVerb = {
62
83
  }
63
84
  },
64
85
  };
86
+ export const popoutVerb = {
87
+ name: 'popout',
88
+ summary: 'Pop a docked view out into a float by slot id.',
89
+ async run(ctx, args) {
90
+ var _a;
91
+ const slotId = args[0];
92
+ if (!slotId) {
93
+ ctx.scrollback.push({
94
+ kind: 'status',
95
+ text: 'usage: popout <slotId>',
96
+ level: 'warn',
97
+ ts: Date.now(),
98
+ });
99
+ return;
100
+ }
101
+ const result = ctx.shell.popoutSlot(slotId);
102
+ if (!result.ok) {
103
+ ctx.scrollback.push({
104
+ kind: 'status',
105
+ text: `shell: popout failed — ${(_a = result.error) !== null && _a !== void 0 ? _a : 'unknown'}`,
106
+ level: 'error',
107
+ ts: Date.now(),
108
+ });
109
+ }
110
+ else {
111
+ ctx.scrollback.push({
112
+ kind: 'status',
113
+ text: `shell: popped out ${slotId} → ${result.floatId}`,
114
+ level: 'info',
115
+ ts: Date.now(),
116
+ });
117
+ }
118
+ },
119
+ };
120
+ export const dockVerb = {
121
+ name: 'dock',
122
+ summary: 'Dock a float back into the current layout by float id. Run with no args to list floats.',
123
+ async run(ctx, args) {
124
+ var _a;
125
+ const floatId = args[0];
126
+ if (!floatId) {
127
+ const floats = ctx.shell.listFloats();
128
+ if (floats.length === 0) {
129
+ ctx.scrollback.push({
130
+ kind: 'status',
131
+ text: 'shell: no active floats.',
132
+ level: 'info',
133
+ ts: Date.now(),
134
+ });
135
+ return;
136
+ }
137
+ ctx.scrollback.push({
138
+ kind: 'status',
139
+ text: floats
140
+ .map((f) => { var _a; return ` ${f.floatId.padEnd(24)} ${(_a = f.viewId) !== null && _a !== void 0 ? _a : '-'}\t${f.label}`; })
141
+ .join('\n'),
142
+ level: 'info',
143
+ ts: Date.now(),
144
+ });
145
+ return;
146
+ }
147
+ const result = ctx.shell.dockFloat(floatId);
148
+ if (!result.ok) {
149
+ ctx.scrollback.push({
150
+ kind: 'status',
151
+ text: `shell: dock failed — ${(_a = result.error) !== null && _a !== void 0 ? _a : 'unknown'}`,
152
+ level: 'error',
153
+ ts: Date.now(),
154
+ });
155
+ }
156
+ else {
157
+ ctx.scrollback.push({
158
+ kind: 'status',
159
+ text: `shell: docked ${floatId}`,
160
+ level: 'info',
161
+ ts: Date.now(),
162
+ });
163
+ }
164
+ },
165
+ };
65
166
  export const closeVerb = {
66
167
  name: 'close',
67
168
  summary: 'Close a view by slot id.',
@@ -0,0 +1,3 @@
1
+ import type { DocumentBackend } from './documents/types';
2
+ /** Factory wrapper so test code can call createMemoryDocumentBackend() without new. */
3
+ export declare function createMemoryDocumentBackend(): DocumentBackend;
@@ -0,0 +1,77 @@
1
+ // src/documents/backends.ts
2
+ function compositeKey(tenantId, shardId, path) {
3
+ return `${tenantId}/${shardId}/${path}`;
4
+ }
5
+ function keyPrefix(tenantId, shardId) {
6
+ return `${tenantId}/${shardId}/`;
7
+ }
8
+ var MemoryDocumentBackend = class {
9
+ #store = /* @__PURE__ */ new Map();
10
+ async read(tenantId, shardId, path) {
11
+ const entry = this.#store.get(compositeKey(tenantId, shardId, path));
12
+ return entry ? entry.content : null;
13
+ }
14
+ async write(tenantId, shardId, path, content) {
15
+ const size = typeof content === "string" ? new Blob([content]).size : content.byteLength;
16
+ this.#store.set(compositeKey(tenantId, shardId, path), {
17
+ content,
18
+ size,
19
+ lastModified: Date.now()
20
+ });
21
+ }
22
+ async delete(tenantId, shardId, path) {
23
+ this.#store.delete(compositeKey(tenantId, shardId, path));
24
+ }
25
+ async list(tenantId, shardId) {
26
+ const prefix = keyPrefix(tenantId, shardId);
27
+ const out = [];
28
+ for (const [key, entry] of this.#store) {
29
+ if (key.startsWith(prefix)) {
30
+ out.push({
31
+ path: key.slice(prefix.length),
32
+ size: entry.size,
33
+ lastModified: entry.lastModified
34
+ });
35
+ }
36
+ }
37
+ return out;
38
+ }
39
+ async exists(tenantId, shardId, path) {
40
+ return this.#store.has(compositeKey(tenantId, shardId, path));
41
+ }
42
+ async listAllShards(tenantId) {
43
+ const prefix = `${tenantId}/`;
44
+ const shards = /* @__PURE__ */ new Set();
45
+ for (const key of this.#store.keys()) {
46
+ if (!key.startsWith(prefix)) continue;
47
+ const rest = key.slice(prefix.length);
48
+ const slash = rest.indexOf("/");
49
+ if (slash < 0) continue;
50
+ shards.add(rest.slice(0, slash));
51
+ }
52
+ return [...shards];
53
+ }
54
+ async listAllDocuments(tenantId) {
55
+ const prefix = `${tenantId}/`;
56
+ const out = [];
57
+ for (const [key, entry] of this.#store) {
58
+ if (!key.startsWith(prefix)) continue;
59
+ const rest = key.slice(prefix.length);
60
+ const slash = rest.indexOf("/");
61
+ if (slash < 0) continue;
62
+ const shardId = rest.slice(0, slash);
63
+ const path = rest.slice(slash + 1);
64
+ out.push({ shardId, path, size: entry.size, lastModified: entry.lastModified });
65
+ }
66
+ return out;
67
+ }
68
+ };
69
+
70
+ // src/testing.ts
71
+ function createMemoryDocumentBackend() {
72
+ return new MemoryDocumentBackend();
73
+ }
74
+ export {
75
+ createMemoryDocumentBackend
76
+ };
77
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/documents/backends.ts", "../src/testing.ts"],
4
+ "sourcesContent": ["/*\n * Document zone backends \u2014 concrete storage implementations.\n *\n * MemoryDocumentBackend: Map-based, for tests and ephemeral use.\n * IndexedDBDocumentBackend: The web default. Lazy-inits on first\n * operation to avoid blocking bootstrap.\n */\n\nimport type { DocumentBackend, DocumentMeta } from './types';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction compositeKey(tenantId: string, shardId: string, path: string): string {\n return `${tenantId}/${shardId}/${path}`;\n}\n\nfunction keyPrefix(tenantId: string, shardId: string): string {\n return `${tenantId}/${shardId}/`;\n}\n\n// ---------------------------------------------------------------------------\n// MemoryDocumentBackend\n// ---------------------------------------------------------------------------\n\ninterface MemoryEntry {\n content: string | ArrayBuffer;\n size: number;\n lastModified: number;\n}\n\nexport class MemoryDocumentBackend implements DocumentBackend {\n #store = new Map<string, MemoryEntry>();\n\n async read(\n tenantId: string,\n shardId: string,\n path: string,\n ): Promise<string | ArrayBuffer | null> {\n const entry = this.#store.get(compositeKey(tenantId, shardId, path));\n return entry ? entry.content : null;\n }\n\n async write(\n tenantId: string,\n shardId: string,\n path: string,\n content: string | ArrayBuffer,\n ): Promise<void> {\n const size =\n typeof content === 'string' ? new Blob([content]).size : content.byteLength;\n this.#store.set(compositeKey(tenantId, shardId, path), {\n content,\n size,\n lastModified: Date.now(),\n });\n }\n\n async delete(tenantId: string, shardId: string, path: string): Promise<void> {\n this.#store.delete(compositeKey(tenantId, shardId, path));\n }\n\n async list(tenantId: string, shardId: string): Promise<DocumentMeta[]> {\n const prefix = keyPrefix(tenantId, shardId);\n const out: DocumentMeta[] = [];\n for (const [key, entry] of this.#store) {\n if (key.startsWith(prefix)) {\n out.push({\n path: key.slice(prefix.length),\n size: entry.size,\n lastModified: entry.lastModified,\n });\n }\n }\n return out;\n }\n\n async exists(tenantId: string, shardId: string, path: string): Promise<boolean> {\n return this.#store.has(compositeKey(tenantId, shardId, path));\n }\n\n async listAllShards(tenantId: string): Promise<string[]> {\n const prefix = `${tenantId}/`;\n const shards = new Set<string>();\n for (const key of this.#store.keys()) {\n if (!key.startsWith(prefix)) continue;\n const rest = key.slice(prefix.length);\n const slash = rest.indexOf('/');\n if (slash < 0) continue;\n shards.add(rest.slice(0, slash));\n }\n return [...shards];\n }\n\n async listAllDocuments(\n tenantId: string,\n ): Promise<Array<DocumentMeta & { shardId: string }>> {\n const prefix = `${tenantId}/`;\n const out: Array<DocumentMeta & { shardId: string }> = [];\n for (const [key, entry] of this.#store) {\n if (!key.startsWith(prefix)) continue;\n const rest = key.slice(prefix.length);\n const slash = rest.indexOf('/');\n if (slash < 0) continue;\n const shardId = rest.slice(0, slash);\n const path = rest.slice(slash + 1);\n out.push({ shardId, path, size: entry.size, lastModified: entry.lastModified });\n }\n return out;\n }\n}\n\n// ---------------------------------------------------------------------------\n// IndexedDBDocumentBackend\n// ---------------------------------------------------------------------------\n\nconst IDB_NAME = 'sh3-documents';\nconst IDB_STORE = 'docs';\nconst IDB_VERSION = 2;\n\ninterface IDBEntry {\n content: string | ArrayBuffer;\n size: number;\n lastModified: number;\n}\n\nexport class IndexedDBDocumentBackend implements DocumentBackend {\n #dbPromise: Promise<IDBDatabase> | null = null;\n\n /**\n * Lazy-open the database on first use. The promise is cached so\n * subsequent calls await the same open.\n */\n #db(): Promise<IDBDatabase> {\n if (!this.#dbPromise) {\n this.#dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const req = indexedDB.open(IDB_NAME, IDB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(IDB_STORE)) {\n db.createObjectStore(IDB_STORE);\n }\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n }\n return this.#dbPromise;\n }\n\n /** Run a single-store transaction and return the request result. */\n async #tx<T>(\n mode: IDBTransactionMode,\n fn: (store: IDBObjectStore) => IDBRequest<T>,\n ): Promise<T> {\n const db = await this.#db();\n return new Promise<T>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE, mode);\n const store = tx.objectStore(IDB_STORE);\n const req = fn(store);\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n }\n\n async read(\n tenantId: string,\n shardId: string,\n path: string,\n ): Promise<string | ArrayBuffer | null> {\n const key = compositeKey(tenantId, shardId, path);\n const entry = await this.#tx<IDBEntry | undefined>('readonly', (s) => s.get(key));\n return entry ? entry.content : null;\n }\n\n async write(\n tenantId: string,\n shardId: string,\n path: string,\n content: string | ArrayBuffer,\n ): Promise<void> {\n const key = compositeKey(tenantId, shardId, path);\n const size =\n typeof content === 'string' ? new Blob([content]).size : content.byteLength;\n const entry: IDBEntry = { content, size, lastModified: Date.now() };\n await this.#tx('readwrite', (s) => s.put(entry, key));\n }\n\n async delete(tenantId: string, shardId: string, path: string): Promise<void> {\n const key = compositeKey(tenantId, shardId, path);\n await this.#tx('readwrite', (s) => s.delete(key));\n }\n\n async list(tenantId: string, shardId: string): Promise<DocumentMeta[]> {\n const prefix = keyPrefix(tenantId, shardId);\n const db = await this.#db();\n return new Promise<DocumentMeta[]>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const store = tx.objectStore(IDB_STORE);\n // IDBKeyRange.bound selects all keys that start with the prefix.\n // The upper bound appends a character beyond '/' to capture all\n // sub-paths without over-selecting.\n const range = IDBKeyRange.bound(prefix, prefix + '\\uffff', false, false);\n const req = store.openCursor(range);\n const out: DocumentMeta[] = [];\n req.onsuccess = () => {\n const cursor = req.result;\n if (cursor) {\n const entry = cursor.value as IDBEntry;\n out.push({\n path: (cursor.key as string).slice(prefix.length),\n size: entry.size,\n lastModified: entry.lastModified,\n });\n cursor.continue();\n } else {\n resolve(out);\n }\n };\n req.onerror = () => reject(req.error);\n });\n }\n\n async exists(tenantId: string, shardId: string, path: string): Promise<boolean> {\n const key = compositeKey(tenantId, shardId, path);\n // getKey is cheaper than get \u2014 avoids deserializing the value.\n const result = await this.#tx<IDBValidKey | undefined>(\n 'readonly',\n (s) => s.getKey(key),\n );\n return result !== undefined;\n }\n\n async listAllShards(tenantId: string): Promise<string[]> {\n const prefix = `${tenantId}/`;\n const db = await this.#db();\n return new Promise<string[]>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const store = tx.objectStore(IDB_STORE);\n const range = IDBKeyRange.bound(prefix, prefix + '\\uffff', false, false);\n const req = store.openKeyCursor(range);\n const shards = new Set<string>();\n req.onsuccess = () => {\n const cursor = req.result;\n if (cursor) {\n const rest = (cursor.key as string).slice(prefix.length);\n const slash = rest.indexOf('/');\n if (slash >= 0) shards.add(rest.slice(0, slash));\n cursor.continue();\n } else {\n resolve([...shards]);\n }\n };\n req.onerror = () => reject(req.error);\n });\n }\n\n async listAllDocuments(\n tenantId: string,\n ): Promise<Array<DocumentMeta & { shardId: string }>> {\n const prefix = `${tenantId}/`;\n const db = await this.#db();\n return new Promise<Array<DocumentMeta & { shardId: string }>>((resolve, reject) => {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const store = tx.objectStore(IDB_STORE);\n const range = IDBKeyRange.bound(prefix, prefix + '\\uffff', false, false);\n const req = store.openCursor(range);\n const out: Array<DocumentMeta & { shardId: string }> = [];\n req.onsuccess = () => {\n const cursor = req.result;\n if (cursor) {\n const rest = (cursor.key as string).slice(prefix.length);\n const slash = rest.indexOf('/');\n if (slash >= 0) {\n const entry = cursor.value as IDBEntry;\n out.push({\n shardId: rest.slice(0, slash),\n path: rest.slice(slash + 1),\n size: entry.size,\n lastModified: entry.lastModified,\n });\n }\n cursor.continue();\n } else {\n resolve(out);\n }\n };\n req.onerror = () => reject(req.error);\n });\n }\n}\n", "/*\n * Testing utilities subpath entry \u2014 exports in-memory helpers for use\n * in sh3-server and shard tests without pulling in browser-only code.\n */\n\nimport { MemoryDocumentBackend } from './documents/backends';\nimport type { DocumentBackend } from './documents/types';\n\n/** Factory wrapper so test code can call createMemoryDocumentBackend() without new. */\nexport function createMemoryDocumentBackend(): DocumentBackend {\n return new MemoryDocumentBackend();\n}\n"],
5
+ "mappings": ";AAcA,SAAS,aAAa,UAAkB,SAAiB,MAAsB;AAC7E,SAAO,GAAG,QAAQ,IAAI,OAAO,IAAI,IAAI;AACvC;AAEA,SAAS,UAAU,UAAkB,SAAyB;AAC5D,SAAO,GAAG,QAAQ,IAAI,OAAO;AAC/B;AAYO,IAAM,wBAAN,MAAuD;AAAA,EAC5D,SAAS,oBAAI,IAAyB;AAAA,EAEtC,MAAM,KACJ,UACA,SACA,MACsC;AACtC,UAAM,QAAQ,KAAK,OAAO,IAAI,aAAa,UAAU,SAAS,IAAI,CAAC;AACnE,WAAO,QAAQ,MAAM,UAAU;AAAA,EACjC;AAAA,EAEA,MAAM,MACJ,UACA,SACA,MACA,SACe;AACf,UAAM,OACJ,OAAO,YAAY,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,QAAQ;AACnE,SAAK,OAAO,IAAI,aAAa,UAAU,SAAS,IAAI,GAAG;AAAA,MACrD;AAAA,MACA;AAAA,MACA,cAAc,KAAK,IAAI;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,UAAkB,SAAiB,MAA6B;AAC3E,SAAK,OAAO,OAAO,aAAa,UAAU,SAAS,IAAI,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAM,KAAK,UAAkB,SAA0C;AACrE,UAAM,SAAS,UAAU,UAAU,OAAO;AAC1C,UAAM,MAAsB,CAAC;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,QAAQ;AACtC,UAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,YAAI,KAAK;AAAA,UACP,MAAM,IAAI,MAAM,OAAO,MAAM;AAAA,UAC7B,MAAM,MAAM;AAAA,UACZ,cAAc,MAAM;AAAA,QACtB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,UAAkB,SAAiB,MAAgC;AAC9E,WAAO,KAAK,OAAO,IAAI,aAAa,UAAU,SAAS,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,cAAc,UAAqC;AACvD,UAAM,SAAS,GAAG,QAAQ;AAC1B,UAAM,SAAS,oBAAI,IAAY;AAC/B,eAAW,OAAO,KAAK,OAAO,KAAK,GAAG;AACpC,UAAI,CAAC,IAAI,WAAW,MAAM,EAAG;AAC7B,YAAM,OAAO,IAAI,MAAM,OAAO,MAAM;AACpC,YAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,UAAI,QAAQ,EAAG;AACf,aAAO,IAAI,KAAK,MAAM,GAAG,KAAK,CAAC;AAAA,IACjC;AACA,WAAO,CAAC,GAAG,MAAM;AAAA,EACnB;AAAA,EAEA,MAAM,iBACJ,UACoD;AACpD,UAAM,SAAS,GAAG,QAAQ;AAC1B,UAAM,MAAiD,CAAC;AACxD,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,QAAQ;AACtC,UAAI,CAAC,IAAI,WAAW,MAAM,EAAG;AAC7B,YAAM,OAAO,IAAI,MAAM,OAAO,MAAM;AACpC,YAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,UAAI,QAAQ,EAAG;AACf,YAAM,UAAU,KAAK,MAAM,GAAG,KAAK;AACnC,YAAM,OAAO,KAAK,MAAM,QAAQ,CAAC;AACjC,UAAI,KAAK,EAAE,SAAS,MAAM,MAAM,MAAM,MAAM,cAAc,MAAM,aAAa,CAAC;AAAA,IAChF;AACA,WAAO;AAAA,EACT;AACF;;;ACtGO,SAAS,8BAA+C;AAC7D,SAAO,IAAI,sBAAsB;AACnC;",
6
+ "names": []
7
+ }
@@ -29,6 +29,25 @@ export interface ShellApi {
29
29
  ok: boolean;
30
30
  error?: string;
31
31
  };
32
+ listStandaloneViews(): Array<{
33
+ shardId: string;
34
+ viewId: string;
35
+ label: string;
36
+ }>;
37
+ popoutSlot(slotId: string): {
38
+ ok: boolean;
39
+ error?: string;
40
+ floatId?: string;
41
+ };
42
+ dockFloat(floatId: string): {
43
+ ok: boolean;
44
+ error?: string;
45
+ };
46
+ listFloats(): Array<{
47
+ floatId: string;
48
+ viewId: string | null;
49
+ label: string;
50
+ }>;
32
51
  listZones(shardId?: string): Array<{
33
52
  shardId: string;
34
53
  zones: string[];
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Auto-generated from package.json — do not edit manually. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.2";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Auto-generated from package.json — do not edit manually. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.2';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh3-core",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -26,10 +26,18 @@
26
26
  "./build": {
27
27
  "types": "./dist/build.d.ts",
28
28
  "default": "./dist/build.js"
29
+ },
30
+ "./server-sync": {
31
+ "types": "./dist/server-sync.d.ts",
32
+ "default": "./dist/server-sync.js"
33
+ },
34
+ "./testing": {
35
+ "types": "./dist/testing.d.ts",
36
+ "default": "./dist/testing.js"
29
37
  }
30
38
  },
31
39
  "scripts": {
32
- "build": "node --import tsx scripts/sync-version.ts && svelte-package -i src -o dist && node --import tsx scripts/generate-api-docs.ts",
40
+ "build": "node --import tsx scripts/sync-version.ts && svelte-package -i src -o dist && node --import tsx scripts/bundle-node-entries.ts && node --import tsx scripts/generate-api-docs.ts",
33
41
  "check": "svelte-check --tsconfig ./tsconfig.json",
34
42
  "pack": "npm run build && npm pack",
35
43
  "test": "vitest run --passWithNoTests",