@arcote.tech/arc-cli 0.4.6 → 0.4.8
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 +577 -2234
- package/package.json +1 -1
- package/src/builder/module-builder.ts +17 -4
- package/src/commands/platform-dev.ts +5 -1
- package/src/commands/platform-start.ts +5 -1
- package/src/i18n/catalog.ts +43 -5
- package/src/i18n/compile.ts +6 -1
- package/src/platform/server.ts +161 -21
- package/src/platform/shared.ts +87 -41
package/src/platform/shared.ts
CHANGED
|
@@ -7,12 +7,13 @@ import {
|
|
|
7
7
|
discoverPackages,
|
|
8
8
|
isContextPackage,
|
|
9
9
|
type BuildManifest,
|
|
10
|
+
type ModuleEntry,
|
|
10
11
|
type WorkspacePackage,
|
|
11
12
|
} from "../builder/module-builder";
|
|
12
13
|
|
|
13
14
|
// Re-export for convenience
|
|
14
15
|
export { buildPackages, buildStyles, isContextPackage };
|
|
15
|
-
export type { BuildManifest, WorkspacePackage };
|
|
16
|
+
export type { BuildManifest, ModuleEntry, WorkspacePackage };
|
|
16
17
|
|
|
17
18
|
// ---------------------------------------------------------------------------
|
|
18
19
|
// Logging
|
|
@@ -134,7 +135,7 @@ export async function buildAll(ws: WorkspaceInfo): Promise<BuildManifest> {
|
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
log("Building shell...");
|
|
137
|
-
await buildShell(ws.shellDir);
|
|
138
|
+
await buildShell(ws.shellDir, ws.packages);
|
|
138
139
|
ok("Shell built");
|
|
139
140
|
|
|
140
141
|
return manifest;
|
|
@@ -144,7 +145,30 @@ export async function buildAll(ws: WorkspaceInfo): Promise<BuildManifest> {
|
|
|
144
145
|
// Shell builder — framework packages for import map
|
|
145
146
|
// ---------------------------------------------------------------------------
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
/** Collect all @arcote.tech/* peerDependencies from workspace packages. */
|
|
149
|
+
export function collectArcPeerDeps(packages: WorkspacePackage[]): [string, string][] {
|
|
150
|
+
const seen = new Set<string>();
|
|
151
|
+
// Always include core framework packages
|
|
152
|
+
for (const pkg of ["@arcote.tech/arc", "@arcote.tech/arc-ds", "@arcote.tech/arc-react", "@arcote.tech/platform"]) {
|
|
153
|
+
seen.add(pkg);
|
|
154
|
+
}
|
|
155
|
+
// Scan all workspace packages for @arcote.tech/* peerDeps
|
|
156
|
+
for (const wp of packages) {
|
|
157
|
+
const peerDeps = wp.packageJson.peerDependencies ?? {};
|
|
158
|
+
for (const dep of Object.keys(peerDeps)) {
|
|
159
|
+
if (dep.startsWith("@arcote.tech/")) seen.add(dep);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Convert to [shortName, fullName] entries
|
|
163
|
+
return [...seen].map((pkg) => {
|
|
164
|
+
const short = pkg === "@arcote.tech/platform"
|
|
165
|
+
? "platform"
|
|
166
|
+
: pkg.replace("@arcote.tech/", "");
|
|
167
|
+
return [short, pkg];
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function buildShell(outDir: string, packages?: WorkspacePackage[]): Promise<void> {
|
|
148
172
|
mkdirSync(outDir, { recursive: true });
|
|
149
173
|
const tmpDir = join(outDir, "_tmp");
|
|
150
174
|
mkdirSync(tmpDir, { recursive: true });
|
|
@@ -202,46 +226,53 @@ export const { createPortal, flushSync } = ReactDOM;`,
|
|
|
202
226
|
}
|
|
203
227
|
|
|
204
228
|
// Step 2: Build Arc layer (react is EXTERNAL — resolved via import map)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
[
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
229
|
+
// Dynamically collect only @arcote.tech/* packages actually used by workspace
|
|
230
|
+
const arcEntries = packages
|
|
231
|
+
? collectArcPeerDeps(packages)
|
|
232
|
+
: [
|
|
233
|
+
// Fallback: core packages only (no workspace packages available)
|
|
234
|
+
["arc", "@arcote.tech/arc"],
|
|
235
|
+
["arc-ds", "@arcote.tech/arc-ds"],
|
|
236
|
+
["arc-react", "@arcote.tech/arc-react"],
|
|
237
|
+
["platform", "@arcote.tech/platform"],
|
|
238
|
+
] as [string, string][];
|
|
239
|
+
|
|
240
|
+
const baseExternal = [
|
|
241
|
+
"react",
|
|
242
|
+
"react-dom",
|
|
243
|
+
"react/jsx-runtime",
|
|
244
|
+
"react/jsx-dev-runtime",
|
|
245
|
+
"react-dom/client",
|
|
213
246
|
];
|
|
247
|
+
const allArcPkgs = arcEntries.map(([, pkg]) => pkg);
|
|
214
248
|
|
|
215
|
-
|
|
249
|
+
// Build each arc entry separately so it can import sibling arc packages
|
|
250
|
+
// as externals (resolved via import map) without circular self-reference.
|
|
216
251
|
for (const [name, pkg] of arcEntries) {
|
|
217
252
|
const f = join(tmpDir, `${name}.ts`);
|
|
218
253
|
Bun.write(f, `export * from "${pkg}";\n`);
|
|
219
|
-
arcEps.push(f);
|
|
220
|
-
}
|
|
221
254
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
for (const l of r2.logs) console.error(l);
|
|
244
|
-
throw new Error("Shell Arc build failed");
|
|
255
|
+
const r2 = await Bun.build({
|
|
256
|
+
entrypoints: [f],
|
|
257
|
+
outdir: outDir,
|
|
258
|
+
format: "esm",
|
|
259
|
+
target: "browser",
|
|
260
|
+
naming: "[name].[ext]",
|
|
261
|
+
external: [
|
|
262
|
+
...baseExternal,
|
|
263
|
+
// Other arc packages are external (not self)
|
|
264
|
+
...allArcPkgs.filter((p) => p !== pkg),
|
|
265
|
+
],
|
|
266
|
+
define: {
|
|
267
|
+
ONLY_SERVER: "false",
|
|
268
|
+
ONLY_BROWSER: "true",
|
|
269
|
+
ONLY_CLIENT: "true",
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
if (!r2.success) {
|
|
273
|
+
for (const l of r2.logs) console.error(l);
|
|
274
|
+
throw new Error(`Shell build failed for ${pkg}`);
|
|
275
|
+
}
|
|
245
276
|
}
|
|
246
277
|
|
|
247
278
|
// Clean tmp
|
|
@@ -255,9 +286,9 @@ export const { createPortal, flushSync } = ReactDOM;`,
|
|
|
255
286
|
|
|
256
287
|
export async function loadServerContext(
|
|
257
288
|
packages: WorkspacePackage[],
|
|
258
|
-
): Promise<any | null> {
|
|
289
|
+
): Promise<{ context: any | null; moduleAccess: Map<string, any> }> {
|
|
259
290
|
const ctxPackages = packages.filter((p) => isContextPackage(p.packageJson));
|
|
260
|
-
if (ctxPackages.length === 0) return null;
|
|
291
|
+
if (ctxPackages.length === 0) return { context: null, moduleAccess: new Map() };
|
|
261
292
|
|
|
262
293
|
// Set globals for server context — framework packages (arc-auth etc.)
|
|
263
294
|
// use these at runtime to tree-shake browser/server code paths.
|
|
@@ -278,6 +309,7 @@ export async function loadServerContext(
|
|
|
278
309
|
// Pre-import platform so it's cached with this absolute path
|
|
279
310
|
await import(platformEntry);
|
|
280
311
|
|
|
312
|
+
// Import context packages from server dist (has server-only code paths)
|
|
281
313
|
for (const ctx of ctxPackages) {
|
|
282
314
|
const serverDist = join(ctx.path, "dist", "server", "main", "index.js");
|
|
283
315
|
if (!existsSync(serverDist)) {
|
|
@@ -292,6 +324,20 @@ export async function loadServerContext(
|
|
|
292
324
|
}
|
|
293
325
|
}
|
|
294
326
|
|
|
295
|
-
|
|
296
|
-
|
|
327
|
+
// Import non-context packages from source to capture module().protectedBy() metadata
|
|
328
|
+
const nonCtxPackages = packages.filter((p) => !isContextPackage(p.packageJson));
|
|
329
|
+
for (const pkg of nonCtxPackages) {
|
|
330
|
+
try {
|
|
331
|
+
await import(pkg.entrypoint);
|
|
332
|
+
} catch {
|
|
333
|
+
// Non-context packages may fail on server (React components etc.) — that's OK,
|
|
334
|
+
// module().protectedBy().build() runs synchronously before any rendering
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const { getContext, getAllModuleAccess } = await import(platformEntry);
|
|
339
|
+
return {
|
|
340
|
+
context: getContext() ?? null,
|
|
341
|
+
moduleAccess: getAllModuleAccess(),
|
|
342
|
+
};
|
|
297
343
|
}
|