@jskit-ai/kernel 0.1.147 → 0.1.149
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/client/moduleBootstrap.js +54 -54
- package/client/moduleBootstrap.test.js +12 -12
- package/client/{descriptorSections.js → packageMetadataSections.js} +15 -15
- package/client/vite/clientBootstrapPlugin.js +67 -100
- package/client/vite/clientBootstrapPlugin.test.js +177 -238
- package/internal/node/installedPackages.js +283 -0
- package/package.json +1 -1
- package/server/platform/providerRuntime/{descriptorCatalog.js → packageCatalog.js} +32 -47
- package/server/platform/providerRuntime/providerLoader.js +18 -18
- package/server/platform/providerRuntime.js +15 -22
- package/server/platform/providerRuntime.test.js +56 -171
- package/server/platform/surfaceRuntime.test.js +1 -1
- package/server/support/index.js +6 -0
- package/server/support/shellOutlets.js +15 -51
- package/server/support/shellOutlets.test.js +23 -26
- package/shared/support/generatedUiContract.js +1 -1
- package/shared/support/generatedUiContract.test.js +11 -1
- package/shared/validators/schemaDefinitions.test.js +39 -0
- package/internal/node/installedPackageDescriptor.js +0 -125
- package/server/platform/providerRuntime/lockfile.js +0 -27
- package/shared/support/packageDescriptor.test.js +0 -147
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
collectRootDependencySpecifiers,
|
|
5
|
+
discoverInstalledPackages
|
|
6
|
+
} from "../../internal/node/installedPackages.js";
|
|
4
7
|
import { normalizeObject } from "../../shared/support/normalize.js";
|
|
5
8
|
import { sortStrings } from "../../shared/support/sorting.js";
|
|
6
9
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "../
|
|
10
|
+
normalizePackageMetadataClientProviders,
|
|
11
|
+
normalizePackageMetadataClientOptimizeSpecifiers,
|
|
12
|
+
normalizePackageMetadataUiRoutes,
|
|
13
|
+
normalizeClientPackageMetadataSections
|
|
14
|
+
} from "../packageMetadataSections.js";
|
|
12
15
|
|
|
13
16
|
const CLIENT_BOOTSTRAP_VIRTUAL_ID = "virtual:jskit-client-bootstrap";
|
|
14
17
|
const CLIENT_BOOTSTRAP_RESOLVED_ID = `\0${CLIENT_BOOTSTRAP_VIRTUAL_ID}`;
|
|
@@ -54,35 +57,23 @@ function isPathInsideRoot(rootPath, candidatePath) {
|
|
|
54
57
|
* That hash does not change when local source changes, which lets a browser reuse stale client code
|
|
55
58
|
* even after Vite restarts.
|
|
56
59
|
*
|
|
57
|
-
* Build this table from every
|
|
60
|
+
* Build this table from every local package declared by the app, not only packages with a ./client export.
|
|
58
61
|
* Resolving only the bootstrap entry is insufficient: a local client can use bare imports from another
|
|
59
62
|
* local package's root, shared entry, or exported subpath and accidentally re-enter node_modules caching.
|
|
60
63
|
*/
|
|
61
|
-
async function resolveLocalPackageSources({ appRoot
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
packages.push(
|
|
77
|
-
Object.freeze({
|
|
78
|
-
packageId,
|
|
79
|
-
installedPackageRoot: path.resolve(appRoot, "node_modules", ...packageId.split("/")),
|
|
80
|
-
sourcePackageRoot: path.resolve(appRoot, packagePath)
|
|
81
|
-
})
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return Object.freeze(packages);
|
|
64
|
+
async function resolveLocalPackageSources({ appRoot }) {
|
|
65
|
+
const installedPackages = await discoverInstalledPackages({ appRoot });
|
|
66
|
+
return Object.freeze(
|
|
67
|
+
installedPackages
|
|
68
|
+
.filter((entry) => LOCAL_PACKAGE_SOURCE_TYPES.has(entry.sourceType))
|
|
69
|
+
.map((entry) =>
|
|
70
|
+
Object.freeze({
|
|
71
|
+
packageId: entry.packageId,
|
|
72
|
+
installedPackageRoot: entry.installedPackageRoot,
|
|
73
|
+
sourcePackageRoot: entry.sourcePackageRoot
|
|
74
|
+
})
|
|
75
|
+
)
|
|
76
|
+
);
|
|
86
77
|
}
|
|
87
78
|
|
|
88
79
|
function splitSpecifierSuffix(source) {
|
|
@@ -126,37 +117,23 @@ function resolveCanonicalLocalPackageId(resolvedId, localPackage) {
|
|
|
126
117
|
: "";
|
|
127
118
|
}
|
|
128
119
|
|
|
129
|
-
async function resolveInstalledClientModules({ appRoot
|
|
130
|
-
const
|
|
131
|
-
const lockPayload = await readJsonFile(absoluteLockPath, {});
|
|
132
|
-
const installedPackages = normalizeObject(lockPayload.installedPackages);
|
|
133
|
-
const packageIds = sortStrings(Object.keys(installedPackages));
|
|
134
|
-
|
|
120
|
+
async function resolveInstalledClientModules({ appRoot }) {
|
|
121
|
+
const installedPackages = await discoverInstalledPackages({ appRoot });
|
|
135
122
|
const modules = [];
|
|
136
|
-
for (const
|
|
137
|
-
|
|
138
|
-
const packageJsonPath = path.resolve(appRoot, "node_modules", ...packageId.split("/"), "package.json");
|
|
139
|
-
const packageJson = await readJsonFile(packageJsonPath, {});
|
|
140
|
-
if (!hasClientExport(packageJson)) {
|
|
123
|
+
for (const installedPackage of installedPackages) {
|
|
124
|
+
if (!hasClientExport(installedPackage.packageJson)) {
|
|
141
125
|
continue;
|
|
142
126
|
}
|
|
143
|
-
|
|
144
|
-
const descriptorRecord = await loadInstalledPackageDescriptor({
|
|
145
|
-
appRoot,
|
|
146
|
-
packageId,
|
|
147
|
-
installedPackageState,
|
|
148
|
-
required: false
|
|
149
|
-
});
|
|
150
|
-
const descriptorSections = normalizeClientDescriptorSections(descriptorRecord.descriptor);
|
|
127
|
+
const packageMetadataSections = normalizeClientPackageMetadataSections(installedPackage.packageMetadata);
|
|
151
128
|
|
|
152
129
|
modules.push(
|
|
153
130
|
Object.freeze({
|
|
154
|
-
packageId,
|
|
155
|
-
sourceType:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
131
|
+
packageId: installedPackage.packageId,
|
|
132
|
+
sourceType: installedPackage.sourceType,
|
|
133
|
+
packageMetadataUiRoutes: packageMetadataSections.packageMetadataUiRoutes,
|
|
134
|
+
packageMetadataClientProviders: packageMetadataSections.packageMetadataClientProviders,
|
|
135
|
+
packageMetadataClientOptimizeIncludeSpecifiers: packageMetadataSections.packageMetadataClientOptimizeIncludeSpecifiers,
|
|
136
|
+
packageMetadataClientOptimizeExcludeSpecifiers: packageMetadataSections.packageMetadataClientOptimizeExcludeSpecifiers
|
|
160
137
|
})
|
|
161
138
|
);
|
|
162
139
|
}
|
|
@@ -169,26 +146,20 @@ async function resolveInstalledClientPackageIds(options) {
|
|
|
169
146
|
return Object.freeze(modules.map((entry) => entry.packageId));
|
|
170
147
|
}
|
|
171
148
|
|
|
172
|
-
async function resolveLocalScopePackageIds({ appRoot
|
|
173
|
-
const absoluteLockPath = path.resolve(appRoot, lockPath);
|
|
174
|
-
const lockPayload = await readJsonFile(absoluteLockPath, {});
|
|
175
|
-
const installedPackages = normalizeObject(lockPayload.installedPackages);
|
|
176
|
-
const localScopeFromLock = Object.keys(installedPackages).filter((packageId) => isLocalScopePackageId(packageId));
|
|
177
|
-
|
|
149
|
+
async function resolveLocalScopePackageIds({ appRoot }) {
|
|
178
150
|
const appPackageJson = await readJsonFile(path.resolve(appRoot, "package.json"), {});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return Object.freeze(sortStrings([...localScopeFromLock, ...localScopeFromPackageJson]));
|
|
151
|
+
return Object.freeze(
|
|
152
|
+
sortStrings(
|
|
153
|
+
[...collectRootDependencySpecifiers(appPackageJson).keys()].filter((packageId) =>
|
|
154
|
+
isLocalScopePackageId(packageId)
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
);
|
|
187
158
|
}
|
|
188
159
|
|
|
189
|
-
function
|
|
160
|
+
function normalizeClientModulePackageMetadataEntries(value) {
|
|
190
161
|
const items = Array.isArray(value) ? value : [];
|
|
191
|
-
const
|
|
162
|
+
const packageMetadataEntries = [];
|
|
192
163
|
|
|
193
164
|
for (const item of items) {
|
|
194
165
|
const record = normalizeObject(item);
|
|
@@ -197,33 +168,33 @@ function normalizeClientModuleDescriptors(value) {
|
|
|
197
168
|
continue;
|
|
198
169
|
}
|
|
199
170
|
const sourceType = String(record.sourceType || "").trim().toLowerCase();
|
|
200
|
-
|
|
171
|
+
packageMetadataEntries.push({
|
|
201
172
|
packageId,
|
|
202
173
|
sourceType,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
record.
|
|
174
|
+
packageMetadataUiRoutes: normalizePackageMetadataUiRoutes(record.packageMetadataUiRoutes),
|
|
175
|
+
packageMetadataClientProviders: normalizePackageMetadataClientProviders(record.packageMetadataClientProviders),
|
|
176
|
+
packageMetadataClientOptimizeIncludeSpecifiers: normalizePackageMetadataClientOptimizeSpecifiers(
|
|
177
|
+
record.packageMetadataClientOptimizeIncludeSpecifiers
|
|
207
178
|
),
|
|
208
|
-
|
|
209
|
-
record.
|
|
179
|
+
packageMetadataClientOptimizeExcludeSpecifiers: normalizePackageMetadataClientOptimizeSpecifiers(
|
|
180
|
+
record.packageMetadataClientOptimizeExcludeSpecifiers
|
|
210
181
|
)
|
|
211
182
|
});
|
|
212
183
|
}
|
|
213
184
|
|
|
214
185
|
return Object.freeze(
|
|
215
|
-
|
|
186
|
+
packageMetadataEntries.sort((left, right) => left.packageId.localeCompare(right.packageId))
|
|
216
187
|
);
|
|
217
188
|
}
|
|
218
189
|
|
|
219
190
|
function createVirtualModuleSource(clientModules = []) {
|
|
220
|
-
const
|
|
221
|
-
const importLines =
|
|
191
|
+
const modulePackageMetadataEntries = normalizeClientModulePackageMetadataEntries(clientModules);
|
|
192
|
+
const importLines = modulePackageMetadataEntries.map(
|
|
222
193
|
(entry, index) => `import * as clientModule${index} from ${JSON.stringify(`${entry.packageId}/client`)};`
|
|
223
194
|
);
|
|
224
|
-
const moduleEntries =
|
|
195
|
+
const moduleEntries = modulePackageMetadataEntries.map(
|
|
225
196
|
(entry, index) =>
|
|
226
|
-
` { packageId: ${JSON.stringify(entry.packageId)}, module: clientModule${index},
|
|
197
|
+
` { packageId: ${JSON.stringify(entry.packageId)}, module: clientModule${index}, packageMetadataUiRoutes: ${JSON.stringify(entry.packageMetadataUiRoutes)}, packageMetadataClientProviders: ${JSON.stringify(entry.packageMetadataClientProviders)} }`
|
|
227
198
|
);
|
|
228
199
|
|
|
229
200
|
const entriesSource = moduleEntries.length > 0 ? moduleEntries.join(",\n") : "";
|
|
@@ -247,26 +218,26 @@ export { installedClientModules, bootInstalledClientModules };
|
|
|
247
218
|
|
|
248
219
|
// Vite-only: this Set-based source-type filter exists solely to drive optimizeDeps include/exclude decisions.
|
|
249
220
|
function resolveClientOptimizeExcludeSpecifiers(clientModules = []) {
|
|
250
|
-
const
|
|
221
|
+
const modulePackageMetadataEntries = normalizeClientModulePackageMetadataEntries(clientModules);
|
|
251
222
|
return sortStrings(
|
|
252
223
|
[
|
|
253
|
-
...
|
|
224
|
+
...modulePackageMetadataEntries
|
|
254
225
|
.filter((entry) => LOCAL_PACKAGE_SOURCE_TYPES.has(entry.sourceType))
|
|
255
226
|
.flatMap((entry) => [entry.packageId, `${entry.packageId}/shared`, `${entry.packageId}/client`]),
|
|
256
|
-
...
|
|
227
|
+
...modulePackageMetadataEntries.flatMap((entry) => entry.packageMetadataClientOptimizeExcludeSpecifiers || [])
|
|
257
228
|
]
|
|
258
229
|
);
|
|
259
230
|
}
|
|
260
231
|
|
|
261
232
|
function resolveClientOptimizeIncludeSpecifiers(clientModules = [], excludeSpecifiers = []) {
|
|
262
|
-
const
|
|
233
|
+
const modulePackageMetadataEntries = normalizeClientModulePackageMetadataEntries(clientModules);
|
|
263
234
|
const excluded = new Set(sortStrings(excludeSpecifiers));
|
|
264
235
|
return sortStrings(
|
|
265
236
|
[
|
|
266
|
-
...
|
|
237
|
+
...modulePackageMetadataEntries
|
|
267
238
|
.filter((entry) => !LOCAL_PACKAGE_SOURCE_TYPES.has(entry.sourceType))
|
|
268
239
|
.map((entry) => `${entry.packageId}/client`),
|
|
269
|
-
...
|
|
240
|
+
...modulePackageMetadataEntries.flatMap((entry) => entry.packageMetadataClientOptimizeIncludeSpecifiers || [])
|
|
270
241
|
].filter((specifier) => !excluded.has(specifier))
|
|
271
242
|
);
|
|
272
243
|
}
|
|
@@ -283,7 +254,7 @@ function resolveClientRuntimeDedupeSpecifiers(userResolveConfig = {}) {
|
|
|
283
254
|
return sortStrings([...userDedupe, ...CLIENT_RUNTIME_DEDUPE_SPECIFIERS]);
|
|
284
255
|
}
|
|
285
256
|
|
|
286
|
-
function createJskitClientBootstrapPlugin(
|
|
257
|
+
function createJskitClientBootstrapPlugin() {
|
|
287
258
|
let appRoot = process.cwd();
|
|
288
259
|
let localPackages = Object.freeze([]);
|
|
289
260
|
let resolvePackageSpecifier = null;
|
|
@@ -295,17 +266,14 @@ function createJskitClientBootstrapPlugin({ lockPath = ".jskit/lock.json" } = {}
|
|
|
295
266
|
async config(userConfig = {}) {
|
|
296
267
|
appRoot = process.cwd();
|
|
297
268
|
const clientModules = await resolveInstalledClientModules({
|
|
298
|
-
appRoot
|
|
299
|
-
lockPath
|
|
269
|
+
appRoot
|
|
300
270
|
});
|
|
301
271
|
const localScopePackageIds = await resolveLocalScopePackageIds({
|
|
302
|
-
appRoot
|
|
303
|
-
lockPath
|
|
272
|
+
appRoot
|
|
304
273
|
});
|
|
305
274
|
const userResolve = normalizeObject(userConfig.resolve);
|
|
306
275
|
localPackages = await resolveLocalPackageSources({
|
|
307
|
-
appRoot
|
|
308
|
-
lockPath
|
|
276
|
+
appRoot
|
|
309
277
|
});
|
|
310
278
|
const clientExcludeSpecifiers = resolveClientOptimizeExcludeSpecifiers(clientModules);
|
|
311
279
|
const localScopeExcludeSpecifiers = resolveLocalScopeOptimizeExcludeSpecifiers(localScopePackageIds);
|
|
@@ -364,8 +332,7 @@ function createJskitClientBootstrapPlugin({ lockPath = ".jskit/lock.json" } = {}
|
|
|
364
332
|
}
|
|
365
333
|
|
|
366
334
|
const clientModules = await resolveInstalledClientModules({
|
|
367
|
-
appRoot
|
|
368
|
-
lockPath
|
|
335
|
+
appRoot
|
|
369
336
|
});
|
|
370
337
|
|
|
371
338
|
return createVirtualModuleSource(clientModules);
|