@jskit-ai/kernel 0.1.4

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 (185) hide show
  1. package/README.md +24 -0
  2. package/_testable/index.js +4 -0
  3. package/client/appConfig.js +33 -0
  4. package/client/componentInteraction.js +51 -0
  5. package/client/componentInteraction.test.js +111 -0
  6. package/client/descriptorSections.js +75 -0
  7. package/client/index.d.ts +70 -0
  8. package/client/index.js +3 -0
  9. package/client/logging.js +38 -0
  10. package/client/moduleBootstrap.js +670 -0
  11. package/client/moduleBootstrap.test.js +403 -0
  12. package/client/shellBootstrap.js +233 -0
  13. package/client/shellBootstrap.test.js +185 -0
  14. package/client/shellRouting.js +321 -0
  15. package/client/shellRouting.test.js +113 -0
  16. package/client/vite/clientBootstrapPlugin.js +259 -0
  17. package/client/vite/clientBootstrapPlugin.test.js +563 -0
  18. package/client/vite/index.js +3 -0
  19. package/internal/node/fileSystem.js +21 -0
  20. package/internal/node/installedPackageDescriptor.js +104 -0
  21. package/package.json +43 -0
  22. package/server/actions/ActionRuntimeServiceProvider.js +309 -0
  23. package/server/actions/ActionRuntimeServiceProvider.test.js +551 -0
  24. package/server/actions/index.js +8 -0
  25. package/server/container/ContainerCoreServiceProvider.js +27 -0
  26. package/server/container/index.js +10 -0
  27. package/server/exportPolicy.test.js +68 -0
  28. package/server/http/HttpFastifyServiceProvider.js +25 -0
  29. package/server/http/_testable/index.js +2 -0
  30. package/server/http/index.js +1 -0
  31. package/server/http/lib/controller.js +183 -0
  32. package/server/http/lib/controller.test.js +143 -0
  33. package/server/http/lib/errors.js +12 -0
  34. package/server/http/lib/httpRuntime.js +82 -0
  35. package/server/http/lib/index.js +18 -0
  36. package/server/http/lib/kernel.js +15 -0
  37. package/server/http/lib/kernel.test.js +880 -0
  38. package/server/http/lib/middlewareRuntime.js +149 -0
  39. package/server/http/lib/requestActionExecutor.js +258 -0
  40. package/server/http/lib/requestScope.js +59 -0
  41. package/server/http/lib/routeRegistration.js +165 -0
  42. package/server/http/lib/routeSupport.js +45 -0
  43. package/server/http/lib/routeValidator.js +469 -0
  44. package/server/http/lib/routeValidator.test.js +474 -0
  45. package/server/http/lib/router.js +206 -0
  46. package/server/kernel/KernelCoreServiceProvider.js +27 -0
  47. package/server/kernel/index.js +10 -0
  48. package/server/platform/PlatformServerRuntimeServiceProvider.js +30 -0
  49. package/server/platform/index.js +5 -0
  50. package/server/platform/providerRuntime/descriptorCatalog.js +170 -0
  51. package/server/platform/providerRuntime/helpers.js +45 -0
  52. package/server/platform/providerRuntime/lockfile.js +27 -0
  53. package/server/platform/providerRuntime/providerLoader.js +283 -0
  54. package/server/platform/providerRuntime.js +142 -0
  55. package/server/platform/providerRuntime.test.js +217 -0
  56. package/server/platform/runtime.js +40 -0
  57. package/server/platform/surfaceRuntime.js +150 -0
  58. package/server/platform/surfaceRuntime.test.js +136 -0
  59. package/server/registries/actionSurfaceSourceRegistry.js +150 -0
  60. package/server/registries/bootstrapPayloadContributorRegistry.js +41 -0
  61. package/server/registries/domainEventListenerRegistry.js +61 -0
  62. package/server/registries/index.js +36 -0
  63. package/server/registries/primitives.js +63 -0
  64. package/server/registries/routeVisibilityResolverRegistry.js +87 -0
  65. package/server/registries/serviceRegistrationRegistry.js +431 -0
  66. package/server/runtime/ServerRuntimeCoreServiceProvider.js +65 -0
  67. package/server/runtime/ServerRuntimeCoreServiceProvider.test.js +53 -0
  68. package/server/runtime/apiRoutePolicyParity.test.js +109 -0
  69. package/server/runtime/apiRouteRegistration.js +65 -0
  70. package/server/runtime/bootBootstrapRoutes.js +46 -0
  71. package/server/runtime/bootBootstrapRoutes.test.js +79 -0
  72. package/server/runtime/bootstrapContributors.test.js +114 -0
  73. package/server/runtime/canonicalJson.js +74 -0
  74. package/server/runtime/composition.js +142 -0
  75. package/server/runtime/domainEvents.test.js +114 -0
  76. package/server/runtime/domainRules.js +50 -0
  77. package/server/runtime/domainRules.test.js +87 -0
  78. package/server/runtime/entityChangeEvents.js +182 -0
  79. package/server/runtime/entityChangeEvents.test.js +211 -0
  80. package/server/runtime/errors.js +68 -0
  81. package/server/runtime/errors.test.js +73 -0
  82. package/server/runtime/fastifyBootstrap.js +372 -0
  83. package/server/runtime/fastifyBootstrap.test.js +194 -0
  84. package/server/runtime/index.js +6 -0
  85. package/server/runtime/integers.js +13 -0
  86. package/server/runtime/moduleConfig.js +269 -0
  87. package/server/runtime/moduleConfig.test.js +141 -0
  88. package/server/runtime/pagination.js +13 -0
  89. package/server/runtime/realtimeNormalization.js +21 -0
  90. package/server/runtime/requestUrl.js +38 -0
  91. package/server/runtime/routeUtils.js +20 -0
  92. package/server/runtime/runtimeAssembly.js +113 -0
  93. package/server/runtime/runtimeKernel.js +55 -0
  94. package/server/runtime/securityAudit.js +269 -0
  95. package/server/runtime/securityAudit.test.js +41 -0
  96. package/server/runtime/serviceAuthorization.js +113 -0
  97. package/server/runtime/serviceAuthorization.test.js +100 -0
  98. package/server/runtime/serviceRegistration.test.js +197 -0
  99. package/server/support/SupportCoreServiceProvider.js +25 -0
  100. package/server/support/appConfig.js +37 -0
  101. package/server/support/appConfig.test.js +94 -0
  102. package/server/support/defaultMissingHandler.js +7 -0
  103. package/server/support/index.js +2 -0
  104. package/server/support/routePolicyConfig.js +51 -0
  105. package/server/support/symlinkSafeRequire.js +78 -0
  106. package/server/support/symlinkSafeRequire.test.js +27 -0
  107. package/server/surface/SurfaceRoutingServiceProvider.js +27 -0
  108. package/server/surface/index.js +19 -0
  109. package/shared/actions/actionContributorHelpers.js +34 -0
  110. package/shared/actions/actionContributorHelpers.test.js +16 -0
  111. package/shared/actions/actionDefinitions.js +488 -0
  112. package/shared/actions/actionDefinitions.test.js +212 -0
  113. package/shared/actions/audit.js +7 -0
  114. package/shared/actions/executionContext.js +97 -0
  115. package/shared/actions/executionContext.test.js +66 -0
  116. package/shared/actions/idempotency.js +62 -0
  117. package/shared/actions/index.js +2 -0
  118. package/shared/actions/observability.js +10 -0
  119. package/shared/actions/pipeline.js +287 -0
  120. package/shared/actions/policies.js +342 -0
  121. package/shared/actions/policies.test.js +233 -0
  122. package/shared/actions/registry.js +187 -0
  123. package/shared/actions/registry.test.js +381 -0
  124. package/shared/actions/requestMeta.js +36 -0
  125. package/shared/actions/textNormalization.js +3 -0
  126. package/shared/actions/withActionDefaults.js +34 -0
  127. package/shared/index.js +2 -0
  128. package/shared/runtime/application.js +323 -0
  129. package/shared/runtime/container.js +261 -0
  130. package/shared/runtime/containerErrors.js +22 -0
  131. package/shared/runtime/index.js +18 -0
  132. package/shared/runtime/kernelErrors.js +20 -0
  133. package/shared/runtime/serviceProvider.js +13 -0
  134. package/shared/support/formatDateTime.js +10 -0
  135. package/shared/support/formatDateTime.test.js +15 -0
  136. package/shared/support/index.js +14 -0
  137. package/shared/support/linkPath.js +67 -0
  138. package/shared/support/linkPath.test.js +35 -0
  139. package/shared/support/normalize.js +116 -0
  140. package/shared/support/normalize.test.js +48 -0
  141. package/shared/support/packageDescriptor.test.js +121 -0
  142. package/shared/support/permissions.js +50 -0
  143. package/shared/support/pickOwnProperties.js +17 -0
  144. package/shared/support/pickOwnProperties.test.js +25 -0
  145. package/shared/support/policies.js +11 -0
  146. package/shared/support/queryPath.js +33 -0
  147. package/shared/support/queryPath.test.js +19 -0
  148. package/shared/support/queryResilience.js +34 -0
  149. package/shared/support/queryResilience.test.js +33 -0
  150. package/shared/support/returnToPath.js +153 -0
  151. package/shared/support/returnToPath.test.js +123 -0
  152. package/shared/support/sorting.js +15 -0
  153. package/shared/support/tokens.js +23 -0
  154. package/shared/support/tokens.test.js +17 -0
  155. package/shared/support/visibility.js +56 -0
  156. package/shared/support/visibility.test.js +45 -0
  157. package/shared/surface/apiPaths.js +84 -0
  158. package/shared/surface/escapeRegExp.js +5 -0
  159. package/shared/surface/index.js +6 -0
  160. package/shared/surface/paths.js +273 -0
  161. package/shared/surface/registry.js +135 -0
  162. package/shared/surface/registry.test.js +44 -0
  163. package/shared/surface/runtime.js +357 -0
  164. package/shared/surface/runtime.test.js +319 -0
  165. package/shared/validators/createCursorListValidator.js +42 -0
  166. package/shared/validators/createCursorListValidator.test.js +34 -0
  167. package/shared/validators/cursorPaginationQueryValidator.js +31 -0
  168. package/shared/validators/cursorPaginationQueryValidator.test.js +21 -0
  169. package/shared/validators/index.js +12 -0
  170. package/shared/validators/inputNormalization.js +13 -0
  171. package/shared/validators/mergeObjectSchemas.js +31 -0
  172. package/shared/validators/mergeObjectSchemas.test.js +67 -0
  173. package/shared/validators/mergeValidators.js +89 -0
  174. package/shared/validators/mergeValidators.test.js +116 -0
  175. package/shared/validators/nestValidator.js +53 -0
  176. package/shared/validators/nestValidator.test.js +60 -0
  177. package/shared/validators/recordIdParamsValidator.js +36 -0
  178. package/shared/validators/recordIdParamsValidator.test.js +20 -0
  179. package/shared/validators/resourceRequiredMetadata.js +41 -0
  180. package/shared/validators/resourceRequiredMetadata.test.js +49 -0
  181. package/test/barrelExposure.test.js +106 -0
  182. package/test/dynamicImportPolicy.test.js +89 -0
  183. package/test/exportsContract.test.js +168 -0
  184. package/test/routeInputContractGuard.test.js +78 -0
  185. package/test/surfaceIndependence.test.js +109 -0
