every-plugin 3.0.0-rc.10 → 3.0.0-rc.12

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 (51) hide show
  1. package/dist/build/artifact-names.cjs +9 -1
  2. package/dist/build/artifact-names.cjs.map +1 -1
  3. package/dist/build/artifact-names.d.cts +1 -0
  4. package/dist/build/artifact-names.d.cts.map +1 -1
  5. package/dist/build/artifact-names.d.mts +1 -0
  6. package/dist/build/artifact-names.d.mts.map +1 -1
  7. package/dist/build/artifact-names.mjs +9 -1
  8. package/dist/build/artifact-names.mjs.map +1 -1
  9. package/dist/build/rspack/build-report-plugin.cjs +9 -3
  10. package/dist/build/rspack/build-report-plugin.cjs.map +1 -1
  11. package/dist/build/rspack/build-report-plugin.d.cts +12 -2
  12. package/dist/build/rspack/build-report-plugin.d.cts.map +1 -1
  13. package/dist/build/rspack/build-report-plugin.d.mts +12 -2
  14. package/dist/build/rspack/build-report-plugin.d.mts.map +1 -1
  15. package/dist/build/rspack/build-report-plugin.mjs +9 -3
  16. package/dist/build/rspack/build-report-plugin.mjs.map +1 -1
  17. package/dist/build/rspack/plugin.cjs +4 -2
  18. package/dist/build/rspack/plugin.cjs.map +1 -1
  19. package/dist/build/rspack/plugin.d.cts.map +1 -1
  20. package/dist/build/rspack/plugin.d.mts.map +1 -1
  21. package/dist/build/rspack/plugin.mjs +4 -2
  22. package/dist/build/rspack/plugin.mjs.map +1 -1
  23. package/dist/build/ui/hash-artifacts-plugin.cjs +4 -1
  24. package/dist/build/ui/hash-artifacts-plugin.cjs.map +1 -1
  25. package/dist/build/ui/hash-artifacts-plugin.d.cts +6 -0
  26. package/dist/build/ui/hash-artifacts-plugin.d.cts.map +1 -1
  27. package/dist/build/ui/hash-artifacts-plugin.d.mts +6 -0
  28. package/dist/build/ui/hash-artifacts-plugin.d.mts.map +1 -1
  29. package/dist/build/ui/hash-artifacts-plugin.mjs +4 -1
  30. package/dist/build/ui/hash-artifacts-plugin.mjs.map +1 -1
  31. package/dist/build/ui/rsbuild-config.cjs +6 -2
  32. package/dist/build/ui/rsbuild-config.cjs.map +1 -1
  33. package/dist/build/ui/rsbuild-config.mjs +7 -3
  34. package/dist/build/ui/rsbuild-config.mjs.map +1 -1
  35. package/dist/runtime/mf-config.cjs +1 -1
  36. package/dist/runtime/mf-config.mjs +1 -1
  37. package/dist/shared-deps-spec.cjs +13 -0
  38. package/dist/shared-deps-spec.cjs.map +1 -1
  39. package/dist/shared-deps-spec.d.cts +13 -1
  40. package/dist/shared-deps-spec.d.cts.map +1 -1
  41. package/dist/shared-deps-spec.d.mts +13 -1
  42. package/dist/shared-deps-spec.d.mts.map +1 -1
  43. package/dist/shared-deps-spec.mjs +13 -1
  44. package/dist/shared-deps-spec.mjs.map +1 -1
  45. package/package.json +2 -2
  46. package/src/build/artifact-names.ts +8 -0
  47. package/src/build/rspack/build-report-plugin.ts +20 -3
  48. package/src/build/rspack/plugin.ts +6 -2
  49. package/src/build/ui/hash-artifacts-plugin.ts +14 -1
  50. package/src/build/ui/rsbuild-config.ts +5 -1
  51. package/src/shared-deps-spec.ts +24 -0
@@ -5,6 +5,12 @@ interface HashArtifactsPluginOptions {
5
5
  entryBase: string;
6
6
  /** Absolute dist root this environment wrote (web: `dist`, node: `dist/ssr`). */
7
7
  distRoot: string;
8
+ /**
9
+ * The shared-singleton `name → version` map this build embedded — recorded
10
+ * in build-report.json so the version manifest carries shared-dep
11
+ * semantics (#546).
12
+ */
13
+ shared?: Record<string, string>;
8
14
  }
9
15
  /**
10
16
  * Emits the additive hashed copies for one environment's dist root (ticket:
@@ -1 +1 @@
1
- {"version":3,"file":"hash-artifacts-plugin.d.mts","names":[],"sources":["../../../src/build/ui/hash-artifacts-plugin.ts"],"mappings":";;UAWiB;;EAEf;;EAEA;;;;;;;;;;iBAsBc,oBAAoB,SAAS,6BAA6B"}
1
+ {"version":3,"file":"hash-artifacts-plugin.d.mts","names":[],"sources":["../../../src/build/ui/hash-artifacts-plugin.ts"],"mappings":";;UAWiB;;EAEf;;EAEA;;;;;;EAMA,SAAS;;;;;;;;;;iBAsBK,oBAAoB,SAAS,6BAA6B"}
@@ -47,7 +47,10 @@ function hashArtifactsPlugin(options) {
47
47
  if (!from) throw new Error(`[hash-artifacts] planned copy source missing: ${copy.from}`);
48
48
  fs.copyFileSync(from, path.join(distRoot, copy.to));
49
49
  }
50
- fs.writeFileSync(path.join(distRoot, "build-report.json"), `${JSON.stringify(BuildEntryReportSchema.parse(plan.report), null, 2)}\n`);
50
+ fs.writeFileSync(path.join(distRoot, "build-report.json"), `${JSON.stringify(BuildEntryReportSchema.parse({
51
+ ...plan.report,
52
+ ...options.shared ? { shared: options.shared } : {}
53
+ }), null, 2)}\n`);
51
54
  });
52
55
  }
53
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"hash-artifacts-plugin.mjs","names":[],"sources":["../../../src/build/ui/hash-artifacts-plugin.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RsbuildPlugin } from \"@rsbuild/core\";\nimport {\n BuildEntryReportSchema,\n findHashedEntry,\n MF_MANIFEST_FILENAME,\n planArtifactCopies,\n STYLE_FILENAME,\n} from \"../artifact-names\";\n\nexport interface HashArtifactsPluginOptions {\n /** The container entry's base name in this environment's dist root. */\n entryBase: string;\n /** Absolute dist root this environment wrote (web: `dist`, node: `dist/ssr`). */\n distRoot: string;\n}\n\nfunction listFiles(dir: string, out: string[] = []): string[] {\n for (const entry of fs\n .readdirSync(dir, { withFileTypes: true })\n .sort((a, b) => a.name.localeCompare(b.name))) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) listFiles(full, out);\n else out.push(path.relative(dir, full).split(path.sep).join(\"/\"));\n }\n return out;\n}\n\n/**\n * Emits the additive hashed copies for one environment's dist root (ticket:\n * atomic-deploys 01). The entry itself is hashed by the build (filename\n * template); this plugin adds immutable hashed copies of the fixed-name\n * browser artifacts (mf-manifest.json at the root, style.css under\n * static/css), and `build-report.json` for the deploy leg. Idempotent under\n * watch: same bytes → same hashed names.\n */\nexport function hashArtifactsPlugin(options: HashArtifactsPluginOptions): RsbuildPlugin {\n return {\n name: \"hash-artifacts\",\n setup(api) {\n api.onAfterEnvironmentCompile(() => {\n const distRoot = options.distRoot;\n if (!fs.existsSync(distRoot)) return;\n\n const resolveExisting = (name: string): string | null => {\n const candidates = [\n path.join(distRoot, name),\n path.join(distRoot, \"static\", \"css\", name),\n ];\n return candidates.find((candidate) => fs.existsSync(candidate)) ?? null;\n };\n\n const assetNames = listFiles(distRoot);\n const entry = findHashedEntry(assetNames, options.entryBase);\n if (!entry) return;\n\n const contents: Record<string, string> = {};\n for (const fixedName of [MF_MANIFEST_FILENAME, STYLE_FILENAME]) {\n const from = resolveExisting(fixedName);\n if (from) contents[fixedName] = fs.readFileSync(from, \"utf8\");\n }\n\n const plan = planArtifactCopies({ assetNames, entryBase: options.entryBase, contents });\n if (!plan) return;\n\n for (const copy of plan.copies) {\n const from = resolveExisting(copy.from);\n if (!from) throw new Error(`[hash-artifacts] planned copy source missing: ${copy.from}`);\n fs.copyFileSync(from, path.join(distRoot, copy.to));\n }\n fs.writeFileSync(\n path.join(distRoot, \"build-report.json\"),\n `${JSON.stringify(BuildEntryReportSchema.parse(plan.report), null, 2)}\\n`,\n );\n });\n },\n };\n}\n"],"mappings":";;;;;AAkBA,SAAS,UAAU,KAAa,MAAgB,CAAC,GAAa;CAC5D,KAAK,MAAM,SAAS,GACjB,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC,CAAC,CACzC,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;EAC/C,MAAM,OAAO,KAAK,KAAK,KAAK,MAAM,IAAI;EACtC,IAAI,MAAM,YAAY,GAAG,UAAU,MAAM,GAAG;OACvC,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;CAClE;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,oBAAoB,SAAoD;CACtF,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,IAAI,gCAAgC;IAClC,MAAM,WAAW,QAAQ;IACzB,IAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;IAE9B,MAAM,mBAAmB,SAAgC;KAKvD,OAAO,CAHL,KAAK,KAAK,UAAU,IAAI,GACxB,KAAK,KAAK,UAAU,UAAU,OAAO,IAAI,CAE3B,CAAC,CAAC,MAAM,cAAc,GAAG,WAAW,SAAS,CAAC,KAAK;IACrE;IAEA,MAAM,aAAa,UAAU,QAAQ;IAErC,IAAI,CADU,gBAAgB,YAAY,QAAQ,SACzC,GAAG;IAEZ,MAAM,WAAmC,CAAC;IAC1C,KAAK,MAAM,aAAa,CAAC,sBAAsB,cAAc,GAAG;KAC9D,MAAM,OAAO,gBAAgB,SAAS;KACtC,IAAI,MAAM,SAAS,aAAa,GAAG,aAAa,MAAM,MAAM;IAC9D;IAEA,MAAM,OAAO,mBAAmB;KAAE;KAAY,WAAW,QAAQ;KAAW;IAAS,CAAC;IACtF,IAAI,CAAC,MAAM;IAEX,KAAK,MAAM,QAAQ,KAAK,QAAQ;KAC9B,MAAM,OAAO,gBAAgB,KAAK,IAAI;KACtC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,iDAAiD,KAAK,MAAM;KACvF,GAAG,aAAa,MAAM,KAAK,KAAK,UAAU,KAAK,EAAE,CAAC;IACpD;IACA,GAAG,cACD,KAAK,KAAK,UAAU,mBAAmB,GACvC,GAAG,KAAK,UAAU,uBAAuB,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC,EAAE,GACxE;GACF,CAAC;EACH;CACF;AACF"}
1
+ {"version":3,"file":"hash-artifacts-plugin.mjs","names":[],"sources":["../../../src/build/ui/hash-artifacts-plugin.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RsbuildPlugin } from \"@rsbuild/core\";\nimport {\n BuildEntryReportSchema,\n findHashedEntry,\n MF_MANIFEST_FILENAME,\n planArtifactCopies,\n STYLE_FILENAME,\n} from \"../artifact-names\";\n\nexport interface HashArtifactsPluginOptions {\n /** The container entry's base name in this environment's dist root. */\n entryBase: string;\n /** Absolute dist root this environment wrote (web: `dist`, node: `dist/ssr`). */\n distRoot: string;\n /**\n * The shared-singleton `name → version` map this build embedded — recorded\n * in build-report.json so the version manifest carries shared-dep\n * semantics (#546).\n */\n shared?: Record<string, string>;\n}\n\nfunction listFiles(dir: string, out: string[] = []): string[] {\n for (const entry of fs\n .readdirSync(dir, { withFileTypes: true })\n .sort((a, b) => a.name.localeCompare(b.name))) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) listFiles(full, out);\n else out.push(path.relative(dir, full).split(path.sep).join(\"/\"));\n }\n return out;\n}\n\n/**\n * Emits the additive hashed copies for one environment's dist root (ticket:\n * atomic-deploys 01). The entry itself is hashed by the build (filename\n * template); this plugin adds immutable hashed copies of the fixed-name\n * browser artifacts (mf-manifest.json at the root, style.css under\n * static/css), and `build-report.json` for the deploy leg. Idempotent under\n * watch: same bytes → same hashed names.\n */\nexport function hashArtifactsPlugin(options: HashArtifactsPluginOptions): RsbuildPlugin {\n return {\n name: \"hash-artifacts\",\n setup(api) {\n api.onAfterEnvironmentCompile(() => {\n const distRoot = options.distRoot;\n if (!fs.existsSync(distRoot)) return;\n\n const resolveExisting = (name: string): string | null => {\n const candidates = [\n path.join(distRoot, name),\n path.join(distRoot, \"static\", \"css\", name),\n ];\n return candidates.find((candidate) => fs.existsSync(candidate)) ?? null;\n };\n\n const assetNames = listFiles(distRoot);\n const entry = findHashedEntry(assetNames, options.entryBase);\n if (!entry) return;\n\n const contents: Record<string, string> = {};\n for (const fixedName of [MF_MANIFEST_FILENAME, STYLE_FILENAME]) {\n const from = resolveExisting(fixedName);\n if (from) contents[fixedName] = fs.readFileSync(from, \"utf8\");\n }\n\n const plan = planArtifactCopies({ assetNames, entryBase: options.entryBase, contents });\n if (!plan) return;\n\n for (const copy of plan.copies) {\n const from = resolveExisting(copy.from);\n if (!from) throw new Error(`[hash-artifacts] planned copy source missing: ${copy.from}`);\n fs.copyFileSync(from, path.join(distRoot, copy.to));\n }\n fs.writeFileSync(\n path.join(distRoot, \"build-report.json\"),\n `${JSON.stringify(\n BuildEntryReportSchema.parse({\n ...plan.report,\n ...(options.shared ? { shared: options.shared } : {}),\n }),\n null,\n 2,\n )}\\n`,\n );\n });\n },\n };\n}\n"],"mappings":";;;;;AAwBA,SAAS,UAAU,KAAa,MAAgB,CAAC,GAAa;CAC5D,KAAK,MAAM,SAAS,GACjB,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC,CAAC,CACzC,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;EAC/C,MAAM,OAAO,KAAK,KAAK,KAAK,MAAM,IAAI;EACtC,IAAI,MAAM,YAAY,GAAG,UAAU,MAAM,GAAG;OACvC,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;CAClE;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,oBAAoB,SAAoD;CACtF,OAAO;EACL,MAAM;EACN,MAAM,KAAK;GACT,IAAI,gCAAgC;IAClC,MAAM,WAAW,QAAQ;IACzB,IAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;IAE9B,MAAM,mBAAmB,SAAgC;KAKvD,OAAO,CAHL,KAAK,KAAK,UAAU,IAAI,GACxB,KAAK,KAAK,UAAU,UAAU,OAAO,IAAI,CAE3B,CAAC,CAAC,MAAM,cAAc,GAAG,WAAW,SAAS,CAAC,KAAK;IACrE;IAEA,MAAM,aAAa,UAAU,QAAQ;IAErC,IAAI,CADU,gBAAgB,YAAY,QAAQ,SACzC,GAAG;IAEZ,MAAM,WAAmC,CAAC;IAC1C,KAAK,MAAM,aAAa,CAAC,sBAAsB,cAAc,GAAG;KAC9D,MAAM,OAAO,gBAAgB,SAAS;KACtC,IAAI,MAAM,SAAS,aAAa,GAAG,aAAa,MAAM,MAAM;IAC9D;IAEA,MAAM,OAAO,mBAAmB;KAAE;KAAY,WAAW,QAAQ;KAAW;IAAS,CAAC;IACtF,IAAI,CAAC,MAAM;IAEX,KAAK,MAAM,QAAQ,KAAK,QAAQ;KAC9B,MAAM,OAAO,gBAAgB,KAAK,IAAI;KACtC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,iDAAiD,KAAK,MAAM;KACvF,GAAG,aAAa,MAAM,KAAK,KAAK,UAAU,KAAK,EAAE,CAAC;IACpD;IACA,GAAG,cACD,KAAK,KAAK,UAAU,mBAAmB,GACvC,GAAG,KAAK,UACN,uBAAuB,MAAM;KAC3B,GAAG,KAAK;KACR,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;IACrD,CAAC,GACD,MACA,CACF,EAAE,GACJ;GACF,CAAC;EACH;CACF;AACF"}
@@ -36,6 +36,7 @@ function createUiRsbuildConfig(options) {
36
36
  role,
37
37
  workspaceRoot: workspaceRootAbsolute
38
38
  });
