@concavejs/cli 0.0.1-alpha.7 → 0.0.1-alpha.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/assets/dashboard/dashboard.js +1 -1
- package/dist/assets/manifest.json +14 -14
- package/dist/assets/runtime-bun/server/index.js +3661 -2885
- package/dist/assets/runtime-cf/runtime.bundle.js +3931 -9033
- package/dist/assets/runtime-node/server/index.js +3576 -2793
- package/dist/cli.js +488 -55
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -4757,7 +4757,7 @@ async function loadAppDefinition(configPath, parentComponentPath, entries, visit
|
|
|
4757
4757
|
for (const child of childComponents) {
|
|
4758
4758
|
const componentPath = joinComponentPath(parentComponentPath, child.name);
|
|
4759
4759
|
const definitionPath = resolveChildDefinitionPath(configPath, child.path);
|
|
4760
|
-
const modulesDir =
|
|
4760
|
+
const modulesDir = await resolveComponentModulesDir(definitionPath);
|
|
4761
4761
|
entries.push({
|
|
4762
4762
|
componentPath,
|
|
4763
4763
|
modulesDir,
|
|
@@ -4780,7 +4780,7 @@ async function loadComponentDefinition(configPath, componentPath, entries, visit
|
|
|
4780
4780
|
for (const child of childComponents) {
|
|
4781
4781
|
const nestedComponentPath = joinComponentPath(componentPath, child.name);
|
|
4782
4782
|
const definitionPath = resolveChildDefinitionPath(configPath, child.path);
|
|
4783
|
-
const modulesDir =
|
|
4783
|
+
const modulesDir = await resolveComponentModulesDir(definitionPath);
|
|
4784
4784
|
entries.push({
|
|
4785
4785
|
componentPath: nestedComponentPath,
|
|
4786
4786
|
modulesDir,
|
|
@@ -4806,6 +4806,17 @@ function resolveChildDefinitionPath(parentConfigPath, childPath) {
|
|
|
4806
4806
|
const parentDir = path.dirname(parentConfigPath);
|
|
4807
4807
|
return path.resolve(parentDir, childPath);
|
|
4808
4808
|
}
|
|
4809
|
+
async function resolveComponentModulesDir(definitionPath) {
|
|
4810
|
+
const definitionDir = path.dirname(definitionPath);
|
|
4811
|
+
const nestedConvexDir = path.join(definitionDir, "convex");
|
|
4812
|
+
try {
|
|
4813
|
+
const stats = await fs.stat(nestedConvexDir);
|
|
4814
|
+
if (stats.isDirectory()) {
|
|
4815
|
+
return nestedConvexDir;
|
|
4816
|
+
}
|
|
4817
|
+
} catch {}
|
|
4818
|
+
return definitionDir;
|
|
4819
|
+
}
|
|
4809
4820
|
function joinComponentPath(parent, child) {
|
|
4810
4821
|
if (!parent) {
|
|
4811
4822
|
return child;
|
|
@@ -5146,6 +5157,7 @@ async function generateUserEntry(projectRoot, outDir) {
|
|
|
5146
5157
|
const componentManifest = await scanComponents(projectRoot);
|
|
5147
5158
|
await writeComponentManifest(targetDir, componentManifest.entries);
|
|
5148
5159
|
await copyComponentModules(targetDir, componentManifest.entries);
|
|
5160
|
+
const componentLoaderBlocks = await buildComponentLoaderBlocks(targetDir, componentManifest.entries);
|
|
5149
5161
|
const fallbackEntries = files.map((filePath) => {
|
|
5150
5162
|
const importPath = formatImportPath(targetDir, filePath);
|
|
5151
5163
|
return ` '${importPath}': () => import('${importPath}'),`;
|
|
@@ -5154,10 +5166,20 @@ async function generateUserEntry(projectRoot, outDir) {
|
|
|
5154
5166
|
const content = `// Generated by concave CLI
|
|
5155
5167
|
// Do not edit this file manually
|
|
5156
5168
|
|
|
5169
|
+
import { createModuleLoaderFromGlob, setConcaveModuleLoader } from "@concavejs/core/udf";
|
|
5170
|
+
|
|
5157
5171
|
const modules = import.meta?.glob?.(["../convex/**/*.*s", "!../**/*.*.*s"]) ?? {
|
|
5158
5172
|
${fallbackEntries}
|
|
5159
5173
|
};
|
|
5160
5174
|
|
|
5175
|
+
const componentLoaders = [];
|
|
5176
|
+
${componentLoaderBlocks.join(`
|
|
5177
|
+
|
|
5178
|
+
`)}
|
|
5179
|
+
for (const { componentPath, loader } of componentLoaders) {
|
|
5180
|
+
setConcaveModuleLoader(loader, { componentPath });
|
|
5181
|
+
}
|
|
5182
|
+
|
|
5161
5183
|
export { modules };
|
|
5162
5184
|
`;
|
|
5163
5185
|
const contentWithFunctionsPath = content.replace('const modules = import.meta?.glob?.(["../convex/**/*.*s", "!../**/*.*.*s"]) ?? {', `const modules = import.meta?.glob?.([${JSON.stringify(functionsGlobPattern)}, "!../**/*.*.*s"]) ?? {`);
|
|
@@ -7387,6 +7409,8 @@ import {
|
|
|
7387
7409
|
} from "convex/server";
|
|
7388
7410
|
import type { DataModel } from "./dataModel.js";
|
|
7389
7411
|
|
|
7412
|
+
export { defineSchema, defineTable } from "convex/server";
|
|
7413
|
+
|
|
7390
7414
|
/**
|
|
7391
7415
|
* Define a query in this Convex app's public API.
|
|
7392
7416
|
*
|
|
@@ -7528,6 +7552,8 @@ import {
|
|
|
7528
7552
|
internalActionGeneric,
|
|
7529
7553
|
internalMutationGeneric,
|
|
7530
7554
|
internalQueryGeneric,
|
|
7555
|
+
defineSchema,
|
|
7556
|
+
defineTable,
|
|
7531
7557
|
} from "convex/server";
|
|
7532
7558
|
|
|
7533
7559
|
/**
|
|
@@ -7599,6 +7625,11 @@ export const internalAction = internalActionGeneric;
|
|
|
7599
7625
|
* @returns The wrapped endpoint function. Route a URL path to this function in \`convex/http.js\`.
|
|
7600
7626
|
*/
|
|
7601
7627
|
export const httpAction = httpActionGeneric;
|
|
7628
|
+
|
|
7629
|
+
/**
|
|
7630
|
+
* Define a table in this Convex app's schema.
|
|
7631
|
+
*/
|
|
7632
|
+
export { defineTable, defineSchema };
|
|
7602
7633
|
`;
|
|
7603
7634
|
await fs9.writeFile(path12.join(generatedDir, "server.js"), content, "utf8");
|
|
7604
7635
|
}
|
|
@@ -7735,8 +7766,59 @@ async function generateApiJs(generatedDir) {
|
|
|
7735
7766
|
* @module
|
|
7736
7767
|
*/
|
|
7737
7768
|
|
|
7738
|
-
|
|
7739
|
-
|
|
7769
|
+
const functionName = Symbol.for("functionName");
|
|
7770
|
+
const toReferencePath = Symbol.for("toReferencePath");
|
|
7771
|
+
|
|
7772
|
+
function createApi(pathParts = []) {
|
|
7773
|
+
return new Proxy(
|
|
7774
|
+
{},
|
|
7775
|
+
{
|
|
7776
|
+
get(_target, prop) {
|
|
7777
|
+
if (typeof prop === "string") {
|
|
7778
|
+
return createApi([...pathParts, prop]);
|
|
7779
|
+
}
|
|
7780
|
+
if (prop === functionName) {
|
|
7781
|
+
if (pathParts.length < 2) {
|
|
7782
|
+
const found = ["api", ...pathParts].join(".");
|
|
7783
|
+
throw new Error(
|
|
7784
|
+
"API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`" + found + "\`",
|
|
7785
|
+
);
|
|
7786
|
+
}
|
|
7787
|
+
const modulePath = pathParts.slice(0, -1).join("/");
|
|
7788
|
+
const exportName = pathParts[pathParts.length - 1];
|
|
7789
|
+
return exportName === "default" ? modulePath : modulePath + ":" + exportName;
|
|
7790
|
+
}
|
|
7791
|
+
if (prop === Symbol.toStringTag) {
|
|
7792
|
+
return "FunctionReference";
|
|
7793
|
+
}
|
|
7794
|
+
return undefined;
|
|
7795
|
+
},
|
|
7796
|
+
},
|
|
7797
|
+
);
|
|
7798
|
+
}
|
|
7799
|
+
|
|
7800
|
+
function createComponents(pathParts = []) {
|
|
7801
|
+
return new Proxy(
|
|
7802
|
+
{},
|
|
7803
|
+
{
|
|
7804
|
+
get(_target, prop) {
|
|
7805
|
+
if (typeof prop === "string") {
|
|
7806
|
+
return createComponents([...pathParts, prop]);
|
|
7807
|
+
}
|
|
7808
|
+
if (prop === toReferencePath) {
|
|
7809
|
+
if (pathParts.length < 1) {
|
|
7810
|
+
const found = ["components", ...pathParts].join(".");
|
|
7811
|
+
throw new Error(
|
|
7812
|
+
"API path is expected to be of the form \`components.childComponent.functionName\`. Found: \`" + found + "\`",
|
|
7813
|
+
);
|
|
7814
|
+
}
|
|
7815
|
+
return "_reference/childComponent/" + pathParts.join("/");
|
|
7816
|
+
}
|
|
7817
|
+
return undefined;
|
|
7818
|
+
},
|
|
7819
|
+
},
|
|
7820
|
+
);
|
|
7821
|
+
}
|
|
7740
7822
|
|
|
7741
7823
|
/**
|
|
7742
7824
|
* A utility for referencing Convex functions in your app's API.
|
|
@@ -7746,9 +7828,9 @@ import { componentsGeneric } from "convex/server";
|
|
|
7746
7828
|
* const myFunctionReference = api.myModule.myFunction;
|
|
7747
7829
|
* \`\`\`
|
|
7748
7830
|
*/
|
|
7749
|
-
export const api =
|
|
7750
|
-
export const internal =
|
|
7751
|
-
export const components =
|
|
7831
|
+
export const api = createApi();
|
|
7832
|
+
export const internal = createApi();
|
|
7833
|
+
export const components = createComponents();
|
|
7752
7834
|
`;
|
|
7753
7835
|
await fs9.writeFile(path12.join(generatedDir, "api.js"), content, "utf8");
|
|
7754
7836
|
}
|
|
@@ -8297,6 +8379,8 @@ import {
|
|
|
8297
8379
|
} from "convex/server";
|
|
8298
8380
|
import type { DataModel } from "./dataModel.js";
|
|
8299
8381
|
|
|
8382
|
+
export { defineSchema, defineTable } from "convex/server";
|
|
8383
|
+
|
|
8300
8384
|
export declare const query: QueryBuilder<DataModel, "public">;
|
|
8301
8385
|
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
8302
8386
|
export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
@@ -8332,15 +8416,84 @@ import {
|
|
|
8332
8416
|
internalActionGeneric,
|
|
8333
8417
|
internalMutationGeneric,
|
|
8334
8418
|
internalQueryGeneric,
|
|
8419
|
+
defineSchema,
|
|
8420
|
+
defineTable,
|
|
8335
8421
|
} from "convex/server";
|
|
8336
8422
|
|
|
8423
|
+
/**
|
|
8424
|
+
* Define a query in this Convex app's public API.
|
|
8425
|
+
*
|
|
8426
|
+
* This function will be allowed to read your Convex database and will be accessible from the client.
|
|
8427
|
+
*
|
|
8428
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
8429
|
+
* @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
|
|
8430
|
+
*/
|
|
8337
8431
|
export const query = queryGeneric;
|
|
8432
|
+
|
|
8433
|
+
/**
|
|
8434
|
+
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
8435
|
+
*
|
|
8436
|
+
* This function will be allowed to read from your Convex database. It will not be accessible from the client.
|
|
8437
|
+
*
|
|
8438
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
8439
|
+
* @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
|
|
8440
|
+
*/
|
|
8338
8441
|
export const internalQuery = internalQueryGeneric;
|
|
8442
|
+
|
|
8443
|
+
/**
|
|
8444
|
+
* Define a mutation in this Convex app's public API.
|
|
8445
|
+
*
|
|
8446
|
+
* This function will be allowed to modify your Convex database and will be accessible from the client.
|
|
8447
|
+
*
|
|
8448
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
8449
|
+
* @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
|
|
8450
|
+
*/
|
|
8339
8451
|
export const mutation = mutationGeneric;
|
|
8452
|
+
|
|
8453
|
+
/**
|
|
8454
|
+
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
8455
|
+
*
|
|
8456
|
+
* This function will be allowed to modify your Convex database. It will not be accessible from the client.
|
|
8457
|
+
*
|
|
8458
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
8459
|
+
* @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
|
|
8460
|
+
*/
|
|
8340
8461
|
export const internalMutation = internalMutationGeneric;
|
|
8462
|
+
|
|
8463
|
+
/**
|
|
8464
|
+
* Define an action in this Convex app's public API.
|
|
8465
|
+
*
|
|
8466
|
+
* An action is a function which can execute any JavaScript code, including non-deterministic
|
|
8467
|
+
* code and code with side-effects, like calling third-party services.
|
|
8468
|
+
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
|
|
8469
|
+
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
|
|
8470
|
+
*
|
|
8471
|
+
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
8472
|
+
* @returns The wrapped action. Include this as an \`export\` to name it and make it accessible.
|
|
8473
|
+
*/
|
|
8341
8474
|
export const action = actionGeneric;
|
|
8475
|
+
|
|
8476
|
+
/**
|
|
8477
|
+
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
8478
|
+
*
|
|
8479
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
8480
|
+
* @returns The wrapped function. Include this as an \`export\` to name it and make it accessible.
|
|
8481
|
+
*/
|
|
8342
8482
|
export const internalAction = internalActionGeneric;
|
|
8483
|
+
|
|
8484
|
+
/**
|
|
8485
|
+
* Define a Convex HTTP action.
|
|
8486
|
+
*
|
|
8487
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument, and a \`Request\` object
|
|
8488
|
+
* as its second.
|
|
8489
|
+
* @returns The wrapped endpoint function. Route a URL path to this function in \`convex/http.js\`.
|
|
8490
|
+
*/
|
|
8343
8491
|
export const httpAction = httpActionGeneric;
|
|
8492
|
+
|
|
8493
|
+
/**
|
|
8494
|
+
* Define a table in this Convex app's schema.
|
|
8495
|
+
*/
|
|
8496
|
+
export { defineTable, defineSchema };
|
|
8344
8497
|
`;
|
|
8345
8498
|
await fs10.writeFile(path13.join(generatedDir, "server.js"), content, "utf8");
|
|
8346
8499
|
}
|
|
@@ -8383,7 +8536,59 @@ async function generateApiJs2(generatedDir) {
|
|
|
8383
8536
|
* @module
|
|
8384
8537
|
*/
|
|
8385
8538
|
|
|
8386
|
-
|
|
8539
|
+
const functionName = Symbol.for("functionName");
|
|
8540
|
+
const toReferencePath = Symbol.for("toReferencePath");
|
|
8541
|
+
|
|
8542
|
+
function createApi(pathParts = []) {
|
|
8543
|
+
return new Proxy(
|
|
8544
|
+
{},
|
|
8545
|
+
{
|
|
8546
|
+
get(_target, prop) {
|
|
8547
|
+
if (typeof prop === "string") {
|
|
8548
|
+
return createApi([...pathParts, prop]);
|
|
8549
|
+
}
|
|
8550
|
+
if (prop === functionName) {
|
|
8551
|
+
if (pathParts.length < 2) {
|
|
8552
|
+
const found = ["api", ...pathParts].join(".");
|
|
8553
|
+
throw new Error(
|
|
8554
|
+
"API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`" + found + "\`",
|
|
8555
|
+
);
|
|
8556
|
+
}
|
|
8557
|
+
const modulePath = pathParts.slice(0, -1).join("/");
|
|
8558
|
+
const exportName = pathParts[pathParts.length - 1];
|
|
8559
|
+
return exportName === "default" ? modulePath : modulePath + ":" + exportName;
|
|
8560
|
+
}
|
|
8561
|
+
if (prop === Symbol.toStringTag) {
|
|
8562
|
+
return "FunctionReference";
|
|
8563
|
+
}
|
|
8564
|
+
return undefined;
|
|
8565
|
+
},
|
|
8566
|
+
},
|
|
8567
|
+
);
|
|
8568
|
+
}
|
|
8569
|
+
|
|
8570
|
+
function createComponents(pathParts = []) {
|
|
8571
|
+
return new Proxy(
|
|
8572
|
+
{},
|
|
8573
|
+
{
|
|
8574
|
+
get(_target, prop) {
|
|
8575
|
+
if (typeof prop === "string") {
|
|
8576
|
+
return createComponents([...pathParts, prop]);
|
|
8577
|
+
}
|
|
8578
|
+
if (prop === toReferencePath) {
|
|
8579
|
+
if (pathParts.length < 1) {
|
|
8580
|
+
const found = ["components", ...pathParts].join(".");
|
|
8581
|
+
throw new Error(
|
|
8582
|
+
"API path is expected to be of the form \`components.childComponent.functionName\`. Found: \`" + found + "\`",
|
|
8583
|
+
);
|
|
8584
|
+
}
|
|
8585
|
+
return "_reference/childComponent/" + pathParts.join("/");
|
|
8586
|
+
}
|
|
8587
|
+
return undefined;
|
|
8588
|
+
},
|
|
8589
|
+
},
|
|
8590
|
+
);
|
|
8591
|
+
}
|
|
8387
8592
|
|
|
8388
8593
|
/**
|
|
8389
8594
|
* A utility for referencing Convex functions in your app's API.
|
|
@@ -8393,9 +8598,9 @@ import { anyApi, componentsGeneric } from "convex/server";
|
|
|
8393
8598
|
* const myFunctionReference = api.myModule.myFunction;
|
|
8394
8599
|
* \`\`\`
|
|
8395
8600
|
*/
|
|
8396
|
-
export const api =
|
|
8397
|
-
export const internal =
|
|
8398
|
-
export const components =
|
|
8601
|
+
export const api = createApi();
|
|
8602
|
+
export const internal = createApi();
|
|
8603
|
+
export const components = createComponents();
|
|
8399
8604
|
`;
|
|
8400
8605
|
await fs10.writeFile(path13.join(generatedDir, "api.js"), content, "utf8");
|
|
8401
8606
|
}
|
|
@@ -10098,7 +10303,7 @@ function setupAuthEnvironment(keys, siteUrl, options = {}) {
|
|
|
10098
10303
|
setEnv("AUTH_SKIP_VERIFICATION", "true");
|
|
10099
10304
|
}
|
|
10100
10305
|
// package.json
|
|
10101
|
-
var version = "0.0.1-alpha.
|
|
10306
|
+
var version = "0.0.1-alpha.8";
|
|
10102
10307
|
|
|
10103
10308
|
// src/cli/cli.ts
|
|
10104
10309
|
var WATCH_IGNORE_PATTERNS = [
|
|
@@ -10284,7 +10489,7 @@ async function ensureConvexDependencyReady(projectRoot, commandName) {
|
|
|
10284
10489
|
}
|
|
10285
10490
|
if (!hasConvexDependency(packageJson)) {
|
|
10286
10491
|
console.error(import_picocolors9.default.red("✗ Missing dependency: convex"));
|
|
10287
|
-
console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated
|
|
10492
|
+
console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated types depend on `convex/server`."));
|
|
10288
10493
|
console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
|
|
10289
10494
|
process.exit(1);
|
|
10290
10495
|
}
|
|
@@ -10947,17 +11152,15 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
|
|
|
10947
11152
|
throw error;
|
|
10948
11153
|
}
|
|
10949
11154
|
};
|
|
10950
|
-
const
|
|
11155
|
+
const reloadServer = async (reason) => {
|
|
10951
11156
|
if (isRestarting)
|
|
10952
11157
|
return;
|
|
10953
11158
|
isRestarting = true;
|
|
10954
11159
|
try {
|
|
10955
|
-
console.log(import_picocolors9.default.
|
|
10956
|
-
⟳ ${reason}`));
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
}
|
|
10960
|
-
await startServer();
|
|
11160
|
+
console.log(import_picocolors9.default.dim(`
|
|
11161
|
+
⟳ ${reason}`));
|
|
11162
|
+
await server.reload();
|
|
11163
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
10961
11164
|
} catch (error) {
|
|
10962
11165
|
console.error(import_picocolors9.default.red("✗ Failed to reload server:"), error.message);
|
|
10963
11166
|
} finally {
|
|
@@ -10981,7 +11184,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
|
|
|
10981
11184
|
try {
|
|
10982
11185
|
await generateTypes(cwd, { silent: true });
|
|
10983
11186
|
} catch {}
|
|
10984
|
-
|
|
11187
|
+
reloadServer(`File changed: ${relPath}`);
|
|
10985
11188
|
}, 300);
|
|
10986
11189
|
};
|
|
10987
11190
|
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
@@ -11088,20 +11291,136 @@ process.on("SIGTERM", async () => {
|
|
|
11088
11291
|
`;
|
|
11089
11292
|
await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
|
|
11090
11293
|
const bunArgs = [tempScriptPath];
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11294
|
+
let watcher;
|
|
11295
|
+
let bunProcess;
|
|
11296
|
+
let reloadTimer;
|
|
11297
|
+
let isRestarting = false;
|
|
11298
|
+
let isShuttingDown = false;
|
|
11299
|
+
const stopBunProcess = async () => {
|
|
11300
|
+
const activeProcess = bunProcess;
|
|
11301
|
+
if (!activeProcess || activeProcess.exitCode !== null) {
|
|
11302
|
+
return;
|
|
11303
|
+
}
|
|
11304
|
+
await new Promise((resolve3) => {
|
|
11305
|
+
let settled = false;
|
|
11306
|
+
let forceKillTimer;
|
|
11307
|
+
const finish = () => {
|
|
11308
|
+
if (settled) {
|
|
11309
|
+
return;
|
|
11310
|
+
}
|
|
11311
|
+
settled = true;
|
|
11312
|
+
if (forceKillTimer) {
|
|
11313
|
+
clearTimeout(forceKillTimer);
|
|
11314
|
+
forceKillTimer = undefined;
|
|
11315
|
+
}
|
|
11316
|
+
activeProcess.off("exit", onExit);
|
|
11317
|
+
resolve3();
|
|
11318
|
+
};
|
|
11319
|
+
const onExit = () => finish();
|
|
11320
|
+
activeProcess.once("exit", onExit);
|
|
11321
|
+
try {
|
|
11322
|
+
activeProcess.kill("SIGTERM");
|
|
11323
|
+
} catch {
|
|
11324
|
+
finish();
|
|
11325
|
+
return;
|
|
11326
|
+
}
|
|
11327
|
+
forceKillTimer = setTimeout(() => {
|
|
11328
|
+
if (settled) {
|
|
11329
|
+
return;
|
|
11330
|
+
}
|
|
11331
|
+
try {
|
|
11332
|
+
activeProcess.kill("SIGKILL");
|
|
11333
|
+
} catch {
|
|
11334
|
+
finish();
|
|
11335
|
+
}
|
|
11336
|
+
}, 2000);
|
|
11337
|
+
});
|
|
11338
|
+
};
|
|
11339
|
+
const cleanup = async () => {
|
|
11340
|
+
if (reloadTimer) {
|
|
11341
|
+
clearTimeout(reloadTimer);
|
|
11342
|
+
reloadTimer = undefined;
|
|
11343
|
+
}
|
|
11344
|
+
if (watcher) {
|
|
11345
|
+
await watcher.close();
|
|
11346
|
+
watcher = undefined;
|
|
11347
|
+
}
|
|
11348
|
+
await stopBunProcess();
|
|
11349
|
+
await fs12.unlink(tempScriptPath).catch(() => {});
|
|
11350
|
+
};
|
|
11351
|
+
const spawnBunProcess = () => {
|
|
11352
|
+
const child = spawn2("bun", bunArgs, {
|
|
11353
|
+
cwd,
|
|
11354
|
+
stdio: "inherit"
|
|
11355
|
+
});
|
|
11356
|
+
child.on("exit", (code) => {
|
|
11357
|
+
if (isRestarting || isShuttingDown) {
|
|
11358
|
+
return;
|
|
11359
|
+
}
|
|
11360
|
+
cleanup().catch(() => {}).finally(() => {
|
|
11361
|
+
process.exit(code ?? 0);
|
|
11362
|
+
});
|
|
11363
|
+
});
|
|
11364
|
+
return child;
|
|
11365
|
+
};
|
|
11366
|
+
const reloadServerViaHttp = async (reason) => {
|
|
11367
|
+
if (isRestarting || isShuttingDown) {
|
|
11368
|
+
return;
|
|
11369
|
+
}
|
|
11370
|
+
isRestarting = true;
|
|
11371
|
+
try {
|
|
11372
|
+
console.log(import_picocolors9.default.dim(`
|
|
11373
|
+
⟳ ${reason}`));
|
|
11374
|
+
const response = await fetch(`http://127.0.0.1:${port}/_dev/reload`, {
|
|
11375
|
+
method: "POST",
|
|
11376
|
+
signal: AbortSignal.timeout(5000)
|
|
11377
|
+
});
|
|
11378
|
+
if (response.ok) {
|
|
11379
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11380
|
+
} else {
|
|
11381
|
+
throw new Error(`HTTP ${response.status}`);
|
|
11382
|
+
}
|
|
11383
|
+
} catch (error) {
|
|
11384
|
+
console.warn(import_picocolors9.default.dim(` HTTP reload failed (${error.message}), restarting process...`));
|
|
11385
|
+
await stopBunProcess();
|
|
11386
|
+
bunProcess = spawnBunProcess();
|
|
11387
|
+
} finally {
|
|
11388
|
+
isRestarting = false;
|
|
11389
|
+
}
|
|
11390
|
+
};
|
|
11391
|
+
bunProcess = spawnBunProcess();
|
|
11392
|
+
watcher = esm_default.watch(convexDir, {
|
|
11393
|
+
ignoreInitial: true,
|
|
11394
|
+
ignored: WATCH_IGNORE_PATTERNS,
|
|
11395
|
+
persistent: true
|
|
11104
11396
|
});
|
|
11397
|
+
const scheduleReload = (_event, filePath) => {
|
|
11398
|
+
if (reloadTimer) {
|
|
11399
|
+
clearTimeout(reloadTimer);
|
|
11400
|
+
}
|
|
11401
|
+
reloadTimer = setTimeout(async () => {
|
|
11402
|
+
reloadTimer = undefined;
|
|
11403
|
+
const relPath = path15.relative(cwd, filePath);
|
|
11404
|
+
try {
|
|
11405
|
+
await generateTypes(cwd, { silent: true });
|
|
11406
|
+
} catch {}
|
|
11407
|
+
await reloadServerViaHttp(`File changed: ${relPath}`);
|
|
11408
|
+
}, 300);
|
|
11409
|
+
};
|
|
11410
|
+
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
11411
|
+
const shutdown = async () => {
|
|
11412
|
+
if (isShuttingDown) {
|
|
11413
|
+
return;
|
|
11414
|
+
}
|
|
11415
|
+
isShuttingDown = true;
|
|
11416
|
+
console.log(import_picocolors9.default.cyan(`
|
|
11417
|
+
|
|
11418
|
+
\uD83C\uDF0A Shutting down Concave dev server...`));
|
|
11419
|
+
await cleanup();
|
|
11420
|
+
process.exit(0);
|
|
11421
|
+
};
|
|
11422
|
+
process.on("SIGINT", shutdown);
|
|
11423
|
+
process.on("SIGTERM", shutdown);
|
|
11105
11424
|
}
|
|
11106
11425
|
async function ensureNodeSqliteReady() {
|
|
11107
11426
|
const hasFlag = process.execArgv.includes("--experimental-sqlite");
|
|
@@ -11254,17 +11573,15 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
|
|
|
11254
11573
|
throw error;
|
|
11255
11574
|
}
|
|
11256
11575
|
};
|
|
11257
|
-
const
|
|
11576
|
+
const reloadServer = async (reason) => {
|
|
11258
11577
|
if (isRestarting)
|
|
11259
11578
|
return;
|
|
11260
11579
|
isRestarting = true;
|
|
11261
11580
|
try {
|
|
11262
|
-
console.log(import_picocolors9.default.
|
|
11263
|
-
⟳ ${reason}`));
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
}
|
|
11267
|
-
await startServer();
|
|
11581
|
+
console.log(import_picocolors9.default.dim(`
|
|
11582
|
+
⟳ ${reason}`));
|
|
11583
|
+
await server.reload();
|
|
11584
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11268
11585
|
} catch (error) {
|
|
11269
11586
|
console.error(import_picocolors9.default.red("✗ Failed to reload server:"), error.message);
|
|
11270
11587
|
} finally {
|
|
@@ -11288,7 +11605,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
|
|
|
11288
11605
|
try {
|
|
11289
11606
|
await generateTypes(cwd, { silent: true });
|
|
11290
11607
|
} catch {}
|
|
11291
|
-
|
|
11608
|
+
reloadServer(`File changed: ${relPath}`);
|
|
11292
11609
|
}, 300);
|
|
11293
11610
|
};
|
|
11294
11611
|
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
@@ -11404,20 +11721,136 @@ process.on("SIGTERM", async () => {
|
|
|
11404
11721
|
await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
|
|
11405
11722
|
const nodeArgs = ["--experimental-sqlite", "--import", tsxLoaderPath, tempScriptPath];
|
|
11406
11723
|
const executable = detectHostRuntime() === "node" ? process.execPath : "node";
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11724
|
+
let watcher;
|
|
11725
|
+
let nodeProcess;
|
|
11726
|
+
let reloadTimer;
|
|
11727
|
+
let isRestarting = false;
|
|
11728
|
+
let isShuttingDown = false;
|
|
11729
|
+
const stopNodeProcess = async () => {
|
|
11730
|
+
const activeProcess = nodeProcess;
|
|
11731
|
+
if (!activeProcess || activeProcess.exitCode !== null) {
|
|
11732
|
+
return;
|
|
11733
|
+
}
|
|
11734
|
+
await new Promise((resolve3) => {
|
|
11735
|
+
let settled = false;
|
|
11736
|
+
let forceKillTimer;
|
|
11737
|
+
const finish = () => {
|
|
11738
|
+
if (settled) {
|
|
11739
|
+
return;
|
|
11740
|
+
}
|
|
11741
|
+
settled = true;
|
|
11742
|
+
if (forceKillTimer) {
|
|
11743
|
+
clearTimeout(forceKillTimer);
|
|
11744
|
+
forceKillTimer = undefined;
|
|
11745
|
+
}
|
|
11746
|
+
activeProcess.off("exit", onExit);
|
|
11747
|
+
resolve3();
|
|
11748
|
+
};
|
|
11749
|
+
const onExit = () => finish();
|
|
11750
|
+
activeProcess.once("exit", onExit);
|
|
11751
|
+
try {
|
|
11752
|
+
activeProcess.kill("SIGTERM");
|
|
11753
|
+
} catch {
|
|
11754
|
+
finish();
|
|
11755
|
+
return;
|
|
11756
|
+
}
|
|
11757
|
+
forceKillTimer = setTimeout(() => {
|
|
11758
|
+
if (settled) {
|
|
11759
|
+
return;
|
|
11760
|
+
}
|
|
11761
|
+
try {
|
|
11762
|
+
activeProcess.kill("SIGKILL");
|
|
11763
|
+
} catch {
|
|
11764
|
+
finish();
|
|
11765
|
+
}
|
|
11766
|
+
}, 2000);
|
|
11767
|
+
});
|
|
11768
|
+
};
|
|
11769
|
+
const cleanup = async () => {
|
|
11770
|
+
if (reloadTimer) {
|
|
11771
|
+
clearTimeout(reloadTimer);
|
|
11772
|
+
reloadTimer = undefined;
|
|
11773
|
+
}
|
|
11774
|
+
if (watcher) {
|
|
11775
|
+
await watcher.close();
|
|
11776
|
+
watcher = undefined;
|
|
11777
|
+
}
|
|
11778
|
+
await stopNodeProcess();
|
|
11779
|
+
await fs12.unlink(tempScriptPath).catch(() => {});
|
|
11780
|
+
};
|
|
11781
|
+
const spawnNodeProcess = () => {
|
|
11782
|
+
const child = spawn2(executable, nodeArgs, {
|
|
11783
|
+
cwd,
|
|
11784
|
+
stdio: "inherit"
|
|
11785
|
+
});
|
|
11786
|
+
child.on("exit", (code) => {
|
|
11787
|
+
if (isRestarting || isShuttingDown) {
|
|
11788
|
+
return;
|
|
11789
|
+
}
|
|
11790
|
+
cleanup().catch(() => {}).finally(() => {
|
|
11791
|
+
process.exit(code ?? 0);
|
|
11792
|
+
});
|
|
11793
|
+
});
|
|
11794
|
+
return child;
|
|
11795
|
+
};
|
|
11796
|
+
const reloadServerViaHttp = async (reason) => {
|
|
11797
|
+
if (isRestarting || isShuttingDown) {
|
|
11798
|
+
return;
|
|
11799
|
+
}
|
|
11800
|
+
isRestarting = true;
|
|
11801
|
+
try {
|
|
11802
|
+
console.log(import_picocolors9.default.dim(`
|
|
11803
|
+
⟳ ${reason}`));
|
|
11804
|
+
const response = await fetch(`http://127.0.0.1:${port}/_dev/reload`, {
|
|
11805
|
+
method: "POST",
|
|
11806
|
+
signal: AbortSignal.timeout(5000)
|
|
11807
|
+
});
|
|
11808
|
+
if (response.ok) {
|
|
11809
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11810
|
+
} else {
|
|
11811
|
+
throw new Error(`HTTP ${response.status}`);
|
|
11812
|
+
}
|
|
11813
|
+
} catch (error) {
|
|
11814
|
+
console.warn(import_picocolors9.default.dim(` HTTP reload failed (${error.message}), restarting process...`));
|
|
11815
|
+
await stopNodeProcess();
|
|
11816
|
+
nodeProcess = spawnNodeProcess();
|
|
11817
|
+
} finally {
|
|
11818
|
+
isRestarting = false;
|
|
11819
|
+
}
|
|
11820
|
+
};
|
|
11821
|
+
nodeProcess = spawnNodeProcess();
|
|
11822
|
+
watcher = esm_default.watch(convexDir, {
|
|
11823
|
+
ignoreInitial: true,
|
|
11824
|
+
ignored: WATCH_IGNORE_PATTERNS,
|
|
11825
|
+
persistent: true
|
|
11420
11826
|
});
|
|
11827
|
+
const scheduleReload = (_event, filePath) => {
|
|
11828
|
+
if (reloadTimer) {
|
|
11829
|
+
clearTimeout(reloadTimer);
|
|
11830
|
+
}
|
|
11831
|
+
reloadTimer = setTimeout(async () => {
|
|
11832
|
+
reloadTimer = undefined;
|
|
11833
|
+
const relPath = path15.relative(cwd, filePath);
|
|
11834
|
+
try {
|
|
11835
|
+
await generateTypes(cwd, { silent: true });
|
|
11836
|
+
} catch {}
|
|
11837
|
+
await reloadServerViaHttp(`File changed: ${relPath}`);
|
|
11838
|
+
}, 300);
|
|
11839
|
+
};
|
|
11840
|
+
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
11841
|
+
const shutdown = async () => {
|
|
11842
|
+
if (isShuttingDown) {
|
|
11843
|
+
return;
|
|
11844
|
+
}
|
|
11845
|
+
isShuttingDown = true;
|
|
11846
|
+
console.log(import_picocolors9.default.cyan(`
|
|
11847
|
+
|
|
11848
|
+
\uD83C\uDF0A Shutting down Concave dev server...`));
|
|
11849
|
+
await cleanup();
|
|
11850
|
+
process.exit(0);
|
|
11851
|
+
};
|
|
11852
|
+
process.on("SIGINT", shutdown);
|
|
11853
|
+
process.on("SIGTERM", shutdown);
|
|
11421
11854
|
}
|
|
11422
11855
|
async function ensureWranglerConfig(cwd) {
|
|
11423
11856
|
const userConfigs = [
|