rwsdk 0.1.0-alpha.9 → 0.1.1

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 (92) hide show
  1. package/dist/runtime/client.d.ts +3 -1
  2. package/dist/runtime/client.js +15 -11
  3. package/dist/runtime/clientNavigation.d.ts +3 -0
  4. package/dist/runtime/clientNavigation.js +43 -0
  5. package/dist/runtime/entries/client.d.ts +1 -0
  6. package/dist/runtime/entries/client.js +1 -0
  7. package/dist/runtime/entries/worker.d.ts +2 -0
  8. package/dist/runtime/entries/worker.js +2 -0
  9. package/dist/runtime/imports/ClientOnly.d.ts +3 -0
  10. package/dist/runtime/imports/ClientOnly.js +8 -0
  11. package/dist/runtime/imports/NoSSRStub.d.ts +1 -0
  12. package/dist/runtime/imports/NoSSRStub.js +4 -0
  13. package/dist/runtime/imports/client.js +15 -2
  14. package/dist/runtime/imports/worker.d.ts +1 -1
  15. package/dist/runtime/imports/worker.js +7 -5
  16. package/dist/runtime/lib/db/DOWorkerDialect.d.ts +29 -0
  17. package/dist/runtime/lib/db/DOWorkerDialect.js +66 -0
  18. package/dist/runtime/lib/db/SqliteDurableObject.d.ts +14 -0
  19. package/dist/runtime/lib/db/SqliteDurableObject.js +42 -0
  20. package/dist/runtime/lib/db/create.d.ts +3 -0
  21. package/dist/runtime/lib/db/create.js +36 -0
  22. package/dist/runtime/lib/db/createDb.d.ts +2 -0
  23. package/dist/runtime/lib/db/createDb.js +33 -0
  24. package/dist/runtime/lib/db/index.d.ts +3 -0
  25. package/dist/runtime/lib/db/index.js +3 -0
  26. package/dist/runtime/lib/db/logger.d.ts +2 -0
  27. package/dist/runtime/lib/db/logger.js +41 -0
  28. package/dist/runtime/lib/db/migrations.d.ts +23 -0
  29. package/dist/runtime/lib/db/migrations.js +34 -0
  30. package/dist/runtime/lib/db/types.d.ts +0 -0
  31. package/dist/runtime/lib/db/types.js +1 -0
  32. package/dist/runtime/lib/debug.d.ts +2 -0
  33. package/dist/runtime/lib/debug.js +36 -0
  34. package/dist/runtime/lib/router.d.ts +6 -1
  35. package/dist/runtime/lib/router.js +9 -2
  36. package/dist/runtime/register/ssr.d.ts +2 -0
  37. package/dist/runtime/register/ssr.js +14 -1
  38. package/dist/runtime/register/worker.d.ts +1 -1
  39. package/dist/runtime/register/worker.js +5 -2
  40. package/dist/runtime/render/renderRscThenableToHtmlStream.d.ts +2 -1
  41. package/dist/runtime/render/renderRscThenableToHtmlStream.js +17 -3
  42. package/dist/runtime/render/renderToStream.d.ts +9 -0
  43. package/dist/runtime/render/renderToStream.js +26 -0
  44. package/dist/runtime/render/renderToString.d.ts +7 -0
  45. package/dist/runtime/render/renderToString.js +26 -0
  46. package/dist/runtime/render/transformRscToHtmlStream.js +1 -0
  47. package/dist/runtime/worker.js +17 -10
  48. package/dist/scripts/debug-sync.mjs +8 -6
  49. package/dist/scripts/worker-run.mjs +1 -0
  50. package/dist/vite/configPlugin.d.mts +2 -2
  51. package/dist/vite/configPlugin.mjs +10 -21
  52. package/dist/vite/createDirectiveLookupPlugin.d.mts +1 -0
  53. package/dist/vite/createDirectiveLookupPlugin.mjs +88 -57
  54. package/dist/vite/devServerTimingPlugin.d.mts +2 -0
  55. package/dist/vite/devServerTimingPlugin.mjs +24 -0
  56. package/dist/vite/directivesPlugin.mjs +168 -70
  57. package/dist/vite/findImportSpecifiers.d.mts +16 -0
  58. package/dist/vite/findImportSpecifiers.mjs +152 -0
  59. package/dist/vite/findImportSpecifiers.test.d.mts +1 -0
  60. package/dist/vite/findImportSpecifiers.test.mjs +73 -0
  61. package/dist/vite/findSpecifiers.d.mts +31 -0
  62. package/dist/vite/findSpecifiers.mjs +230 -0
  63. package/dist/vite/hasDirective.d.mts +7 -0
  64. package/dist/vite/hasDirective.mjs +54 -0
  65. package/dist/vite/hasOwnCloudflareVitePlugin.d.mts +3 -0
  66. package/dist/vite/hasOwnCloudflareVitePlugin.mjs +14 -0
  67. package/dist/vite/injectVitePreamblePlugin.d.mts +2 -2
  68. package/dist/vite/injectVitePreamblePlugin.mjs +5 -2
  69. package/dist/vite/invalidateModule.d.mts +2 -0
  70. package/dist/vite/invalidateModule.mjs +14 -0
  71. package/dist/vite/miniflareHMRPlugin.d.mts +8 -0
  72. package/dist/vite/miniflareHMRPlugin.mjs +133 -0
  73. package/dist/vite/normalizeModulePath.mjs +12 -1
  74. package/dist/vite/reactConditionsResolverPlugin.d.mts +1 -1
  75. package/dist/vite/reactConditionsResolverPlugin.mjs +64 -59
  76. package/dist/vite/redwoodPlugin.d.mts +2 -1
  77. package/dist/vite/redwoodPlugin.mjs +24 -7
  78. package/dist/vite/resolveModuleId.d.mts +6 -0
  79. package/dist/vite/resolveModuleId.mjs +14 -0
  80. package/dist/vite/ssrBridgePlugin.d.mts +5 -1
  81. package/dist/vite/ssrBridgePlugin.mjs +4 -43
  82. package/dist/vite/transformClientComponents.d.mts +1 -0
  83. package/dist/vite/transformClientComponents.mjs +61 -125
  84. package/dist/vite/transformJsxScriptTagsPlugin.mjs +14 -3
  85. package/dist/vite/transformServerFunctions.d.mts +11 -3
  86. package/dist/vite/transformServerFunctions.mjs +256 -171
  87. package/dist/vite/transformServerFunctions.test.mjs +22 -3
  88. package/dist/vite/useClientLookupPlugin.mjs +1 -0
  89. package/dist/vite/useServerLookupPlugin.mjs +1 -0
  90. package/dist/vite/useServerPlugin.d.mts +1 -1
  91. package/dist/vite/useServerPlugin.mjs +1 -1
  92. package/package.json +14 -3
