-
Notifications
You must be signed in to change notification settings - Fork 1
spike: slim facade — bundler comparison (sum/enter-numbers-v3) #1644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,3 @@ | ||
| block-pack/ | ||
| dist-dbg/ | ||
| dist-rdp/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| // Scratch facade-bundle build for the slim-facade spike. | ||
| // Runs both bundlers side-by-side. Output is for inspection only. | ||
| // | ||
| // pnpm build:facade | ||
| // | ||
| // Produces: | ||
| // dist-dbg/index.d.ts — dts-bundle-generator output | ||
| // dist-rdp/index.d.ts — rolldown-plugin-dts output | ||
| // | ||
| // Both bundlers configured to fully inline @platforma-sdk/model and the | ||
| // sibling model package so the facade is self-contained. | ||
|
|
||
| import { readFileSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; | ||
| import { dirname, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| import { generateDtsBundle } from "dts-bundle-generator"; | ||
| import { rolldown } from "rolldown"; | ||
| import { dts } from "rolldown-plugin-dts"; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const pkg = JSON.parse(readFileSync(resolve(__dirname, "package.json"), "utf-8")); | ||
|
|
||
| const entryTs = resolve(__dirname, "src/index.ts"); | ||
| const tsconfigPath = resolve(__dirname, "tsconfig.json"); | ||
|
|
||
| const modelPkgName = Object.keys(pkg.dependencies ?? {}).find((n) => n.endsWith(".model")); | ||
| if (!modelPkgName) throw new Error("Could not find sibling .model package in dependencies."); | ||
|
|
||
| const inlineList = ["@platforma-sdk/model", modelPkgName]; | ||
|
|
||
| console.log(`Facade source: ${entryTs}`); | ||
| console.log(`Inlining: ${inlineList.join(", ")}`); | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // dts-bundle-generator | ||
| // --------------------------------------------------------------------------- | ||
| { | ||
| const outDir = resolve(__dirname, "dist-dbg"); | ||
| rmSync(outDir, { recursive: true, force: true }); | ||
| mkdirSync(outDir, { recursive: true }); | ||
|
|
||
| const t0 = Date.now(); | ||
| const [content] = generateDtsBundle( | ||
| [ | ||
| { | ||
| filePath: entryTs, | ||
| libraries: { inlinedLibraries: inlineList }, | ||
| output: { sortNodes: false, noBanner: false }, | ||
| }, | ||
| ], | ||
| { preferredConfigPath: tsconfigPath, followSymlinks: true }, | ||
| ); | ||
| writeFileSync(resolve(outDir, "index.d.ts"), content); | ||
| console.log(`dts-bundle-generator → dist-dbg/index.d.ts (${Date.now() - t0} ms, ${content.length} bytes)`); | ||
| } | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // rolldown-plugin-dts | ||
| // --------------------------------------------------------------------------- | ||
| { | ||
| const outDir = resolve(__dirname, "dist-rdp"); | ||
| rmSync(outDir, { recursive: true, force: true }); | ||
| mkdirSync(outDir, { recursive: true }); | ||
|
|
||
| const t0 = Date.now(); | ||
| const bundle = await rolldown({ | ||
| input: entryTs, | ||
| // Force every package to be resolved and pulled into the bundle so the | ||
| // facade is self-contained. Default Rolldown behavior would keep | ||
| // non-relative imports external. | ||
| external: () => false, | ||
| plugins: [ | ||
| dts({ | ||
| tsconfig: tsconfigPath, | ||
| emitDtsOnly: true, | ||
| sourcemap: false, | ||
| }), | ||
| ], | ||
| }); | ||
| await bundle.write({ dir: outDir, format: "es" }); | ||
| await bundle.close(); | ||
| const out = readFileSync(resolve(outDir, "index.d.ts"), "utf-8"); | ||
| console.log(`rolldown-plugin-dts → dist-rdp/index.d.ts (${Date.now() - t0} ms, ${out.length} bytes)`); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||
| import type { InferDataType, InferHrefType, InferOutputsType } from "@platforma-sdk/model"; | ||||||
| import type { | ||||||
| BlockData, | ||||||
| EnterNumbersRef, | ||||||
| } from "@milaboratories/milaboratories.test-enter-numbers-v3.model"; | ||||||
| import { platforma } from "@milaboratories/milaboratories.test-enter-numbers-v3.model"; | ||||||
|
|
||||||
| /** | ||||||
| * Spec marker for the Enter Numbers v3 block. Phantom type — encodes the | ||||||
| * outputs, data, and href shapes so consumers (tests, MCP, other blocks) | ||||||
| * can reach them via the `OutputsOf` / `DataOf` / `HrefOf` generators. | ||||||
| * | ||||||
| * Spike probe — top-level alias JSDoc with rich content. | ||||||
| */ | ||||||
| export interface EnterNumbersV3Spec { | ||||||
| /** Nominal tag pinning this Spec to the enter-numbers-v3 block. */ | ||||||
| readonly __block: "enter-numbers-v3"; | ||||||
| /** Outputs reachable through the block's workflow run. */ | ||||||
| outputs: InferOutputsType<typeof platforma>; | ||||||
| /** Persistent block state (data) — see {@link BlockData}. */ | ||||||
| data: InferDataType<typeof platforma>; | ||||||
| /** Hrefs the block UI advertises. */ | ||||||
| href: InferHrefType<typeof platforma>; | ||||||
| } | ||||||
|
|
||||||
| /** Universal Spec twin — every facade exports `BlockSpec` as an alias of its block-named Spec. */ | ||||||
| export type BlockSpec = EnterNumbersV3Spec; | ||||||
|
|
||||||
| /** Extract the outputs shape from a block Spec. */ | ||||||
| export type OutputsOf<S> = S extends { outputs: infer O } ? O : never; | ||||||
|
|
||||||
| /** Extract the data (block state) shape from a block Spec. */ | ||||||
| export type DataOf<S> = S extends { data: infer D } ? D : never; | ||||||
|
|
||||||
| /** Extract the href shape from a block Spec. */ | ||||||
| export type HrefOf<S> = S extends { href: infer H } ? H : never; | ||||||
|
|
||||||
| /** | ||||||
| * Outputs of this block. Convenience alias equal to `OutputsOf<BlockSpec>`. | ||||||
| * The shape is derived via `InferOutputsType<typeof platforma>` — JSDoc | ||||||
| * placed on the individual `.output(...)` builders in the model package must | ||||||
| * survive into the bundled facade `.d.ts`. | ||||||
| */ | ||||||
| export type BlockOutputs = InferOutputsType<typeof platforma>; | ||||||
|
|
||||||
| export type { BlockData, EnterNumbersRef }; | ||||||
|
|
||||||
| const __facadeDir__ = new URL(".", import.meta.url).pathname; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
References
|
||||||
|
|
||||||
| /** | ||||||
| * Dev-v2 block spec — folder-based, resolved relative to the facade directory. | ||||||
| * | ||||||
| * Phase C will replace the runtime side with a registry-aware dispatcher; | ||||||
| * Phase B keeps the existing dev-v2 shape unchanged. | ||||||
| */ | ||||||
| export const blockSpec = { | ||||||
| type: "dev-v2" as const, | ||||||
| folder: __facadeDir__, | ||||||
| }; | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "extends": "@milaboratories/ts-configs/node", | ||
| "compilerOptions": { | ||
| "noEmit": false, | ||
| "declaration": true, | ||
| "emitDeclarationOnly": true, | ||
| "outDir": "dist-types", | ||
| "customConditions": [] | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist", "dist-types", "dist-dbg", "dist-rdp", "**/*.test.ts"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| // Scratch facade-bundle build for the slim-facade spike. | ||
| // Runs both bundlers side-by-side. Output is for inspection only. | ||
| // | ||
| // pnpm build:facade | ||
| // | ||
| // Produces: | ||
| // dist-dbg/index.d.ts — dts-bundle-generator output | ||
| // dist-rdp/index.d.ts — rolldown-plugin-dts output | ||
| // | ||
| // Both bundlers configured to fully inline @platforma-sdk/model and the | ||
| // sibling model package so the facade is self-contained. | ||
|
|
||
| import { readFileSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; | ||
| import { dirname, resolve } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| import { generateDtsBundle } from "dts-bundle-generator"; | ||
| import { rolldown } from "rolldown"; | ||
| import { dts } from "rolldown-plugin-dts"; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const pkg = JSON.parse(readFileSync(resolve(__dirname, "package.json"), "utf-8")); | ||
|
|
||
| const entryTs = resolve(__dirname, "src/index.ts"); | ||
| const tsconfigPath = resolve(__dirname, "tsconfig.json"); | ||
|
|
||
| const modelPkgName = Object.keys(pkg.dependencies ?? {}).find((n) => n.endsWith(".model")); | ||
| if (!modelPkgName) throw new Error("Could not find sibling .model package in dependencies."); | ||
|
|
||
| const inlineList = ["@platforma-sdk/model", modelPkgName]; | ||
|
|
||
| console.log(`Facade source: ${entryTs}`); | ||
| console.log(`Inlining: ${inlineList.join(", ")}`); | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // dts-bundle-generator | ||
| // --------------------------------------------------------------------------- | ||
| { | ||
| const outDir = resolve(__dirname, "dist-dbg"); | ||
| rmSync(outDir, { recursive: true, force: true }); | ||
| mkdirSync(outDir, { recursive: true }); | ||
|
|
||
| const t0 = Date.now(); | ||
| const [content] = generateDtsBundle( | ||
| [ | ||
| { | ||
| filePath: entryTs, | ||
| libraries: { inlinedLibraries: inlineList }, | ||
| output: { sortNodes: false, noBanner: false }, | ||
| }, | ||
| ], | ||
| { preferredConfigPath: tsconfigPath, followSymlinks: true }, | ||
| ); | ||
| writeFileSync(resolve(outDir, "index.d.ts"), content); | ||
| console.log(`dts-bundle-generator → dist-dbg/index.d.ts (${Date.now() - t0} ms, ${content.length} bytes)`); | ||
| } | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // rolldown-plugin-dts | ||
| // --------------------------------------------------------------------------- | ||
| { | ||
| const outDir = resolve(__dirname, "dist-rdp"); | ||
| rmSync(outDir, { recursive: true, force: true }); | ||
| mkdirSync(outDir, { recursive: true }); | ||
|
|
||
| const t0 = Date.now(); | ||
| const bundle = await rolldown({ | ||
| input: entryTs, | ||
| // Force every package to be resolved and pulled into the bundle so the | ||
| // facade is self-contained. Default Rolldown behavior would keep | ||
| // non-relative imports external. | ||
| external: () => false, | ||
| plugins: [ | ||
| dts({ | ||
| tsconfig: tsconfigPath, | ||
| emitDtsOnly: true, | ||
| sourcemap: false, | ||
| }), | ||
| ], | ||
| }); | ||
| await bundle.write({ dir: outDir, format: "es" }); | ||
| await bundle.close(); | ||
| const out = readFileSync(resolve(outDir, "index.d.ts"), "utf-8"); | ||
| console.log(`rolldown-plugin-dts → dist-rdp/index.d.ts (${Date.now() - t0} ms, ${out.length} bytes)`); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To ensure cross-platform compatibility, especially on Windows, it is recommended to use
fileURLToPathfrom thenode:urlmodule when deriving file system paths fromimport.meta.url. This avoids issues with URI-encoded characters and the leading slash present in.pathnameon Windows.