39
+ const uiSharedVersions = require_shared_deps_spec.sharedVersionRecord(uiSharedDeps);
39
40
  const isBuild = require_build_artifact_names.isBuildInvocation();
40
41
  const webEnvironment = {
41
42
  plugins: [
@@ -50,7 +51,8 @@ function createUiRsbuildConfig(options) {
50
51
  }, { environment: "web" }),
51
52
  ...isBuild ? [require_hash_artifacts_plugin.hashArtifactsPlugin({
52
53
  entryBase: "remoteEntry",
53
- distRoot: node_path.default.join(workspaceRootAbsolute, "dist")
54
+ distRoot: node_path.default.join(workspaceRootAbsolute, "dist"),
55
+ shared: uiSharedVersions
54
56
  })] : []
55
57
  ],
56
58
  source: {
@@ -88,6 +90,7 @@ function createUiRsbuildConfig(options) {
88
90
  target: "react",
89
91
  autoCodeSplitting: true,
90
92
  routeFileIgnorePattern: "\\.(test|spec)\\.(ts|tsx)$",
93
+ generatedRouteTree: node_path.default.join(workspaceRootAbsolute, "src/routeTree.gen.ts"),
91
94
  ...routesDirectory ? { routesDirectory } : {}
92
95
  }),
93
96
  new require_fix_mf_data_uri_plugin.FixMfDataUriPlugin()
@@ -133,7 +136,8 @@ function createUiRsbuildConfig(options) {
133
136
  require_build_ui_index.restoreManifestPublicPath(node_path.default.resolve(workspaceRootAbsolute, "dist", "ssr")),
134
137
  ...isBuild ? [require_hash_artifacts_plugin.hashArtifactsPlugin({
135
138
  entryBase: "remoteEntry.server",
136
- distRoot: node_path.default.resolve(workspaceRootAbsolute, "dist", "ssr")
139
+ distRoot: node_path.default.resolve(workspaceRootAbsolute, "dist", "ssr"),
140
+ shared: uiSharedVersions
137
141
  })] : []
138
142
  ],
139
143
  source: { entry: { index: nodeEntry } },