@@ -0,0 +1,259 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { loadInstalledPackageDescriptor } from "../../internal/node/installedPackageDescriptor.js";
4
+ import { normalizeObject } from "../../shared/support/normalize.js";
5
+ import { sortStrings } from "../../shared/support/sorting.js";
6
+ import {
7
+ normalizeDescriptorClientProviders,
8
+ normalizeDescriptorClientOptimizeIncludeSpecifiers,
9
+ normalizeDescriptorUiRoutes,
10
+ normalizeClientDescriptorSections
11
+ } from "../descriptorSections.js";
12
+
13
+ const CLIENT_BOOTSTRAP_VIRTUAL_ID = "virtual:jskit-client-bootstrap";
14
+ const CLIENT_BOOTSTRAP_RESOLVED_ID = `\0${CLIENT_BOOTSTRAP_VIRTUAL_ID}`;
15
+ const CLIENT_RUNTIME_DEDUPE_SPECIFIERS = Object.freeze([
16
+ "@tanstack/vue-query",
17
+ "vue",
18
+ "vue-router",
19
+ "vuetify"
20
+ ]);
21
+
22
+ function isLocalScopePackageId(value) {
23
+ return String(value || "").trim().startsWith("@local/");
24
+ }
25
+
26
+ async function readJsonFile(filePath, fallback) {
27
+ try {
28
+ const source = await readFile(filePath, "utf8");
29
+ return JSON.parse(source);
30
+ } catch {
31
+ return fallback;
32
+ }
33
+ }
34
+
35
+ function hasClientExport(packageJson) {
36
+ const exportsMap = normalizeObject(packageJson?.exports);
37
+ return Boolean(exportsMap["./client"]);
38
+ }
39
+
40
+ async function resolveInstalledClientModules({ appRoot, lockPath }) {
41
+ const absoluteLockPath = path.resolve(appRoot, lockPath);
42
+ const lockPayload = await readJsonFile(absoluteLockPath, {});
43
+ const installedPackages = normalizeObject(lockPayload.installedPackages);
44
+ const packageIds = sortStrings(Object.keys(installedPackages));
45
+
46
+ const modules = [];
47
+ for (const packageId of packageIds) {
48
+ const installedPackageState = normalizeObject(installedPackages[packageId]);
49
+ const packageJsonPath = path.resolve(appRoot, "node_modules", ...packageId.split("/"), "package.json");
50
+ const packageJson = await readJsonFile(packageJsonPath, {});
51
+ if (!hasClientExport(packageJson)) {
52
+ continue;
53
+ }
54
+
55
+ const descriptorRecord = await loadInstalledPackageDescriptor({
56
+ appRoot,
57
+ packageId,
58
+ installedPackageState,
59
+ required: false
60
+ });
61
+ const descriptorSections = normalizeClientDescriptorSections(descriptorRecord.descriptor);
62
+
63
+ modules.push(
64
+ Object.freeze({
65
+ packageId,
66
+ sourceType: String(installedPackageState?.source?.type || "").trim().toLowerCase(),
67
+ descriptorUiRoutes: descriptorSections.descriptorUiRoutes,
68
+ descriptorClientProviders: descriptorSections.descriptorClientProviders,
69
+ descriptorClientOptimizeIncludeSpecifiers: descriptorSections.descriptorClientOptimizeIncludeSpecifiers
70
+ })
71
+ );
72
+ }
73
+
74
+ return Object.freeze(modules);
75
+ }
76
+
77
+ async function resolveInstalledClientPackageIds(options) {
78
+ const modules = await resolveInstalledClientModules(options);
79
+ return Object.freeze(modules.map((entry) => entry.packageId));
80
+ }
81
+
82
+ async function resolveLocalScopePackageIds({ appRoot, lockPath }) {
83
+ const absoluteLockPath = path.resolve(appRoot, lockPath);
84
+ const lockPayload = await readJsonFile(absoluteLockPath, {});
85
+ const installedPackages = normalizeObject(lockPayload.installedPackages);
86
+ const localScopeFromLock = Object.keys(installedPackages).filter((packageId) => isLocalScopePackageId(packageId));
87
+
88
+ const appPackageJson = await readJsonFile(path.resolve(appRoot, "package.json"), {});
89
+ const localScopeFromPackageJson = Object.keys({
90
+ ...normalizeObject(appPackageJson.dependencies),
91
+ ...normalizeObject(appPackageJson.devDependencies),
92
+ ...normalizeObject(appPackageJson.optionalDependencies),
93
+ ...normalizeObject(appPackageJson.peerDependencies)
94
+ }).filter((packageId) => isLocalScopePackageId(packageId));
95
+
96
+ return Object.freeze(sortStrings([...localScopeFromLock, ...localScopeFromPackageJson]));
97
+ }
98
+
99
+ function normalizeClientModuleDescriptors(value) {
100
+ const items = Array.isArray(value) ? value : [];
101
+ const descriptors = [];
102
+
103
+ for (const item of items) {
104
+ const record = normalizeObject(item);
105
+ const packageId = String(record.packageId || "").trim();
106
+ if (!packageId) {
107
+ continue;
108
+ }
109
+ const sourceType = String(record.sourceType || "").trim().toLowerCase();
110
+ descriptors.push({
111
+ packageId,
112
+ sourceType,
113
+ descriptorUiRoutes: normalizeDescriptorUiRoutes(record.descriptorUiRoutes),
114
+ descriptorClientProviders: normalizeDescriptorClientProviders(record.descriptorClientProviders),
115
+ descriptorClientOptimizeIncludeSpecifiers: normalizeDescriptorClientOptimizeIncludeSpecifiers(
116
+ record.descriptorClientOptimizeIncludeSpecifiers
117
+ )
118
+ });
119
+ }
120
+
121
+ return Object.freeze(
122
+ descriptors.sort((left, right) => left.packageId.localeCompare(right.packageId))
123
+ );
124
+ }
125
+
126
+ function createVirtualModuleSource(clientModules = []) {
127
+ const moduleDescriptors = normalizeClientModuleDescriptors(clientModules);
128
+ const importLines = moduleDescriptors.map(
129
+ (entry, index) => `import * as clientModule${index} from ${JSON.stringify(`${entry.packageId}/client`)};`
130
+ );
131
+ const moduleEntries = moduleDescriptors.map(
132
+ (entry, index) =>
133
+ ` { packageId: ${JSON.stringify(entry.packageId)}, module: clientModule${index}, descriptorUiRoutes: ${JSON.stringify(entry.descriptorUiRoutes)}, descriptorClientProviders: ${JSON.stringify(entry.descriptorClientProviders)} }`
134
+ );
135
+
136
+ const entriesSource = moduleEntries.length > 0 ? moduleEntries.join(",\n") : "";
137
+
138
+ return `${importLines.join("\n")}${importLines.length > 0 ? "\n\n" : ""}import { bootClientModules } from "@jskit-ai/kernel/client/moduleBootstrap";
139
+
140
+ const installedClientModules = Object.freeze([
141
+ ${entriesSource}
142
+ ]);
143
+
144
+ async function bootInstalledClientModules(context = {}) {
145
+ return bootClientModules({
146
+ ...context,
147
+ clientModules: installedClientModules
148
+ });
149
+ }
150
+
151
+ export { installedClientModules, bootInstalledClientModules };
152
+ `;
153
+ }
154
+
155
+ // Vite-only: this Set-based source-type filter exists solely to drive optimizeDeps include/exclude decisions.
156
+ function resolveClientOptimizeExcludeSpecifiers(clientModules = []) {
157
+ const moduleDescriptors = normalizeClientModuleDescriptors(clientModules);
158
+ const localSourceTypes = new Set(["local-package", "app-local-package"]);
159
+ return sortStrings(
160
+ moduleDescriptors
161
+ .filter((entry) => localSourceTypes.has(entry.sourceType))
162
+ .flatMap((entry) => [entry.packageId, `${entry.packageId}/shared`, `${entry.packageId}/client`])
163
+ );
164
+ }
165
+
166
+ function resolveClientOptimizeIncludeSpecifiers(clientModules = []) {
167
+ const moduleDescriptors = normalizeClientModuleDescriptors(clientModules);
168
+ const localSourceTypes = new Set(["local-package", "app-local-package"]);
169
+ return sortStrings(
170
+ [
171
+ ...moduleDescriptors
172
+ .filter((entry) => !localSourceTypes.has(entry.sourceType))
173
+ .map((entry) => `${entry.packageId}/client`),
174
+ ...moduleDescriptors.flatMap((entry) => entry.descriptorClientOptimizeIncludeSpecifiers || [])
175
+ ]
176
+ );
177
+ }
178
+
179
+ function resolveLocalScopeOptimizeExcludeSpecifiers(localScopePackageIds = []) {
180
+ return sortStrings(
181
+ localScopePackageIds.flatMap((packageId) => [packageId, `${packageId}/shared`, `${packageId}/client`])
182
+ );
183
+ }
184
+
185
+ function resolveClientRuntimeDedupeSpecifiers(userResolveConfig = {}) {
186
+ const resolveConfig = normalizeObject(userResolveConfig);
187
+ const userDedupe = sortStrings(resolveConfig.dedupe);
188
+ return sortStrings([...userDedupe, ...CLIENT_RUNTIME_DEDUPE_SPECIFIERS]);
189
+ }
190
+
191
+ function createJskitClientBootstrapPlugin({ lockPath = ".jskit/lock.json" } = {}) {
192
+ return {
193
+ name: "jskit-client-bootstrap",
194
+ async config(userConfig = {}) {
195
+ const appRoot = process.cwd();
196
+ const clientModules = await resolveInstalledClientModules({
197
+ appRoot,
198
+ lockPath
199
+ });
200
+ const localScopePackageIds = await resolveLocalScopePackageIds({
201
+ appRoot,
202
+ lockPath
203
+ });
204
+ const clientExcludeSpecifiers = resolveClientOptimizeExcludeSpecifiers(clientModules);
205
+ const localScopeExcludeSpecifiers = resolveLocalScopeOptimizeExcludeSpecifiers(localScopePackageIds);
206
+ const clientIncludeSpecifiers = resolveClientOptimizeIncludeSpecifiers(clientModules);
207
+ const userOptimizeDeps = normalizeObject(userConfig.optimizeDeps);
208
+ const userExclude = sortStrings(userOptimizeDeps.exclude);
209
+ const userInclude = sortStrings(userOptimizeDeps.include);
210
+ const exclude = sortStrings([...userExclude, ...clientExcludeSpecifiers, ...localScopeExcludeSpecifiers]);
211
+ const include = sortStrings([...userInclude, ...clientIncludeSpecifiers]);
212
+ const userResolve = normalizeObject(userConfig.resolve);
213
+ const dedupe = resolveClientRuntimeDedupeSpecifiers(userResolve);
214
+
215
+ return {
216
+ optimizeDeps: {
217
+ ...userOptimizeDeps,
218
+ include,
219
+ exclude
220
+ },
221
+ resolve: {
222
+ ...userResolve,
223
+ dedupe
224
+ }
225
+ };
226
+ },
227
+ resolveId(source) {
228
+ if (source === CLIENT_BOOTSTRAP_VIRTUAL_ID) {
229
+ return CLIENT_BOOTSTRAP_RESOLVED_ID;
230
+ }
231
+ return null;
232
+ },
233
+ async load(id) {
234
+ if (id !== CLIENT_BOOTSTRAP_RESOLVED_ID) {
235
+ return null;
236
+ }
237
+
238
+ const clientModules = await resolveInstalledClientModules({
239
+ appRoot: process.cwd(),
240
+ lockPath
241
+ });
242
+
243
+ return createVirtualModuleSource(clientModules);
244
+ }
245
+ };
246
+ }
247
+
248
+ export {
249
+ CLIENT_BOOTSTRAP_VIRTUAL_ID,
250
+ CLIENT_BOOTSTRAP_RESOLVED_ID,
251
+ createVirtualModuleSource,
252
+ resolveClientOptimizeIncludeSpecifiers,
253
+ resolveClientOptimizeExcludeSpecifiers,
254
+ resolveLocalScopeOptimizeExcludeSpecifiers,
255
+ resolveInstalledClientPackageIds,
256
+ resolveLocalScopePackageIds,
257
+ resolveInstalledClientModules,
258
+ createJskitClientBootstrapPlugin
259
+ };