@happyvertical/smrt-svelte 0.37.8 → 0.37.10
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/AGENTS.md +22 -86
- package/README.md +14 -10
- package/dist/components/workspace/MIGRATION.md +55 -0
- package/dist/components/workspace/README.md +22 -25
- package/dist/components/workspace/__tests__/AdminShell.test.js +55 -0
- package/dist/components/workspace/__tests__/admin-shell-hotkeys.test.js +34 -0
- package/dist/components/workspace/__tests__/admin-shell-settings.test.js +25 -0
- package/dist/components/workspace/__tests__/admin-shell-state.test.js +110 -0
- package/dist/components/workspace/__tests__/index.test.js +15 -24
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts +2 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts.map +1 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.js +1 -1
- package/dist/components/workspace/admin-shell/ActivityBadge.svelte +25 -0
- package/dist/components/workspace/admin-shell/ActivityBadge.svelte.d.ts +9 -0
- package/dist/components/workspace/admin-shell/ActivityBadge.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ActivityItem.svelte +85 -0
- package/dist/components/workspace/admin-shell/ActivityItem.svelte.d.ts +8 -0
- package/dist/components/workspace/admin-shell/ActivityItem.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ActivityList.svelte +41 -0
- package/dist/components/workspace/admin-shell/ActivityList.svelte.d.ts +10 -0
- package/dist/components/workspace/admin-shell/ActivityList.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ActivityToasts.svelte +140 -0
- package/dist/components/workspace/admin-shell/ActivityToasts.svelte.d.ts +16 -0
- package/dist/components/workspace/admin-shell/ActivityToasts.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte +691 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +24 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/AppScopePanel.svelte +94 -0
- package/dist/components/workspace/admin-shell/AppScopePanel.svelte.d.ts +14 -0
- package/dist/components/workspace/admin-shell/AppScopePanel.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/HotkeyInput.svelte +74 -0
- package/dist/components/workspace/admin-shell/HotkeyInput.svelte.d.ts +11 -0
- package/dist/components/workspace/admin-shell/HotkeyInput.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellCorner.svelte +25 -0
- package/dist/components/workspace/admin-shell/ShellCorner.svelte.d.ts +9 -0
- package/dist/components/workspace/admin-shell/ShellCorner.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellDockTool.svelte +19 -0
- package/dist/components/workspace/admin-shell/ShellDockTool.svelte.d.ts +7 -0
- package/dist/components/workspace/admin-shell/ShellDockTool.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte +146 -0
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts +4 -0
- package/dist/components/workspace/admin-shell/ShellSettingsPanel.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/ShortcutsOverlay.svelte +81 -0
- package/dist/components/workspace/admin-shell/ShortcutsOverlay.svelte.d.ts +7 -0
- package/dist/components/workspace/admin-shell/ShortcutsOverlay.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/SystemScopePanel.svelte +118 -0
- package/dist/components/workspace/admin-shell/SystemScopePanel.svelte.d.ts +9 -0
- package/dist/components/workspace/admin-shell/SystemScopePanel.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/SystemStatusChips.svelte +71 -0
- package/dist/components/workspace/admin-shell/SystemStatusChips.svelte.d.ts +8 -0
- package/dist/components/workspace/admin-shell/SystemStatusChips.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte +101 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +10 -0
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/context.d.ts +6 -0
- package/dist/components/workspace/admin-shell/context.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/context.js +16 -0
- package/dist/components/workspace/admin-shell/hotkeys.d.ts +14 -0
- package/dist/components/workspace/admin-shell/hotkeys.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/hotkeys.js +62 -0
- package/dist/components/workspace/admin-shell/settings.d.ts +14 -0
- package/dist/components/workspace/admin-shell/settings.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/settings.js +139 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts +47 -0
- package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/state.svelte.js +252 -0
- package/dist/components/workspace/admin-shell/types.d.ts +137 -0
- package/dist/components/workspace/admin-shell/types.d.ts.map +1 -0
- package/dist/components/workspace/admin-shell/types.js +13 -0
- package/dist/components/workspace/index.d.ts +25 -11
- package/dist/components/workspace/index.d.ts.map +1 -1
- package/dist/components/workspace/index.js +24 -10
- package/dist/i18n/strings.workspace.d.ts +30 -0
- package/dist/i18n/strings.workspace.d.ts.map +1 -1
- package/dist/i18n/strings.workspace.js +31 -0
- package/dist/internal/logger.d.ts +13 -6
- package/dist/internal/logger.d.ts.map +1 -1
- package/dist/internal/logger.js +33 -8
- package/dist/internal/logger.test.js +54 -0
- package/dist/web/__tests__/harness.svelte +25 -0
- package/dist/web/__tests__/harness.svelte.d.ts +15 -0
- package/dist/web/__tests__/harness.svelte.d.ts.map +1 -0
- package/dist/web/__tests__/live-collection.svelte.test.js +184 -0
- package/dist/web/index.d.ts +13 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +12 -0
- package/dist/web/live-collection.svelte.d.ts +132 -0
- package/dist/web/live-collection.svelte.d.ts.map +1 -0
- package/dist/web/live-collection.svelte.js +173 -0
- package/package.json +13 -4
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte 5 live-query bindings for `@happyvertical/smrt-web` (#1761, slice A).
|
|
3
|
+
*
|
|
4
|
+
* Turns a SMRT-owned {@link SmrtWebCollection} into runes-reactive live-query
|
|
5
|
+
* state plus mutation helpers, so a consumer writes reactive components WITHOUT
|
|
6
|
+
* importing TanStack. The client-data engine (`@tanstack/db` +
|
|
7
|
+
* `@tanstack/svelte-db`) is used only inside this module — its types never
|
|
8
|
+
* appear on the public surface, mirroring smrt-web's own engine-absorption
|
|
9
|
+
* boundary (ratified condition for #1761).
|
|
10
|
+
*
|
|
11
|
+
* Two engine facts drive the shape of this file:
|
|
12
|
+
*
|
|
13
|
+
* 1. `useLiveQuery` internally uses `$state`/`$derived`/`$effect`, so it (and
|
|
14
|
+
* therefore {@link liveCollection}) MUST be called during Svelte component
|
|
15
|
+
* initialization — exactly like this package's other `use*` composables.
|
|
16
|
+
* Its internal `$effect` binds to the calling component's lifecycle, so the
|
|
17
|
+
* live subscription is torn down automatically when the component unmounts.
|
|
18
|
+
*
|
|
19
|
+
* 2. `@tanstack/svelte-db` live-query rows carry ENUMERABLE engine virtual
|
|
20
|
+
* props (`$key`/`$origin`/`$synced`/`$collectionId`) that would otherwise
|
|
21
|
+
* escape through spread or JSON. Every exposed row is projected to a plain
|
|
22
|
+
* DTO by stripping `$`-prefixed keys (the `$` prefix is reserved for the
|
|
23
|
+
* engine; SMRT columns never begin with it), mirroring smrt-web's internal
|
|
24
|
+
* `toPlainRow`.
|
|
25
|
+
*/
|
|
26
|
+
import { getEngineCollection, } from '@happyvertical/smrt-web';
|
|
27
|
+
import { useLiveQuery } from '@tanstack/svelte-db';
|
|
28
|
+
/**
|
|
29
|
+
* Project an engine live-query row to a plain public DTO by dropping every
|
|
30
|
+
* `$`-prefixed key. Mirrors smrt-web's internal `toPlainRow`: the `$` prefix is
|
|
31
|
+
* reserved for the engine's enumerable virtual props (`$key`/`$origin`/
|
|
32
|
+
* `$synced`/`$collectionId`); SMRT columns never begin with it. Char code 36
|
|
33
|
+
* is `'$'`.
|
|
34
|
+
*/
|
|
35
|
+
function toPlainRow(row) {
|
|
36
|
+
const plain = {};
|
|
37
|
+
for (const [key, value] of Object.entries(row)) {
|
|
38
|
+
if (key.charCodeAt(0) !== 36)
|
|
39
|
+
plain[key] = value;
|
|
40
|
+
}
|
|
41
|
+
return plain;
|
|
42
|
+
}
|
|
43
|
+
/** Map the engine's fine-grained status to the coarse SMRT-owned status. */
|
|
44
|
+
function toLiveStatus(isReady, isError) {
|
|
45
|
+
if (isError)
|
|
46
|
+
return 'error';
|
|
47
|
+
if (isReady)
|
|
48
|
+
return 'ready';
|
|
49
|
+
return 'loading';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a runes-reactive live view over a {@link SmrtWebCollection}.
|
|
53
|
+
*
|
|
54
|
+
* MUST be called during Svelte component initialization (it delegates to
|
|
55
|
+
* `@tanstack/svelte-db`'s `useLiveQuery`, which sets up a `$effect`). The live
|
|
56
|
+
* subscription is torn down automatically when the calling component unmounts.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```svelte
|
|
60
|
+
* <script lang="ts">
|
|
61
|
+
* import { createSmrtCollection } from '@happyvertical/smrt-web';
|
|
62
|
+
* import { liveCollection } from '@happyvertical/smrt-svelte/web';
|
|
63
|
+
* import { productsDefinition } from '@happyvertical/smrt-virt-web';
|
|
64
|
+
*
|
|
65
|
+
* const products = createSmrtCollection(productsDefinition, {});
|
|
66
|
+
* const view = liveCollection(products);
|
|
67
|
+
*
|
|
68
|
+
* async function add() {
|
|
69
|
+
* const m = view.insert({ id: crypto.randomUUID(), name: 'New' });
|
|
70
|
+
* await m.done.catch(() => {}); // error also reflected on m.error
|
|
71
|
+
* }
|
|
72
|
+
* </script>
|
|
73
|
+
*
|
|
74
|
+
* {#if view.isLoading}
|
|
75
|
+
* <p>Loading…</p>
|
|
76
|
+
* {:else if view.isError}
|
|
77
|
+
* <p>Failed: {String(view.error)}</p>
|
|
78
|
+
* {:else}
|
|
79
|
+
* <ul>
|
|
80
|
+
* {#each view.rows as row (row.id)}
|
|
81
|
+
* <li>{row.name}</li>
|
|
82
|
+
* {/each}
|
|
83
|
+
* </ul>
|
|
84
|
+
* {/if}
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function liveCollection(handle, options = {}) {
|
|
88
|
+
const { preload = true } = options;
|
|
89
|
+
// Bridge to the engine collection (typed `unknown` at the boundary — cast to
|
|
90
|
+
// the engine `Collection` here, and confine that type to this module).
|
|
91
|
+
const engine = getEngineCollection(handle);
|
|
92
|
+
// Kick the first load without forcing consumers to await preload() — the
|
|
93
|
+
// live query subscribes lazily, so nudge it when requested. Swallow the
|
|
94
|
+
// rejection: a load failure (network error, or an SSR relative-URL
|
|
95
|
+
// `Failed to parse URL` TypeError) already surfaces reactively via the
|
|
96
|
+
// live-query status; this fire-and-forget must not become an unhandled
|
|
97
|
+
// rejection.
|
|
98
|
+
if (preload) {
|
|
99
|
+
void handle.preload().catch(() => { });
|
|
100
|
+
}
|
|
101
|
+
// The live query over the whole base collection. No `.select()` → `data`
|
|
102
|
+
// carries the full row objects (with engine virtual props, stripped below).
|
|
103
|
+
// `useLiveQuery` installs a `$effect`; calling `liveCollection` outside a
|
|
104
|
+
// component surfaces Svelte's own "effect outside component" error, which is
|
|
105
|
+
// the correct signal.
|
|
106
|
+
const query = useLiveQuery((q) => q.from({ row: engine }));
|
|
107
|
+
// Project rows to plain DTOs reactively. `query.data` is a $state-backed
|
|
108
|
+
// reactive array; `$derived.by` recomputes the projection when it changes.
|
|
109
|
+
const rows = $derived.by(() => query.data.map((row) => toPlainRow(row)));
|
|
110
|
+
const status = $derived(toLiveStatus(query.isReady, query.isError));
|
|
111
|
+
// useLiveQuery does not surface an error object, only an error status; expose
|
|
112
|
+
// the status string as the error payload when the read has failed.
|
|
113
|
+
const error = $derived(query.isError ? query.status : null);
|
|
114
|
+
return {
|
|
115
|
+
get rows() {
|
|
116
|
+
return rows;
|
|
117
|
+
},
|
|
118
|
+
get status() {
|
|
119
|
+
return status;
|
|
120
|
+
},
|
|
121
|
+
get error() {
|
|
122
|
+
return error;
|
|
123
|
+
},
|
|
124
|
+
get isLoading() {
|
|
125
|
+
return status === 'loading';
|
|
126
|
+
},
|
|
127
|
+
get isReady() {
|
|
128
|
+
return status === 'ready';
|
|
129
|
+
},
|
|
130
|
+
get isError() {
|
|
131
|
+
return status === 'error';
|
|
132
|
+
},
|
|
133
|
+
insert(row) {
|
|
134
|
+
return createMutation(() => handle.insert(row).isPersisted.promise);
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Wrap a transaction's settle promise in a reactive {@link LiveCollectionMutation}.
|
|
140
|
+
* Runs the mutation immediately; tracks pending/error via runes. Kept separate
|
|
141
|
+
* so `insert` (and future `update`/`delete` helpers) share one reactive shape.
|
|
142
|
+
*/
|
|
143
|
+
function createMutation(run) {
|
|
144
|
+
let pending = $state(true);
|
|
145
|
+
let settled = $state(false);
|
|
146
|
+
let error = $state(null);
|
|
147
|
+
// `done` RESOLVES on settle whether the write persisted or rolled back — the
|
|
148
|
+
// failure is surfaced only reactively via `error`. Re-throwing here would
|
|
149
|
+
// reject `done`, which a reactive-only consumer (reads `error`/`pending` in
|
|
150
|
+
// markup, never awaits `done`) would leave as an unhandled rejection.
|
|
151
|
+
const done = run().then(() => {
|
|
152
|
+
pending = false;
|
|
153
|
+
settled = true;
|
|
154
|
+
}, (cause) => {
|
|
155
|
+
pending = false;
|
|
156
|
+
settled = true;
|
|
157
|
+
error = cause;
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
get pending() {
|
|
161
|
+
return pending;
|
|
162
|
+
},
|
|
163
|
+
get settled() {
|
|
164
|
+
return settled;
|
|
165
|
+
},
|
|
166
|
+
get error() {
|
|
167
|
+
return error;
|
|
168
|
+
},
|
|
169
|
+
get done() {
|
|
170
|
+
return done;
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-svelte",
|
|
3
|
-
"version": "0.37.
|
|
3
|
+
"version": "0.37.10",
|
|
4
4
|
"description": "Svelte 5 components for SMRT user management - auth, users, tenants, roles, permissions, groups",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"smrtRawPrimitives": "strict",
|
|
@@ -46,6 +46,12 @@
|
|
|
46
46
|
"svelte": "./dist/browser-ai/svelte/index.js",
|
|
47
47
|
"import": "./dist/browser-ai/svelte/index.js",
|
|
48
48
|
"default": "./dist/browser-ai/svelte/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./web": {
|
|
51
|
+
"types": "./dist/web/index.d.ts",
|
|
52
|
+
"svelte": "./dist/web/index.js",
|
|
53
|
+
"import": "./dist/web/index.js",
|
|
54
|
+
"default": "./dist/web/index.js"
|
|
49
55
|
}
|
|
50
56
|
},
|
|
51
57
|
"files": [
|
|
@@ -77,10 +83,13 @@
|
|
|
77
83
|
},
|
|
78
84
|
"dependencies": {
|
|
79
85
|
"@happyvertical/logger": "^0.74.11",
|
|
86
|
+
"@tanstack/db": "^0.6.14",
|
|
87
|
+
"@tanstack/svelte-db": "^0.1.91",
|
|
80
88
|
"esm-env": "^1.2.2",
|
|
81
|
-
"@happyvertical/smrt-
|
|
82
|
-
"@happyvertical/smrt-
|
|
83
|
-
"@happyvertical/smrt-
|
|
89
|
+
"@happyvertical/smrt-languages": "0.37.10",
|
|
90
|
+
"@happyvertical/smrt-types": "0.37.10",
|
|
91
|
+
"@happyvertical/smrt-ui": "0.37.10",
|
|
92
|
+
"@happyvertical/smrt-web": "0.37.10"
|
|
84
93
|
},
|
|
85
94
|
"peerDependencies": {
|
|
86
95
|
"@huggingface/transformers": ">=3.8.1",
|