@@ -1,204 +1,289 @@
1
- import { Project, SyntaxKind, Node } from "ts-morph";
1
+ import MagicString from "magic-string";
2
2
  import debug from "debug";
3
+ import { hasDirective } from "./hasDirective.mjs";
4
+ import { findExports } from "./findSpecifiers.mjs";
5
+ import { parse as sgParse, Lang as SgLang, Lang } from "@ast-grep/napi";
6
+ import path from "path";
3
7
  const log = debug("rwsdk:vite:transform-server-functions");
4
8
  const verboseLog = debug("verbose:rwsdk:vite:transform-server-functions");
5
- export const findExportedFunctions = (sourceFile) => {
9
+ export const findExportedFunctions = (code, normalizedId) => {
10
+ return findExportInfo(code, normalizedId).localFunctions;
11
+ };
12
+ export const findExportInfo = (code, normalizedId) => {
6
13
  verboseLog("Finding exported functions in source file");
7
- const exportedFunctions = new Set();
8
- const exportAssignments = sourceFile.getDescendantsOfKind(SyntaxKind.ExportAssignment);
9
- for (const e of exportAssignments) {
10
- const name = e.getExpression().getText();
11
- if (name === "default") {
12
- continue;
13
- }
14
- exportedFunctions.add(name);
15
- verboseLog("Found export assignment: %s", name);
16
- }
17
- const functionDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration);
18
- for (const func of functionDeclarations) {
19
- if (func.hasModifier(SyntaxKind.ExportKeyword)) {
20
- const name = func.getName();
21
- if (name) {
22
- exportedFunctions.add(name);
23
- verboseLog("Found exported function declaration: %s", name);
14
+ const localFunctions = new Set();
15
+ const reExports = [];
16
+ const exportInfos = findExports(normalizedId || "file.ts", code, verboseLog);
17
+ for (const exportInfo of exportInfos) {
18
+ if (exportInfo.isReExport && exportInfo.moduleSpecifier) {
19
+ // For re-exports, we need to determine the original name by parsing the code
20
+ // For "export { default as multiply }", we want localName="multiply", originalName="default"
21
+ // For "export { sum }", we want localName="sum", originalName="sum"
22
+ let originalName = exportInfo.name;
23
+ // Check if this is a default re-export with alias
24
+ if (exportInfo.isDefault && exportInfo.alias) {
25
+ originalName = "default";
24
26
  }
27
+ reExports.push({
28
+ localName: exportInfo.name,
29
+ originalName: originalName,
30
+ moduleSpecifier: exportInfo.moduleSpecifier,
31
+ });
32
+ verboseLog("Found re-exported function: %s (original: %s) from %s", exportInfo.name, originalName, exportInfo.moduleSpecifier);
25
33
  }
26
- }
27
- const variableStatements = sourceFile.getDescendantsOfKind(SyntaxKind.VariableStatement);
28
- for (const statement of variableStatements) {
29
- if (statement.hasModifier(SyntaxKind.ExportKeyword)) {
30
- const declarations = statement.getDeclarationList().getDeclarations();
31
- for (const declaration of declarations) {
32
- const initializer = declaration.getInitializer();
33
- if (initializer && Node.isArrowFunction(initializer)) {
34
- const name = declaration.getName();
35
- if (name) {
36
- exportedFunctions.add(name);
37
- verboseLog("Found exported arrow function: %s", name);
38
- }
39
- }
40
- }
34
+ else {
35
+ localFunctions.add(exportInfo.name);
36
+ verboseLog("Found exported function: %s", exportInfo.name);
41
37
  }
42
38
  }
43
- log("Found %d exported functions: %O", exportedFunctions.size, Array.from(exportedFunctions));
44
- return exportedFunctions;
39
+ log("Found %d local functions: %O", localFunctions.size, Array.from(localFunctions));
40
+ log("Found %d re-exports: %O", reExports.length, reExports.map((r) => `${r.localName} from ${r.moduleSpecifier}`));
41
+ return { localFunctions, reExports };
45
42
  };
46
- export const transformServerFunctions = (code, normalizedId, environment, serverFiles) => {
47
- verboseLog("Transform server functions called for normalizedId=%s, environment=%s", normalizedId, environment);
48
- const project = new Project({
49
- useInMemoryFileSystem: true,
50
- compilerOptions: {
51
- sourceMap: true,
52
- target: 2,
53
- module: 1,
54
- jsx: 2,
55
- },
56
- });
57
- const sourceFile = project.createSourceFile(normalizedId, code);
58
- const statements = sourceFile.getStatements();
59
- let hasUseServerDirective = false;
60
- for (const stmt of statements) {
61
- if (!Node.isExpressionStatement(stmt))
62
- break;
63
- const expr = stmt.getExpression();
64
- if (!expr || !Node.isStringLiteral(expr))
65
- break;
66
- const value = expr.getLiteralText();
67
- if (value === "use server") {
68
- hasUseServerDirective = true;
69
- log("Found 'use server' directive at top level for normalizedId=%s", normalizedId);
70
- stmt.remove();
71
- verboseLog("Removed 'use server' directive from normalizedId=%s", normalizedId);
72
- break;
43
+ // Helper function to find default function names using ast-grep
44
+ function findDefaultFunctionName(code, normalizedId) {
45
+ const ext = path.extname(normalizedId).toLowerCase();
46
+ const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
47
+ try {
48
+ const root = sgParse(lang, code);
49
+ const matches = root
50
+ .root()
51
+ .findAll("export default function $NAME($$$) { $$$ }");
52
+ if (matches.length > 0) {
53
+ const nameCapture = matches[0].getMatch("NAME");
54
+ return nameCapture?.text() || null;
55
+ }
56
+ }
57
+ catch (err) {
58
+ verboseLog("Error finding default function name: %O", err);
59
+ }
60
+ return null;
61
+ }
62
+ // Helper function to check if there's a default export (not re-export)
63
+ function hasDefaultExport(code, normalizedId) {
64
+ const ext = path.extname(normalizedId).toLowerCase();
65
+ const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
66
+ try {
67
+ const root = sgParse(lang, code);
68
+ // Check for any export default statements
69
+ const patterns = [
70
+ "export default function $$$",
71
+ "export default function($$$) { $$$ }",
72
+ "export default $$$",
73
+ ];
74
+ for (const pattern of patterns) {
75
+ const matches = root.root().findAll(pattern);
76
+ if (matches.length > 0) {
77
+ return true;
78
+ }
73
79
  }
74
80
  }
75
- if (!hasUseServerDirective) {
76
- verboseLog("No 'use server' directive found at top-level, skipping transformation for normalizedId=%s", normalizedId);
81
+ catch (err) {
82
+ verboseLog("Error checking for default export: %O", err);
83
+ }
84
+ return false;
85
+ }
86
+ export const transformServerFunctions = (code, normalizedId, environment, serverFiles, addServerModule) => {
87
+ verboseLog("Transform server functions called for normalizedId=%s, environment=%s", normalizedId, environment);
88
+ if (!hasDirective(code, "use server")) {
89
+ log("Skipping: no 'use server' directive in id=%s", normalizedId);
90
+ verboseLog(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
77
91
  return;
78
92
  }
79
93
  log("Processing 'use server' module: normalizedId=%s, environment=%s", normalizedId, environment);
80
- serverFiles?.add(normalizedId);
81
- if (environment === "ssr") {
82
- log("Transforming for SSR environment: normalizedId=%s", normalizedId);
83
- const ssrSourceFile = project.createSourceFile("ssr.tsx", "");
84
- ssrSourceFile.addImportDeclaration({
85
- moduleSpecifier: "rwsdk/__ssr",
86
- namedImports: ["createServerReference"],
87
- });
88
- const exports = findExportedFunctions(sourceFile);
89
- for (const name of exports) {
90
- ssrSourceFile.addVariableStatement({
91
- isExported: true,
92
- declarations: [
93
- {
94
- name: name,
95
- initializer: `createServerReference(${JSON.stringify(normalizedId)}, ${JSON.stringify(name)})`,
96
- },
97
- ],
98
- });
99
- log("Added SSR server reference for function: %s in normalizedId=%s", name, normalizedId);
94
+ addServerModule?.(environment, normalizedId);
95
+ if (environment === "ssr" || environment === "client") {
96
+ log(`Transforming for ${environment} environment: normalizedId=%s`, normalizedId);
97
+ const exportInfo = findExportInfo(code, normalizedId);
98
+ const allExports = new Set([
99
+ ...exportInfo.localFunctions,
100
+ ...exportInfo.reExports.map((r) => r.localName),
101
+ ]);
102
+ // Check for default function exports that should also be named exports
103
+ const defaultFunctionName = findDefaultFunctionName(code, normalizedId);
104
+ if (defaultFunctionName) {
105
+ allExports.add(defaultFunctionName);
100
106
  }
101
- const hadDefaultExport = !!sourceFile.getDefaultExportSymbol();
102
- if (hadDefaultExport) {
103
- ssrSourceFile.addExportAssignment({
104
- expression: `createServerReference(${JSON.stringify(normalizedId)}, "default")`,
105
- isExportEquals: false,
106
- });
107
- log("Added SSR server reference for default export in normalizedId=%s", normalizedId);
107
+ // Generate completely new code for SSR
108
+ const s = new MagicString("");
109
+ if (environment === "ssr") {
110
+ s.append('import { createServerReference } from "rwsdk/__ssr";\n\n');
111
+ }
112
+ else {
113
+ s.append('import { createServerReference } from "rwsdk/client";\n\n');
108
114
  }
109
- const emitOutput = ssrSourceFile.getEmitOutput();
110
- let sourceMap;
111
- for (const outputFile of emitOutput.getOutputFiles()) {
112
- if (outputFile.getFilePath().endsWith(".js.map")) {
113
- sourceMap = JSON.parse(outputFile.getText());
115
+ for (const name of allExports) {
116
+ if (name !== "default" && name !== defaultFunctionName) {
117
+ s.append(`export let ${name} = createServerReference(${JSON.stringify(normalizedId)}, ${JSON.stringify(name)});\n`);
118
+ log(`Added ${environment} server reference for function: %s in normalizedId=%s`, name, normalizedId);
114
119
  }
115
120
  }
116
- log("SSR transformation complete for normalizedId=%s", normalizedId);
121
+ // Check for default export in the actual module (not re-exports)
122
+ if (hasDefaultExport(code, normalizedId)) {
123
+ s.append(`\nexport default createServerReference(${JSON.stringify(normalizedId)}, "default");\n`);
124
+ log(`Added ${environment} server reference for default export in normalizedId=%s`, normalizedId);
125
+ }
126
+ log(`${environment} transformation complete for normalizedId=%s`, normalizedId);
117
127
  return {
118
- code: ssrSourceFile.getFullText(),
119
- map: sourceMap,
128
+ code: s.toString(),
129
+ map: s.generateMap({
130
+ source: normalizedId,
131
+ includeContent: true,
132
+ hires: true,
133
+ }),
120
134
  };
121
135
  }
122
136
  else if (environment === "worker") {
123
137
  log("Transforming for worker environment: normalizedId=%s", normalizedId);
124
- sourceFile.addImportDeclaration({
125
- moduleSpecifier: "rwsdk/worker",
126
- namedImports: ["registerServerReference"],
127
- });
128
- const defaultExportSymbol = sourceFile.getDefaultExportSymbol();
129
- const defaultExportDecl = defaultExportSymbol?.getDeclarations()[0];
130
- let hasDefaultExport = false;
131
- if (defaultExportDecl && Node.isFunctionDeclaration(defaultExportDecl)) {
132
- hasDefaultExport = true;
133
- defaultExportDecl.setIsDefaultExport(false);
134
- defaultExportDecl.rename("__defaultServerFunction__");
135
- sourceFile.addExportAssignment({
136
- expression: "__defaultServerFunction__",
137
- isExportEquals: false,
138
- });
139
- sourceFile.addStatements(`registerServerReference(__defaultServerFunction__, ${JSON.stringify(normalizedId)}, "default")`);
138
+ const exportInfo = findExportInfo(code, normalizedId);
139
+ const s = new MagicString(code);
140
+ // Remove "use server" directive first
141
+ const directiveRegex = /^(\s*)(['"]use server['"])\s*;?\s*$/gm;
142
+ let match;
143
+ while ((match = directiveRegex.exec(code)) !== null) {
144
+ const start = match.index;
145
+ const end = match.index + match[0].length;
146
+ s.remove(start, end);
147
+ verboseLog("Removed 'use server' directive from normalizedId=%s", normalizedId);
148
+ break; // Only remove the first one
149
+ }
150
+ // Add imports at the very beginning
151
+ let importsToAdd = [];
152
+ // Add imports for re-exported functions so they exist in scope
153
+ for (const reExport of exportInfo.reExports) {
154
+ // Fix the import statement - the originalName is what we import, localName is the alias
155
+ const importStatement = reExport.originalName === "default"
156
+ ? `import { default as ${reExport.localName} } from "${reExport.moduleSpecifier}";`
157
+ : reExport.originalName === reExport.localName
158
+ ? `import { ${reExport.originalName} } from "${reExport.moduleSpecifier}";`
159
+ : `import { ${reExport.originalName} as ${reExport.localName} } from "${reExport.moduleSpecifier}";`;
160
+ importsToAdd.push(importStatement);
161
+ log("Added import for re-exported function: %s from %s in normalizedId=%s", reExport.localName, reExport.moduleSpecifier, normalizedId);
162
+ }
163
+ // Add registerServerReference import
164
+ importsToAdd.push('import { registerServerReference } from "rwsdk/worker";');
165
+ // Add imports - position depends on whether file starts with block comment
166
+ if (importsToAdd.length > 0) {
167
+ const trimmedCode = code.trim();
168
+ if (trimmedCode.startsWith("/*")) {
169
+ // Find the end of the block comment
170
+ const blockCommentEnd = code.indexOf("*/");
171
+ if (blockCommentEnd !== -1) {
172
+ // Insert after the block comment
173
+ const insertPos = blockCommentEnd + 2;
174
+ // Find the next newline after the block comment
175
+ const nextNewline = code.indexOf("\n", insertPos);
176
+ const actualInsertPos = nextNewline !== -1 ? nextNewline + 1 : insertPos;
177
+ s.appendLeft(actualInsertPos, importsToAdd.join("\n") + "\n");
178
+ }
179
+ else {
180
+ s.prepend(importsToAdd.join("\n") + "\n");
181
+ }
182
+ }
183
+ else {
184
+ // No block comment at start, add at beginning
185
+ s.prepend(importsToAdd.join("\n") + "\n");
186
+ }
187
+ }
188
+ // Handle default export renaming if present
189
+ const hasDefExport = hasDefaultExport(code, normalizedId);
190
+ if (hasDefExport) {
191
+ // Find and rename default function export using ast-grep
192
+ const ext = path.extname(normalizedId).toLowerCase();
193
+ const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
194
+ try {
195
+ const root = sgParse(lang, code);
196
+ // Handle named default function: export default function myFunc() {}
197
+ const namedMatches = root
198
+ .root()
199
+ .findAll("export default function $NAME($$$) { $$$ }");
200
+ if (namedMatches.length > 0) {
201
+ const match = namedMatches[0];
202
+ const range = match.range();
203
+ const funcName = match.getMatch("NAME")?.text();
204
+ if (funcName) {
205
+ // Replace "export default function myFunc" with "function __defaultServerFunction__"
206
+ const newText = match
207
+ .text()
208
+ .replace(`export default function ${funcName}`, "function __defaultServerFunction__");
209
+ s.overwrite(range.start.index, range.end.index, newText);
210
+ s.append("\nexport default __defaultServerFunction__;\n");
211
+ }
212
+ }
213
+ else {
214
+ // Handle anonymous default function: export default function() {}
215
+ const anonMatches = root
216
+ .root()
217
+ .findAll("export default function($$$) { $$$ }");
218
+ if (anonMatches.length > 0) {
219
+ const match = anonMatches[0];
220
+ const range = match.range();
221
+ const newText = match
222
+ .text()
223
+ .replace("export default function", "function __defaultServerFunction__");
224
+ s.overwrite(range.start.index, range.end.index, newText);
225
+ s.append("\nexport default __defaultServerFunction__;\n");
226
+ }
227
+ else {
228
+ const predefinedMatches = root
229
+ .root()
230
+ .findAll("export default $NAME");
231
+ if (predefinedMatches.length > 0) {
232
+ const match = predefinedMatches[0];
233
+ const nameCapture = match.getMatch("NAME")?.text();
234
+ if (nameCapture) {
235
+ s.append(`const __defaultServerFunction__ = ${nameCapture};\n`);
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
241
+ catch (err) {
242
+ verboseLog("Error processing default function: %O", err);
243
+ }
244
+ }
245
+ // Add registration calls at the end
246
+ let registrationCalls = [];
247
+ const registeredFunctions = new Set(); // Track to avoid duplicates
248
+ if (hasDefExport) {
249
+ registrationCalls.push(`registerServerReference(__defaultServerFunction__, ${JSON.stringify(normalizedId)}, "default")`);
250
+ registeredFunctions.add("default");
140
251
  log("Registered worker server reference for default export in normalizedId=%s", normalizedId);
141
252
  }
142
- const exports = findExportedFunctions(sourceFile);
143
- for (const name of exports) {
144
- if (name === "__defaultServerFunction__")
253
+ // Register local functions
254
+ const defaultFunctionName = findDefaultFunctionName(code, normalizedId);
255
+ for (const name of exportInfo.localFunctions) {
256
+ if (name === "__defaultServerFunction__" ||
257
+ name === "default" ||
258
+ name === defaultFunctionName)
145
259
  continue;
146
- sourceFile.addStatements(`registerServerReference(${name}, ${JSON.stringify(normalizedId)}, ${JSON.stringify(name)})`);
147
- log("Registered worker server reference for function: %s in normalizedId=%s", name, normalizedId);
148
- }
149
- const emitOutput = sourceFile.getEmitOutput();
150
- let sourceMap;
151
- for (const outputFile of emitOutput.getOutputFiles()) {
152
- if (outputFile.getFilePath().endsWith(".js.map")) {
153
- sourceMap = JSON.parse(outputFile.getText());
154
- }
260
+ // Skip if already registered
261
+ if (registeredFunctions.has(name))
262
+ continue;
263
+ registrationCalls.push(`registerServerReference(${name}, ${JSON.stringify(normalizedId)}, ${JSON.stringify(name)})`);
264
+ registeredFunctions.add(name);
265
+ log("Registered worker server reference for local function: %s in normalizedId=%s", name, normalizedId);
155
266
  }
156
- log("Worker transformation complete for normalizedId=%s", normalizedId);
157
- return {
158
- code: sourceFile.getFullText(),
159
- map: sourceMap,
160
- };
161
- }
162
- else if (environment === "client") {
163
- log("Transforming for client environment: normalizedId=%s", normalizedId);
164
- const clientSourceFile = project.createSourceFile("client.tsx", "");
165
- clientSourceFile.addImportDeclaration({
166
- moduleSpecifier: "rwsdk/client",
167
- namedImports: ["createServerReference"],
168
- });
169
- const exports = findExportedFunctions(sourceFile);
170
- for (const name of exports) {
171
- clientSourceFile.addVariableStatement({
172
- isExported: true,
173
- declarations: [
174
- {
175
- name: name,
176
- initializer: `createServerReference(${JSON.stringify(normalizedId)}, ${JSON.stringify(name)})`,
177
- },
178
- ],
179
- });
180
- log("Added client server reference for function: %s in normalizedId=%s", name, normalizedId);
181
- verboseLog("Added client server reference for function: %s in normalizedId=%s", name, normalizedId);
182
- }
183
- const hadDefaultExport = !!sourceFile.getDefaultExportSymbol();
184
- if (hadDefaultExport) {
185
- clientSourceFile.addExportAssignment({
186
- expression: `createServerReference(${JSON.stringify(normalizedId)}, "default")`,
187
- isExportEquals: false,
188
- });
189
- log("Added client server reference for default export in normalizedId=%s", normalizedId);
267
+ // Register re-exported functions
268
+ for (const reExport of exportInfo.reExports) {
269
+ // Skip if already registered
270
+ if (registeredFunctions.has(reExport.localName))
271
+ continue;
272
+ registrationCalls.push(`registerServerReference(${reExport.localName}, ${JSON.stringify(normalizedId)}, ${JSON.stringify(reExport.localName)})`);
273
+ registeredFunctions.add(reExport.localName);
274
+ log("Registered worker server reference for re-exported function: %s in normalizedId=%s", reExport.localName, normalizedId);
190
275
  }
191
- const emitOutput = clientSourceFile.getEmitOutput();
192
- let sourceMap;
193
- for (const outputFile of emitOutput.getOutputFiles()) {
194
- if (outputFile.getFilePath().endsWith(".js.map")) {
195
- sourceMap = JSON.parse(outputFile.getText());
196
- }
276
+ if (registrationCalls.length > 0) {
277
+ s.append(registrationCalls.join("\n") + "\n");
197
278
  }
198
- log("Client transformation complete for normalizedId=%s", normalizedId);
279
+ log("Worker transformation complete for normalizedId=%s", normalizedId);
199
280
  return {
200
- code: clientSourceFile.getFullText(),
201
- map: sourceMap,
281
+ code: s.toString(),
282
+ map: s.generateMap({
283
+ source: normalizedId,
284
+ includeContent: true,
285
+ hires: true,
286
+ }),
202
287
  };
203
288
  }
204
289
  verboseLog("No transformation applied for environment=%s, normalizedId=%s", environment, normalizedId);
@@ -46,6 +46,21 @@ export function sum() {
46
46
  export default function sum() {
47
47
  return 1 + 2;
48
48
  }
49
+ `;
50
+ let PREDEFINED_DEFAULT_EXPORT_CODE = `
51
+ "use server";
52
+
53
+ const sum = () => {
54
+ return 1 + 1;
55
+ }
56
+
57
+ export default sum;
58
+ `;
59
+ let EXPORT_DEFAULT_FUNCTION_CODE = `
60
+ "use server";
61
+ export default function sum() {
62
+ return 1 + 1;
63
+ }
49
64
  `;
50
65
  let NAMED_EXPORT_CODE = `
51
66
  "use server";
@@ -68,10 +83,12 @@ export async function sum() {
68
83
  return 1 + 1
69
84
  }
70
85
  `;
71
- let IGNORE_NON_FUNCTION_EXPORT_CODE = `
86
+ let RE_EXPORT_CODE = `
72
87
  "use server";
73
88
 
74
- export const a = "string";
89
+ export { sum } from './math';
90
+ export { default as multiply } from './multiply';
91
+ export * from './utils';
75
92
  `;
76
93
  const TEST_CASES = {
77
94
  COMMENT_CODE,
@@ -81,8 +98,10 @@ export const a = "string";
81
98
  NAMED_EXPORT_CODE,
82
99
  ARROW_FUNCTION_EXPORT_CODE,
83
100
  ASYNC_FUNCTION_EXPORT_CODE,
84
- IGNORE_NON_FUNCTION_EXPORT_CODE,
85
101
  DEFAULT_AND_NAMED_EXPORTS_CODE,
102
+ RE_EXPORT_CODE,
103
+ PREDEFINED_DEFAULT_EXPORT_CODE,
104
+ EXPORT_DEFAULT_FUNCTION_CODE,
86
105
  };
87
106
  describe("TRANSFORMS", () => {
88
107
  for (const [key, CODE] of Object.entries(TEST_CASES)) {
@@ -4,6 +4,7 @@ export const useClientLookupPlugin = async ({ projectRootDir, clientFiles, }) =>
4
4
  projectRootDir,
5
5
  files: clientFiles,
6
6
  config: {
7
+ kind: "client",
7
8
  directive: "use client",
8
9
  virtualModuleName: "virtual:use-client-lookup",
9
10
  exportName: "useClientLookup",
@@ -4,6 +4,7 @@ export const useServerLookupPlugin = async ({ projectRootDir, serverFiles, }) =>
4
4
  projectRootDir,
5
5
  files: serverFiles,
6
6
  config: {
7
+ kind: "server",
7
8
  directive: "use server",
8
9
  virtualModuleName: "virtual:use-server-lookup",
9
10
  exportName: "useServerLookup",
@@ -1 +1 @@
1
- export { findExportedFunctions, transformServerFunctions, } from "./transformServerFunctions.mjs";
1
+ export { transformServerFunctions } from "./transformServerFunctions.mjs";
@@ -1 +1 @@
1
- export { findExportedFunctions, transformServerFunctions, } from "./transformServerFunctions.mjs";
1
+ export { transformServerFunctions } from "./transformServerFunctions.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.1.1",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,6 +44,14 @@
44
44
  "types": "./dist/runtime/entries/auth.d.ts",
45
45
  "default": "./dist/runtime/entries/auth.js"
46
46
  },
47
+ "./db": {
48
+ "types": "./dist/runtime/lib/db/index.d.ts",
49
+ "default": "./dist/runtime/lib/db/index.js"
50
+ },
51
+ "./debug": {
52
+ "types": "./dist/runtime/lib/debug.d.ts",
53
+ "default": "./dist/runtime/lib/debug.js"
54
+ },
47
55
  "./constants": {
48
56
  "types": "./dist/runtime/constants.d.ts",
49
57
  "default": "./dist/runtime/constants.js"
@@ -101,7 +109,8 @@
101
109
  "author": "RedwoodSDK <peter@redwoodjs.com>",
102
110
  "license": "MIT",
103
111
  "dependencies": {
104
- "@cloudflare/vite-plugin": "0.0.0-1bae8618b",
112
+ "@ast-grep/napi": "^0.38.5",
113
+ "@cloudflare/vite-plugin": "1.7.4",
105
114
  "@cloudflare/workers-types": "^4.20250407.0",
106
115
  "@puppeteer/browsers": "^2.8.0",
107
116
  "@types/fs-extra": "^11.0.4",
@@ -117,6 +126,8 @@
117
126
  "glob": "^11.0.1",
118
127
  "ignore": "^7.0.4",
119
128
  "jsonc-parser": "^3.3.1",
129
+ "kysely": "^0.28.2",
130
+ "kysely-do": "^0.0.1-rc.1",
120
131
  "lodash": "^4.17.21",
121
132
  "magic-string": "^0.30.17",
122
133
  "miniflare": "^4.20250405.0",
@@ -132,7 +143,7 @@
132
143
  "unique-names-generator": "^4.7.1",
133
144
  "vibe-rules": "^0.2.31",
134
145
  "vite-tsconfig-paths": "^5.1.4",
135
- "wrangler": "^4.16.0"
146
+ "wrangler": "^4.20.5"
136
147
  },
137
148
  "peerDependencies": {
138
149
  "vite": "^6.2.6"