@jami-studio/core 0.92.22 → 0.92.24

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.
@@ -1,5 +1,17 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.92.24
4
+
5
+ ### Patch Changes
6
+
7
+ - 300ff1a: Dedupe Yjs in Cloudflare worker bundles. The per-app cloudflare_pages build keeps `yjs` external and emits it as a standalone `_worker.js/_libs/yjs.mjs` (bare imports rewritten to it); unified workspace deploys then hoist ONE shared copy to `dist/_yjs/yjs.mjs` and shim every app's lib to re-export it, so wrangler's final re-bundle instantiates Yjs exactly once. Fixes the "Yjs was already imported. This breaks constructor checks" error logged once per extra app copy per isolate and removes the cross-copy instanceof risk in real-time collab.
8
+
9
+ ## 0.92.23
10
+
11
+ ### Patch Changes
12
+
13
+ - df6be1b: Fix authed deep links 404ing on unified workspace deployments: the Cloudflare worker's static-app-shell fallback fetched an unprefixed "/index.html" from the shared ASSETS binding, but workspace apps serve their shell under the app base path (/dispatch/index.html) — so after sign-in, client-route navigations like /dispatch/overview leaked h3's JSON 404 instead of the SPA shell. The fallback now tries the base-path-prefixed shell first and falls back to the root shell for single-app deployments.
14
+
3
15
  ## 0.92.22
4
16
 
