@arcote.tech/arc-cli 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +32 -15
- package/package.json +10 -10
- package/src/builder/module-builder.ts +64 -15
- package/src/builder/seed-guard.ts +21 -4
package/dist/index.js
CHANGED
|
@@ -31890,19 +31890,23 @@ function discoverPackages(rootDir) {
|
|
|
31890
31890
|
if (pkg.name?.startsWith("@arcote.tech/"))
|
|
31891
31891
|
continue;
|
|
31892
31892
|
const pkgDir = join9(baseDir, entry);
|
|
31893
|
-
const
|
|
31894
|
-
join9(pkgDir, "src",
|
|
31895
|
-
join9(pkgDir, "src",
|
|
31896
|
-
join9(pkgDir,
|
|
31897
|
-
join9(pkgDir,
|
|
31893
|
+
const entryCandidates = (variant) => [
|
|
31894
|
+
join9(pkgDir, "src", `index${variant}.ts`),
|
|
31895
|
+
join9(pkgDir, "src", `index${variant}.tsx`),
|
|
31896
|
+
join9(pkgDir, `index${variant}.ts`),
|
|
31897
|
+
join9(pkgDir, `index${variant}.tsx`)
|
|
31898
31898
|
];
|
|
31899
|
-
const entrypoint =
|
|
31899
|
+
const entrypoint = entryCandidates("").find((c) => existsSync8(c)) ?? null;
|
|
31900
31900
|
if (!entrypoint)
|
|
31901
31901
|
continue;
|
|
31902
|
+
const serverEntrypoint = entryCandidates(".server").find((c) => existsSync8(c)) ?? entrypoint;
|
|
31903
|
+
const clientEntrypoint = entryCandidates(".client").find((c) => existsSync8(c)) ?? entrypoint;
|
|
31902
31904
|
results.push({
|
|
31903
31905
|
name: pkg.name,
|
|
31904
31906
|
path: join9(baseDir, entry),
|
|
31905
31907
|
entrypoint,
|
|
31908
|
+
serverEntrypoint,
|
|
31909
|
+
clientEntrypoint,
|
|
31906
31910
|
packageJson: pkg
|
|
31907
31911
|
});
|
|
31908
31912
|
}
|
|
@@ -31944,13 +31948,15 @@ function depVersionsHash(rootDir, pkg) {
|
|
|
31944
31948
|
async function buildContextClient(pkg, rootDir, client, cache, noCache) {
|
|
31945
31949
|
const unitId = `context-pkg:${pkg.name}:${client.name}`;
|
|
31946
31950
|
const outDir = join9(pkg.path, "dist", client.name);
|
|
31951
|
+
const entry = client.target === "browser" ? pkg.clientEntrypoint : pkg.entrypoint;
|
|
31947
31952
|
const inputHash = sha256OfJson({
|
|
31948
31953
|
src: pkgSourceHash(pkg),
|
|
31949
31954
|
pkg: pkg.packageJson,
|
|
31950
31955
|
deps: depVersionsHash(rootDir, pkg),
|
|
31951
31956
|
client: client.name,
|
|
31952
31957
|
target: client.target,
|
|
31953
|
-
defines: client.defines
|
|
31958
|
+
defines: client.defines,
|
|
31959
|
+
entry: relative3(pkg.path, entry)
|
|
31954
31960
|
});
|
|
31955
31961
|
if (!noCache && isCacheHit(cache, unitId, inputHash, [join9(outDir, "main", "index.js")])) {
|
|
31956
31962
|
console.log(` \u2713 cached: ${pkg.name} (${client.name})`);
|
|
@@ -31961,7 +31967,7 @@ async function buildContextClient(pkg, rootDir, client, cache, noCache) {
|
|
|
31961
31967
|
const allDeps = pkg.packageJson.dependencies ?? {};
|
|
31962
31968
|
const externals = [...peerDeps, ...Object.keys(allDeps)];
|
|
31963
31969
|
const result = await Bun.build({
|
|
31964
|
-
entrypoints: [
|
|
31970
|
+
entrypoints: [entry],
|
|
31965
31971
|
outdir: join9(outDir, "main"),
|
|
31966
31972
|
target: client.target,
|
|
31967
31973
|
format: "esm",
|
|
@@ -31981,7 +31987,7 @@ async function buildContextClient(pkg, rootDir, client, cache, noCache) {
|
|
|
31981
31987
|
}
|
|
31982
31988
|
const globalsContent = Object.entries(client.defines).map(([k, v]) => `declare const ${k}: ${v};`).join(`
|
|
31983
31989
|
`);
|
|
31984
|
-
const declResult = await buildTypeDeclarations([
|
|
31990
|
+
const declResult = await buildTypeDeclarations([entry], outDir, dirname6(entry), globalsContent);
|
|
31985
31991
|
const declarationErrors = !declResult.success && declResult.errors.length > 0 ? declResult.errors.map((e) => `[${pkg.name}/${client.name}] ${e}`) : [];
|
|
31986
31992
|
const outputHash = sha256OfDir(outDir);
|
|
31987
31993
|
updateCache(cache, unitId, inputHash, { outputHash });
|
|
@@ -32036,7 +32042,7 @@ async function buildContextPackages(rootDir, packages, cache, noCache) {
|
|
|
32036
32042
|
async function buildServerApp(rootDir, serverDir, packages, cache, noCache) {
|
|
32037
32043
|
const contexts = packages.filter((p) => isContextPackage(p.packageJson));
|
|
32038
32044
|
mkdirSync7(serverDir, { recursive: true });
|
|
32039
|
-
const srcByName = new Map(packages.map((p) => [p.name, p.
|
|
32045
|
+
const srcByName = new Map(packages.map((p) => [p.name, p.serverEntrypoint]));
|
|
32040
32046
|
const externalSet = new Set(FRAMEWORK_PEERS);
|
|
32041
32047
|
for (const p of packages) {
|
|
32042
32048
|
for (const name of Object.keys(p.packageJson.peerDependencies ?? {})) {
|
|
@@ -32050,7 +32056,11 @@ async function buildServerApp(rootDir, serverDir, packages, cache, noCache) {
|
|
|
32050
32056
|
const external = [...externalSet];
|
|
32051
32057
|
const unitId = "server-app";
|
|
32052
32058
|
const inputHash = sha256OfJson({
|
|
32053
|
-
members: packages.map((p) => ({
|
|
32059
|
+
members: packages.map((p) => ({
|
|
32060
|
+
name: p.name,
|
|
32061
|
+
src: pkgSourceHash(p),
|
|
32062
|
+
serverEntry: relative3(p.path, p.serverEntrypoint)
|
|
32063
|
+
})).sort((a, b) => a.name.localeCompare(b.name)),
|
|
32054
32064
|
contexts: contexts.map((p) => p.name).sort(),
|
|
32055
32065
|
external: [...external].sort(),
|
|
32056
32066
|
defines: SERVER_DEFINES,
|
|
@@ -32292,11 +32302,11 @@ async function buildBrowserApp(rootDir, outDir, plan, cache, noCache, i18nCollec
|
|
|
32292
32302
|
const unitId = opts?.unitId ?? "browser-app";
|
|
32293
32303
|
const allMembers = [];
|
|
32294
32304
|
for (const m of publicMembers) {
|
|
32295
|
-
allMembers.push({ name: m.pkg.name, group: "public", srcHash: pkgSourceHash(m.pkg) });
|
|
32305
|
+
allMembers.push({ name: m.pkg.name, group: "public", srcHash: pkgSourceHash(m.pkg), clientEntry: relative3(m.pkg.path, m.pkg.clientEntrypoint) });
|
|
32296
32306
|
}
|
|
32297
32307
|
for (const g of protectedGroups) {
|
|
32298
32308
|
for (const m of g.members) {
|
|
32299
|
-
allMembers.push({ name: m.pkg.name, group: g.name, srcHash: pkgSourceHash(m.pkg) });
|
|
32309
|
+
allMembers.push({ name: m.pkg.name, group: g.name, srcHash: pkgSourceHash(m.pkg), clientEntry: relative3(m.pkg.path, m.pkg.clientEntrypoint) });
|
|
32300
32310
|
}
|
|
32301
32311
|
}
|
|
32302
32312
|
const inputHash = sha256OfJson({
|
|
@@ -32310,7 +32320,7 @@ async function buildBrowserApp(rootDir, outDir, plan, cache, noCache, i18nCollec
|
|
|
32310
32320
|
exposeRuntime,
|
|
32311
32321
|
minify,
|
|
32312
32322
|
externals: federated ? [...SHELL_EXTERNALS] : [],
|
|
32313
|
-
builderRev:
|
|
32323
|
+
builderRev: 4
|
|
32314
32324
|
});
|
|
32315
32325
|
if (!noCache && !buildStatsEnabled() && isCacheHit(cache, unitId, inputHash)) {
|
|
32316
32326
|
const cached = cache.units[unitId]?.outputHashes;
|
|
@@ -32363,6 +32373,12 @@ export { startApp } from "@arcote.tech/platform";
|
|
|
32363
32373
|
for (const g of protectedGroups)
|
|
32364
32374
|
for (const m of g.members)
|
|
32365
32375
|
allMemberPkgs.set(m.pkg.name, m.pkg);
|
|
32376
|
+
const clientByName = new Map;
|
|
32377
|
+
for (const pkg of allMemberPkgs.values()) {
|
|
32378
|
+
if (pkg.clientEntrypoint !== pkg.entrypoint) {
|
|
32379
|
+
clientByName.set(pkg.name, pkg.clientEntrypoint);
|
|
32380
|
+
}
|
|
32381
|
+
}
|
|
32366
32382
|
const patchedPkgJsons = [];
|
|
32367
32383
|
for (const pkg of allMemberPkgs.values()) {
|
|
32368
32384
|
const pkgJsonPath = join9(pkg.path, "package.json");
|
|
@@ -32389,6 +32405,7 @@ export { startApp } from "@arcote.tech/platform";
|
|
|
32389
32405
|
target: "browser",
|
|
32390
32406
|
external: federated ? [...SHELL_EXTERNALS] : [],
|
|
32391
32407
|
plugins: [
|
|
32408
|
+
...clientByName.size > 0 ? [workspaceSourcePlugin(clientByName)] : [],
|
|
32392
32409
|
...federated ? [] : [singleReactPlugin(rootDir)],
|
|
32393
32410
|
jsxDevShimPlugin(),
|
|
32394
32411
|
nodeServerBuiltinStubPlugin(),
|
|
@@ -32780,7 +32797,7 @@ function walkTsFiles(dir, out) {
|
|
|
32780
32797
|
if (entry.name === "__tests__")
|
|
32781
32798
|
continue;
|
|
32782
32799
|
walkTsFiles(abs, out);
|
|
32783
|
-
} else if (entry.isFile() && /\.(ts|tsx)$/.test(entry.name) && !entry.name.endsWith(".d.ts")) {
|
|
32800
|
+
} else if (entry.isFile() && /\.(ts|tsx)$/.test(entry.name) && !entry.name.endsWith(".d.ts") && !/\.server\.tsx?$/.test(entry.name)) {
|
|
32784
32801
|
out.push(abs);
|
|
32785
32802
|
}
|
|
32786
32803
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "CLI tool for Arc framework",
|
|
5
5
|
"module": "index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"build": "bun build --target=bun ./src/index.ts --outdir=dist --external @arcote.tech/arc --external @arcote.tech/arc-ds --external @arcote.tech/arc-react --external @arcote.tech/platform --external @arcote.tech/arc-map --external '@opentelemetry/*' && chmod +x dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@arcote.tech/arc": "^0.8.
|
|
16
|
-
"@arcote.tech/arc-ds": "^0.8.
|
|
17
|
-
"@arcote.tech/arc-react": "^0.8.
|
|
18
|
-
"@arcote.tech/arc-host": "^0.8.
|
|
19
|
-
"@arcote.tech/arc-adapter-db-sqlite": "^0.8.
|
|
20
|
-
"@arcote.tech/arc-adapter-db-postgres": "^0.8.
|
|
21
|
-
"@arcote.tech/arc-otel": "^0.8.
|
|
15
|
+
"@arcote.tech/arc": "^0.8.7",
|
|
16
|
+
"@arcote.tech/arc-ds": "^0.8.7",
|
|
17
|
+
"@arcote.tech/arc-react": "^0.8.7",
|
|
18
|
+
"@arcote.tech/arc-host": "^0.8.7",
|
|
19
|
+
"@arcote.tech/arc-adapter-db-sqlite": "^0.8.7",
|
|
20
|
+
"@arcote.tech/arc-adapter-db-postgres": "^0.8.7",
|
|
21
|
+
"@arcote.tech/arc-otel": "^0.8.7",
|
|
22
22
|
"@opentelemetry/api": "^1.9.0",
|
|
23
23
|
"@opentelemetry/api-logs": "^0.57.0",
|
|
24
24
|
"@opentelemetry/core": "^1.30.0",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|
|
32
32
|
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
33
33
|
"@opentelemetry/semantic-conventions": "^1.27.0",
|
|
34
|
-
"@arcote.tech/platform": "^0.8.
|
|
35
|
-
"@arcote.tech/arc-map": "^0.8.
|
|
34
|
+
"@arcote.tech/platform": "^0.8.7",
|
|
35
|
+
"@arcote.tech/arc-map": "^0.8.7",
|
|
36
36
|
"@clack/prompts": "^0.9.0",
|
|
37
37
|
"commander": "^11.1.0",
|
|
38
38
|
"chokidar": "^3.5.3",
|
|
@@ -345,7 +345,12 @@ export const SERVER_EXTERNALS_FILE = "_externals.json";
|
|
|
345
345
|
export interface WorkspacePackage {
|
|
346
346
|
name: string;
|
|
347
347
|
path: string;
|
|
348
|
+
/** Base entry (src/index.ts). Fallback for both targets. */
|
|
348
349
|
entrypoint: string;
|
|
350
|
+
/** src/index.server.ts if present, else `entrypoint`. Used by the SERVER bundle. */
|
|
351
|
+
serverEntrypoint: string;
|
|
352
|
+
/** src/index.client.ts if present, else `entrypoint`. Used by the CLIENT (browser) bundle. */
|
|
353
|
+
clientEntrypoint: string;
|
|
349
354
|
packageJson: Record<string, any>;
|
|
350
355
|
}
|
|
351
356
|
|
|
@@ -387,19 +392,30 @@ export function discoverPackages(rootDir: string): WorkspacePackage[] {
|
|
|
387
392
|
if (pkg.name?.startsWith("@arcote.tech/")) continue;
|
|
388
393
|
|
|
389
394
|
const pkgDir = join(baseDir, entry);
|
|
390
|
-
const
|
|
391
|
-
join(pkgDir, "src",
|
|
392
|
-
join(pkgDir, "src",
|
|
393
|
-
join(pkgDir,
|
|
394
|
-
join(pkgDir,
|
|
395
|
+
const entryCandidates = (variant: "" | ".server" | ".client") => [
|
|
396
|
+
join(pkgDir, "src", `index${variant}.ts`),
|
|
397
|
+
join(pkgDir, "src", `index${variant}.tsx`),
|
|
398
|
+
join(pkgDir, `index${variant}.ts`),
|
|
399
|
+
join(pkgDir, `index${variant}.tsx`),
|
|
395
400
|
];
|
|
396
|
-
const entrypoint =
|
|
401
|
+
const entrypoint = entryCandidates("").find((c) => existsSync(c)) ?? null;
|
|
397
402
|
if (!entrypoint) continue;
|
|
398
403
|
|
|
404
|
+
// Per-target entry override by file convention: index.server.ts /
|
|
405
|
+
// index.client.ts. Absent → fall back to the base entry (zero change for
|
|
406
|
+
// packages that don't opt in). Lets seeds live in index.server.ts so they
|
|
407
|
+
// never enter the client graph (see seed-guard.ts).
|
|
408
|
+
const serverEntrypoint =
|
|
409
|
+
entryCandidates(".server").find((c) => existsSync(c)) ?? entrypoint;
|
|
410
|
+
const clientEntrypoint =
|
|
411
|
+
entryCandidates(".client").find((c) => existsSync(c)) ?? entrypoint;
|
|
412
|
+
|
|
399
413
|
results.push({
|
|
400
414
|
name: pkg.name,
|
|
401
415
|
path: join(baseDir, entry),
|
|
402
416
|
entrypoint,
|
|
417
|
+
serverEntrypoint,
|
|
418
|
+
clientEntrypoint,
|
|
403
419
|
packageJson: pkg,
|
|
404
420
|
});
|
|
405
421
|
}
|
|
@@ -480,6 +496,12 @@ async function buildContextClient(
|
|
|
480
496
|
const unitId = `context-pkg:${pkg.name}:${client.name}`;
|
|
481
497
|
const outDir = join(pkg.path, "dist", client.name);
|
|
482
498
|
|
|
499
|
+
// Per-target entry: the browser dist is built from the CLIENT entry
|
|
500
|
+
// (index.client.ts if present, else index.ts) so dist/browser reflects exactly
|
|
501
|
+
// what ships to the browser. Non-browser clients keep the base entry.
|
|
502
|
+
const entry =
|
|
503
|
+
client.target === "browser" ? pkg.clientEntrypoint : pkg.entrypoint;
|
|
504
|
+
|
|
483
505
|
const inputHash = sha256OfJson({
|
|
484
506
|
src: pkgSourceHash(pkg),
|
|
485
507
|
pkg: pkg.packageJson,
|
|
@@ -487,6 +509,7 @@ async function buildContextClient(
|
|
|
487
509
|
client: client.name,
|
|
488
510
|
target: client.target,
|
|
489
511
|
defines: client.defines,
|
|
512
|
+
entry: relative(pkg.path, entry),
|
|
490
513
|
});
|
|
491
514
|
|
|
492
515
|
if (!noCache && isCacheHit(cache, unitId, inputHash, [join(outDir, "main", "index.js")])) {
|
|
@@ -508,7 +531,7 @@ async function buildContextClient(
|
|
|
508
531
|
const externals = [...peerDeps, ...Object.keys(allDeps)];
|
|
509
532
|
|
|
510
533
|
const result = await Bun.build({
|
|
511
|
-
entrypoints: [
|
|
534
|
+
entrypoints: [entry],
|
|
512
535
|
outdir: join(outDir, "main"),
|
|
513
536
|
target: client.target,
|
|
514
537
|
format: "esm",
|
|
@@ -535,9 +558,9 @@ async function buildContextClient(
|
|
|
535
558
|
.join("\n");
|
|
536
559
|
|
|
537
560
|
const declResult = await buildTypeDeclarations(
|
|
538
|
-
[
|
|
561
|
+
[entry],
|
|
539
562
|
outDir,
|
|
540
|
-
dirname(
|
|
563
|
+
dirname(entry),
|
|
541
564
|
globalsContent,
|
|
542
565
|
);
|
|
543
566
|
|
|
@@ -671,7 +694,9 @@ export async function buildServerApp(
|
|
|
671
694
|
// Every workspace package name → its SOURCE entry. Spans ALL packages, not
|
|
672
695
|
// just context ones — a context package imports non-context workspace libs
|
|
673
696
|
// (e.g. content-core) that must inline from source too.
|
|
674
|
-
|
|
697
|
+
// SERVER bundle resolves every `@pkg` to its server entry (index.server.ts if
|
|
698
|
+
// present, else index.ts) via workspaceSourcePlugin — bypassing package.json.
|
|
699
|
+
const srcByName = new Map(packages.map((p) => [p.name, p.serverEntrypoint]));
|
|
675
700
|
|
|
676
701
|
// External = framework peers + every non-workspace npm dep any package
|
|
677
702
|
// declares. NOT bundled; resolved at runtime from /app/node_modules (the
|
|
@@ -693,7 +718,13 @@ export async function buildServerApp(
|
|
|
693
718
|
const unitId = "server-app";
|
|
694
719
|
const inputHash = sha256OfJson({
|
|
695
720
|
members: packages
|
|
696
|
-
.map((p) => ({
|
|
721
|
+
.map((p) => ({
|
|
722
|
+
name: p.name,
|
|
723
|
+
src: pkgSourceHash(p),
|
|
724
|
+
// Which file is the server entry — invalidate if the selection changes
|
|
725
|
+
// (e.g. an index.server.ts is added/removed) even without other src edits.
|
|
726
|
+
serverEntry: relative(p.path, p.serverEntrypoint),
|
|
727
|
+
}))
|
|
697
728
|
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
698
729
|
contexts: contexts.map((p) => p.name).sort(),
|
|
699
730
|
external: [...external].sort(),
|
|
@@ -1131,13 +1162,13 @@ export async function buildBrowserApp(
|
|
|
1131
1162
|
|
|
1132
1163
|
// Cache key spans every package's source plus the build config that
|
|
1133
1164
|
// matters. If anything changes, full rebuild.
|
|
1134
|
-
const allMembers: { name: string; group: string; srcHash: string }[] = [];
|
|
1165
|
+
const allMembers: { name: string; group: string; srcHash: string; clientEntry: string }[] = [];
|
|
1135
1166
|
for (const m of publicMembers) {
|
|
1136
|
-
allMembers.push({ name: m.pkg.name, group: "public", srcHash: pkgSourceHash(m.pkg) });
|
|
1167
|
+
allMembers.push({ name: m.pkg.name, group: "public", srcHash: pkgSourceHash(m.pkg), clientEntry: relative(m.pkg.path, m.pkg.clientEntrypoint) });
|
|
1137
1168
|
}
|
|
1138
1169
|
for (const g of protectedGroups) {
|
|
1139
1170
|
for (const m of g.members) {
|
|
1140
|
-
allMembers.push({ name: m.pkg.name, group: g.name, srcHash: pkgSourceHash(m.pkg) });
|
|
1171
|
+
allMembers.push({ name: m.pkg.name, group: g.name, srcHash: pkgSourceHash(m.pkg), clientEntry: relative(m.pkg.path, m.pkg.clientEntrypoint) });
|
|
1141
1172
|
}
|
|
1142
1173
|
}
|
|
1143
1174
|
const inputHash = sha256OfJson({
|
|
@@ -1155,7 +1186,8 @@ export async function buildBrowserApp(
|
|
|
1155
1186
|
externals: federated ? [...SHELL_EXTERNALS] : [],
|
|
1156
1187
|
// Podbij przy zmianie SEMANTYKI builda (pluginy/flagi), której nie widać
|
|
1157
1188
|
// w źródłach — inaczej cache odda bundle zbudowany starą logiką.
|
|
1158
|
-
|
|
1189
|
+
// 4: client-entry (index.client.ts) + workspaceClientSourcePlugin.
|
|
1190
|
+
builderRev: 4,
|
|
1159
1191
|
});
|
|
1160
1192
|
|
|
1161
1193
|
// Tryb stats zawsze buduje od nowa — cache-hit pominąłby analizę i nie
|
|
@@ -1248,6 +1280,18 @@ export async function buildBrowserApp(
|
|
|
1248
1280
|
for (const g of protectedGroups)
|
|
1249
1281
|
for (const m of g.members) allMemberPkgs.set(m.pkg.name, m.pkg);
|
|
1250
1282
|
|
|
1283
|
+
// Client-entry override: only packages that DECLARE `index.client.ts`
|
|
1284
|
+
// (clientEntrypoint !== entrypoint) are redirected to their client source.
|
|
1285
|
+
// Everything else — packages without a variant, framework peers, npm — misses
|
|
1286
|
+
// the map and resolves natively (package.json `exports.browser`, e.g. the
|
|
1287
|
+
// per-pkg dist/browser). Empty map ⇒ identical to today's behaviour.
|
|
1288
|
+
const clientByName = new Map<string, string>();
|
|
1289
|
+
for (const pkg of allMemberPkgs.values()) {
|
|
1290
|
+
if (pkg.clientEntrypoint !== pkg.entrypoint) {
|
|
1291
|
+
clientByName.set(pkg.name, pkg.clientEntrypoint);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1251
1295
|
const patchedPkgJsons: { path: string; original: string }[] = [];
|
|
1252
1296
|
for (const pkg of allMemberPkgs.values()) {
|
|
1253
1297
|
const pkgJsonPath = join(pkg.path, "package.json");
|
|
@@ -1288,6 +1332,11 @@ export async function buildBrowserApp(
|
|
|
1288
1332
|
// singletonów React/rejestru z hostem federacji.
|
|
1289
1333
|
external: federated ? [...SHELL_EXTERNALS] : [],
|
|
1290
1334
|
plugins: [
|
|
1335
|
+
// Client-entry: `@pkg` z wariantem index.client.ts → jego source. MUSI
|
|
1336
|
+
// być pierwszy (onResolve first-wins), ale mapa zawiera tylko pakiety
|
|
1337
|
+
// workspace z wariantem — react/@arcote.tech/*/npm i pakiety bez wariantu
|
|
1338
|
+
// miss → null → natywna rezolucja / external niżej. Zero regresji.
|
|
1339
|
+
...(clientByName.size > 0 ? [workspaceSourcePlugin(clientByName)] : []),
|
|
1291
1340
|
// Federated: singleReactPlugin MUSI zniknąć (jego onResolve wygrałby z
|
|
1292
1341
|
// `external` → React zbundlowany; singleton daje import mapa). Ale
|
|
1293
1342
|
// jsxDevShimPlugin ZOSTAJE (Bun i tak emituje jsxDEV) — jego shim jest
|
|
@@ -16,9 +16,17 @@ import type { WorkspacePackage } from "./module-builder";
|
|
|
16
16
|
// w PUBLICZNYM bundlu przeglądarki. Seedy czyta wyłącznie host (`runSeeds()`),
|
|
17
17
|
// po stronie klienta nie mają żadnego zastosowania — czysty wyciek.
|
|
18
18
|
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
19
|
+
// KANONICZNY WZORZEC (rekomendowany): trzymaj seedy w `index.server.ts` pakietu.
|
|
20
|
+
// Build serwera rozwiązuje `@pkg` do `index.server.ts`, a build przeglądarki go
|
|
21
|
+
// nigdy nie importuje — seedy są izolowane FIZYCZNIE (zero DCE, zero ternary,
|
|
22
|
+
// zero szansy na regresję z nieczystym top-level modułu seed). Guard POMIJA pliki
|
|
23
|
+
// `*.server.ts`, więc `.withSeeds(...)` nie wymaga tam gejtu. Patrz discoverPackages
|
|
24
|
+
// / buildServerApp (module-builder.ts).
|
|
25
|
+
//
|
|
26
|
+
// ŚCIEŻKA LEGACY (pliki współdzielone klient+serwer): gejt wywołania to WARUNEK
|
|
27
|
+
// KONIECZNY (ten guard go egzekwuje), ale to, gdzie fizycznie leży treść seeda,
|
|
28
|
+
// decyduje czy bajty realnie znikają. Zweryfikowane empirycznie (migracja ndt+bmf,
|
|
29
|
+
// grep bundla klienta):
|
|
22
30
|
//
|
|
23
31
|
// // mały seed — inline w gejtowanym literale (ZAWSZE działa: constant-fold):
|
|
24
32
|
// .seedWith(ONLY_SERVER ? [ { /* wiersze */ } ] : [])
|
|
@@ -63,7 +71,16 @@ function walkTsFiles(dir: string, out: string[]): void {
|
|
|
63
71
|
if (entry.isDirectory()) {
|
|
64
72
|
if (entry.name === "__tests__") continue;
|
|
65
73
|
walkTsFiles(abs, out);
|
|
66
|
-
} else if (
|
|
74
|
+
} else if (
|
|
75
|
+
entry.isFile() &&
|
|
76
|
+
/\.(ts|tsx)$/.test(entry.name) &&
|
|
77
|
+
!entry.name.endsWith(".d.ts") &&
|
|
78
|
+
// `*.server.ts(x)` (w tym index.server.ts) NIE trafiają do bundla klienta —
|
|
79
|
+
// build serwera rozwiązuje `@pkg` do index.server.ts, a build przeglądarki
|
|
80
|
+
// nigdy go nie importuje. Seedy w tych plikach są izolowane fizycznie, więc
|
|
81
|
+
// `.withSeeds(...)` nie wymaga tam gejtu `ONLY_SERVER`.
|
|
82
|
+
!/\.server\.tsx?$/.test(entry.name)
|
|
83
|
+
) {
|
|
67
84
|
out.push(abs);
|
|
68
85
|
}
|
|
69
86
|
}
|