@jskit-ai/shell-web 0.1.162 → 0.1.164

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 (46) hide show
  1. package/fixtures/adaptive-shell/src/ScreenPage.vue +1 -1
  2. package/package.json +8 -253
  3. package/patterns/application-shell/PATTERN.md +66 -0
  4. package/{templates → patterns/application-shell/example}/expected-existing/src/pages/home/index.vue +8 -8
  5. package/{templates → patterns/application-shell/example}/src/pages/home/index.vue +8 -8
  6. package/{templates → patterns/application-shell/example}/src/pages/home/settings/general/index.vue +1 -1
  7. package/{templates → patterns/application-shell/example}/src/pages/home/settings.vue +8 -8
  8. package/patterns/page-and-placement/PATTERN.md +76 -0
  9. package/patterns/page-and-placement/example/packages/main/src/client/providers/MainClientProvider.js +14 -0
  10. package/patterns/page-and-placement/example/src/components/SyncStatusElement.vue +16 -0
  11. package/patterns/page-and-placement/example/src/pages/home/reports/activity.vue +8 -0
  12. package/patterns/page-and-placement/example/src/pages/home/reports/index.vue +7 -0
  13. package/patterns/page-and-placement/example/src/pages/home/reports/overview.vue +8 -0
  14. package/patterns/page-and-placement/example/src/pages/home/reports.vue +33 -0
  15. package/patterns/page-and-placement/example/src/placement.js +52 -0
  16. package/patterns/page-and-placement/example/src/placementTopology.js +29 -0
  17. package/src/client/bootstrap/bootstrapPayloadHandlerRegistry.js +30 -42
  18. package/src/client/bootstrap/index.js +2 -3
  19. package/src/client/index.js +2 -11
  20. package/src/client/placement/runtime.js +9 -12
  21. package/src/client/providers/ShellWebClientProvider.js +95 -129
  22. package/src/client/requestRecovery/runtime.js +9 -29
  23. package/src/client/runtime/bootstrapRuntime.js +18 -29
  24. package/src/test/adaptiveShellSmoke.js +3 -9
  25. package/test/bootstrapRuntime.test.js +10 -61
  26. package/test/pageAndPlacementPattern.test.js +38 -0
  27. package/test/placementRuntime.test.js +36 -50
  28. package/test/playwrightContract.test.js +2 -12
  29. package/test/provider.test.js +126 -737
  30. package/test/settingsPlacementContract.test.js +75 -126
  31. package/src/server/support/localLinkItemScaffolds.js +0 -80
  32. package/test/bootstrapClaimContract.test.js +0 -76
  33. package/test/linkItemScaffoldContract.test.js +0 -248
  34. /package/{templates → patterns/application-shell/example}/expected-existing/src/App.vue +0 -0
  35. /package/{templates → patterns/application-shell/example}/expected-existing/src/pages/home.vue +0 -0
  36. /package/{templates → patterns/application-shell/example}/src/App.vue +0 -0
  37. /package/{templates → patterns/application-shell/example}/src/components/ShellLayout.vue +0 -0
  38. /package/{templates → patterns/application-shell/example}/src/components/menus/MenuLinkItem.vue +0 -0
  39. /package/{templates → patterns/application-shell/example}/src/components/menus/SurfaceAwareMenuLinkItem.vue +0 -0
  40. /package/{templates → patterns/application-shell/example}/src/components/menus/TabLinkItem.vue +0 -0
  41. /package/{templates → patterns/application-shell/example}/src/error.js +0 -0
  42. /package/{templates → patterns/application-shell/example}/src/pages/home/settings/index.vue +0 -0
  43. /package/{templates → patterns/application-shell/example}/src/pages/home.vue +0 -0
  44. /package/{templates → patterns/application-shell/example}/src/placement.js +0 -0
  45. /package/{templates → patterns/application-shell/example}/src/placementTopology.js +0 -0
  46. /package/{templates → patterns/application-shell/example}/tests/e2e/adaptive-shell.spec.ts +0 -0
