rwsdk 1.0.0-beta.0 → 1.0.0-beta.10

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 (43) hide show
  1. package/dist/lib/e2e/constants.d.mts +13 -0
  2. package/dist/lib/e2e/constants.mjs +67 -0
  3. package/dist/lib/e2e/environment.d.mts +1 -1
  4. package/dist/lib/e2e/environment.mjs +29 -6
  5. package/dist/lib/e2e/index.d.mts +1 -0
  6. package/dist/lib/e2e/index.mjs +1 -0
  7. package/dist/lib/e2e/tarball.mjs +25 -0
  8. package/dist/lib/e2e/testHarness.d.mts +33 -3
  9. package/dist/lib/e2e/testHarness.mjs +181 -109
  10. package/dist/runtime/client/client.d.ts +1 -0
  11. package/dist/runtime/client/client.js +2 -0
  12. package/dist/runtime/client/navigation.d.ts +8 -0
  13. package/dist/runtime/client/navigation.js +39 -31
  14. package/dist/runtime/entries/clientSSR.d.ts +1 -0
  15. package/dist/runtime/entries/clientSSR.js +3 -0
  16. package/dist/runtime/lib/db/createDb.d.ts +1 -2
  17. package/dist/runtime/lib/db/createDb.js +4 -0
  18. package/dist/runtime/lib/manifest.d.ts +1 -1
  19. package/dist/runtime/lib/manifest.js +7 -4
  20. package/dist/runtime/lib/realtime/client.js +8 -2
  21. package/dist/runtime/lib/router.d.ts +1 -19
  22. package/dist/runtime/lib/router.test.js +2 -0
  23. package/dist/runtime/lib/{rwContext.d.ts → types.d.ts} +1 -0
  24. package/dist/runtime/render/renderDocumentHtmlStream.d.ts +1 -1
  25. package/dist/runtime/render/renderToStream.d.ts +1 -1
  26. package/dist/runtime/render/renderToString.d.ts +1 -1
  27. package/dist/runtime/requestInfo/types.d.ts +1 -1
  28. package/dist/runtime/script.d.ts +1 -3
  29. package/dist/runtime/script.js +1 -10
  30. package/dist/runtime/worker.js +25 -0
  31. package/dist/scripts/addon.mjs +3 -0
  32. package/dist/scripts/smoke-test.mjs +4 -9
  33. package/dist/scripts/worker-run.d.mts +1 -1
  34. package/dist/scripts/worker-run.mjs +50 -113
  35. package/dist/vite/buildApp.mjs +2 -0
  36. package/dist/vite/directiveModulesDevPlugin.mjs +1 -1
  37. package/dist/vite/linkerPlugin.mjs +1 -1
  38. package/dist/vite/redwoodPlugin.mjs +0 -4
  39. package/dist/vite/runDirectivesScan.mjs +57 -12
  40. package/package.json +9 -7
  41. package/dist/vite/manifestPlugin.d.mts +0 -4
  42. package/dist/vite/manifestPlugin.mjs +0 -63
  43. /package/dist/runtime/lib/{rwContext.js → types.js} +0 -0