5
17
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.92.22",
3
+ "version": "0.92.24",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/studio-jami/jami-studio#readme",
6
6
  "bugs": {
@@ -1201,13 +1201,27 @@ async function fetchStaticAppShell(request, env) {
1201
1201
  if (!env?.ASSETS || !isStaticAppShellRequest(request)) return null;
1202
1202
  const basePath = getAppBasePath();
1203
1203
  const p = stripAppBasePath(new URL(request.url).pathname);
1204
- const shellRequest = requestWithPathname(
1205
- requestWithMethod(request, "GET"),
1206
- "/index.html",
1207
- );
1204
+ // Workspace deployments serve each app's static files under its base path
1205
+ // (/dispatch/index.html on the unified origin) — an unprefixed
1206
+ // "/index.html" 404s against the shared ASSETS binding and authed deep
1207
+ // links (e.g. /dispatch/overview) leaked h3's JSON 404 instead of the SPA
1208
+ // shell. Try the base-path-prefixed shell first, fall back to the root
1209
+ // shell for single-app deployments.
1208
1210
  let response;
1209
1211
  try {
1210
- response = await env.ASSETS.fetch(shellRequest);
1212
+ if (basePath) {
1213
+ response = await env.ASSETS.fetch(
1214
+ requestWithPathname(
1215
+ requestWithMethod(request, "GET"),
1216
+ basePath + "/index.html",
1217
+ ),
1218
+ );
1219
+ }
1220
+ if (!response || response.status === 404) {
1221
+ response = await env.ASSETS.fetch(
1222
+ requestWithPathname(requestWithMethod(request, "GET"), "/index.html"),
1223
+ );
1224
+ }
1211
1225
  } catch {
1212
1226
  return null;
1213
1227
  }
@@ -1812,6 +1826,13 @@ async function buildCloudflarePages() {
1812
1826
  "--conditions=workerd,worker,import",
1813
1827
  // The ssr-handler imports a virtual module that only exists at dev time
1814
1828
  "--external:virtual:react-router/server-build",
1829
+ // Keep Yjs out of the monolithic bundle so it can be emitted as a
1830
+ // standalone _libs/yjs.mjs below. On unified workspace deploys the
1831
+ // workspace assembly step points every app's lib at ONE shared copy so
1832
+ // wrangler's final re-bundle instantiates Yjs exactly once — inlining it
1833
+ // here would put N copies in a single isolate (Yjs logs "Yjs was already
1834
+ // imported" per extra copy and cross-copy instanceof checks break).
1835
+ "--external:yjs",
1815
1836
  `--alias:#nitro/virtual/server-assets=${nitroServerAssetsStub}`,
1816
1837
  // Banner: override the __require shim that esbuild generates for CJS modules.
1817
1838
  // This provides a real require() backed by ESM imports of node builtins.
@@ -1831,6 +1852,15 @@ async function buildCloudflarePages() {
1831
1852
  cwd,
1832
1853
  });
1833
1854
 
1855
+ // Bundle the one real Yjs copy into _libs/yjs.mjs and rewrite the bare
1856
+ // imports the --external:yjs flag left behind (see the flag comment above).
1857
+ bundleSharedYjsLibForWorkerOutput({
1858
+ workerOutDir,
1859
+ esbuildBin,
1860
+ projectCwd: cwd,
1861
+ tmpDir,
1862
+ });
1863
+
1834
1864
  // Clean up tmp
1835
1865
  fs.rmSync(tmpDir, { recursive: true });
1836
1866
 
@@ -2680,6 +2710,112 @@ export function rewriteBareYjsImportsForServerlessOutput(
2680
2710
  return bareImports;
2681
2711
  }
2682
2712
 
2713
+ /**
2714
+ * Resolve Yjs's ESM entry for bundling into a worker `_libs/yjs.mjs`.
2715
+ * Templates don't depend on `yjs` directly (it's a core dependency), so when
2716
+ * the project itself can't resolve it, resolve through the installed
2717
+ * `@agent-native/core` package location instead.
2718
+ */
2719
+ export function resolveYjsEsmEntry(projectCwd: string): string | null {
2720
+ const resolveFrom = (base: string): string | null => {
2721
+ try {
2722
+ return createRequire(path.join(base, "package.json")).resolve("yjs");
2723
+ } catch {
2724
+ return null;
2725
+ }
2726
+ };
2727
+ let resolved = resolveFrom(projectCwd);
2728
+ if (!resolved) {
2729
+ try {
2730
+ const corePkg = createRequire(
2731
+ path.join(projectCwd, "package.json"),
2732
+ ).resolve("@agent-native/core/package.json");
2733
+ resolved = resolveFrom(path.dirname(fs.realpathSync(corePkg)));
2734
+ } catch {
2735
+ resolved = null;
2736
+ }
2737
+ }
2738
+ if (!resolved) return null;
2739
+ // require.resolve returns the CJS entry; prefer the sibling ESM build so
2740
+ // `export * from` re-exports Yjs's real named exports statically.
2741
+ const esmSibling = resolved.replace(/\.c?js$/, ".mjs");
2742
+ return esmSibling !== resolved && fs.existsSync(esmSibling)
2743
+ ? esmSibling
2744
+ : resolved;
2745
+ }
2746
+
2747
+ /**
2748
+ * Emit Yjs as a standalone `_libs/yjs.mjs` in the Cloudflare worker output
2749
+ * and rewrite every bare `yjs` import (left external by the main esbuild
2750
+ * bundle) to it. Keeping Yjs in its own module file is what lets the unified
2751
+ * workspace assembly (`workspace-deploy.ts`) collapse all apps onto ONE
2752
+ * shared copy — wrangler's final re-bundle dedupes modules by file path, so
2753
+ * N inlined copies would otherwise land in a single isolate and trip Yjs's
2754
+ * "Yjs was already imported. This breaks constructor checks" guard.
2755
+ */
2756
+ export function bundleSharedYjsLibForWorkerOutput(opts: {
2757
+ workerOutDir: string;
2758
+ esbuildBin: string;
2759
+ projectCwd: string;
2760
+ tmpDir: string;
2761
+ }): string[] {
2762
+ const { workerOutDir, esbuildBin, projectCwd, tmpDir } = opts;
2763
+
2764
+ // Fail loud on CJS require sites — the import rewrite below cannot fix a
2765
+ // `require("yjs")`, and leaving one would crash at runtime instead.
2766
+ const requireSites: string[] = [];
2767
+ let hasBareImport = false;
2768
+ walkServerJavaScriptFiles(workerOutDir, (filePath) => {
2769
+ const source = fs.readFileSync(filePath, "utf-8");
2770
+ if (/\brequire\(\s*["']yjs["']\s*\)/.test(source)) {
2771
+ requireSites.push(filePath);
2772
+ }
2773
+ if (hasBareYjsRuntimeImport(source)) hasBareImport = true;
2774
+ });
2775
+ if (requireSites.length > 0) {
2776
+ throw new Error(
2777
+ `[deploy] Cloudflare worker output left CJS require("yjs") sites the Yjs lib rewrite cannot fix: ${requireSites.join(", ")}`,
2778
+ );
2779
+ }
2780
+ if (!hasBareImport) return [];
2781
+
2782
+ const yjsEntry = resolveYjsEsmEntry(projectCwd);
2783
+ if (!yjsEntry) {
2784
+ throw new Error(
2785
+ "[deploy] Cloudflare worker output imports yjs but the package could not be resolved for _libs bundling",
2786
+ );
2787
+ }
2788
+
2789
+ const libsDir = path.join(workerOutDir, "_libs");
2790
+ fs.mkdirSync(libsDir, { recursive: true });
2791
+ const entryFile = path.join(tmpDir, "_yjs-lib-entry.js");
2792
+ // Forward slashes: backslashes in an import specifier are escape sequences.
2793
+ fs.writeFileSync(
2794
+ entryFile,
2795
+ `export * from "${yjsEntry.split(path.sep).join("/")}";\n`,
2796
+ );
2797
+ const command = esbuildSpawnCommand(esbuildBin, [
2798
+ entryFile,
2799
+ "--bundle",
2800
+ `--outfile=${path.join(libsDir, "yjs.mjs")}`,
2801
+ "--format=esm",
2802
+ "--platform=browser",
2803
+ "--target=es2022",
2804
+ "--minify",
2805
+ "--conditions=workerd,worker,import",
2806
+ ]);
2807
+ execFileSync(command.file, command.args, {
2808
+ stdio: "inherit",
2809
+ cwd: projectCwd,
2810
+ });
2811
+
2812
+ const rewritten = rewriteBareYjsImportsForServerlessOutput(workerOutDir);
2813
+ console.log(
2814
+ `[deploy] Bundled yjs into _libs/yjs.mjs (${rewritten.length} import site file(s) rewritten)`,
2815
+ );
2816
+ return rewritten;
2817
+ }
2818
+
2683
2819
  export function assertSingleTemplateNetlifyBuildOutput(
2684
2820
  projectCwd: string,
2685
2821
  ): void {
@@ -178,6 +178,7 @@ export async function runWorkspaceDeploy(
178
178
  } else if (preset === "vercel") {
179
179
  writeVercelBuildConfig(vercelOutputDir, apps);
180
180
  } else {
181
+ dedupeCloudflareWorkspaceYjs(distDir, apps);
181
182
  writeCloudflareRoutingManifest(distDir, apps);
182
183
  }
183
184
 
@@ -405,6 +406,58 @@ function copyVercelAppBuildIntoWorkspace(
405
406
  patchVercelFunctionEntry(functionDest, app, workspaceApps);
406
407
  }
407
408
 
409
+ /**
410
+ * Collapse every app's Yjs copy onto ONE shared module in the unified
411
+ * Cloudflare artifact. wrangler re-bundles all app workers into a single
412
+ * final bundle behind the dispatcher, so per-app Yjs copies all land in one
413
+ * isolate — Yjs's own guard logs "Yjs was already imported. This breaks
414
+ * constructor checks" once per extra copy, and Yjs objects crossing copies
415
+ * fail instanceof checks (real-time collab risk). Per-app builds emit Yjs as
416
+ * a standalone `dist/<app>/_worker.js/_libs/yjs.mjs` (see deploy/build.ts);
417
+ * here the first copy is hoisted to `dist/_yjs/yjs.mjs` and every app's lib
418
+ * becomes a re-export shim of it, so esbuild's path-keyed module dedupe
419
+ * instantiates Yjs exactly once.
420
+ */
421
+ export function dedupeCloudflareWorkspaceYjs(
422
+ distDir: string,
423
+ apps: string[],
424
+ ): string[] {
425
+ const libPaths = apps
426
+ .map((app) => path.join(distDir, app, "_worker.js", "_libs", "yjs.mjs"))
427
+ .filter((libPath) => fs.existsSync(libPath));
428
+ if (libPaths.length === 0) return [];
429
+
430
+ const sharedFile = path.join(distDir, "_yjs", "yjs.mjs");
431
+ fs.mkdirSync(path.dirname(sharedFile), { recursive: true });
432
+ fs.copyFileSync(libPaths[0], sharedFile);
433
+ for (const libPath of libPaths) {
434
+ const rel = path
435
+ .relative(path.dirname(libPath), sharedFile)
436
+ .split(path.sep)
437
+ .join("/");
438
+ fs.writeFileSync(
439
+ libPath,
440
+ `export * from "${rel.startsWith(".") ? rel : `./${rel}`}";\n`,
441
+ );
442
+ }
443
+
444
+ // Keep the shared module (and the dispatcher worker) out of the public
445
+ // static asset set. `.assetsignore` is only honored at the output root.
446
+ const assetsIgnorePath = path.join(distDir, ".assetsignore");
447
+ const existing = fs.existsSync(assetsIgnorePath)
448
+ ? fs.readFileSync(assetsIgnorePath, "utf-8")
449
+ : "";
450
+ const lines = new Set(existing.split(/\r?\n/).filter(Boolean));
451
+ lines.add("_worker.js");
452
+ lines.add("_yjs");
453
+ fs.writeFileSync(assetsIgnorePath, [...lines].join("\n") + "\n");
454
+
455
+ console.log(
456
+ `[workspace-deploy] Deduped yjs across ${libPaths.length} app worker(s) into _yjs/yjs.mjs`,
457
+ );
458
+ return libPaths;
459
+ }
460
+
408
461
  /**
409
462
  * Write the Cloudflare Pages `_routes.json` and a dispatcher `_worker.js` at
410
463
  * the workspace dist root so each app is reachable under /<app>/*.
@@ -435,8 +488,7 @@ function writeCloudflareRoutingManifest(distDir: string, apps: string[]): void {
435
488
  const dedupedInclude = [
436
489
  ...new Set(
437
490
  include.filter(
438
- (r) =>
439
- !splatPrefixes.some((p) => r !== `${p}*` && r.startsWith(p)),
491
+ (r) => !splatPrefixes.some((p) => r !== `${p}*` && r.startsWith(p)),
440
492
  ),
441
493
  ),
442
494
  ];
@@ -179,6 +179,28 @@ export declare function emitSingleTemplateNetlifyBackgroundFunction(projectCwd:
179
179
  * bundled copy before its function is packaged.
180
180
  */
181
181
  export declare function rewriteBareYjsImportsForServerlessOutput(serverDir: string): string[];
182
+ /**
183
+ * Resolve Yjs's ESM entry for bundling into a worker `_libs/yjs.mjs`.
184
+ * Templates don't depend on `yjs` directly (it's a core dependency), so when
185
+ * the project itself can't resolve it, resolve through the installed
186
+ * `@agent-native/core` package location instead.
187
+ */
188
+ export declare function resolveYjsEsmEntry(projectCwd: string): string | null;
189
+ /**
190
+ * Emit Yjs as a standalone `_libs/yjs.mjs` in the Cloudflare worker output
191
+ * and rewrite every bare `yjs` import (left external by the main esbuild
192
+ * bundle) to it. Keeping Yjs in its own module file is what lets the unified
193
+ * workspace assembly (`workspace-deploy.ts`) collapse all apps onto ONE
194
+ * shared copy — wrangler's final re-bundle dedupes modules by file path, so
195
+ * N inlined copies would otherwise land in a single isolate and trip Yjs's
196
+ * "Yjs was already imported. This breaks constructor checks" guard.
197
+ */
198
+ export declare function bundleSharedYjsLibForWorkerOutput(opts: {
199
+ workerOutDir: string;
200
+ esbuildBin: string;
201
+ projectCwd: string;
202
+ tmpDir: string;
203
+ }): string[];
182
204
  export declare function assertSingleTemplateNetlifyBuildOutput(projectCwd: string): void;
183
205
  /**
184
206
  * Strip the harmful single-template catch-all rewrite that points at
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAmCH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,6BAA6B,UAiBzC,CAAC;AAEF,eAAO,MAAM,mCAAmC,UAiB/C,CAAC;AACF,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkIjE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,UAUnC,CAAC;AAEF,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAaxB;AAoCD,eAAO,MAAM,2CAA2C,EAAE,MAAM,CAC9D,MAAM,EACN,MAAM,CAmSP,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,wBAAwB;IAChC,KAAK,EAAE,6BAA6B,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,6BAA6B;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,UAAU,6BAA6B;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAwBD,wBAAgB,wCAAwC,CACtD,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAaR;AAgBD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAgBvE,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAK,GACf,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EAAE,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,GAAE,MAAM,EAAO,EACjC,OAAO,GAAE,gBAAgB,EAAO,EAChC,aAAa,GAAE,oBAAoB,GAAG,IAAW,EACjD,mBAAmB,GAAE,MAAM,EAAO,EAClC,gBAAgB,SAAmC,EACnD,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAgpBR;AA4FD,wBAAgB,8CAA8C,CAC5D,QAAQ,EAAE,wBAAwB,EAClC,QAAQ,SAAmC,GAC1C,MAAM,CAiCR;AA0fD,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAoED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKlC;AA6DD,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,iBAAiB,cAAoB,QAoCtC;AAiCD,KAAK,0BAA0B,GAAG,OAAO,GAAG,KAAK,CAAC;AAQlD,wBAAgB,qCAAqC,CACnD,YAAY,GAAE,MAAM,CAAC,QAA2B,EAChD,QAAQ,GAAE,MAAM,CAAC,YAA2B,EAC5C,UAAU,GAAE,0BAA0B,GAAG,IAAgD,GACxF,OAAO,CAOT;AAqED,wBAAgB,gCAAgC,CAC9C,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,GAAG,IAAI,CA8Bf;AAED,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,EAAE,GACzB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCpD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAK1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CA0GN;AA0DD;;;;;GAKG;AACH,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,MAAM,GAChB,MAAM,EAAE,CA+CV;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,EAAE,CAwDX;AAED,wBAAgB,sCAAsC,CACpD,UAAU,EAAE,MAAM,GACjB,IAAI,CAwJN;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAY5E;AA6GD;;;;;;GAMG;AACH,wBAAgB,yCAAyC,CACvD,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,IAAI,CAqDN;AA6ID;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAkBD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iCAAiC,YAAI,KAAK,CAAU,CAAC;AAElE;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,GACnB,IAAI,GAAG,SAAS,MAAM,EAAE,CAK1B"}
@@ -1017,13 +1017,27 @@ async function fetchStaticAppShell(request, env) {
1017
1017
  if (!env?.ASSETS || !isStaticAppShellRequest(request)) return null;
1018
1018
  const basePath = getAppBasePath();
1019
1019
  const p = stripAppBasePath(new URL(request.url).pathname);
1020
- const shellRequest = requestWithPathname(
1021
- requestWithMethod(request, "GET"),
1022
- "/index.html",
1023
- );
1020
+ // Workspace deployments serve each app's static files under its base path
1021
+ // (/dispatch/index.html on the unified origin) — an unprefixed
1022
+ // "/index.html" 404s against the shared ASSETS binding and authed deep
1023
+ // links (e.g. /dispatch/overview) leaked h3's JSON 404 instead of the SPA
1024
+ // shell. Try the base-path-prefixed shell first, fall back to the root
1025
+ // shell for single-app deployments.
1024
1026
  let response;
1025
1027
  try {
1026
- response = await env.ASSETS.fetch(shellRequest);
1028
+ if (basePath) {
1029
+ response = await env.ASSETS.fetch(
1030
+ requestWithPathname(
1031
+ requestWithMethod(request, "GET"),
1032
+ basePath + "/index.html",
1033
+ ),
1034
+ );
1035
+ }
1036
+ if (!response || response.status === 404) {
1037
+ response = await env.ASSETS.fetch(
1038
+ requestWithPathname(requestWithMethod(request, "GET"), "/index.html"),
1039
+ );
1040
+ }
1027
1041
  } catch {
1028
1042
  return null;
1029
1043
  }
@@ -1494,6 +1508,13 @@ async function buildCloudflarePages() {
1494
1508
  "--conditions=workerd,worker,import",
1495
1509
  // The ssr-handler imports a virtual module that only exists at dev time
1496
1510
  "--external:virtual:react-router/server-build",
1511
+ // Keep Yjs out of the monolithic bundle so it can be emitted as a
1512
+ // standalone _libs/yjs.mjs below. On unified workspace deploys the
1513
+ // workspace assembly step points every app's lib at ONE shared copy so
1514
+ // wrangler's final re-bundle instantiates Yjs exactly once — inlining it
1515
+ // here would put N copies in a single isolate (Yjs logs "Yjs was already
1516
+ // imported" per extra copy and cross-copy instanceof checks break).
1517
+ "--external:yjs",
1497
1518
  `--alias:#nitro/virtual/server-assets=${nitroServerAssetsStub}`,
1498
1519
  // Banner: override the __require shim that esbuild generates for CJS modules.
1499
1520
  // This provides a real require() backed by ESM imports of node builtins.
@@ -1512,6 +1533,14 @@ async function buildCloudflarePages() {
1512
1533
  stdio: "inherit",
1513
1534
  cwd,
1514
1535
  });
1536
+ // Bundle the one real Yjs copy into _libs/yjs.mjs and rewrite the bare
1537
+ // imports the --external:yjs flag left behind (see the flag comment above).
1538
+ bundleSharedYjsLibForWorkerOutput({
1539
+ workerOutDir,
1540
+ esbuildBin,
1541
+ projectCwd: cwd,
1542
+ tmpDir,
1543
+ });
1515
1544
  // Clean up tmp
1516
1545
  fs.rmSync(tmpDir, { recursive: true });
1517
1546
  // Rewrite the external virtual import to a local stub.
@@ -2231,6 +2260,95 @@ export function rewriteBareYjsImportsForServerlessOutput(serverDir) {
2231
2260
  }
2232
2261
  return bareImports;
2233
2262
  }
2263
+ /**
2264
+ * Resolve Yjs's ESM entry for bundling into a worker `_libs/yjs.mjs`.
2265
+ * Templates don't depend on `yjs` directly (it's a core dependency), so when
2266
+ * the project itself can't resolve it, resolve through the installed
2267
+ * `@agent-native/core` package location instead.
2268
+ */
2269
+ export function resolveYjsEsmEntry(projectCwd) {
2270
+ const resolveFrom = (base) => {
2271
+ try {
2272
+ return createRequire(path.join(base, "package.json")).resolve("yjs");
2273
+ }
2274
+ catch {
2275
+ return null;
2276
+ }
2277
+ };
2278
+ let resolved = resolveFrom(projectCwd);
2279
+ if (!resolved) {
2280
+ try {
2281
+ const corePkg = createRequire(path.join(projectCwd, "package.json")).resolve("@agent-native/core/package.json");
2282
+ resolved = resolveFrom(path.dirname(fs.realpathSync(corePkg)));
2283
+ }
2284
+ catch {
2285
+ resolved = null;
2286
+ }
2287
+ }
2288
+ if (!resolved)
2289
+ return null;
2290
+ // require.resolve returns the CJS entry; prefer the sibling ESM build so
2291
+ // `export * from` re-exports Yjs's real named exports statically.
2292
+ const esmSibling = resolved.replace(/\.c?js$/, ".mjs");
2293
+ return esmSibling !== resolved && fs.existsSync(esmSibling)
2294
+ ? esmSibling
2295
+ : resolved;
2296
+ }
2297
+ /**
2298
+ * Emit Yjs as a standalone `_libs/yjs.mjs` in the Cloudflare worker output
2299
+ * and rewrite every bare `yjs` import (left external by the main esbuild
2300
+ * bundle) to it. Keeping Yjs in its own module file is what lets the unified
2301
+ * workspace assembly (`workspace-deploy.ts`) collapse all apps onto ONE
2302
+ * shared copy — wrangler's final re-bundle dedupes modules by file path, so
2303
+ * N inlined copies would otherwise land in a single isolate and trip Yjs's
2304
+ * "Yjs was already imported. This breaks constructor checks" guard.
2305
+ */
2306
+ export function bundleSharedYjsLibForWorkerOutput(opts) {
2307
+ const { workerOutDir, esbuildBin, projectCwd, tmpDir } = opts;
2308
+ // Fail loud on CJS require sites — the import rewrite below cannot fix a
2309
+ // `require("yjs")`, and leaving one would crash at runtime instead.
2310
+ const requireSites = [];
2311
+ let hasBareImport = false;
2312
+ walkServerJavaScriptFiles(workerOutDir, (filePath) => {
2313
+ const source = fs.readFileSync(filePath, "utf-8");
2314
+ if (/\brequire\(\s*["']yjs["']\s*\)/.test(source)) {
2315
+ requireSites.push(filePath);
2316
+ }
2317
+ if (hasBareYjsRuntimeImport(source))
2318
+ hasBareImport = true;
2319
+ });
2320
+ if (requireSites.length > 0) {
2321
+ throw new Error(`[deploy] Cloudflare worker output left CJS require("yjs") sites the Yjs lib rewrite cannot fix: ${requireSites.join(", ")}`);
2322
+ }
2323
+ if (!hasBareImport)
2324
+ return [];
2325
+ const yjsEntry = resolveYjsEsmEntry(projectCwd);
2326
+ if (!yjsEntry) {
2327
+ throw new Error("[deploy] Cloudflare worker output imports yjs but the package could not be resolved for _libs bundling");
2328
+ }
2329
+ const libsDir = path.join(workerOutDir, "_libs");
2330
+ fs.mkdirSync(libsDir, { recursive: true });
2331
+ const entryFile = path.join(tmpDir, "_yjs-lib-entry.js");
2332
+ // Forward slashes: backslashes in an import specifier are escape sequences.
2333
+ fs.writeFileSync(entryFile, `export * from "${yjsEntry.split(path.sep).join("/")}";\n`);
2334
+ const command = esbuildSpawnCommand(esbuildBin, [
2335
+ entryFile,
2336
+ "--bundle",
2337
+ `--outfile=${path.join(libsDir, "yjs.mjs")}`,
2338
+ "--format=esm",
2339
+ "--platform=browser",
2340
+ "--target=es2022",
2341
+ "--minify",
2342
+ "--conditions=workerd,worker,import",
2343
+ ]);
2344
+ execFileSync(command.file, command.args, {
2345
+ stdio: "inherit",
2346
+ cwd: projectCwd,
2347
+ });
2348
+ const rewritten = rewriteBareYjsImportsForServerlessOutput(workerOutDir);
2349
+ console.log(`[deploy] Bundled yjs into _libs/yjs.mjs (${rewritten.length} import site file(s) rewritten)`);
2350
+ return rewritten;
2351
+ }
2234
2352
  export function assertSingleTemplateNetlifyBuildOutput(projectCwd) {
2235
2353
  const failures = [];
2236
2354
  const publishDir = path.join(projectCwd, "dist");