@@ -1,248 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import path from "node:path";
3
- import test from "node:test";
4
- import { readFile } from "node:fs/promises";
5
- import { fileURLToPath } from "node:url";
6
- import packageJson from "../package.json" with { type: "json" };
7
-
8
- const packageMetadata = packageJson.jskit;
9
- import {
10
- LOCAL_LINK_ITEM_COMPONENT_DEFINITIONS,
11
- findLocalLinkItemDefinition,
12
- readLocalLinkItemComponentSource
13
- } from "../src/server/support/localLinkItemScaffolds.js";
14
-
15
- const TEST_DIRECTORY = path.dirname(fileURLToPath(import.meta.url));
16
- const PACKAGE_DIR = path.resolve(TEST_DIRECTORY, "..");
17
-
18
- function findFileMutation(id) {
19
- const files = packageMetadata?.mutations?.files;
20
- return Array.isArray(files)
21
- ? files.find((entry) => String(entry?.id || "").trim() === id) || null
22
- : null;
23
- }
24
-
25
- function findSourceMutation(id) {
26
- const sourceMutations = packageMetadata?.mutations?.source;
27
- return Array.isArray(sourceMutations)
28
- ? sourceMutations.find((entry) => String(entry?.id || "").trim() === id) || null
29
- : null;
30
- }
31
-
32
- test("shell-web exports generic link-item components for app-owned shell wrappers", async () => {
33
- const clientIndexSource = await readFile(path.join(PACKAGE_DIR, "src", "client", "index.js"), "utf8");
34
- assert.match(clientIndexSource, /ShellMenuLinkItem/);
35
- assert.match(clientIndexSource, /ShellSurfaceAwareMenuLinkItem/);
36
- assert.match(clientIndexSource, /ShellTabLinkItem/);
37
- assert.match(clientIndexSource, /ShellRouteTransition/);
38
-
39
- const packageJson = JSON.parse(await readFile(path.join(PACKAGE_DIR, "package.json"), "utf8"));
40
- assert.equal(
41
- packageJson?.exports?.["./client/components/ShellRouteTransition"],
42
- "./src/client/components/ShellRouteTransition.vue"
43
- );
44
- assert.equal(
45
- packageJson?.exports?.["./client/components/ShellMenuLinkItem"],
46
- "./src/client/components/ShellMenuLinkItem.vue"
47
- );
48
- assert.equal(
49
- packageJson?.exports?.["./client/components/ShellSurfaceAwareMenuLinkItem"],
50
- "./src/client/components/ShellSurfaceAwareMenuLinkItem.vue"
51
- );
52
- assert.equal(
53
- packageJson?.exports?.["./client/components/ShellTabLinkItem"],
54
- "./src/client/components/ShellTabLinkItem.vue"
55
- );
56
- assert.equal(
57
- packageJson?.exports?.["./server/support/localLinkItemScaffolds"],
58
- "./src/server/support/localLinkItemScaffolds.js"
59
- );
60
- });
61
-
62
- test("shell-web scaffolds app-owned local link-item wrappers under src/components/menus", async () => {
63
- const menuWrapperSource = await readFile(
64
- path.join(PACKAGE_DIR, "templates", "src", "components", "menus", "MenuLinkItem.vue"),
65
- "utf8"
66
- );
67
- const surfaceAwareWrapperSource = await readFile(
68
- path.join(PACKAGE_DIR, "templates", "src", "components", "menus", "SurfaceAwareMenuLinkItem.vue"),
69
- "utf8"
70
- );
71
- const tabWrapperSource = await readFile(
72
- path.join(PACKAGE_DIR, "templates", "src", "components", "menus", "TabLinkItem.vue"),
73
- "utf8"
74
- );
75
-
76
- assert.match(menuWrapperSource, /@jskit-ai\/shell-web\/client\/components\/ShellMenuLinkItem/);
77
- assert.match(surfaceAwareWrapperSource, /@jskit-ai\/shell-web\/client\/components\/ShellSurfaceAwareMenuLinkItem/);
78
- assert.match(tabWrapperSource, /@jskit-ai\/shell-web\/client\/components\/ShellTabLinkItem/);
79
- assert.match(menuWrapperSource, /exact:\s*\{/);
80
- assert.match(surfaceAwareWrapperSource, /exact:\s*\{/);
81
- assert.match(tabWrapperSource, /icon:\s*\{/);
82
-
83
- assert.deepEqual(findFileMutation("shell-web-component-menu-link-item"), {
84
- from: "templates/src/components/menus/MenuLinkItem.vue",
85
- to: "src/components/menus/MenuLinkItem.vue",
86
- ownership: "app",
87
- reason: "Install app-owned shell menu link-item scaffold for local placement customization.",
88
- category: "shell-web",
89
- id: "shell-web-component-menu-link-item"
90
- });
91
- assert.deepEqual(findFileMutation("shell-web-component-surface-aware-menu-link-item"), {
92
- from: "templates/src/components/menus/SurfaceAwareMenuLinkItem.vue",
93
- to: "src/components/menus/SurfaceAwareMenuLinkItem.vue",
94
- ownership: "app",
95
- reason: "Install app-owned surface-aware shell menu link-item scaffold for local placement customization.",
96
- category: "shell-web",
97
- id: "shell-web-component-surface-aware-menu-link-item"
98
- });
99
- assert.deepEqual(findFileMutation("shell-web-component-tab-link-item"), {
100
- from: "templates/src/components/menus/TabLinkItem.vue",
101
- to: "src/components/menus/TabLinkItem.vue",
102
- ownership: "app",
103
- reason: "Install app-owned shell tab link-item scaffold for local placement customization.",
104
- category: "shell-web",
105
- id: "shell-web-component-tab-link-item"
106
- });
107
-
108
- assert.deepEqual(
109
- LOCAL_LINK_ITEM_COMPONENT_DEFINITIONS.map((entry) => ({
110
- token: entry.token,
111
- componentFile: entry.componentFile,
112
- componentName: entry.componentName,
113
- templateFile: entry.templateFile
114
- })),
115
- [
116
- {
117
- token: "local.main.ui.menu-link-item",
118
- componentFile: "src/components/menus/MenuLinkItem.vue",
119
- componentName: "MenuLinkItem",
120
- templateFile: "templates/src/components/menus/MenuLinkItem.vue"
121
- },
122
- {
123
- token: "local.main.ui.surface-aware-menu-link-item",
124
- componentFile: "src/components/menus/SurfaceAwareMenuLinkItem.vue",
125
- componentName: "SurfaceAwareMenuLinkItem",
126
- templateFile: "templates/src/components/menus/SurfaceAwareMenuLinkItem.vue"
127
- },
128
- {
129
- token: "local.main.ui.tab-link-item",
130
- componentFile: "src/components/menus/TabLinkItem.vue",
131
- componentName: "TabLinkItem",
132
- templateFile: "templates/src/components/menus/TabLinkItem.vue"
133
- }
134
- ]
135
- );
136
- assert.equal(findLocalLinkItemDefinition("local.main.ui.tab-link-item")?.componentName, "TabLinkItem");
137
- assert.equal(await readLocalLinkItemComponentSource("local.main.ui.tab-link-item"), tabWrapperSource);
138
- });
139
-
140
- test("shell-web generic link items support the expected shared route and icon behavior", async () => {
141
- const shellMenuSource = await readFile(
142
- path.join(PACKAGE_DIR, "src", "client", "components", "ShellMenuLinkItem.vue"),
143
- "utf8"
144
- );
145
- const shellSurfaceAwareSource = await readFile(
146
- path.join(PACKAGE_DIR, "src", "client", "components", "ShellSurfaceAwareMenuLinkItem.vue"),
147
- "utf8"
148
- );
149
- const shellTabSource = await readFile(
150
- path.join(PACKAGE_DIR, "src", "client", "components", "ShellTabLinkItem.vue"),
151
- "utf8"
152
- );
153
-
154
- assert.match(shellMenuSource, /exact:\s*\{/);
155
- assert.match(shellMenuSource, /:exact="props\.exact"/);
156
- assert.match(shellMenuSource, /:aria-label="props\.label"/);
157
- assert.match(shellMenuSource, /ShellNavigationTooltip/);
158
- assert.match(shellMenuSource, /@keydown\.space="activateShellNavigationLinkOnSpace"/);
159
- assert.doesNotMatch(shellMenuSource, /v-tooltip="props\.label"/);
160
- assert.match(shellMenuSource, /class="shell-menu-link-item"/);
161
- assert.match(shellMenuSource, /min-height:\s*48px/);
162
- assert.match(shellSurfaceAwareSource, /exact:\s*\{/);
163
- assert.match(shellSurfaceAwareSource, /:exact="props\.exact"/);
164
- assert.match(shellSurfaceAwareSource, /:aria-label="props\.label"/);
165
- assert.match(shellSurfaceAwareSource, /ShellNavigationTooltip/);
166
- assert.match(shellSurfaceAwareSource, /@keydown\.space="activateShellNavigationLinkOnSpace"/);
167
- assert.doesNotMatch(shellSurfaceAwareSource, /v-tooltip="props\.label"/);
168
- assert.match(shellSurfaceAwareSource, /class="shell-menu-link-item"/);
169
- assert.match(shellSurfaceAwareSource, /min-height:\s*48px/);
170
- assert.match(shellTabSource, /icon:\s*\{/);
171
- assert.match(shellTabSource, /resolveMenuLinkIcon/);
172
- assert.match(shellTabSource, /<v-btn/);
173
- assert.match(shellTabSource, /stacked/);
174
- assert.match(shellTabSource, /min-height:\s*48px/);
175
- assert.match(shellTabSource, /<v-icon v-if="resolvedIcon" :icon="resolvedIcon" \/>/);
176
-
177
- const tooltipSource = await readFile(
178
- path.join(PACKAGE_DIR, "src", "client", "components", "ShellNavigationTooltip.vue"),
179
- "utf8"
180
- );
181
- assert.match(tooltipSource, /:theme="theme\.name\.value"/);
182
- assert.match(tooltipSource, /location="end"/);
183
- assert.match(tooltipSource, /:open-on-focus="true"/);
184
- assert.match(tooltipSource, /:open-on-hover="true"/);
185
- assert.match(tooltipSource, /--v-theme-inverse-surface, var\(--v-theme-on-surface\)/);
186
- assert.match(tooltipSource, /--v-theme-inverse-on-surface, var\(--v-theme-surface\)/);
187
- assert.match(tooltipSource, /opacity:\s*1\s*!important/);
188
- });
189
-
190
- test("shell-web binds the local link-item wrapper tokens into MainClientProvider", () => {
191
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-menu-link-item-import"), {
192
- op: "ensure-import",
193
- file: "packages/main/src/client/providers/MainClientProvider.js",
194
- defaultImport: "MenuLinkItem",
195
- from: "/src/components/menus/MenuLinkItem.vue",
196
- reason: "Bind app-owned shell menu link-item scaffold into local main client provider imports.",
197
- category: "shell-web",
198
- id: "shell-web-main-client-provider-menu-link-item-import"
199
- });
200
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-surface-aware-menu-link-item-import"), {
201
- op: "ensure-import",
202
- file: "packages/main/src/client/providers/MainClientProvider.js",
203
- defaultImport: "SurfaceAwareMenuLinkItem",
204
- from: "/src/components/menus/SurfaceAwareMenuLinkItem.vue",
205
- reason: "Bind app-owned shell surface-aware menu link-item scaffold into local main client provider imports.",
206
- category: "shell-web",
207
- id: "shell-web-main-client-provider-surface-aware-menu-link-item-import"
208
- });
209
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-tab-link-item-import"), {
210
- op: "ensure-import",
211
- file: "packages/main/src/client/providers/MainClientProvider.js",
212
- defaultImport: "TabLinkItem",
213
- from: "/src/components/menus/TabLinkItem.vue",
214
- reason: "Bind app-owned shell tab link-item scaffold into local main client provider imports.",
215
- category: "shell-web",
216
- id: "shell-web-main-client-provider-tab-link-item-import"
217
- });
218
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-menu-link-item-register"), {
219
- op: "ensure-call",
220
- file: "packages/main/src/client/providers/MainClientProvider.js",
221
- callee: "registerMainClientComponent",
222
- args: ["\"local.main.ui.menu-link-item\"", "() => MenuLinkItem"],
223
- beforeClass: "MainClientProvider",
224
- reason: "Bind app-owned shell menu link-item token into local main client provider registry.",
225
- category: "shell-web",
226
- id: "shell-web-main-client-provider-menu-link-item-register"
227
- });
228
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-surface-aware-menu-link-item-register"), {
229
- op: "ensure-call",
230
- file: "packages/main/src/client/providers/MainClientProvider.js",
231
- callee: "registerMainClientComponent",
232
- args: ["\"local.main.ui.surface-aware-menu-link-item\"", "() => SurfaceAwareMenuLinkItem"],
233
- beforeClass: "MainClientProvider",
234
- reason: "Bind app-owned shell surface-aware menu link-item token into local main client provider registry.",
235
- category: "shell-web",
236
- id: "shell-web-main-client-provider-surface-aware-menu-link-item-register"
237
- });
238
- assert.deepEqual(findSourceMutation("shell-web-main-client-provider-tab-link-item-register"), {
239
- op: "ensure-call",
240
- file: "packages/main/src/client/providers/MainClientProvider.js",
241
- callee: "registerMainClientComponent",
242
- args: ["\"local.main.ui.tab-link-item\"", "() => TabLinkItem"],
243
- beforeClass: "MainClientProvider",
244
- reason: "Bind app-owned shell tab link-item token into local main client provider registry.",
245
- category: "shell-web",
246
- id: "shell-web-main-client-provider-tab-link-item-register"
247
- });
248
- });