@@ -0,0 +1,13 @@
1
+ export declare const IS_DEBUG_MODE: string | boolean;
2
+ export declare const SETUP_PLAYGROUND_ENV_TIMEOUT: number;
3
+ export declare const DEPLOYMENT_TIMEOUT: number;
4
+ export declare const DEPLOYMENT_MIN_TRIES: number;
5
+ export declare const DEPLOYMENT_CHECK_TIMEOUT: number;
6
+ export declare const PUPPETEER_TIMEOUT: number;
7
+ export declare const HYDRATION_TIMEOUT: number;
8
+ export declare const DEV_SERVER_TIMEOUT: number;
9
+ export declare const DEV_SERVER_MIN_TRIES: number;
10
+ export declare const SETUP_WAIT_TIMEOUT: number;
11
+ export declare const TEST_MAX_RETRIES: number;
12
+ export declare const TEST_MAX_RETRIES_PER_CODE: number;
13
+ export declare const INSTALL_DEPENDENCIES_RETRIES: number;
@@ -0,0 +1,67 @@
1
+ export const IS_DEBUG_MODE = process.env.RWSDK_E2E_DEBUG
2
+ ? process.env.RWSDK_E2E_DEBUG
3
+ : !process.env.CI;
4
+ export const SETUP_PLAYGROUND_ENV_TIMEOUT = process.env
5
+ .RWSDK_SETUP_PLAYGROUND_ENV_TIMEOUT
6
+ ? parseInt(process.env.RWSDK_SETUP_PLAYGROUND_ENV_TIMEOUT, 10)
7
+ : IS_DEBUG_MODE
8
+ ? 10 * 60 * 1000
9
+ : 15 * 60 * 1000;
10
+ export const DEPLOYMENT_TIMEOUT = process.env.RWSDK_DEPLOYMENT_TIMEOUT
11
+ ? parseInt(process.env.RWSDK_DEPLOYMENT_TIMEOUT, 10)
12
+ : IS_DEBUG_MODE
13
+ ? 5 * 30 * 1000
14
+ : 5 * 60 * 1000;
15
+ export const DEPLOYMENT_MIN_TRIES = process.env.RWSDK_DEPLOYMENT_MIN_TRIES
16
+ ? parseInt(process.env.RWSDK_DEPLOYMENT_MIN_TRIES, 10)
17
+ : IS_DEBUG_MODE
18
+ ? 1
19
+ : 5;
20
+ export const DEPLOYMENT_CHECK_TIMEOUT = process.env
21
+ .RWSDK_DEPLOYMENT_CHECK_TIMEOUT
22
+ ? parseInt(process.env.RWSDK_DEPLOYMENT_CHECK_TIMEOUT, 10)
23
+ : IS_DEBUG_MODE
24
+ ? 30 * 1000
25
+ : 5 * 60 * 1000;
26
+ export const PUPPETEER_TIMEOUT = process.env.RWSDK_PUPPETEER_TIMEOUT
27
+ ? parseInt(process.env.RWSDK_PUPPETEER_TIMEOUT, 10)
28
+ : IS_DEBUG_MODE
29
+ ? 30 * 1000
30
+ : 60 * 1000 * 2;
31
+ export const HYDRATION_TIMEOUT = process.env.RWSDK_HYDRATION_TIMEOUT
32
+ ? parseInt(process.env.RWSDK_HYDRATION_TIMEOUT, 10)
33
+ : IS_DEBUG_MODE
34
+ ? 2000
35
+ : 5000;
36
+ export const DEV_SERVER_TIMEOUT = process.env.RWSDK_DEV_SERVER_TIMEOUT
37
+ ? parseInt(process.env.RWSDK_DEV_SERVER_TIMEOUT, 10)
38
+ : IS_DEBUG_MODE
39
+ ? 60 * 1000
40
+ : 5 * 60 * 1000;
41
+ export const DEV_SERVER_MIN_TRIES = process.env.RWSDK_DEV_SERVER_MIN_TRIES
42
+ ? parseInt(process.env.RWSDK_DEV_SERVER_MIN_TRIES, 10)
43
+ : IS_DEBUG_MODE
44
+ ? 1
45
+ : 5;
46
+ export const SETUP_WAIT_TIMEOUT = process.env.RWSDK_SETUP_WAIT_TIMEOUT
47
+ ? parseInt(process.env.RWSDK_SETUP_WAIT_TIMEOUT, 10)
48
+ : IS_DEBUG_MODE
49
+ ? 60 * 1000
50
+ : 10 * 60 * 1000;
51
+ export const TEST_MAX_RETRIES = process.env.RWSDK_TEST_MAX_RETRIES
52
+ ? parseInt(process.env.RWSDK_TEST_MAX_RETRIES, 10)
53
+ : IS_DEBUG_MODE
54
+ ? 1
55
+ : 10;
56
+ export const TEST_MAX_RETRIES_PER_CODE = process.env
57
+ .RWSDK_TEST_MAX_RETRIES_PER_CODE
58
+ ? parseInt(process.env.RWSDK_TEST_MAX_RETRIES_PER_CODE, 10)
59
+ : IS_DEBUG_MODE
60
+ ? 0
61
+ : 6;
62
+ export const INSTALL_DEPENDENCIES_RETRIES = process.env
63
+ .RWSDK_INSTALL_DEPENDENCIES_RETRIES
64
+ ? parseInt(process.env.RWSDK_INSTALL_DEPENDENCIES_RETRIES, 10)
65
+ : IS_DEBUG_MODE
66
+ ? 1
67
+ : 10;
@@ -3,7 +3,7 @@ import { PackageManager } from "./types.mjs";
3
3
  /**
4
4
  * Copy project to a temporary directory with a unique name
5
5
  */
