devflare 1.0.0-next.4 → 1.0.0-next.6
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/LLM.md +7 -2
- package/README.md +4 -2
- package/dist/browser.d.ts +50 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +149 -0
- package/dist/{dev-pa8dhm20.js → dev-7agn9g5s.js} +319 -63
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/index-62b3gt2g.js +12 -0
- package/dist/index-9ats0s83.js +70 -0
- package/dist/{index-pf5s73n9.js → index-ccrh4w3t.js} +1 -281
- package/dist/index-k7r18na8.js +0 -0
- package/dist/{index-m2q41jwa.js → index-n3np2d6t.js} +1 -1
- package/dist/index-npc1c8jx.js +44 -0
- package/dist/index-p7g30wd2.js +281 -0
- package/dist/{index-ep3445yc.js → index-rprrn24p.js} +25 -97
- package/dist/{index-07q6yxyc.js → index-v8vvsn9x.js} +1 -0
- package/dist/index.js +25 -26
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +73 -0
- package/dist/sveltekit/index.js +5 -3
- package/dist/test/index.js +10 -5
- package/dist/{types-5nyrz1sz.js → types-vss6vrz7.js} +5 -4
- package/package.json +3 -2
- package/dist/{build-mnf6v8gd.js → build-nz5yrj7f.js} +3 -3
- package/dist/{deploy-nhceck39.js → deploy-a5pcxd5w.js} +3 -3
- package/dist/{doctor-fmgb3d28.js → doctor-v7jy4s3r.js} +3 -3
|
@@ -21,7 +21,7 @@ import { createConsola } from "consola";
|
|
|
21
21
|
import { resolve as resolve3 } from "pathe";
|
|
22
22
|
|
|
23
23
|
// src/dev-server/server.ts
|
|
24
|
-
import { resolve as resolve2 } from "pathe";
|
|
24
|
+
import { dirname as dirname2, resolve as resolve2 } from "pathe";
|
|
25
25
|
|
|
26
26
|
// src/bundler/do-bundler.ts
|
|
27
27
|
import { resolve, dirname, relative } from "pathe";
|
|
@@ -1093,8 +1093,60 @@ async function checkRemoteBindingRequirements(config) {
|
|
|
1093
1093
|
}
|
|
1094
1094
|
|
|
1095
1095
|
// src/dev-server/server.ts
|
|
1096
|
-
|
|
1096
|
+
var DEFAULT_FETCH_ENTRY_FILES = [
|
|
1097
|
+
"src/fetch.ts",
|
|
1098
|
+
"src/fetch.js",
|
|
1099
|
+
"src/fetch.mts",
|
|
1100
|
+
"src/fetch.mjs"
|
|
1101
|
+
];
|
|
1102
|
+
var INTERNAL_APP_SERVICE_BINDING = "__DEVFLARE_APP";
|
|
1103
|
+
async function resolveMainWorkerScriptPath(cwd, config) {
|
|
1104
|
+
if (config.files?.fetch === false) {
|
|
1105
|
+
return null;
|
|
1106
|
+
}
|
|
1107
|
+
const fs = await import("node:fs/promises");
|
|
1108
|
+
const candidates = new Set;
|
|
1109
|
+
if (typeof config.files?.fetch === "string" && config.files.fetch) {
|
|
1110
|
+
candidates.add(config.files.fetch);
|
|
1111
|
+
}
|
|
1112
|
+
for (const defaultEntry of DEFAULT_FETCH_ENTRY_FILES) {
|
|
1113
|
+
candidates.add(defaultEntry);
|
|
1114
|
+
}
|
|
1115
|
+
for (const candidate of candidates) {
|
|
1116
|
+
const absolutePath = resolve2(cwd, candidate);
|
|
1117
|
+
try {
|
|
1118
|
+
await fs.access(absolutePath);
|
|
1119
|
+
return absolutePath;
|
|
1120
|
+
} catch {
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return null;
|
|
1125
|
+
}
|
|
1126
|
+
function collectWorkerWatchRoots(cwd, config, mainWorkerScriptPath) {
|
|
1127
|
+
const roots = new Set;
|
|
1128
|
+
const addFileParent = (filePath) => {
|
|
1129
|
+
if (typeof filePath !== "string" || !filePath) {
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
roots.add(dirname2(resolve2(cwd, filePath)));
|
|
1133
|
+
};
|
|
1134
|
+
if (mainWorkerScriptPath) {
|
|
1135
|
+
roots.add(dirname2(mainWorkerScriptPath));
|
|
1136
|
+
}
|
|
1137
|
+
addFileParent(config.files?.fetch);
|
|
1138
|
+
addFileParent(config.files?.queue);
|
|
1139
|
+
addFileParent(config.files?.scheduled);
|
|
1140
|
+
addFileParent(config.files?.email);
|
|
1141
|
+
addFileParent(config.files?.transport);
|
|
1142
|
+
if (config.files?.routes && typeof config.files.routes === "object") {
|
|
1143
|
+
roots.add(resolve2(cwd, config.files.routes.dir));
|
|
1144
|
+
}
|
|
1145
|
+
return [...roots];
|
|
1146
|
+
}
|
|
1147
|
+
function getGatewayScript(wsRoutes = [], debug = false, appServiceBindingName = null) {
|
|
1097
1148
|
const wsRoutesJson = JSON.stringify(wsRoutes);
|
|
1149
|
+
const appServiceBindingJson = JSON.stringify(appServiceBindingName);
|
|
1098
1150
|
return `
|
|
1099
1151
|
// Bridge Gateway Worker — RPC Handler
|
|
1100
1152
|
// Handles all binding operations via WebSocket RPC
|
|
@@ -1109,6 +1161,7 @@ const incomingStreams = new Map()
|
|
|
1109
1161
|
|
|
1110
1162
|
// WebSocket routes configuration (injected at build time)
|
|
1111
1163
|
const WS_ROUTES = ${wsRoutesJson}
|
|
1164
|
+
const APP_SERVICE_BINDING = ${appServiceBindingJson}
|
|
1112
1165
|
|
|
1113
1166
|
export default {
|
|
1114
1167
|
async fetch(request, env, ctx) {
|
|
@@ -1149,6 +1202,13 @@ export default {
|
|
|
1149
1202
|
}), { headers: { 'Content-Type': 'application/json' } })
|
|
1150
1203
|
}
|
|
1151
1204
|
|
|
1205
|
+
if (APP_SERVICE_BINDING) {
|
|
1206
|
+
const appWorker = env[APP_SERVICE_BINDING]
|
|
1207
|
+
if (appWorker && typeof appWorker.fetch === 'function') {
|
|
1208
|
+
return appWorker.fetch(request)
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1152
1212
|
return new Response('Devflare Bridge Gateway', { status: 200 })
|
|
1153
1213
|
}
|
|
1154
1214
|
}
|
|
@@ -1676,15 +1736,64 @@ function createDevServer(options) {
|
|
|
1676
1736
|
} = options;
|
|
1677
1737
|
let miniflare = null;
|
|
1678
1738
|
let doBundler = null;
|
|
1739
|
+
let workerSourceWatcher = null;
|
|
1679
1740
|
let viteProcess = null;
|
|
1680
1741
|
let config = null;
|
|
1681
1742
|
let browserShim = null;
|
|
1682
1743
|
let browserShimPort = 8788;
|
|
1744
|
+
let mainWorkerScriptPath = null;
|
|
1745
|
+
let bundledMainWorkerScriptPath = null;
|
|
1746
|
+
let currentDoResult = null;
|
|
1747
|
+
let reloadChain = Promise.resolve();
|
|
1748
|
+
async function bundleMainWorker() {
|
|
1749
|
+
if (!mainWorkerScriptPath) {
|
|
1750
|
+
bundledMainWorkerScriptPath = null;
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
if (typeof Bun === "undefined" || typeof Bun.build !== "function") {
|
|
1754
|
+
throw new Error("Worker-only dev mode requires the Bun runtime for main worker bundling");
|
|
1755
|
+
}
|
|
1756
|
+
const fs = await import("node:fs/promises");
|
|
1757
|
+
const outDir = resolve2(cwd, ".devflare", "worker-bundles");
|
|
1758
|
+
await fs.rm(outDir, { recursive: true, force: true });
|
|
1759
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
1760
|
+
const result = await Bun.build({
|
|
1761
|
+
entrypoints: [mainWorkerScriptPath],
|
|
1762
|
+
outdir: outDir,
|
|
1763
|
+
target: "browser",
|
|
1764
|
+
conditions: ["browser"],
|
|
1765
|
+
format: "esm",
|
|
1766
|
+
minify: false,
|
|
1767
|
+
splitting: false,
|
|
1768
|
+
external: ["cloudflare:workers", "cloudflare:*"]
|
|
1769
|
+
});
|
|
1770
|
+
if (!result.success || result.outputs.length === 0) {
|
|
1771
|
+
const logs = result.logs.map((log) => ("message" in log) ? log.message : String(log)).join(`
|
|
1772
|
+
`);
|
|
1773
|
+
throw new Error(`Failed to bundle main worker:
|
|
1774
|
+
${logs}`);
|
|
1775
|
+
}
|
|
1776
|
+
bundledMainWorkerScriptPath = result.outputs[0].path;
|
|
1777
|
+
logger?.debug(`Bundled main worker → ${bundledMainWorkerScriptPath}`);
|
|
1778
|
+
}
|
|
1683
1779
|
function buildMiniflareConfig(doResult) {
|
|
1684
1780
|
if (!config)
|
|
1685
1781
|
throw new Error("Config not loaded");
|
|
1686
|
-
const
|
|
1782
|
+
const loadedConfig = config;
|
|
1783
|
+
const bindings = loadedConfig.bindings ?? {};
|
|
1687
1784
|
const persistPath = resolve2(cwd, ".devflare/data");
|
|
1785
|
+
const appWorkerName = loadedConfig.name;
|
|
1786
|
+
const shouldRunMainWorker = !enableVite && !!mainWorkerScriptPath;
|
|
1787
|
+
const queueProducers = (() => {
|
|
1788
|
+
if (!bindings.queues?.producers) {
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
const producers = {};
|
|
1792
|
+
for (const [bindingName, queueName] of Object.entries(bindings.queues.producers)) {
|
|
1793
|
+
producers[bindingName] = { queueName };
|
|
1794
|
+
}
|
|
1795
|
+
return producers;
|
|
1796
|
+
})();
|
|
1688
1797
|
const sharedOptions = {
|
|
1689
1798
|
port: miniflarePort,
|
|
1690
1799
|
host: "127.0.0.1",
|
|
@@ -1693,19 +1802,67 @@ function createDevServer(options) {
|
|
|
1693
1802
|
d1Persist: persist ? `${persistPath}/d1` : undefined,
|
|
1694
1803
|
durableObjectsPersist: persist ? `${persistPath}/do` : undefined
|
|
1695
1804
|
};
|
|
1696
|
-
const
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1805
|
+
const createServiceBindings = (extraBindings = {}) => {
|
|
1806
|
+
const serviceBindings = {};
|
|
1807
|
+
if (bindings.services) {
|
|
1808
|
+
for (const [bindingName, serviceConfig] of Object.entries(bindings.services)) {
|
|
1809
|
+
serviceBindings[bindingName] = {
|
|
1810
|
+
name: serviceConfig.service,
|
|
1811
|
+
...serviceConfig.entrypoint && { entrypoint: serviceConfig.entrypoint }
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
for (const [bindingName, target] of Object.entries(extraBindings)) {
|
|
1816
|
+
serviceBindings[bindingName] = target;
|
|
1817
|
+
}
|
|
1818
|
+
return Object.keys(serviceBindings).length > 0 ? serviceBindings : undefined;
|
|
1819
|
+
};
|
|
1820
|
+
const createWorkerConfig = (options2) => {
|
|
1821
|
+
const baseFlags = loadedConfig.compatibilityFlags ?? [];
|
|
1822
|
+
const compatFlags = baseFlags.includes("nodejs_compat") ? baseFlags : [...baseFlags, "nodejs_compat"];
|
|
1823
|
+
const workerConfig = {
|
|
1824
|
+
name: options2.name,
|
|
1825
|
+
modules: true,
|
|
1826
|
+
compatibilityDate: loadedConfig.compatibilityDate,
|
|
1827
|
+
compatibilityFlags: compatFlags,
|
|
1828
|
+
...bindings.kv && { kvNamespaces: bindings.kv },
|
|
1829
|
+
...bindings.r2 && { r2Buckets: bindings.r2 },
|
|
1830
|
+
...bindings.d1 && { d1Databases: bindings.d1 },
|
|
1831
|
+
...loadedConfig.vars && Object.keys(loadedConfig.vars).length > 0 && { bindings: loadedConfig.vars },
|
|
1832
|
+
...queueProducers && { queueProducers }
|
|
1833
|
+
};
|
|
1834
|
+
if (options2.scriptPath) {
|
|
1835
|
+
workerConfig.scriptPath = options2.scriptPath;
|
|
1836
|
+
workerConfig.modulesRoot = cwd;
|
|
1837
|
+
workerConfig.modulesRules = [
|
|
1838
|
+
{ type: "ESModule", include: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.mjs"] },
|
|
1839
|
+
{ type: "CommonJS", include: ["**/*.js", "**/*.cjs"] },
|
|
1840
|
+
{ type: "ESModule", include: ["**/*.jsx"] }
|
|
1841
|
+
];
|
|
1842
|
+
}
|
|
1843
|
+
if (options2.script) {
|
|
1844
|
+
workerConfig.script = options2.script;
|
|
1845
|
+
}
|
|
1846
|
+
if (options2.durableObjects && Object.keys(options2.durableObjects).length > 0) {
|
|
1847
|
+
workerConfig.durableObjects = options2.durableObjects;
|
|
1848
|
+
}
|
|
1849
|
+
if (options2.serviceBindings && Object.keys(options2.serviceBindings).length > 0) {
|
|
1850
|
+
workerConfig.serviceBindings = options2.serviceBindings;
|
|
1851
|
+
}
|
|
1852
|
+
return workerConfig;
|
|
1707
1853
|
};
|
|
1708
|
-
|
|
1854
|
+
const gatewayWorker = createWorkerConfig({
|
|
1855
|
+
name: "gateway",
|
|
1856
|
+
script: getGatewayScript(loadedConfig.wsRoutes, debug, shouldRunMainWorker ? INTERNAL_APP_SERVICE_BINDING : null),
|
|
1857
|
+
serviceBindings: shouldRunMainWorker ? createServiceBindings({
|
|
1858
|
+
[INTERNAL_APP_SERVICE_BINDING]: { name: appWorkerName }
|
|
1859
|
+
}) : createServiceBindings()
|
|
1860
|
+
});
|
|
1861
|
+
gatewayWorker.routes = ["*"];
|
|
1862
|
+
const hasDurableObjectBundles = !!doResult && doResult.bundles.size > 0;
|
|
1863
|
+
const browserBindingName = bindings.browser?.binding;
|
|
1864
|
+
const needsBrowserWorker = Boolean(browserBindingName && (hasDurableObjectBundles || shouldRunMainWorker));
|
|
1865
|
+
if (!shouldRunMainWorker && !hasDurableObjectBundles && !needsBrowserWorker) {
|
|
1709
1866
|
return {
|
|
1710
1867
|
...sharedOptions,
|
|
1711
1868
|
...gatewayWorker
|
|
@@ -1714,56 +1871,62 @@ function createDevServer(options) {
|
|
|
1714
1871
|
const workers = [];
|
|
1715
1872
|
const durableObjects = {};
|
|
1716
1873
|
const browserShimUrl = `http://127.0.0.1:${browserShimPort}`;
|
|
1717
|
-
const browserBindingName = bindings.browser?.binding;
|
|
1718
1874
|
const browserWorkerName = "browser-binding";
|
|
1719
|
-
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
const
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1875
|
+
if (shouldRunMainWorker && mainWorkerScriptPath) {
|
|
1876
|
+
const mainWorkerServiceBindings = createServiceBindings(browserBindingName ? {
|
|
1877
|
+
[browserBindingName]: { name: browserWorkerName }
|
|
1878
|
+
} : {});
|
|
1879
|
+
const mainWorkerConfig = createWorkerConfig({
|
|
1880
|
+
name: appWorkerName,
|
|
1881
|
+
scriptPath: bundledMainWorkerScriptPath ?? mainWorkerScriptPath,
|
|
1882
|
+
serviceBindings: mainWorkerServiceBindings
|
|
1883
|
+
});
|
|
1884
|
+
workers.push(mainWorkerConfig);
|
|
1885
|
+
}
|
|
1886
|
+
if (doResult) {
|
|
1887
|
+
for (const [bindingName, bundlePath] of doResult.bundles) {
|
|
1888
|
+
const className = doResult.classes.get(bindingName);
|
|
1889
|
+
if (!className)
|
|
1890
|
+
continue;
|
|
1891
|
+
const workerName = `do-${bindingName.toLowerCase()}`;
|
|
1892
|
+
const workerConfig = createWorkerConfig({
|
|
1893
|
+
name: workerName,
|
|
1894
|
+
scriptPath: bundlePath,
|
|
1895
|
+
durableObjects: {
|
|
1896
|
+
[bindingName]: className
|
|
1897
|
+
},
|
|
1898
|
+
serviceBindings: createServiceBindings(browserBindingName ? {
|
|
1899
|
+
[browserBindingName]: { name: browserWorkerName }
|
|
1900
|
+
} : {})
|
|
1901
|
+
});
|
|
1902
|
+
if (browserBindingName) {
|
|
1903
|
+
logger?.debug(`DO ${workerName} has browser service binding: ${browserBindingName} → ${browserWorkerName}`);
|
|
1739
1904
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1905
|
+
logger?.debug(`DO ${workerName} config:`, JSON.stringify(workerConfig, null, 2));
|
|
1906
|
+
workers.push(workerConfig);
|
|
1907
|
+
durableObjects[bindingName] = {
|
|
1908
|
+
className,
|
|
1909
|
+
scriptName: workerName
|
|
1745
1910
|
};
|
|
1746
|
-
logger?.debug(`DO ${workerName} has browser service binding: ${browserBindingName} → ${browserWorkerName}`);
|
|
1747
1911
|
}
|
|
1748
|
-
logger?.debug(`DO ${workerName} config:`, JSON.stringify(workerConfig, null, 2));
|
|
1749
|
-
workers.push(workerConfig);
|
|
1750
|
-
durableObjects[bindingName] = {
|
|
1751
|
-
className,
|
|
1752
|
-
scriptName: workerName
|
|
1753
|
-
};
|
|
1754
1912
|
}
|
|
1755
|
-
if (
|
|
1756
|
-
const browserWorker = {
|
|
1913
|
+
if (needsBrowserWorker) {
|
|
1914
|
+
const browserWorker = createWorkerConfig({
|
|
1757
1915
|
name: browserWorkerName,
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
compatibilityDate: config.compatibilityDate,
|
|
1761
|
-
compatibilityFlags: config.compatibilityFlags ?? []
|
|
1762
|
-
};
|
|
1916
|
+
script: getBrowserBindingScript(browserShimUrl, debug)
|
|
1917
|
+
});
|
|
1763
1918
|
workers.push(browserWorker);
|
|
1764
1919
|
logger?.info(`Browser binding worker configured: ${browserBindingName} → ${browserShimUrl}`);
|
|
1765
1920
|
}
|
|
1766
|
-
|
|
1921
|
+
if (Object.keys(durableObjects).length > 0) {
|
|
1922
|
+
gatewayWorker.durableObjects = durableObjects;
|
|
1923
|
+
if (shouldRunMainWorker) {
|
|
1924
|
+
const mainWorker = workers.find((worker) => worker.name === appWorkerName);
|
|
1925
|
+
if (mainWorker) {
|
|
1926
|
+
mainWorker.durableObjects = durableObjects;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1767
1930
|
return {
|
|
1768
1931
|
...sharedOptions,
|
|
1769
1932
|
workers: [gatewayWorker, ...workers]
|
|
@@ -1817,14 +1980,93 @@ function createDevServer(options) {
|
|
|
1817
1980
|
}
|
|
1818
1981
|
}
|
|
1819
1982
|
async function reloadMiniflare(doResult) {
|
|
1820
|
-
|
|
1983
|
+
currentDoResult = doResult;
|
|
1984
|
+
const queuedReload = reloadChain.then(async () => {
|
|
1985
|
+
if (!miniflare)
|
|
1986
|
+
return;
|
|
1987
|
+
const { Log, LogLevel } = await import("miniflare");
|
|
1988
|
+
const mfConfig = buildMiniflareConfig(currentDoResult);
|
|
1989
|
+
mfConfig.log = new Log(LogLevel.DEBUG);
|
|
1990
|
+
logger?.info("Reloading Miniflare...");
|
|
1991
|
+
await miniflare.setOptions(mfConfig);
|
|
1992
|
+
logger?.success("Miniflare reloaded");
|
|
1993
|
+
});
|
|
1994
|
+
reloadChain = queuedReload.catch(() => {});
|
|
1995
|
+
await queuedReload;
|
|
1996
|
+
}
|
|
1997
|
+
async function startWorkerSourceWatcher() {
|
|
1998
|
+
if (enableVite || !config || !mainWorkerScriptPath) {
|
|
1821
1999
|
return;
|
|
1822
|
-
|
|
1823
|
-
const
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2000
|
+
}
|
|
2001
|
+
const watchRoots = collectWorkerWatchRoots(cwd, config, mainWorkerScriptPath);
|
|
2002
|
+
if (watchRoots.length === 0) {
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
const chokidar = await import("chokidar");
|
|
2006
|
+
const isWindows = process.platform === "win32";
|
|
2007
|
+
const ignoredSegments = ["/node_modules/", "/.git/", "/.devflare/", "/dist/"];
|
|
2008
|
+
const normalizePath = (filePath) => filePath.replace(/\\/g, "/");
|
|
2009
|
+
const isIgnoredPath = (filePath) => {
|
|
2010
|
+
const normalizedPath = normalizePath(filePath);
|
|
2011
|
+
return ignoredSegments.some((segment) => normalizedPath.includes(segment));
|
|
2012
|
+
};
|
|
2013
|
+
let reloadTimeout = null;
|
|
2014
|
+
let reloadInProgress = false;
|
|
2015
|
+
let pendingReloadPath = null;
|
|
2016
|
+
const triggerReload = async (filePath) => {
|
|
2017
|
+
if (reloadInProgress) {
|
|
2018
|
+
pendingReloadPath = filePath;
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2021
|
+
reloadInProgress = true;
|
|
2022
|
+
try {
|
|
2023
|
+
logger?.info(`Worker source changed: ${filePath}`);
|
|
2024
|
+
await bundleMainWorker();
|
|
2025
|
+
await reloadMiniflare(currentDoResult);
|
|
2026
|
+
} catch (error) {
|
|
2027
|
+
logger?.error("Worker source reload failed:", error);
|
|
2028
|
+
} finally {
|
|
2029
|
+
reloadInProgress = false;
|
|
2030
|
+
if (pendingReloadPath) {
|
|
2031
|
+
const nextPath = pendingReloadPath;
|
|
2032
|
+
pendingReloadPath = null;
|
|
2033
|
+
await triggerReload(nextPath);
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
const scheduleReload = (filePath) => {
|
|
2038
|
+
if (reloadTimeout) {
|
|
2039
|
+
clearTimeout(reloadTimeout);
|
|
2040
|
+
}
|
|
2041
|
+
reloadTimeout = setTimeout(() => {
|
|
2042
|
+
triggerReload(filePath);
|
|
2043
|
+
}, 150);
|
|
2044
|
+
};
|
|
2045
|
+
workerSourceWatcher = chokidar.watch(watchRoots, {
|
|
2046
|
+
ignoreInitial: true,
|
|
2047
|
+
usePolling: isWindows,
|
|
2048
|
+
interval: isWindows ? 300 : undefined,
|
|
2049
|
+
awaitWriteFinish: {
|
|
2050
|
+
stabilityThreshold: 100,
|
|
2051
|
+
pollInterval: 50
|
|
2052
|
+
},
|
|
2053
|
+
ignored: (filePath) => isIgnoredPath(filePath)
|
|
2054
|
+
});
|
|
2055
|
+
const onFileEvent = (filePath) => {
|
|
2056
|
+
if (isIgnoredPath(filePath)) {
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
scheduleReload(filePath);
|
|
2060
|
+
};
|
|
2061
|
+
workerSourceWatcher.on("change", onFileEvent);
|
|
2062
|
+
workerSourceWatcher.on("add", onFileEvent);
|
|
2063
|
+
workerSourceWatcher.on("unlink", onFileEvent);
|
|
2064
|
+
workerSourceWatcher.on("ready", () => {
|
|
2065
|
+
logger?.info(`Worker source watcher ready (${watchRoots.length} root(s))`);
|
|
2066
|
+
});
|
|
2067
|
+
workerSourceWatcher.on("error", (error) => {
|
|
2068
|
+
logger?.error("Worker source watcher error:", error);
|
|
2069
|
+
});
|
|
1828
2070
|
}
|
|
1829
2071
|
async function runD1Migrations() {
|
|
1830
2072
|
if (!miniflare || !config?.bindings?.d1)
|
|
@@ -1911,6 +2153,13 @@ function createDevServer(options) {
|
|
|
1911
2153
|
logger?.info("Starting unified dev server...");
|
|
1912
2154
|
config = await loadConfig({ cwd, configFile: configPath });
|
|
1913
2155
|
logger?.debug("Loaded config:", config.name);
|
|
2156
|
+
mainWorkerScriptPath = await resolveMainWorkerScriptPath(cwd, config);
|
|
2157
|
+
if (!enableVite && mainWorkerScriptPath) {
|
|
2158
|
+
logger?.info(`Worker entry detected: ${mainWorkerScriptPath}`);
|
|
2159
|
+
await bundleMainWorker();
|
|
2160
|
+
} else if (!enableVite) {
|
|
2161
|
+
logger?.warn("No local fetch worker entry was found for worker-only mode");
|
|
2162
|
+
}
|
|
1914
2163
|
const remoteCheck = await checkRemoteBindingRequirements(config);
|
|
1915
2164
|
if (remoteCheck.hasRemoteBindings) {
|
|
1916
2165
|
logger?.info("");
|
|
@@ -1961,9 +2210,12 @@ function createDevServer(options) {
|
|
|
1961
2210
|
}
|
|
1962
2211
|
});
|
|
1963
2212
|
doResult = await doBundler.build();
|
|
2213
|
+
currentDoResult = doResult;
|
|
1964
2214
|
await doBundler.watch();
|
|
1965
2215
|
}
|
|
2216
|
+
currentDoResult = doResult;
|
|
1966
2217
|
await startMiniflare(doResult);
|
|
2218
|
+
await startWorkerSourceWatcher();
|
|
1967
2219
|
if (enableVite) {
|
|
1968
2220
|
await startVite();
|
|
1969
2221
|
} else {
|
|
@@ -1977,6 +2229,10 @@ function createDevServer(options) {
|
|
|
1977
2229
|
await doBundler.close();
|
|
1978
2230
|
doBundler = null;
|
|
1979
2231
|
}
|
|
2232
|
+
if (workerSourceWatcher) {
|
|
2233
|
+
await workerSourceWatcher.close();
|
|
2234
|
+
workerSourceWatcher = null;
|
|
2235
|
+
}
|
|
1980
2236
|
if (miniflare) {
|
|
1981
2237
|
await miniflare.dispose();
|
|
1982
2238
|
miniflare = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAA;AAc3D,MAAM,WAAW,gBAAgB;IAChC,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sBAAsB;IACtB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACzB,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,0BAA0B;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,yCAAyC;IACzC,YAAY,IAAI,aAAa,GAAG,IAAI,CAAA;CACpC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAA;AAc3D,MAAM,WAAW,gBAAgB;IAChC,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sBAAsB;IACtB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACzB,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,0BAA0B;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,yCAAyC;IACzC,YAAY,IAAI,aAAa,GAAG,IAAI,CAAA;CACpC;AAmqBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAmuBpE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/workerName.ts
|
|
2
|
+
var workerName = (() => {
|
|
3
|
+
if (typeof __DEVFLARE_WORKER_NAME__ !== "undefined") {
|
|
4
|
+
return __DEVFLARE_WORKER_NAME__;
|
|
5
|
+
}
|
|
6
|
+
if (typeof process !== "undefined" && process.env?.DEVFLARE_WORKER_NAME) {
|
|
7
|
+
return process.env.DEVFLARE_WORKER_NAME;
|
|
8
|
+
}
|
|
9
|
+
return "unknown";
|
|
10
|
+
})();
|
|
11
|
+
|
|
12
|
+
export { workerName };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getContextOrNull
|
|
3
|
+
} from "./index-npc1c8jx.js";
|
|
4
|
+
import {
|
|
5
|
+
bridgeEnv
|
|
6
|
+
} from "./index-ccrh4w3t.js";
|
|
7
|
+
|
|
8
|
+
// src/env.ts
|
|
9
|
+
var testContextEnv = null;
|
|
10
|
+
var testContextDispose = null;
|
|
11
|
+
function __setTestContext(envBindings, dispose) {
|
|
12
|
+
testContextEnv = envBindings;
|
|
13
|
+
testContextDispose = dispose;
|
|
14
|
+
}
|
|
15
|
+
function __clearTestContext() {
|
|
16
|
+
testContextEnv = null;
|
|
17
|
+
testContextDispose = null;
|
|
18
|
+
}
|
|
19
|
+
var env = new Proxy({}, {
|
|
20
|
+
get(_target, prop) {
|
|
21
|
+
if (prop === "dispose") {
|
|
22
|
+
return async () => {
|
|
23
|
+
if (testContextDispose) {
|
|
24
|
+
await testContextDispose();
|
|
25
|
+
__clearTestContext();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const ctx = getContextOrNull();
|
|
30
|
+
if (ctx?.env) {
|
|
31
|
+
return ctx.env[prop];
|
|
32
|
+
}
|
|
33
|
+
if (testContextEnv) {
|
|
34
|
+
return testContextEnv[prop];
|
|
35
|
+
}
|
|
36
|
+
return bridgeEnv[prop];
|
|
37
|
+
},
|
|
38
|
+
has(_target, prop) {
|
|
39
|
+
if (prop === "dispose")
|
|
40
|
+
return true;
|
|
41
|
+
const ctx = getContextOrNull();
|
|
42
|
+
if (ctx?.env) {
|
|
43
|
+
return prop in ctx.env;
|
|
44
|
+
}
|
|
45
|
+
if (testContextEnv) {
|
|
46
|
+
return prop in testContextEnv;
|
|
47
|
+
}
|
|
48
|
+
return prop in bridgeEnv;
|
|
49
|
+
},
|
|
50
|
+
ownKeys(_target) {
|
|
51
|
+
const ctx = getContextOrNull();
|
|
52
|
+
if (ctx?.env) {
|
|
53
|
+
return Reflect.ownKeys(ctx.env);
|
|
54
|
+
}
|
|
55
|
+
if (testContextEnv) {
|
|
56
|
+
return Reflect.ownKeys(testContextEnv);
|
|
57
|
+
}
|
|
58
|
+
return Reflect.ownKeys(bridgeEnv);
|
|
59
|
+
},
|
|
60
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
61
|
+
if (prop === "dispose") {
|
|
62
|
+
return { configurable: true, enumerable: false, writable: false };
|
|
63
|
+
}
|
|
64
|
+
const ctx = getContextOrNull();
|
|
65
|
+
const source = ctx?.env ?? testContextEnv ?? bridgeEnv;
|
|
66
|
+
return Reflect.getOwnPropertyDescriptor(source, prop);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export { __setTestContext, __clearTestContext, env };
|