@@ -1 +1 @@
1
- {"version":3,"file":"rsbuild-config.cjs","names":["path","sanitizeContainerName","uiManifestGenPlugin","createUiSharedDeps","isBuildInvocation","pluginReact","pluginModuleFederation","uiEntryFilename","hashArtifactsPlugin","rspack","TanStackRouterRspack","FixMfDataUriPlugin","MANIFEST_FILENAME","restoreManifestPublicPath","defineConfig"],"sources":["../../../src/build/ui/rsbuild-config.ts"],"sourcesContent":["import path from \"node:path\";\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\nimport { defineConfig, type EnvironmentConfig, type RsbuildConfig, rspack } from \"@rsbuild/core\";\nimport { pluginReact } from \"@rsbuild/plugin-react\";\nimport { TanStackRouterRspack } from \"@tanstack/router-plugin/rspack\";\nimport { FixMfDataUriPlugin } from \"../../build/rspack\";\nimport { createUiSharedDeps } from \"../../shared-deps-spec\";\nimport { sanitizeContainerName } from \"../../ui/manifest/contract\";\nimport { isBuildInvocation, uiEntryFilename } from \"../artifact-names\";\nimport { hashArtifactsPlugin } from \"./hash-artifacts-plugin\";\nimport { MANIFEST_FILENAME, restoreManifestPublicPath } from \"./index\";\nimport { uiManifestGenPlugin } from \"./manifest-plugin\";\n\n/**\n * The full dual-environment rsbuild config for a manifest-composed ui source\n * (ADR 0008 §7 — the plugin build contract, not per-plugin config). The core\n * ui and every plugin ui source build from this one factory: `web` emits the\n * browser remote, `node` the commonjs SSR container; shared deps are strict\n * singletons in the given role.\n */\nexport interface UiRsbuildConfigOptions {\n /** the ui source root — contains package.json, src/, and the routes dir */\n workspaceRoot: string;\n /** the ui workspace's package.json (shared-dep version resolution) */\n pkg: {\n name: string;\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n /** core provides the shared singletons; plugin remotes consume (`import: false`) */\n role: \"provider\" | \"consumer\";\n /** the composition key written into manifest.gen.json (the config-side key) */\n manifestName: string;\n devPort: number;\n webEntry: string;\n webExposes: Record<string, string>;\n nodeEntry: string;\n nodeExposes: Record<string, string>;\n copy?: Array<{\n from: string;\n to: string;\n globOptions?: { ignore?: string[] };\n }>;\n define?: Record<string, string>;\n /** routes dir relative to the rsbuild cwd — folder-form ui sources live at\n * `ui/src/routes` while the build runs from the plugin root */\n routesDirectory?: string;\n}\n\nexport { sanitizeContainerName };\n\n/**\n * The node environment never owns the routeTree write: the web env's\n * generator produces identical content, and both environments resolve the\n * same on-disk tree. Redirecting the node write to scratch removes the\n * concurrent-writers race on src/routeTree.gen.ts (the generator's\n * \"Cannot overwrite\" retry noise).\n */\nconst NODE_ROUTE_TREE_SCRATCH = \"./node_modules/.cache/manifest-compose/routeTree.node.gen.ts\";\n\nexport function createUiRsbuildConfig(options: UiRsbuildConfigOptions): RsbuildConfig {\n const {\n workspaceRoot,\n pkg,\n role,\n manifestName,\n devPort,\n webEntry,\n webExposes,\n nodeEntry,\n nodeExposes,\n copy = [],\n define,\n routesDirectory,\n } = options;\n const workspaceRootAbsolute = path.resolve(workspaceRoot);\n const normalizedName = sanitizeContainerName(pkg.name);\n const manifestGen = () =>\n uiManifestGenPlugin({ workspaceRoot: workspaceRootAbsolute, pluginName: manifestName });\n const uiSharedDeps = createUiSharedDeps({ role, workspaceRoot: workspaceRootAbsolute });\n\n const isBuild = isBuildInvocation();\n\n const webEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild }),\n dts: false,\n exposes: webExposes,\n shared: uiSharedDeps,\n },\n { environment: \"web\" },\n ),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry\",\n distRoot: path.join(workspaceRootAbsolute, \"dist\"),\n }),\n ]\n : []),\n ],\n source: { entry: { index: webEntry }, ...(define ? { define } : {}) },\n resolve: { alias: { \"@\": path.join(workspaceRootAbsolute, \"src\") } },\n tools: {\n rspack: (config) => {\n const cssPlugin = config.plugins?.find((p) => p instanceof rspack.CssExtractRspackPlugin) as\n | { options?: Record<string, string> }\n | undefined;\n if (cssPlugin) {\n cssPlugin.options ??= {};\n cssPlugin.options.chunkFilename = \"static/css/async/[name].[contenthash].css\";\n }\n Object.assign(config, {\n target: \"web\",\n output: {\n ...config.output,\n publicPath: \"auto\",\n uniqueName: normalizedName,\n chunkFilename: \"static/js/async/[name].[contenthash].js\",\n crossOriginLoading: \"anonymous\",\n },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: true,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n output: {\n // Absolute: the ui source root owns dist even when the build cwd is the\n // parent plugin workspace (folder-form ui sources).\n distPath: {\n root: path.join(workspaceRootAbsolute, \"dist\"),\n css: \"static/css\",\n js: \"static/js\",\n },\n assetPrefix: \"auto\",\n filename: { js: \"[name].js\", css: \"style.css\" },\n copy: [\n ...copy,\n { from: path.join(workspaceRootAbsolute, \"src\", MANIFEST_FILENAME), to: \"./\" },\n ],\n },\n };\n\n // Dev without SSR skips the node environment: it exists for the host's dev\n // SSR container and nothing else. Builds always emit both.\n const includeNodeEnv =\n process.env.BOS_SSR === \"1\" ||\n process.env.DEPLOY === \"true\" ||\n process.env.NODE_ENV !== \"development\";\n\n const nodeEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild, server: true }),\n dts: false,\n exposes: nodeExposes,\n shared: uiSharedDeps,\n },\n { target: \"node\", environment: \"node\" },\n ),\n restoreManifestPublicPath(path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\")),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry.server\",\n distRoot: path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\"),\n }),\n ]\n : []),\n ],\n source: { entry: { index: nodeEntry } },\n resolve: {\n alias: {\n \"@\": path.join(workspaceRootAbsolute, \"src\"),\n \"@tanstack/react-devtools\": false,\n \"@tanstack/react-router-devtools\": false,\n },\n },\n tools: {\n rspack: (config) => {\n Object.assign(config, {\n output: { ...config.output, uniqueName: `${normalizedName}_server` },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n externals: [/^node:/],\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: false,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: NODE_ROUTE_TREE_SCRATCH,\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n // Absolute, like the web dist above — the node container must land in the\n // ui source root's dist/ssr where the host's local container server looks.\n output: { distPath: { root: path.join(workspaceRootAbsolute, \"dist\", \"ssr\") } },\n };\n\n return defineConfig({\n environments: {\n web: webEnvironment,\n ...(includeNodeEnv ? { node: nodeEnvironment } : {}),\n },\n dev: {\n lazyCompilation: false,\n progressBar: false,\n writeToDisk: true,\n client: { overlay: false },\n },\n server: {\n port: Number(process.env.PORT) || devPort,\n printUrls: ({ urls }) => urls.filter((url) => url.includes(\"localhost\")),\n headers: {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n },\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rsbuild-config.cjs","names":["path","sanitizeContainerName","uiManifestGenPlugin","createUiSharedDeps","sharedVersionRecord","isBuildInvocation","pluginReact","pluginModuleFederation","uiEntryFilename","hashArtifactsPlugin","rspack","TanStackRouterRspack","FixMfDataUriPlugin","MANIFEST_FILENAME","restoreManifestPublicPath","defineConfig"],"sources":["../../../src/build/ui/rsbuild-config.ts"],"sourcesContent":["import path from \"node:path\";\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\nimport { defineConfig, type EnvironmentConfig, type RsbuildConfig, rspack } from \"@rsbuild/core\";\nimport { pluginReact } from \"@rsbuild/plugin-react\";\nimport { TanStackRouterRspack } from \"@tanstack/router-plugin/rspack\";\nimport { FixMfDataUriPlugin } from \"../../build/rspack\";\nimport { createUiSharedDeps, sharedVersionRecord } from \"../../shared-deps-spec\";\nimport { sanitizeContainerName } from \"../../ui/manifest/contract\";\nimport { isBuildInvocation, uiEntryFilename } from \"../artifact-names\";\nimport { hashArtifactsPlugin } from \"./hash-artifacts-plugin\";\nimport { MANIFEST_FILENAME, restoreManifestPublicPath } from \"./index\";\nimport { uiManifestGenPlugin } from \"./manifest-plugin\";\n\n/**\n * The full dual-environment rsbuild config for a manifest-composed ui source\n * (ADR 0008 §7 — the plugin build contract, not per-plugin config). The core\n * ui and every plugin ui source build from this one factory: `web` emits the\n * browser remote, `node` the commonjs SSR container; shared deps are strict\n * singletons in the given role.\n */\nexport interface UiRsbuildConfigOptions {\n /** the ui source root — contains package.json, src/, and the routes dir */\n workspaceRoot: string;\n /** the ui workspace's package.json (shared-dep version resolution) */\n pkg: {\n name: string;\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n /** core provides the shared singletons; plugin remotes consume (`import: false`) */\n role: \"provider\" | \"consumer\";\n /** the composition key written into manifest.gen.json (the config-side key) */\n manifestName: string;\n devPort: number;\n webEntry: string;\n webExposes: Record<string, string>;\n nodeEntry: string;\n nodeExposes: Record<string, string>;\n copy?: Array<{\n from: string;\n to: string;\n globOptions?: { ignore?: string[] };\n }>;\n define?: Record<string, string>;\n /** routes dir relative to the rsbuild cwd — folder-form ui sources live at\n * `ui/src/routes` while the build runs from the plugin root */\n routesDirectory?: string;\n}\n\nexport { sanitizeContainerName };\n\n/**\n * The node environment never owns the routeTree write: the web env's\n * generator produces identical content, and both environments resolve the\n * same on-disk tree. Redirecting the node write to scratch removes the\n * concurrent-writers race on src/routeTree.gen.ts (the generator's\n * \"Cannot overwrite\" retry noise).\n */\nconst NODE_ROUTE_TREE_SCRATCH = \"./node_modules/.cache/manifest-compose/routeTree.node.gen.ts\";\n\nexport function createUiRsbuildConfig(options: UiRsbuildConfigOptions): RsbuildConfig {\n const {\n workspaceRoot,\n pkg,\n role,\n manifestName,\n devPort,\n webEntry,\n webExposes,\n nodeEntry,\n nodeExposes,\n copy = [],\n define,\n routesDirectory,\n } = options;\n const workspaceRootAbsolute = path.resolve(workspaceRoot);\n const normalizedName = sanitizeContainerName(pkg.name);\n const manifestGen = () =>\n uiManifestGenPlugin({ workspaceRoot: workspaceRootAbsolute, pluginName: manifestName });\n const uiSharedDeps = createUiSharedDeps({ role, workspaceRoot: workspaceRootAbsolute });\n const uiSharedVersions = sharedVersionRecord(uiSharedDeps);\n\n const isBuild = isBuildInvocation();\n\n const webEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild }),\n dts: false,\n exposes: webExposes,\n shared: uiSharedDeps,\n },\n { environment: \"web\" },\n ),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry\",\n distRoot: path.join(workspaceRootAbsolute, \"dist\"),\n shared: uiSharedVersions,\n }),\n ]\n : []),\n ],\n source: { entry: { index: webEntry }, ...(define ? { define } : {}) },\n resolve: { alias: { \"@\": path.join(workspaceRootAbsolute, \"src\") } },\n tools: {\n rspack: (config) => {\n const cssPlugin = config.plugins?.find((p) => p instanceof rspack.CssExtractRspackPlugin) as\n | { options?: Record<string, string> }\n | undefined;\n if (cssPlugin) {\n cssPlugin.options ??= {};\n cssPlugin.options.chunkFilename = \"static/css/async/[name].[contenthash].css\";\n }\n Object.assign(config, {\n target: \"web\",\n output: {\n ...config.output,\n publicPath: \"auto\",\n uniqueName: normalizedName,\n chunkFilename: \"static/js/async/[name].[contenthash].js\",\n crossOriginLoading: \"anonymous\",\n },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: true,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: path.join(workspaceRootAbsolute, \"src/routeTree.gen.ts\"),\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n output: {\n // Absolute: the ui source root owns dist even when the build cwd is the\n // parent plugin workspace (folder-form ui sources).\n distPath: {\n root: path.join(workspaceRootAbsolute, \"dist\"),\n css: \"static/css\",\n js: \"static/js\",\n },\n assetPrefix: \"auto\",\n filename: { js: \"[name].js\", css: \"style.css\" },\n copy: [\n ...copy,\n { from: path.join(workspaceRootAbsolute, \"src\", MANIFEST_FILENAME), to: \"./\" },\n ],\n },\n };\n\n // Dev without SSR skips the node environment: it exists for the host's dev\n // SSR container and nothing else. Builds always emit both.\n const includeNodeEnv =\n process.env.BOS_SSR === \"1\" ||\n process.env.DEPLOY === \"true\" ||\n process.env.NODE_ENV !== \"development\";\n\n const nodeEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild, server: true }),\n dts: false,\n exposes: nodeExposes,\n shared: uiSharedDeps,\n },\n { target: \"node\", environment: \"node\" },\n ),\n restoreManifestPublicPath(path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\")),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry.server\",\n distRoot: path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\"),\n shared: uiSharedVersions,\n }),\n ]\n : []),\n ],\n source: { entry: { index: nodeEntry } },\n resolve: {\n alias: {\n \"@\": path.join(workspaceRootAbsolute, \"src\"),\n \"@tanstack/react-devtools\": false,\n \"@tanstack/react-router-devtools\": false,\n },\n },\n tools: {\n rspack: (config) => {\n Object.assign(config, {\n output: { ...config.output, uniqueName: `${normalizedName}_server` },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n externals: [/^node:/],\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: false,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: NODE_ROUTE_TREE_SCRATCH,\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n // Absolute, like the web dist above — the node container must land in the\n // ui source root's dist/ssr where the host's local container server looks.\n output: { distPath: { root: path.join(workspaceRootAbsolute, \"dist\", \"ssr\") } },\n };\n\n return defineConfig({\n environments: {\n web: webEnvironment,\n ...(includeNodeEnv ? { node: nodeEnvironment } : {}),\n },\n dev: {\n lazyCompilation: false,\n progressBar: false,\n writeToDisk: true,\n client: { overlay: false },\n },\n server: {\n port: Number(process.env.PORT) || devPort,\n printUrls: ({ urls }) => urls.filter((url) => url.includes(\"localhost\")),\n headers: {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n },\n },\n });\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { isBuildInvocation, uiEntryFilename } from "../artifact-names.mjs";
2
- import { createUiSharedDeps } from "../../shared-deps-spec.mjs";
2
+ import { createUiSharedDeps, sharedVersionRecord } from "../../shared-deps-spec.mjs";
3
3
  import { containerName } from "../../identity.mjs";
4
4
  import { FixMfDataUriPlugin } from "../rspack/fix-mf-data-uri-plugin.mjs";
5
5
  import "../rspack/index.mjs";
@@ -34,6 +34,7 @@ function createUiRsbuildConfig(options) {
34
34
  role,
35
35
  workspaceRoot: workspaceRootAbsolute
36
36
  });
37
+ const uiSharedVersions = sharedVersionRecord(uiSharedDeps);
37
38
  const isBuild = isBuildInvocation();
38
39
  const webEnvironment = {
39
40
  plugins: [
@@ -48,7 +49,8 @@ function createUiRsbuildConfig(options) {
48
49
  }, { environment: "web" }),
49
50
  ...isBuild ? [hashArtifactsPlugin({
50
51
  entryBase: "remoteEntry",
51
- distRoot: path.join(workspaceRootAbsolute, "dist")
52
+ distRoot: path.join(workspaceRootAbsolute, "dist"),
53
+ shared: uiSharedVersions
52
54
  })] : []
53
55
  ],
54
56
  source: {
@@ -86,6 +88,7 @@ function createUiRsbuildConfig(options) {
86
88
  target: "react",
87
89
  autoCodeSplitting: true,
88
90
  routeFileIgnorePattern: "\\.(test|spec)\\.(ts|tsx)$",
91
+ generatedRouteTree: path.join(workspaceRootAbsolute, "src/routeTree.gen.ts"),
89
92
  ...routesDirectory ? { routesDirectory } : {}
90
93
  }),
91
94
  new FixMfDataUriPlugin()
@@ -131,7 +134,8 @@ function createUiRsbuildConfig(options) {
131
134
  restoreManifestPublicPath(path.resolve(workspaceRootAbsolute, "dist", "ssr")),
132
135
  ...isBuild ? [hashArtifactsPlugin({
133
136
  entryBase: "remoteEntry.server",
134
- distRoot: path.resolve(workspaceRootAbsolute, "dist", "ssr")
137
+ distRoot: path.resolve(workspaceRootAbsolute, "dist", "ssr"),
138
+ shared: uiSharedVersions
135
139
  })] : []
136
140
  ],
137
141
  source: { entry: { index: nodeEntry } },
@@ -1 +1 @@
1
- {"version":3,"file":"rsbuild-config.mjs","names":["sanitizeContainerName"],"sources":["../../../src/build/ui/rsbuild-config.ts"],"sourcesContent":["import path from \"node:path\";\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\nimport { defineConfig, type EnvironmentConfig, type RsbuildConfig, rspack } from \"@rsbuild/core\";\nimport { pluginReact } from \"@rsbuild/plugin-react\";\nimport { TanStackRouterRspack } from \"@tanstack/router-plugin/rspack\";\nimport { FixMfDataUriPlugin } from \"../../build/rspack\";\nimport { createUiSharedDeps } from \"../../shared-deps-spec\";\nimport { sanitizeContainerName } from \"../../ui/manifest/contract\";\nimport { isBuildInvocation, uiEntryFilename } from \"../artifact-names\";\nimport { hashArtifactsPlugin } from \"./hash-artifacts-plugin\";\nimport { MANIFEST_FILENAME, restoreManifestPublicPath } from \"./index\";\nimport { uiManifestGenPlugin } from \"./manifest-plugin\";\n\n/**\n * The full dual-environment rsbuild config for a manifest-composed ui source\n * (ADR 0008 §7 — the plugin build contract, not per-plugin config). The core\n * ui and every plugin ui source build from this one factory: `web` emits the\n * browser remote, `node` the commonjs SSR container; shared deps are strict\n * singletons in the given role.\n */\nexport interface UiRsbuildConfigOptions {\n /** the ui source root — contains package.json, src/, and the routes dir */\n workspaceRoot: string;\n /** the ui workspace's package.json (shared-dep version resolution) */\n pkg: {\n name: string;\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n /** core provides the shared singletons; plugin remotes consume (`import: false`) */\n role: \"provider\" | \"consumer\";\n /** the composition key written into manifest.gen.json (the config-side key) */\n manifestName: string;\n devPort: number;\n webEntry: string;\n webExposes: Record<string, string>;\n nodeEntry: string;\n nodeExposes: Record<string, string>;\n copy?: Array<{\n from: string;\n to: string;\n globOptions?: { ignore?: string[] };\n }>;\n define?: Record<string, string>;\n /** routes dir relative to the rsbuild cwd — folder-form ui sources live at\n * `ui/src/routes` while the build runs from the plugin root */\n routesDirectory?: string;\n}\n\nexport { sanitizeContainerName };\n\n/**\n * The node environment never owns the routeTree write: the web env's\n * generator produces identical content, and both environments resolve the\n * same on-disk tree. Redirecting the node write to scratch removes the\n * concurrent-writers race on src/routeTree.gen.ts (the generator's\n * \"Cannot overwrite\" retry noise).\n */\nconst NODE_ROUTE_TREE_SCRATCH = \"./node_modules/.cache/manifest-compose/routeTree.node.gen.ts\";\n\nexport function createUiRsbuildConfig(options: UiRsbuildConfigOptions): RsbuildConfig {\n const {\n workspaceRoot,\n pkg,\n role,\n manifestName,\n devPort,\n webEntry,\n webExposes,\n nodeEntry,\n nodeExposes,\n copy = [],\n define,\n routesDirectory,\n } = options;\n const workspaceRootAbsolute = path.resolve(workspaceRoot);\n const normalizedName = sanitizeContainerName(pkg.name);\n const manifestGen = () =>\n uiManifestGenPlugin({ workspaceRoot: workspaceRootAbsolute, pluginName: manifestName });\n const uiSharedDeps = createUiSharedDeps({ role, workspaceRoot: workspaceRootAbsolute });\n\n const isBuild = isBuildInvocation();\n\n const webEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild }),\n dts: false,\n exposes: webExposes,\n shared: uiSharedDeps,\n },\n { environment: \"web\" },\n ),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry\",\n distRoot: path.join(workspaceRootAbsolute, \"dist\"),\n }),\n ]\n : []),\n ],\n source: { entry: { index: webEntry }, ...(define ? { define } : {}) },\n resolve: { alias: { \"@\": path.join(workspaceRootAbsolute, \"src\") } },\n tools: {\n rspack: (config) => {\n const cssPlugin = config.plugins?.find((p) => p instanceof rspack.CssExtractRspackPlugin) as\n | { options?: Record<string, string> }\n | undefined;\n if (cssPlugin) {\n cssPlugin.options ??= {};\n cssPlugin.options.chunkFilename = \"static/css/async/[name].[contenthash].css\";\n }\n Object.assign(config, {\n target: \"web\",\n output: {\n ...config.output,\n publicPath: \"auto\",\n uniqueName: normalizedName,\n chunkFilename: \"static/js/async/[name].[contenthash].js\",\n crossOriginLoading: \"anonymous\",\n },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: true,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n output: {\n // Absolute: the ui source root owns dist even when the build cwd is the\n // parent plugin workspace (folder-form ui sources).\n distPath: {\n root: path.join(workspaceRootAbsolute, \"dist\"),\n css: \"static/css\",\n js: \"static/js\",\n },\n assetPrefix: \"auto\",\n filename: { js: \"[name].js\", css: \"style.css\" },\n copy: [\n ...copy,\n { from: path.join(workspaceRootAbsolute, \"src\", MANIFEST_FILENAME), to: \"./\" },\n ],\n },\n };\n\n // Dev without SSR skips the node environment: it exists for the host's dev\n // SSR container and nothing else. Builds always emit both.\n const includeNodeEnv =\n process.env.BOS_SSR === \"1\" ||\n process.env.DEPLOY === \"true\" ||\n process.env.NODE_ENV !== \"development\";\n\n const nodeEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild, server: true }),\n dts: false,\n exposes: nodeExposes,\n shared: uiSharedDeps,\n },\n { target: \"node\", environment: \"node\" },\n ),\n restoreManifestPublicPath(path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\")),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry.server\",\n distRoot: path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\"),\n }),\n ]\n : []),\n ],\n source: { entry: { index: nodeEntry } },\n resolve: {\n alias: {\n \"@\": path.join(workspaceRootAbsolute, \"src\"),\n \"@tanstack/react-devtools\": false,\n \"@tanstack/react-router-devtools\": false,\n },\n },\n tools: {\n rspack: (config) => {\n Object.assign(config, {\n output: { ...config.output, uniqueName: `${normalizedName}_server` },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n externals: [/^node:/],\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: false,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: NODE_ROUTE_TREE_SCRATCH,\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n // Absolute, like the web dist above — the node container must land in the\n // ui source root's dist/ssr where the host's local container server looks.\n output: { distPath: { root: path.join(workspaceRootAbsolute, \"dist\", \"ssr\") } },\n };\n\n return defineConfig({\n environments: {\n web: webEnvironment,\n ...(includeNodeEnv ? { node: nodeEnvironment } : {}),\n },\n dev: {\n lazyCompilation: false,\n progressBar: false,\n writeToDisk: true,\n client: { overlay: false },\n },\n server: {\n port: Number(process.env.PORT) || devPort,\n printUrls: ({ urls }) => urls.filter((url) => url.includes(\"localhost\")),\n headers: {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n },\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rsbuild-config.mjs","names":["sanitizeContainerName"],"sources":["../../../src/build/ui/rsbuild-config.ts"],"sourcesContent":["import path from \"node:path\";\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\nimport { defineConfig, type EnvironmentConfig, type RsbuildConfig, rspack } from \"@rsbuild/core\";\nimport { pluginReact } from \"@rsbuild/plugin-react\";\nimport { TanStackRouterRspack } from \"@tanstack/router-plugin/rspack\";\nimport { FixMfDataUriPlugin } from \"../../build/rspack\";\nimport { createUiSharedDeps, sharedVersionRecord } from \"../../shared-deps-spec\";\nimport { sanitizeContainerName } from \"../../ui/manifest/contract\";\nimport { isBuildInvocation, uiEntryFilename } from \"../artifact-names\";\nimport { hashArtifactsPlugin } from \"./hash-artifacts-plugin\";\nimport { MANIFEST_FILENAME, restoreManifestPublicPath } from \"./index\";\nimport { uiManifestGenPlugin } from \"./manifest-plugin\";\n\n/**\n * The full dual-environment rsbuild config for a manifest-composed ui source\n * (ADR 0008 §7 — the plugin build contract, not per-plugin config). The core\n * ui and every plugin ui source build from this one factory: `web` emits the\n * browser remote, `node` the commonjs SSR container; shared deps are strict\n * singletons in the given role.\n */\nexport interface UiRsbuildConfigOptions {\n /** the ui source root — contains package.json, src/, and the routes dir */\n workspaceRoot: string;\n /** the ui workspace's package.json (shared-dep version resolution) */\n pkg: {\n name: string;\n version?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n /** core provides the shared singletons; plugin remotes consume (`import: false`) */\n role: \"provider\" | \"consumer\";\n /** the composition key written into manifest.gen.json (the config-side key) */\n manifestName: string;\n devPort: number;\n webEntry: string;\n webExposes: Record<string, string>;\n nodeEntry: string;\n nodeExposes: Record<string, string>;\n copy?: Array<{\n from: string;\n to: string;\n globOptions?: { ignore?: string[] };\n }>;\n define?: Record<string, string>;\n /** routes dir relative to the rsbuild cwd — folder-form ui sources live at\n * `ui/src/routes` while the build runs from the plugin root */\n routesDirectory?: string;\n}\n\nexport { sanitizeContainerName };\n\n/**\n * The node environment never owns the routeTree write: the web env's\n * generator produces identical content, and both environments resolve the\n * same on-disk tree. Redirecting the node write to scratch removes the\n * concurrent-writers race on src/routeTree.gen.ts (the generator's\n * \"Cannot overwrite\" retry noise).\n */\nconst NODE_ROUTE_TREE_SCRATCH = \"./node_modules/.cache/manifest-compose/routeTree.node.gen.ts\";\n\nexport function createUiRsbuildConfig(options: UiRsbuildConfigOptions): RsbuildConfig {\n const {\n workspaceRoot,\n pkg,\n role,\n manifestName,\n devPort,\n webEntry,\n webExposes,\n nodeEntry,\n nodeExposes,\n copy = [],\n define,\n routesDirectory,\n } = options;\n const workspaceRootAbsolute = path.resolve(workspaceRoot);\n const normalizedName = sanitizeContainerName(pkg.name);\n const manifestGen = () =>\n uiManifestGenPlugin({ workspaceRoot: workspaceRootAbsolute, pluginName: manifestName });\n const uiSharedDeps = createUiSharedDeps({ role, workspaceRoot: workspaceRootAbsolute });\n const uiSharedVersions = sharedVersionRecord(uiSharedDeps);\n\n const isBuild = isBuildInvocation();\n\n const webEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild }),\n dts: false,\n exposes: webExposes,\n shared: uiSharedDeps,\n },\n { environment: \"web\" },\n ),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry\",\n distRoot: path.join(workspaceRootAbsolute, \"dist\"),\n shared: uiSharedVersions,\n }),\n ]\n : []),\n ],\n source: { entry: { index: webEntry }, ...(define ? { define } : {}) },\n resolve: { alias: { \"@\": path.join(workspaceRootAbsolute, \"src\") } },\n tools: {\n rspack: (config) => {\n const cssPlugin = config.plugins?.find((p) => p instanceof rspack.CssExtractRspackPlugin) as\n | { options?: Record<string, string> }\n | undefined;\n if (cssPlugin) {\n cssPlugin.options ??= {};\n cssPlugin.options.chunkFilename = \"static/css/async/[name].[contenthash].css\";\n }\n Object.assign(config, {\n target: \"web\",\n output: {\n ...config.output,\n publicPath: \"auto\",\n uniqueName: normalizedName,\n chunkFilename: \"static/js/async/[name].[contenthash].js\",\n crossOriginLoading: \"anonymous\",\n },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: true,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: path.join(workspaceRootAbsolute, \"src/routeTree.gen.ts\"),\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n output: {\n // Absolute: the ui source root owns dist even when the build cwd is the\n // parent plugin workspace (folder-form ui sources).\n distPath: {\n root: path.join(workspaceRootAbsolute, \"dist\"),\n css: \"static/css\",\n js: \"static/js\",\n },\n assetPrefix: \"auto\",\n filename: { js: \"[name].js\", css: \"style.css\" },\n copy: [\n ...copy,\n { from: path.join(workspaceRootAbsolute, \"src\", MANIFEST_FILENAME), to: \"./\" },\n ],\n },\n };\n\n // Dev without SSR skips the node environment: it exists for the host's dev\n // SSR container and nothing else. Builds always emit both.\n const includeNodeEnv =\n process.env.BOS_SSR === \"1\" ||\n process.env.DEPLOY === \"true\" ||\n process.env.NODE_ENV !== \"development\";\n\n const nodeEnvironment: EnvironmentConfig = {\n plugins: [\n pluginReact(),\n manifestGen(),\n pluginModuleFederation(\n {\n name: normalizedName,\n filename: uiEntryFilename({ isBuild, server: true }),\n dts: false,\n exposes: nodeExposes,\n shared: uiSharedDeps,\n },\n { target: \"node\", environment: \"node\" },\n ),\n restoreManifestPublicPath(path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\")),\n ...(isBuild\n ? [\n hashArtifactsPlugin({\n entryBase: \"remoteEntry.server\",\n distRoot: path.resolve(workspaceRootAbsolute, \"dist\", \"ssr\"),\n shared: uiSharedVersions,\n }),\n ]\n : []),\n ],\n source: { entry: { index: nodeEntry } },\n resolve: {\n alias: {\n \"@\": path.join(workspaceRootAbsolute, \"src\"),\n \"@tanstack/react-devtools\": false,\n \"@tanstack/react-router-devtools\": false,\n },\n },\n tools: {\n rspack: (config) => {\n Object.assign(config, {\n output: { ...config.output, uniqueName: `${normalizedName}_server` },\n resolve: {\n ...config.resolve,\n fallback: { bufferutil: false, \"utf-8-validate\": false },\n },\n externals: [/^node:/],\n infrastructureLogging: { level: \"error\" },\n stats: \"errors-warnings\",\n plugins: [\n ...(config.plugins ?? []),\n TanStackRouterRspack({\n target: \"react\",\n autoCodeSplitting: false,\n routeFileIgnorePattern: \"\\\\.(test|spec)\\\\.(ts|tsx)$\",\n generatedRouteTree: NODE_ROUTE_TREE_SCRATCH,\n ...(routesDirectory ? { routesDirectory } : {}),\n }),\n new FixMfDataUriPlugin(),\n ],\n });\n return config;\n },\n },\n // Absolute, like the web dist above — the node container must land in the\n // ui source root's dist/ssr where the host's local container server looks.\n output: { distPath: { root: path.join(workspaceRootAbsolute, \"dist\", \"ssr\") } },\n };\n\n return defineConfig({\n environments: {\n web: webEnvironment,\n ...(includeNodeEnv ? { node: nodeEnvironment } : {}),\n },\n dev: {\n lazyCompilation: false,\n progressBar: false,\n writeToDisk: true,\n client: { overlay: false },\n },\n server: {\n port: Number(process.env.PORT) || devPort,\n printUrls: ({ urls }) => urls.filter((url) => url.includes(\"localhost\")),\n headers: {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type\",\n },\n },\n });\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ const require_shared_deps_spec = require('../shared-deps-spec.cjs');
3
3
  let node_fs = require("node:fs");
4
4
 
5
5
  //#region src/runtime/mf-config.ts
6
- const PLUGIN_VERSION = "3.0.0-rc.10";
6
+ const PLUGIN_VERSION = "3.0.0-rc.12";
7
7
  const MF_CORE_SHARED_DEPS = require_shared_deps_spec.buildMfCoreSharedDependencies({ ownVersion: PLUGIN_VERSION });
8
8
 
9
9
  //#endregion
@@ -2,7 +2,7 @@ import { buildMfCoreSharedDependencies } from "../shared-deps-spec.mjs";
2
2
  import { readFileSync } from "node:fs";
3
3
 
4
4
  //#region src/runtime/mf-config.ts
5
- const PLUGIN_VERSION = "3.0.0-rc.10";
5
+ const PLUGIN_VERSION = "3.0.0-rc.12";
6
6
  const MF_CORE_SHARED_DEPS = buildMfCoreSharedDependencies({ ownVersion: PLUGIN_VERSION });
7
7
 
8
8
  //#endregion
@@ -363,6 +363,18 @@ function mergeSharedMaps(...maps) {
363
363
  }
364
364
  return merged;
365
365
  }
366
+ /**
367
+ * The `name → version` record of a build's shared-singleton map, for the
368
+ * build report (and from there the version manifest's `shared` field) —
369
+ * #546: a slot's pin must carry shared-dep semantics so consumers can detect
370
+ * a build skew before loading. Singletons only — non-singletons never take
371
+ * part in the negotiation a skew breaks.
372
+ */
373
+ function sharedVersionRecord(shared) {
374
+ const out = {};
375
+ for (const [name, config] of Object.entries(shared)) if (config.singleton !== false && config.version) out[name] = config.version;
376
+ return out;
377
+ }
366
378
 
367
379
  //#endregion
368
380
  exports.CORE_SHARED_DEPS = CORE_SHARED_DEPS;
@@ -380,5 +392,6 @@ exports.mergeSharedMaps = mergeSharedMaps;
380
392
  exports.normalizeSharedConfig = normalizeSharedConfig;
381
393
  exports.resolveSharedVersion = resolveSharedVersion;
382
394
  exports.shareConfigFor = shareConfigFor;
395
+ exports.sharedVersionRecord = sharedVersionRecord;
383
396
  exports.toHostSharedEntry = toHostSharedEntry;
384
397
  //# sourceMappingURL=shared-deps-spec.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-deps-spec.cjs","names":["require","createRequire","Data","join","existsSync","readFileSync","dirname","resolve","fileURLToPath"],"sources":["../src/shared-deps-spec.ts"],"sourcesContent":["/**\n * SharedDependencySpec: the one module owning shared-dependency names,\n * criticality, version resolution, and fallback policy across the Module\n * Federation graph. Four consumers derive from it — the rspack config\n * factory (plugin builds), the rsbuild config factory (ui remotes), the\n * runtime mf-config (the every-plugin MF instance), and the host's shared\n * pre-registration — so a name or criticality can never disagree between\n * them, and an unresolved version fails the build loudly instead of\n * silently degrading to \"*\"/\"latest\" (which disables the strict-singleton\n * guard).\n *\n * Lists:\n * - core: shared by the host and server-side plugin remotes (every-plugin,\n * effect, zod, @orpc/*). Effect-critical entries pin the exact installed\n * version (strictVersion) — the version-check machinery in\n * runtime/services/shared-identity.ts relies on it.\n * - ui: shared by the core ui provider and ui remotes (react, react-dom,\n * @orpc/client, @orpc/contract, TanStack, lingui, the everything-dev\n * session/i18n subpath modules). All strict singletons; consumers add\n * `import: false`.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Data } from \"effect\";\n\nconst require = createRequire(import.meta.url);\n\nexport class SharedDependencyResolutionError extends Data.TaggedError(\n \"SharedDependencyResolutionError\",\n)<{\n readonly packageName: string;\n readonly searched: string[];\n}> {\n constructor(packageName: string, searched: string[]) {\n super({\n packageName,\n searched,\n });\n }\n\n override get message() {\n return (\n `Could not resolve shared dependency \"${this.packageName}\". Looked in:\\n` +\n this.searched.map((location) => ` - ${location}`).join(\"\\n\") +\n `\\nUnresolved shared dependencies fail loudly (no \"*\", no \"latest\" fallback) — ` +\n `install the package in the resolving workspace or pin a resolvable version.`\n );\n }\n}\n\nexport type SharedDependencyResolution = \"self\" | \"package\" | \"subpath\";\n\nexport interface SharedDependencySpec {\n name: string;\n singleton: true;\n /** exact-version pin (requiredVersion = resolved version, strictVersion = true) */\n critical: boolean;\n resolution: SharedDependencyResolution;\n}\n\nexport const CORE_SHARED_DEPS = [\n { name: \"every-plugin\", singleton: true, critical: true, resolution: \"self\" },\n { name: \"effect\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"zod\", singleton: true, critical: false, resolution: \"package\" },\n { name: \"@orpc/contract\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/client\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/server\", singleton: true, critical: true, resolution: \"package\" },\n // v1's proven sharing set, restored: @orpc/openapi, @orpc/experimental-effect,\n // and @orpc/publisher joined this list in the v2 fleet-spec pass and their\n // share-scope consumption broke plugin loading at runtime\n // (__webpack_modules__[r] is not a function — the runtime's import()-based\n // provides hand the consumer an ESM namespace where a module factory is\n // expected). They stay declared in each workspace's package.json and are\n // bundled per workspace instead.\n] as const satisfies readonly SharedDependencySpec[];\n\nexport type CoreSharedDepName = (typeof CORE_SHARED_DEPS)[number][\"name\"];\n\nconst coreCriticalNames = CORE_SHARED_DEPS.flatMap((spec) => (spec.critical ? [spec.name] : []));\n\n/**\n * Effect-critical shared names, derived from the core list's `critical: true`\n * entries — the one source of criticality (`strictVersion` pinning in the\n * runtime's version-check machinery keys off this list).\n */\nexport const EFFECT_CRITICAL_SHARED_DEPS: readonly EffectCriticalSharedDepName[] =\n coreCriticalNames;\n\nexport type EffectCriticalSharedDepName = (typeof coreCriticalNames)[number];\n\nexport const isEffectCriticalSharedDep = (name: string): boolean =>\n (EFFECT_CRITICAL_SHARED_DEPS as readonly string[]).includes(name);\n\nexport const UI_SHARED_DEPS = [\n { name: \"react\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"react-dom\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/client\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/contract\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@tanstack/react-query\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@tanstack/react-router\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@lingui/core\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@lingui/react\", singleton: true, critical: true, resolution: \"package\" },\n {\n name: \"everything-dev/ui/auth\",\n singleton: true,\n critical: true,\n resolution: \"subpath\",\n },\n {\n name: \"everything-dev/ui/i18n\",\n singleton: true,\n critical: true,\n resolution: \"subpath\",\n },\n] as const satisfies readonly SharedDependencySpec[];\n\nexport const SHARED_DEP_SPECS: readonly SharedDependencySpec[] = (() => {\n const byName = new Map<string, SharedDependencySpec>();\n for (const spec of [...CORE_SHARED_DEPS, ...UI_SHARED_DEPS]) {\n const existing = byName.get(spec.name);\n if (existing) {\n if (existing.critical !== spec.critical) {\n throw new Error(\n `Shared dependency spec conflict for \"${spec.name}\": criticality disagrees between the core and ui lists`,\n );\n }\n continue;\n }\n byName.set(spec.name, spec);\n }\n return [...byName.values()];\n})();\n\nexport interface SharedDependencyConfig {\n version: string;\n requiredVersion: string | false;\n singleton: boolean;\n strictVersion: boolean;\n eager: boolean;\n shareScope: string;\n}\n\nexport type SharedDependencies = Record<string, SharedDependencyConfig>;\n\nexport type SharedConfigInput = {\n version: string;\n requiredVersion?: string | false;\n singleton?: boolean;\n strictVersion?: boolean;\n eager?: boolean;\n shareScope?: string;\n};\n\nexport interface SharedDependencyResolutionOptions {\n /** the building workspace to resolve from; default is this module's own location */\n workspaceRoot?: string;\n resolution?: \"package\" | \"subpath\";\n}\n\nfunction searchedNote(target: string): string {\n return `require.resolve(\"${target}\")`;\n}\n\nfunction findPackageJsonVersion(startDir: string, searched: string[]): string | null {\n let currentDir = startDir;\n for (let i = 0; i < 5; i += 1) {\n const packageJsonPath = join(currentDir, \"package.json\");\n searched.push(packageJsonPath);\n if (existsSync(packageJsonPath)) {\n try {\n const version = (JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: string })\n .version;\n if (version) return version;\n } catch {}\n }\n const parent = dirname(currentDir);\n if (parent === currentDir) break;\n currentDir = parent;\n }\n return null;\n}\n\nfunction resolveSubpathVersion(\n request: string,\n workspaceRoot: string | undefined,\n searched: string[],\n): string | null {\n if (request.startsWith(\"@\")) {\n throw new Error(\n `Scoped-package subpath \"${request}\" is not supported — subpath version resolution ` +\n `handles unscoped specifiers only (the known subpath specs, everything-dev/ui/*, are unscoped).`,\n );\n }\n const packageName = request.split(\"/\")[0] ?? request;\n const subpath = request.split(\"/\").slice(1).join(\"/\");\n const candidates: string[] = [];\n if (workspaceRoot) {\n candidates.push(join(workspaceRoot, \"node_modules\", packageName, \"package.json\"));\n }\n const resolveRequests: Array<{ request: string; paths?: string[] }> = [\n { request: `${packageName}/${subpath}`, ...(workspaceRoot ? { paths: [workspaceRoot] } : {}) },\n { request: `${packageName}/${subpath}` },\n {\n request: `${packageName}/package.json`,\n ...(workspaceRoot ? { paths: [workspaceRoot] } : {}),\n },\n { request: `${packageName}/package.json` },\n ];\n for (const { request: target, paths } of resolveRequests) {\n try {\n const resolved = require.resolve(target, paths ? { paths } : undefined);\n searched.push(resolved);\n candidates.push(\n resolved.endsWith(\"package.json\")\n ? resolved\n : resolve(dirname(resolved), \"..\", \"..\", \"package.json\"),\n );\n } catch {\n searched.push(searchedNote(target));\n }\n }\n for (const candidate of candidates) {\n if (!existsSync(candidate)) continue;\n try {\n const version = (JSON.parse(readFileSync(candidate, \"utf8\")) as { version?: string }).version;\n if (version) return version;\n } catch {}\n }\n return null;\n}\n\nexport function resolveSharedVersion(\n name: string,\n options: SharedDependencyResolutionOptions = {},\n): string {\n const searched: string[] = [];\n const { workspaceRoot, resolution = \"package\" } = options;\n\n if (resolution === \"subpath\") {\n const version = resolveSubpathVersion(name, workspaceRoot, searched);\n if (version) return version;\n throw new SharedDependencyResolutionError(name, searched);\n }\n\n const roots: Array<string | undefined> = workspaceRoot ? [workspaceRoot, undefined] : [undefined];\n for (const root of roots) {\n try {\n const resolved = root ? require.resolve(name, { paths: [root] }) : require.resolve(name);\n searched.push(resolved);\n const version = findPackageJsonVersion(dirname(resolved), searched);\n if (version) return version;\n } catch {\n searched.push(searchedNote(name));\n }\n }\n throw new SharedDependencyResolutionError(name, searched);\n}\n\nfunction resolveOwnVersion(searched: string[]): string {\n const localPackageJson = join(dirname(fileURLToPath(import.meta.url)), \"..\", \"package.json\");\n searched.push(localPackageJson);\n if (existsSync(localPackageJson)) {\n try {\n const version = (JSON.parse(readFileSync(localPackageJson, \"utf8\")) as { version?: string })\n .version;\n if (version) return version;\n } catch {}\n }\n try {\n const resolved = require.resolve(\"every-plugin/package.json\");\n searched.push(resolved);\n const version = (JSON.parse(readFileSync(resolved, \"utf8\")) as { version?: string }).version;\n if (version) return version;\n } catch {\n searched.push(searchedNote(\"every-plugin/package.json\"));\n }\n throw new SharedDependencyResolutionError(\"every-plugin\", searched);\n}\n\nexport function shareConfigFor(\n spec: SharedDependencySpec,\n version: string,\n): Omit<SharedDependencyConfig, \"version\"> {\n return spec.critical\n ? {\n requiredVersion: version,\n singleton: true,\n strictVersion: true,\n eager: false,\n shareScope: \"default\",\n }\n : {\n requiredVersion: false,\n singleton: true,\n strictVersion: false,\n eager: false,\n shareScope: \"default\",\n };\n}\n\nexport interface SharedDepsBuildOptions {\n /** the every-plugin share version; default resolves the installed package.json */\n ownVersion?: string;\n}\n\nfunction specVersion(spec: SharedDependencySpec, options: SharedDepsBuildOptions): string {\n if (spec.resolution === \"self\") {\n return options.ownVersion ?? resolveOwnVersion([`own package.json of \"${spec.name}\"`]);\n }\n return resolveSharedVersion(spec.name, {\n resolution: spec.resolution === \"subpath\" ? \"subpath\" : \"package\",\n });\n}\n\nexport function getPluginSharedDependencies(\n options: SharedDepsBuildOptions = {},\n): SharedDependencies {\n return Object.fromEntries(\n CORE_SHARED_DEPS.map((spec) => {\n const version = specVersion(spec, options);\n return [spec.name, { version, ...shareConfigFor(spec, version) }];\n }),\n );\n}\n\nexport interface HostSharedEntry {\n version: string;\n shareScope: string;\n shareConfig: {\n singleton: boolean;\n requiredVersion: string | false;\n strictVersion: boolean;\n eager: boolean;\n };\n}\n\nexport function toHostSharedEntry(name: string, config: SharedConfigInput): HostSharedEntry {\n const normalized = normalizeSharedConfig(config, name);\n return {\n version: normalized.version,\n shareScope: normalized.shareScope,\n shareConfig: {\n singleton: normalized.singleton,\n requiredVersion: normalized.requiredVersion,\n strictVersion: normalized.strictVersion,\n eager: normalized.eager,\n },\n };\n}\n\n/**\n * The runtime mf-config's core shared map: the same entries\n * `getPluginSharedDependencies` assembles, shaped through the one host mapper\n * (`toHostSharedEntry`) so both consumers derive from a single entry type.\n */\nexport function buildMfCoreSharedDependencies(\n options: SharedDepsBuildOptions = {},\n): Record<string, HostSharedEntry> {\n return Object.fromEntries(\n Object.entries(getPluginSharedDependencies(options)).map(([name, config]) => [\n name,\n toHostSharedEntry(name, config),\n ]),\n );\n}\n\nexport interface UiSharedDepEntry {\n version: string;\n requiredVersion: string | false;\n singleton: true;\n strictVersion: boolean;\n eager: false;\n shareScope: \"default\";\n /** consumer role only: no bundled fallback copy — the provider provides */\n import?: false;\n}\n\nexport interface UiSharedDepsOptions {\n /** explicit core-shell parity opt-out; default is the strict singleton */\n strictVersion?: boolean;\n role?: \"provider\" | \"consumer\";\n workspaceRoot?: string;\n}\n\nexport function createUiSharedDeps(\n options: UiSharedDepsOptions = {},\n): Record<string, UiSharedDepEntry> {\n const deps: Record<string, UiSharedDepEntry> = {};\n for (const spec of UI_SHARED_DEPS) {\n const version = resolveSharedVersion(spec.name, {\n workspaceRoot: options.workspaceRoot,\n resolution: spec.resolution === \"subpath\" ? \"subpath\" : \"package\",\n });\n const strict = options.strictVersion !== false;\n deps[spec.name] = {\n version,\n requiredVersion: strict ? version : false,\n singleton: true,\n strictVersion: strict,\n eager: false,\n shareScope: \"default\",\n ...(options.role === \"consumer\" ? { import: false as const } : {}),\n };\n }\n return deps;\n}\n\nconst UNRESOLVED_VERSIONS = new Set([\"*\", \"latest\", \"\"]);\n\nexport function assertResolvedSharedVersion(name: string, version: unknown): string {\n if (typeof version !== \"string\" || UNRESOLVED_VERSIONS.has(version.trim())) {\n throw new SharedDependencyResolutionError(name, [\n `declared version ${JSON.stringify(version ?? null)} is not resolvable — \"*\", \"latest\", and empty fail loudly instead of disabling the strict-singleton guard`,\n ]);\n }\n return version;\n}\n\nexport function normalizeSharedConfig(\n config: SharedConfigInput,\n name: string,\n): SharedDependencyConfig {\n const version = assertResolvedSharedVersion(name, config.version);\n return {\n version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n strictVersion: config.strictVersion ?? false,\n eager: config.eager ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nfunction comparableSharedConfig(config: SharedConfigInput) {\n return {\n version: config.version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n strictVersion: config.strictVersion ?? false,\n eager: config.eager ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nexport function isSameSharedConfig(a: SharedConfigInput, b: SharedConfigInput): boolean {\n const left = comparableSharedConfig(a);\n const right = comparableSharedConfig(b);\n return (\n left.version === right.version &&\n left.requiredVersion === right.requiredVersion &&\n left.singleton === right.singleton &&\n left.strictVersion === right.strictVersion &&\n left.eager === right.eager &&\n left.shareScope === right.shareScope\n );\n}\n\nexport function mergeSharedMaps(\n ...maps: Array<Record<string, SharedConfigInput> | undefined>\n): Record<string, SharedDependencyConfig> {\n const merged: Record<string, SharedDependencyConfig> = {};\n for (const map of maps) {\n if (!map) continue;\n for (const [name, config] of Object.entries(map)) {\n const normalized = normalizeSharedConfig(config, name);\n const existing = merged[name];\n if (existing && !isSameSharedConfig(existing, normalized)) {\n throw new Error(\n `Conflicting shared dependency \"${name}\" in shared dependency configuration`,\n );\n }\n merged[name] = normalized;\n }\n }\n return merged;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-deps-spec.cjs","names":["require","createRequire","Data","join","existsSync","readFileSync","dirname","resolve","fileURLToPath"],"sources":["../src/shared-deps-spec.ts"],"sourcesContent":["/**\n * SharedDependencySpec: the one module owning shared-dependency names,\n * criticality, version resolution, and fallback policy across the Module\n * Federation graph. Four consumers derive from it — the rspack config\n * factory (plugin builds), the rsbuild config factory (ui remotes), the\n * runtime mf-config (the every-plugin MF instance), and the host's shared\n * pre-registration — so a name or criticality can never disagree between\n * them, and an unresolved version fails the build loudly instead of\n * silently degrading to \"*\"/\"latest\" (which disables the strict-singleton\n * guard).\n *\n * Lists:\n * - core: shared by the host and server-side plugin remotes (every-plugin,\n * effect, zod, @orpc/*). Effect-critical entries pin the exact installed\n * version (strictVersion) — the version-check machinery in\n * runtime/services/shared-identity.ts relies on it.\n * - ui: shared by the core ui provider and ui remotes (react, react-dom,\n * @orpc/client, @orpc/contract, TanStack, lingui, the everything-dev\n * session/i18n subpath modules). All strict singletons; consumers add\n * `import: false`.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Data } from \"effect\";\n\nconst require = createRequire(import.meta.url);\n\nexport class SharedDependencyResolutionError extends Data.TaggedError(\n \"SharedDependencyResolutionError\",\n)<{\n readonly packageName: string;\n readonly searched: string[];\n}> {\n constructor(packageName: string, searched: string[]) {\n super({\n packageName,\n searched,\n });\n }\n\n override get message() {\n return (\n `Could not resolve shared dependency \"${this.packageName}\". Looked in:\\n` +\n this.searched.map((location) => ` - ${location}`).join(\"\\n\") +\n `\\nUnresolved shared dependencies fail loudly (no \"*\", no \"latest\" fallback) — ` +\n `install the package in the resolving workspace or pin a resolvable version.`\n );\n }\n}\n\nexport type SharedDependencyResolution = \"self\" | \"package\" | \"subpath\";\n\nexport interface SharedDependencySpec {\n name: string;\n singleton: true;\n /** exact-version pin (requiredVersion = resolved version, strictVersion = true) */\n critical: boolean;\n resolution: SharedDependencyResolution;\n}\n\nexport const CORE_SHARED_DEPS = [\n { name: \"every-plugin\", singleton: true, critical: true, resolution: \"self\" },\n { name: \"effect\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"zod\", singleton: true, critical: false, resolution: \"package\" },\n { name: \"@orpc/contract\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/client\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/server\", singleton: true, critical: true, resolution: \"package\" },\n // v1's proven sharing set, restored: @orpc/openapi, @orpc/experimental-effect,\n // and @orpc/publisher joined this list in the v2 fleet-spec pass and their\n // share-scope consumption broke plugin loading at runtime\n // (__webpack_modules__[r] is not a function — the runtime's import()-based\n // provides hand the consumer an ESM namespace where a module factory is\n // expected). They stay declared in each workspace's package.json and are\n // bundled per workspace instead.\n] as const satisfies readonly SharedDependencySpec[];\n\nexport type CoreSharedDepName = (typeof CORE_SHARED_DEPS)[number][\"name\"];\n\nconst coreCriticalNames = CORE_SHARED_DEPS.flatMap((spec) => (spec.critical ? [spec.name] : []));\n\n/**\n * Effect-critical shared names, derived from the core list's `critical: true`\n * entries — the one source of criticality (`strictVersion` pinning in the\n * runtime's version-check machinery keys off this list).\n */\nexport const EFFECT_CRITICAL_SHARED_DEPS: readonly EffectCriticalSharedDepName[] =\n coreCriticalNames;\n\nexport type EffectCriticalSharedDepName = (typeof coreCriticalNames)[number];\n\nexport const isEffectCriticalSharedDep = (name: string): boolean =>\n (EFFECT_CRITICAL_SHARED_DEPS as readonly string[]).includes(name);\n\nexport const UI_SHARED_DEPS = [\n { name: \"react\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"react-dom\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/client\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@orpc/contract\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@tanstack/react-query\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@tanstack/react-router\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@lingui/core\", singleton: true, critical: true, resolution: \"package\" },\n { name: \"@lingui/react\", singleton: true, critical: true, resolution: \"package\" },\n {\n name: \"everything-dev/ui/auth\",\n singleton: true,\n critical: true,\n resolution: \"subpath\",\n },\n {\n name: \"everything-dev/ui/i18n\",\n singleton: true,\n critical: true,\n resolution: \"subpath\",\n },\n] as const satisfies readonly SharedDependencySpec[];\n\nexport const SHARED_DEP_SPECS: readonly SharedDependencySpec[] = (() => {\n const byName = new Map<string, SharedDependencySpec>();\n for (const spec of [...CORE_SHARED_DEPS, ...UI_SHARED_DEPS]) {\n const existing = byName.get(spec.name);\n if (existing) {\n if (existing.critical !== spec.critical) {\n throw new Error(\n `Shared dependency spec conflict for \"${spec.name}\": criticality disagrees between the core and ui lists`,\n );\n }\n continue;\n }\n byName.set(spec.name, spec);\n }\n return [...byName.values()];\n})();\n\nexport interface SharedDependencyConfig {\n version: string;\n requiredVersion: string | false;\n singleton: boolean;\n strictVersion: boolean;\n eager: boolean;\n shareScope: string;\n}\n\nexport type SharedDependencies = Record<string, SharedDependencyConfig>;\n\nexport type SharedConfigInput = {\n version: string;\n requiredVersion?: string | false;\n singleton?: boolean;\n strictVersion?: boolean;\n eager?: boolean;\n shareScope?: string;\n};\n\nexport interface SharedDependencyResolutionOptions {\n /** the building workspace to resolve from; default is this module's own location */\n workspaceRoot?: string;\n resolution?: \"package\" | \"subpath\";\n}\n\nfunction searchedNote(target: string): string {\n return `require.resolve(\"${target}\")`;\n}\n\nfunction findPackageJsonVersion(startDir: string, searched: string[]): string | null {\n let currentDir = startDir;\n for (let i = 0; i < 5; i += 1) {\n const packageJsonPath = join(currentDir, \"package.json\");\n searched.push(packageJsonPath);\n if (existsSync(packageJsonPath)) {\n try {\n const version = (JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: string })\n .version;\n if (version) return version;\n } catch {}\n }\n const parent = dirname(currentDir);\n if (parent === currentDir) break;\n currentDir = parent;\n }\n return null;\n}\n\nfunction resolveSubpathVersion(\n request: string,\n workspaceRoot: string | undefined,\n searched: string[],\n): string | null {\n if (request.startsWith(\"@\")) {\n throw new Error(\n `Scoped-package subpath \"${request}\" is not supported — subpath version resolution ` +\n `handles unscoped specifiers only (the known subpath specs, everything-dev/ui/*, are unscoped).`,\n );\n }\n const packageName = request.split(\"/\")[0] ?? request;\n const subpath = request.split(\"/\").slice(1).join(\"/\");\n const candidates: string[] = [];\n if (workspaceRoot) {\n candidates.push(join(workspaceRoot, \"node_modules\", packageName, \"package.json\"));\n }\n const resolveRequests: Array<{ request: string; paths?: string[] }> = [\n { request: `${packageName}/${subpath}`, ...(workspaceRoot ? { paths: [workspaceRoot] } : {}) },\n { request: `${packageName}/${subpath}` },\n {\n request: `${packageName}/package.json`,\n ...(workspaceRoot ? { paths: [workspaceRoot] } : {}),\n },\n { request: `${packageName}/package.json` },\n ];\n for (const { request: target, paths } of resolveRequests) {\n try {\n const resolved = require.resolve(target, paths ? { paths } : undefined);\n searched.push(resolved);\n candidates.push(\n resolved.endsWith(\"package.json\")\n ? resolved\n : resolve(dirname(resolved), \"..\", \"..\", \"package.json\"),\n );\n } catch {\n searched.push(searchedNote(target));\n }\n }\n for (const candidate of candidates) {\n if (!existsSync(candidate)) continue;\n try {\n const version = (JSON.parse(readFileSync(candidate, \"utf8\")) as { version?: string }).version;\n if (version) return version;\n } catch {}\n }\n return null;\n}\n\nexport function resolveSharedVersion(\n name: string,\n options: SharedDependencyResolutionOptions = {},\n): string {\n const searched: string[] = [];\n const { workspaceRoot, resolution = \"package\" } = options;\n\n if (resolution === \"subpath\") {\n const version = resolveSubpathVersion(name, workspaceRoot, searched);\n if (version) return version;\n throw new SharedDependencyResolutionError(name, searched);\n }\n\n const roots: Array<string | undefined> = workspaceRoot ? [workspaceRoot, undefined] : [undefined];\n for (const root of roots) {\n try {\n const resolved = root ? require.resolve(name, { paths: [root] }) : require.resolve(name);\n searched.push(resolved);\n const version = findPackageJsonVersion(dirname(resolved), searched);\n if (version) return version;\n } catch {\n searched.push(searchedNote(name));\n }\n }\n throw new SharedDependencyResolutionError(name, searched);\n}\n\nfunction resolveOwnVersion(searched: string[]): string {\n const localPackageJson = join(dirname(fileURLToPath(import.meta.url)), \"..\", \"package.json\");\n searched.push(localPackageJson);\n if (existsSync(localPackageJson)) {\n try {\n const version = (JSON.parse(readFileSync(localPackageJson, \"utf8\")) as { version?: string })\n .version;\n if (version) return version;\n } catch {}\n }\n try {\n const resolved = require.resolve(\"every-plugin/package.json\");\n searched.push(resolved);\n const version = (JSON.parse(readFileSync(resolved, \"utf8\")) as { version?: string }).version;\n if (version) return version;\n } catch {\n searched.push(searchedNote(\"every-plugin/package.json\"));\n }\n throw new SharedDependencyResolutionError(\"every-plugin\", searched);\n}\n\nexport function shareConfigFor(\n spec: SharedDependencySpec,\n version: string,\n): Omit<SharedDependencyConfig, \"version\"> {\n return spec.critical\n ? {\n requiredVersion: version,\n singleton: true,\n strictVersion: true,\n eager: false,\n shareScope: \"default\",\n }\n : {\n requiredVersion: false,\n singleton: true,\n strictVersion: false,\n eager: false,\n shareScope: \"default\",\n };\n}\n\nexport interface SharedDepsBuildOptions {\n /** the every-plugin share version; default resolves the installed package.json */\n ownVersion?: string;\n}\n\nfunction specVersion(spec: SharedDependencySpec, options: SharedDepsBuildOptions): string {\n if (spec.resolution === \"self\") {\n return options.ownVersion ?? resolveOwnVersion([`own package.json of \"${spec.name}\"`]);\n }\n return resolveSharedVersion(spec.name, {\n resolution: spec.resolution === \"subpath\" ? \"subpath\" : \"package\",\n });\n}\n\nexport function getPluginSharedDependencies(\n options: SharedDepsBuildOptions = {},\n): SharedDependencies {\n return Object.fromEntries(\n CORE_SHARED_DEPS.map((spec) => {\n const version = specVersion(spec, options);\n return [spec.name, { version, ...shareConfigFor(spec, version) }];\n }),\n );\n}\n\nexport interface HostSharedEntry {\n version: string;\n shareScope: string;\n shareConfig: {\n singleton: boolean;\n requiredVersion: string | false;\n strictVersion: boolean;\n eager: boolean;\n };\n}\n\nexport function toHostSharedEntry(name: string, config: SharedConfigInput): HostSharedEntry {\n const normalized = normalizeSharedConfig(config, name);\n return {\n version: normalized.version,\n shareScope: normalized.shareScope,\n shareConfig: {\n singleton: normalized.singleton,\n requiredVersion: normalized.requiredVersion,\n strictVersion: normalized.strictVersion,\n eager: normalized.eager,\n },\n };\n}\n\n/**\n * The runtime mf-config's core shared map: the same entries\n * `getPluginSharedDependencies` assembles, shaped through the one host mapper\n * (`toHostSharedEntry`) so both consumers derive from a single entry type.\n */\nexport function buildMfCoreSharedDependencies(\n options: SharedDepsBuildOptions = {},\n): Record<string, HostSharedEntry> {\n return Object.fromEntries(\n Object.entries(getPluginSharedDependencies(options)).map(([name, config]) => [\n name,\n toHostSharedEntry(name, config),\n ]),\n );\n}\n\nexport interface UiSharedDepEntry {\n version: string;\n requiredVersion: string | false;\n singleton: true;\n strictVersion: boolean;\n eager: false;\n shareScope: \"default\";\n /** consumer role only: no bundled fallback copy — the provider provides */\n import?: false;\n}\n\nexport interface UiSharedDepsOptions {\n /** explicit core-shell parity opt-out; default is the strict singleton */\n strictVersion?: boolean;\n role?: \"provider\" | \"consumer\";\n workspaceRoot?: string;\n}\n\nexport function createUiSharedDeps(\n options: UiSharedDepsOptions = {},\n): Record<string, UiSharedDepEntry> {\n const deps: Record<string, UiSharedDepEntry> = {};\n for (const spec of UI_SHARED_DEPS) {\n const version = resolveSharedVersion(spec.name, {\n workspaceRoot: options.workspaceRoot,\n resolution: spec.resolution === \"subpath\" ? \"subpath\" : \"package\",\n });\n const strict = options.strictVersion !== false;\n deps[spec.name] = {\n version,\n requiredVersion: strict ? version : false,\n singleton: true,\n strictVersion: strict,\n eager: false,\n shareScope: \"default\",\n ...(options.role === \"consumer\" ? { import: false as const } : {}),\n };\n }\n return deps;\n}\n\nconst UNRESOLVED_VERSIONS = new Set([\"*\", \"latest\", \"\"]);\n\nexport function assertResolvedSharedVersion(name: string, version: unknown): string {\n if (typeof version !== \"string\" || UNRESOLVED_VERSIONS.has(version.trim())) {\n throw new SharedDependencyResolutionError(name, [\n `declared version ${JSON.stringify(version ?? null)} is not resolvable — \"*\", \"latest\", and empty fail loudly instead of disabling the strict-singleton guard`,\n ]);\n }\n return version;\n}\n\nexport function normalizeSharedConfig(\n config: SharedConfigInput,\n name: string,\n): SharedDependencyConfig {\n const version = assertResolvedSharedVersion(name, config.version);\n return {\n version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n strictVersion: config.strictVersion ?? false,\n eager: config.eager ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nfunction comparableSharedConfig(config: SharedConfigInput) {\n return {\n version: config.version,\n requiredVersion: config.requiredVersion ?? false,\n singleton: config.singleton ?? false,\n strictVersion: config.strictVersion ?? false,\n eager: config.eager ?? false,\n shareScope: config.shareScope ?? \"default\",\n };\n}\n\nexport function isSameSharedConfig(a: SharedConfigInput, b: SharedConfigInput): boolean {\n const left = comparableSharedConfig(a);\n const right = comparableSharedConfig(b);\n return (\n left.version === right.version &&\n left.requiredVersion === right.requiredVersion &&\n left.singleton === right.singleton &&\n left.strictVersion === right.strictVersion &&\n left.eager === right.eager &&\n left.shareScope === right.shareScope\n );\n}\n\nexport function mergeSharedMaps(\n ...maps: Array<Record<string, SharedConfigInput> | undefined>\n): Record<string, SharedDependencyConfig> {\n const merged: Record<string, SharedDependencyConfig> = {};\n for (const map of maps) {\n if (!map) continue;\n for (const [name, config] of Object.entries(map)) {\n const normalized = normalizeSharedConfig(config, name);\n const existing = merged[name];\n if (existing && !isSameSharedConfig(existing, normalized)) {\n throw new Error(\n `Conflicting shared dependency \"${name}\" in shared dependency configuration`,\n );\n }\n merged[name] = normalized;\n }\n }\n return merged;\n}\n\nexport interface SharedVersionRecordEntry {\n version: string;\n singleton?: boolean;\n}\n\n/**\n * The `name → version` record of a build's shared-singleton map, for the\n * build report (and from there the version manifest's `shared` field) —\n * #546: a slot's pin must carry shared-dep semantics so consumers can detect\n * a build skew before loading. Singletons only — non-singletons never take\n * part in the negotiation a skew breaks.\n */\nexport function sharedVersionRecord(\n shared: Record<string, SharedVersionRecordEntry>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, config] of Object.entries(shared)) {\n if (config.singleton !== false && config.version) {\n out[name] = config.version;\n }\n }\n return out;\n}\n"],"mappings":"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"}
@@ -177,6 +177,18 @@ declare function assertResolvedSharedVersion(name: string, version: unknown): st
177
177
  declare function normalizeSharedConfig(config: SharedConfigInput, name: string): SharedDependencyConfig;
178
178
  declare function isSameSharedConfig(a: SharedConfigInput, b: SharedConfigInput): boolean;
179
179
  declare function mergeSharedMaps(...maps: Array<Record<string, SharedConfigInput> | undefined>): Record<string, SharedDependencyConfig>;
180
+ interface SharedVersionRecordEntry {
181
+ version: string;
182
+ singleton?: boolean;
183
+ }
184
+ /**
185
+ * The `name → version` record of a build's shared-singleton map, for the
186
+ * build report (and from there the version manifest's `shared` field) —
187
+ * #546: a slot's pin must carry shared-dep semantics so consumers can detect
188
+ * a build skew before loading. Singletons only — non-singletons never take
189
+ * part in the negotiation a skew breaks.
190
+ */
191
+ declare function sharedVersionRecord(shared: Record<string, SharedVersionRecordEntry>): Record<string, string>;
180
192
  //#endregion
181
- export { CORE_SHARED_DEPS, CoreSharedDepName, EFFECT_CRITICAL_SHARED_DEPS, EffectCriticalSharedDepName, HostSharedEntry, SHARED_DEP_SPECS, SharedConfigInput, SharedDependencies, SharedDependencyConfig, SharedDependencyResolution, SharedDependencyResolutionError, SharedDependencyResolutionOptions, SharedDependencySpec, SharedDepsBuildOptions, UI_SHARED_DEPS, UiSharedDepEntry, UiSharedDepsOptions, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, toHostSharedEntry };
193
+ export { CORE_SHARED_DEPS, CoreSharedDepName, EFFECT_CRITICAL_SHARED_DEPS, EffectCriticalSharedDepName, HostSharedEntry, SHARED_DEP_SPECS, SharedConfigInput, SharedDependencies, SharedDependencyConfig, SharedDependencyResolution, SharedDependencyResolutionError, SharedDependencyResolutionOptions, SharedDependencySpec, SharedDepsBuildOptions, SharedVersionRecordEntry, UI_SHARED_DEPS, UiSharedDepEntry, UiSharedDepsOptions, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, sharedVersionRecord, toHostSharedEntry };
182
194
  //# sourceMappingURL=shared-deps-spec.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-deps-spec.d.cts","names":[],"sources":["../src/shared-deps-spec.ts"],"mappings":";;;;cA6Ba,wCAAwC;WAG1C;WACA;;EAET,YAAY,qBAAqB;MAOpB;;KAUH;UAEK;EACf;EACA;;EAEA;EACA,YAAY;;cAGD;WACH;;;WAA6D;;WAC7D;;;WAAuD;;WACvD;;;WAAqD;;WACrD;;;WAA+D;;WAC/D;;;WAA6D;;WAC7D;;;WAA6D;;KAU3D,4BAA4B;cAElC;;;;;;cAOO,sCAAsC;KAGvC,sCAAsC;cAErC,4BAAyB;cAGzB;WACH;;;WAAsD;;WACtD;;;WAA0D;;WAC1D;;;WAA6D;;WAC7D;;;WAA+D;;WAC/D;;;WAAsE;;WACtE;;;WAAuE;;WACvE;;;WAA6D;;WAC7D;;;WAA8D;;WAE9D;;;WAGM;;WAGN;;;WAGM;;cAIH,2BAA2B;UAiBvB;EACf;EACA;EACA;EACA;EACA;EACA;;KAGU,qBAAqB,eAAe;KAEpC;EACV;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;iBA2Ec,qBACd,cACA,UAAS;iBA8CK,eACd,MAAM,sBACN,kBACC,KAAK;UAkBS;;EAEf;;iBAYc,4BACd,UAAS,yBACR;UASc;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAIY,kBAAkB,cAAc,QAAQ,oBAAoB;;;;;;iBAmB5D,8BACd,UAAS,yBACR,eAAe;UASD;EACf;EACA;EACA;EACA;EACA;EACA;;EAEA;;UAGe;;EAEf;EACA;EACA;;iBAGc,mBACd,UAAS,sBACR,eAAe;iBAuBF,4BAA4B,cAAc;iBAS1C,sBACd,QAAQ,mBACR,eACC;iBAuBa,mBAAmB,GAAG,mBAAmB,GAAG;iBAa5C,mBACX,MAAM,MAAM,eAAe,kCAC7B,eAAe"}
1
+ {"version":3,"file":"shared-deps-spec.d.cts","names":[],"sources":["../src/shared-deps-spec.ts"],"mappings":";;;;cA6Ba,wCAAwC;WAG1C;WACA;;EAET,YAAY,qBAAqB;MAOpB;;KAUH;UAEK;EACf;EACA;;EAEA;EACA,YAAY;;cAGD;WACH;;;WAA6D;;WAC7D;;;WAAuD;;WACvD;;;WAAqD;;WACrD;;;WAA+D;;WAC/D;;;WAA6D;;WAC7D;;;WAA6D;;KAU3D,4BAA4B;cAElC;;;;;;cAOO,sCAAsC;KAGvC,sCAAsC;cAErC,4BAAyB;cAGzB;WACH;;;WAAsD;;WACtD;;;WAA0D;;WAC1D;;;WAA6D;;WAC7D;;;WAA+D;;WAC/D;;;WAAsE;;WACtE;;;WAAuE;;WACvE;;;WAA6D;;WAC7D;;;WAA8D;;WAE9D;;;WAGM;;WAGN;;;WAGM;;cAIH,2BAA2B;UAiBvB;EACf;EACA;EACA;EACA;EACA;EACA;;KAGU,qBAAqB,eAAe;KAEpC;EACV;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;iBA2Ec,qBACd,cACA,UAAS;iBA8CK,eACd,MAAM,sBACN,kBACC,KAAK;UAkBS;;EAEf;;iBAYc,4BACd,UAAS,yBACR;UASc;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAIY,kBAAkB,cAAc,QAAQ,oBAAoB;;;;;;iBAmB5D,8BACd,UAAS,yBACR,eAAe;UASD;EACf;EACA;EACA;EACA;EACA;EACA;;EAEA;;UAGe;;EAEf;EACA;EACA;;iBAGc,mBACd,UAAS,sBACR,eAAe;iBAuBF,4BAA4B,cAAc;iBAS1C,sBACd,QAAQ,mBACR,eACC;iBAuBa,mBAAmB,GAAG,mBAAmB,GAAG;iBAa5C,mBACX,MAAM,MAAM,eAAe,kCAC7B,eAAe;UAkBD;EACf;EACA;;;;;;;;;iBAUc,oBACd,QAAQ,eAAe,4BACtB"}
@@ -177,6 +177,18 @@ declare function assertResolvedSharedVersion(name: string, version: unknown): st
177
177
  declare function normalizeSharedConfig(config: SharedConfigInput, name: string): SharedDependencyConfig;
178
178
  declare function isSameSharedConfig(a: SharedConfigInput, b: SharedConfigInput): boolean;
179
179
  declare function mergeSharedMaps(...maps: Array<Record<string, SharedConfigInput> | undefined>): Record<string, SharedDependencyConfig>;
180
+ interface SharedVersionRecordEntry {
181
+ version: string;
182
+ singleton?: boolean;
183
+ }
184
+ /**
185
+ * The `name → version` record of a build's shared-singleton map, for the
186
+ * build report (and from there the version manifest's `shared` field) —
187
+ * #546: a slot's pin must carry shared-dep semantics so consumers can detect
188
+ * a build skew before loading. Singletons only — non-singletons never take
189
+ * part in the negotiation a skew breaks.
190
+ */
191
+ declare function sharedVersionRecord(shared: Record<string, SharedVersionRecordEntry>): Record<string, string>;
180
192
  //#endregion
181
- export { CORE_SHARED_DEPS, CoreSharedDepName, EFFECT_CRITICAL_SHARED_DEPS, EffectCriticalSharedDepName, HostSharedEntry, SHARED_DEP_SPECS, SharedConfigInput, SharedDependencies, SharedDependencyConfig, SharedDependencyResolution, SharedDependencyResolutionError, SharedDependencyResolutionOptions, SharedDependencySpec, SharedDepsBuildOptions, UI_SHARED_DEPS, UiSharedDepEntry, UiSharedDepsOptions, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, toHostSharedEntry };
193
+ export { CORE_SHARED_DEPS, CoreSharedDepName, EFFECT_CRITICAL_SHARED_DEPS, EffectCriticalSharedDepName, HostSharedEntry, SHARED_DEP_SPECS, SharedConfigInput, SharedDependencies, SharedDependencyConfig, SharedDependencyResolution, SharedDependencyResolutionError, SharedDependencyResolutionOptions, SharedDependencySpec, SharedDepsBuildOptions, SharedVersionRecordEntry, UI_SHARED_DEPS, UiSharedDepEntry, UiSharedDepsOptions, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, sharedVersionRecord, toHostSharedEntry };
182
194
  //# sourceMappingURL=shared-deps-spec.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-deps-spec.d.mts","names":[],"sources":["../src/shared-deps-spec.ts"],"mappings":";;;;cA6Ba,wCAAwC;WAG1C;WACA;;EAET,YAAY,qBAAqB;MAOpB;;KAUH;UAEK;EACf;EACA;;EAEA;EACA,YAAY;;cAGD;WACH;;;WAA6D;;WAC7D;;;WAAuD;;WACvD;;;WAAqD;;WACrD;;;WAA+D;;WAC/D;;;WAA6D;;WAC7D;;;WAA6D;;KAU3D,4BAA4B;cAElC;;;;;;cAOO,sCAAsC;KAGvC,sCAAsC;cAErC,4BAAyB;cAGzB;WACH;;;WAAsD;;WACtD;;;WAA0D;;WAC1D;;;WAA6D;;WAC7D;;;WAA+D;;WAC/D;;;WAAsE;;WACtE;;;WAAuE;;WACvE;;;WAA6D;;WAC7D;;;WAA8D;;WAE9D;;;WAGM;;WAGN;;;WAGM;;cAIH,2BAA2B;UAiBvB;EACf;EACA;EACA;EACA;EACA;EACA;;KAGU,qBAAqB,eAAe;KAEpC;EACV;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;iBA2Ec,qBACd,cACA,UAAS;iBA8CK,eACd,MAAM,sBACN,kBACC,KAAK;UAkBS;;EAEf;;iBAYc,4BACd,UAAS,yBACR;UASc;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAIY,kBAAkB,cAAc,QAAQ,oBAAoB;;;;;;iBAmB5D,8BACd,UAAS,yBACR,eAAe;UASD;EACf;EACA;EACA;EACA;EACA;EACA;;EAEA;;UAGe;;EAEf;EACA;EACA;;iBAGc,mBACd,UAAS,sBACR,eAAe;iBAuBF,4BAA4B,cAAc;iBAS1C,sBACd,QAAQ,mBACR,eACC;iBAuBa,mBAAmB,GAAG,mBAAmB,GAAG;iBAa5C,mBACX,MAAM,MAAM,eAAe,kCAC7B,eAAe"}
1
+ {"version":3,"file":"shared-deps-spec.d.mts","names":[],"sources":["../src/shared-deps-spec.ts"],"mappings":";;;;cA6Ba,wCAAwC;WAG1C;WACA;;EAET,YAAY,qBAAqB;MAOpB;;KAUH;UAEK;EACf;EACA;;EAEA;EACA,YAAY;;cAGD;WACH;;;WAA6D;;WAC7D;;;WAAuD;;WACvD;;;WAAqD;;WACrD;;;WAA+D;;WAC/D;;;WAA6D;;WAC7D;;;WAA6D;;KAU3D,4BAA4B;cAElC;;;;;;cAOO,sCAAsC;KAGvC,sCAAsC;cAErC,4BAAyB;cAGzB;WACH;;;WAAsD;;WACtD;;;WAA0D;;WAC1D;;;WAA6D;;WAC7D;;;WAA+D;;WAC/D;;;WAAsE;;WACtE;;;WAAuE;;WACvE;;;WAA6D;;WAC7D;;;WAA8D;;WAE9D;;;WAGM;;WAGN;;;WAGM;;cAIH,2BAA2B;UAiBvB;EACf;EACA;EACA;EACA;EACA;EACA;;KAGU,qBAAqB,eAAe;KAEpC;EACV;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;iBA2Ec,qBACd,cACA,UAAS;iBA8CK,eACd,MAAM,sBACN,kBACC,KAAK;UAkBS;;EAEf;;iBAYc,4BACd,UAAS,yBACR;UASc;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAIY,kBAAkB,cAAc,QAAQ,oBAAoB;;;;;;iBAmB5D,8BACd,UAAS,yBACR,eAAe;UASD;EACf;EACA;EACA;EACA;EACA;EACA;;EAEA;;UAGe;;EAEf;EACA;EACA;;iBAGc,mBACd,UAAS,sBACR,eAAe;iBAuBF,4BAA4B,cAAc;iBAS1C,sBACd,QAAQ,mBACR,eACC;iBAuBa,mBAAmB,GAAG,mBAAmB,GAAG;iBAa5C,mBACX,MAAM,MAAM,eAAe,kCAC7B,eAAe;UAkBD;EACf;EACA;;;;;;;;;iBAUc,oBACd,QAAQ,eAAe,4BACtB"}
@@ -362,7 +362,19 @@ function mergeSharedMaps(...maps) {
362
362
  }
363
363
  return merged;
364
364
  }
365
+ /**
366
+ * The `name → version` record of a build's shared-singleton map, for the
367
+ * build report (and from there the version manifest's `shared` field) —
368
+ * #546: a slot's pin must carry shared-dep semantics so consumers can detect
369
+ * a build skew before loading. Singletons only — non-singletons never take
370
+ * part in the negotiation a skew breaks.
371
+ */
372
+ function sharedVersionRecord(shared) {
373
+ const out = {};
374
+ for (const [name, config] of Object.entries(shared)) if (config.singleton !== false && config.version) out[name] = config.version;
375
+ return out;
376
+ }
365
377
 
366
378
  //#endregion
367
- export { CORE_SHARED_DEPS, EFFECT_CRITICAL_SHARED_DEPS, SHARED_DEP_SPECS, SharedDependencyResolutionError, UI_SHARED_DEPS, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, toHostSharedEntry };
379
+ export { CORE_SHARED_DEPS, EFFECT_CRITICAL_SHARED_DEPS, SHARED_DEP_SPECS, SharedDependencyResolutionError, UI_SHARED_DEPS, assertResolvedSharedVersion, buildMfCoreSharedDependencies, createUiSharedDeps, getPluginSharedDependencies, isEffectCriticalSharedDep, isSameSharedConfig, mergeSharedMaps, normalizeSharedConfig, resolveSharedVersion, shareConfigFor, sharedVersionRecord, toHostSharedEntry };
368
380
  //# sourceMappingURL=shared-deps-spec.mjs.map