6
- export declare function copyProjectToTempDir(projectDir: string, resourceUniqueKey: string, packageManager?: PackageManager, monorepoRoot?: string): Promise<{
6
+ export declare function copyProjectToTempDir(projectDir: string, resourceUniqueKey: string, packageManager?: PackageManager, monorepoRoot?: string, installDependenciesRetries?: number): Promise<{
7
7
  tempDir: tmp.DirectoryResult;
8
8
  targetDir: string;
9
9
  workerName: string;
@@ -8,9 +8,26 @@ import { basename, join, relative, resolve } from "path";
8
8
  import tmp from "tmp-promise";
9
9
  import { $ } from "../../lib/$.mjs";
10
10
  import { ROOT_DIR } from "../constants.mjs";
11
+ import { INSTALL_DEPENDENCIES_RETRIES } from "./constants.mjs";
11
12
  import { retry } from "./retry.mjs";
12
13
  const log = debug("rwsdk:e2e:environment");
14
+ const getTempDir = async () => {
15
+ return tmp.dir({ unsafeCleanup: true });
16
+ };
13
17
  const createSdkTarball = async () => {
18
+ const existingTarballPath = process.env.RWSKD_SMOKE_TEST_TARBALL_PATH;
19
+ if (existingTarballPath) {
20
+ if (!fs.existsSync(existingTarballPath)) {
21
+ throw new Error(`Provided tarball path does not exist: ${existingTarballPath}`);
22
+ }
23
+ log(`📦 Using existing tarball: ${existingTarballPath}`);
24
+ return {
25
+ tarballPath: existingTarballPath,
26
+ cleanupTarball: async () => {
27
+ /* no-op */
28
+ }, // No-op cleanup
29
+ };
30
+ }
14
31
  const packResult = await $({ cwd: ROOT_DIR, stdio: "pipe" }) `npm pack`;
15
32
  const tarballName = packResult.stdout?.trim();
16
33
  const tarballPath = path.join(ROOT_DIR, tarballName);
@@ -33,12 +50,11 @@ const setTarballDependency = async (targetDir, tarballName) => {
33
50
  /**
34
51
  * Copy project to a temporary directory with a unique name
35
52
  */
36
- export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot) {
53
+ export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot, installDependenciesRetries) {
37
54
  const { tarballPath, cleanupTarball } = await createSdkTarball();
38
55
  try {
39
56
  log("Creating temporary directory for project");
40
- // Create a temporary directory
41
- const tempDir = await tmp.dir({ unsafeCleanup: true });
57
+ const tempDir = await getTempDir();
42
58
  // Determine the source directory to copy from
43
59
  const sourceDir = monorepoRoot || projectDir;
44
60
  // Create unique project directory name
@@ -117,7 +133,6 @@ export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packag
117
133
  log("⚙️ Configuring temp project to not use frozen lockfile...");
118
134
  const npmrcPath = join(targetDir, ".npmrc");
119
135
  await fs.promises.writeFile(npmrcPath, "frozen-lockfile=false\n");
120
- // For yarn, create .yarnrc.yml to disable PnP and allow lockfile changes
121
136
  if (packageManager === "yarn") {
122
137
  const yarnrcPath = join(targetDir, ".yarnrc.yml");
123
138
  const yarnCacheDir = path.join(os.tmpdir(), "yarn-cache");
@@ -131,11 +146,19 @@ export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packag
131
146
  await fs.promises.writeFile(yarnrcPath, yarnConfig);
132
147
  log("Created .yarnrc.yml to allow lockfile changes for yarn");
133
148
  }
149
+ if (packageManager === "yarn-classic") {
150
+ const yarnrcPath = join(targetDir, ".yarnrc");
151
+ const yarnCacheDir = path.join(os.tmpdir(), "yarn-classic-cache");
152
+ await fs.promises.mkdir(yarnCacheDir, { recursive: true });
153
+ const yarnConfig = `cache-folder "${yarnCacheDir}"`;
154
+ await fs.promises.writeFile(yarnrcPath, yarnConfig);
155
+ log("Created .yarnrc with cache-folder for yarn-classic");
156
+ }
134
157
  await setTarballDependency(targetDir, tarballFilename);
135
158
  // Install dependencies in the target directory
136
159
  const installDir = monorepoRoot ? tempCopyRoot : targetDir;
137
160
  await retry(() => installDependencies(installDir, packageManager), {
138
- retries: 3,
161
+ retries: INSTALL_DEPENDENCIES_RETRIES,
139
162
  delay: 1000,
140
163
  });
141
164
  // Return the environment details
@@ -172,7 +195,7 @@ async function installDependencies(targetDir, packageManager = "pnpm") {
172
195
  }
173
196
  else if (packageManager === "yarn-classic") {
174
197
  log(`Preparing yarn@1.22.19 with corepack...`);
175
- await $("corepack", ["prepare", "yarn@1.22.19", "--activate"], {
198
+ await $("corepack", ["prepare", "yarn@1.x", "--activate"], {
176
199
  cwd: targetDir,
177
200
  stdio: "pipe",
178
201
  });
@@ -1,3 +1,4 @@
1
+ export * from "../$.mjs";
1
2
  export * from "./browser.mjs";
2
3
  export * from "./dev.mjs";
3
4
  export * from "./environment.mjs";
@@ -1,3 +1,4 @@
1
+ export * from "../$.mjs";
1
2
  export * from "./browser.mjs";
2
3
  export * from "./dev.mjs";
3
4
  export * from "./environment.mjs";
@@ -6,6 +6,30 @@ import { adjectives, animals, uniqueNamesGenerator, } from "unique-names-generat
6
6
  import { ROOT_DIR } from "../constants.mjs";
7
7
  import { copyProjectToTempDir } from "./environment.mjs";
8
8
  const log = (message) => console.log(message);
9
+ async function verifyPackedContents(targetDir) {
10
+ log(" - Verifying installed package contents...");
11
+ const packageName = "rwsdk";
12
+ const installedDistPath = path.join(targetDir, "node_modules", packageName, "dist");
13
+ if (!fs.existsSync(installedDistPath)) {
14
+ throw new Error(`dist/ directory not found in installed package at ${installedDistPath}.`);
15
+ }
16
+ const { stdout: originalDistChecksumOut } = await $("find . -type f | sort | md5sum", {
17
+ shell: true,
18
+ cwd: path.join(ROOT_DIR, "dist"),
19
+ });
20
+ const originalDistChecksum = originalDistChecksumOut.split(" ")[0];
21
+ const { stdout: installedDistChecksumOut } = await $("find . -type f | sort | md5sum", {
22
+ shell: true,
23
+ cwd: installedDistPath,
24
+ });
25
+ const installedDistChecksum = installedDistChecksumOut.split(" ")[0];
26
+ log(` - Original dist checksum: ${originalDistChecksum}`);
27
+ log(` - Installed dist checksum: ${installedDistChecksum}`);
28
+ if (originalDistChecksum !== installedDistChecksum) {
29
+ throw new Error("File list in installed dist/ does not match original dist/.");
30
+ }
31
+ log(" ✅ Installed package contents match the local build.");
32
+ }
9
33
  /**
10
34
  * Copies wrangler cache from monorepo to temp directory for deployment tests
11
35
  */
@@ -80,6 +104,7 @@ export async function setupTarballEnvironment({ projectDir, monorepoRoot, packag
80
104
  const resourceUniqueKey = `${uniqueNameSuffix}-${hash}`;
81
105
  try {
82
106
  const { tempDir, targetDir } = await copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot);
107
+ await verifyPackedContents(targetDir);
83
108
  // Copy wrangler cache to improve deployment performance
84
109
  const sdkRoot = ROOT_DIR;
85
110
  await copyWranglerCache(targetDir, sdkRoot);
@@ -1,8 +1,11 @@
1
1
  import { type Browser, type Page } from "puppeteer-core";
2
2
  import { test } from "vitest";
3
+ import { DEPLOYMENT_CHECK_TIMEOUT, DEPLOYMENT_MIN_TRIES, DEPLOYMENT_TIMEOUT, DEV_SERVER_MIN_TRIES, DEV_SERVER_TIMEOUT, HYDRATION_TIMEOUT, INSTALL_DEPENDENCIES_RETRIES, PUPPETEER_TIMEOUT, SETUP_PLAYGROUND_ENV_TIMEOUT, SETUP_WAIT_TIMEOUT, TEST_MAX_RETRIES, TEST_MAX_RETRIES_PER_CODE } from "./constants.mjs";
3
4
  export type { Browser, Page } from "puppeteer-core";
5
+ export { DEPLOYMENT_CHECK_TIMEOUT, DEPLOYMENT_MIN_TRIES, DEPLOYMENT_TIMEOUT, DEV_SERVER_MIN_TRIES, DEV_SERVER_TIMEOUT, HYDRATION_TIMEOUT, INSTALL_DEPENDENCIES_RETRIES, PUPPETEER_TIMEOUT, SETUP_PLAYGROUND_ENV_TIMEOUT, SETUP_WAIT_TIMEOUT, TEST_MAX_RETRIES, TEST_MAX_RETRIES_PER_CODE, };
4
6
  interface DevServerInstance {
5
7
  url: string;
8
+ projectDir: string;
6
9
  stopDev: () => Promise<void>;
7
10
  }
8
11
  interface DeploymentInstance {
@@ -41,17 +44,29 @@ export interface SetupPlaygroundEnvironmentOptions {
41
44
  * and installs dependencies using a tarball of the SDK.
42
45
  * This ensures that tests run in a clean, isolated environment.
43
46
  */
44
- export declare function setupPlaygroundEnvironment(options?: string | SetupPlaygroundEnvironmentOptions): void;
47
+ export declare function setupPlaygroundEnvironment(options: SetupPlaygroundEnvironmentOptions | string): void;
45
48
  /**
46
49
  * Creates a dev server instance using the shared playground environment.
47
50
  * Automatically registers cleanup to run after the test.
48
51
  */
49
- export declare function createDevServer(projectDir: string): Promise<DevServerInstance>;
52
+ export declare function createDevServer(): {
53
+ projectDir: string;
54
+ start: () => Promise<DevServerInstance>;
55
+ };
50
56
  /**
51
57
  * Creates a deployment instance using the shared playground environment.
52
58
  * Automatically registers cleanup to run after the test.
53
59
  */
54
- export declare function createDeployment(projectDir: string): Promise<DeploymentInstance>;
60
+ export declare function createDeployment(): {
61
+ projectDir: string;
62
+ start: () => Promise<{
63
+ url: string;
64
+ workerName: string;
65
+ resourceUniqueKey: string;
66
+ projectDir: string;
67
+ cleanup: () => Promise<void>;
68
+ }>;
69
+ };
55
70
  /**
56
71
  * Executes a test function with a retry mechanism for specific error codes.
57
72
  * @param name - The name of the test, used for logging.
@@ -61,13 +76,25 @@ export declare function createDeployment(projectDir: string): Promise<Deployment
61
76
  * called automatically on failure.
62
77
  */
63
78
  export declare function runTestWithRetries(name: string, attemptFn: () => Promise<void>): Promise<void>;
79
+ type SDKRunner = (name: string, testLogic: (context: {
80
+ createDevServer: () => Promise<DevServerInstance>;
81
+ createDeployment: () => Promise<DeploymentInstance>;
82
+ browser: Browser;
83
+ page: Page;
84
+ projectDir: string;
85
+ }) => Promise<void>) => void;
64
86
  declare function createTestRunner(testFn: (typeof test | typeof test.only)["concurrent"], envType: "dev" | "deploy"): (name: string, testLogic: (context: {
65
87
  devServer?: DevServerInstance;
66
88
  deployment?: DeploymentInstance;
67
89
  browser: Browser;
68
90
  page: Page;
69
91
  url: string;
92
+ projectDir: string;
70
93
  }) => Promise<void>) => void;
94
+ export declare const testSDK: SDKRunner & {
95
+ only: SDKRunner;
96
+ skip: typeof test.skip;
97
+ };
71
98
  /**
72
99
  * High-level test wrapper for dev server tests.
73
100
  * Automatically skips if RWSDK_SKIP_DEV=1
@@ -81,6 +108,7 @@ export declare namespace testDev {
81
108
  browser: Browser;
82
109
  page: Page;
83
110
  url: string;
111
+ projectDir: string;
84
112
  }) => Promise<void>) => void;
85
113
  }
86
114
  /**
@@ -96,6 +124,7 @@ export declare namespace testDeploy {
96
124
  browser: Browser;
97
125
  page: Page;
98
126
  url: string;
127
+ projectDir: string;
99
128
  }) => Promise<void>) => void;
100
129
  }
101
130
  /**
@@ -108,6 +137,7 @@ export declare function testDevAndDeploy(name: string, testFn: (context: {
108
137
  browser: Browser;
109
138
  page: Page;
110
139
  url: string;
140
+ projectDir: string;
111
141
  }) => Promise<void>): void;
112
142
  export declare namespace testDevAndDeploy {
113
143
  var skip: (name: string, testFn?: any) => void;